pairiter.h

00001 //
00002 // pairiter.h
00003 //
00004 // Copyright (C) 2004 Edward Valeev
00005 //
00006 // Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
00007 // Maintainer: EV
00008 //
00009 // This file is part of the SC Toolkit.
00010 //
00011 // The SC Toolkit is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Library General Public License as published by
00013 // the Free Software Foundation; either version 2, or (at your option)
00014 // any later version.
00015 //
00016 // The SC Toolkit is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 // GNU Library General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Library General Public License
00022 // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
00024 //
00025 // The U.S. Government is granted a limited license as per AL 91-7.
00026 //
00027 
00028 #ifndef _chemistry_qc_mbptr12_pairiter_h
00029 #define _chemistry_qc_mbptr12_pairiter_h
00030 
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034 
00035 #include <stdexcept>
00036 #include <chemistry/qc/mbptr12/moindexspace.h>
00037 
00038 namespace sc {
00039 
00041 class MOPairIter : public RefCount {
00042 
00043   protected:
00044     bool i_eq_j_;
00045     int ni_;
00046     int nj_;
00047     int i_;
00048     int j_;
00049     int nij_;
00050     int ij_;
00051 
00052   public:
00054     MOPairIter(const Ref<MOIndexSpace>& space_i, const Ref<MOIndexSpace>& space_j);
00055     virtual ~MOPairIter();
00056 
00058     virtual void start(const int first_ij =0) =0;
00060     virtual void next() =0;
00062     virtual operator int() const =0;
00063 
00065     int ni() const { return ni_; }
00067     int nj() const { return nj_; }
00069     int i() const { return i_; }
00071     int j() const { return j_; }
00073     int nij() const { return nij_; }
00075     int ij() const { return ij_; }
00076 };
00077 
00078 
00081 class SpatialMOPairIter : public MOPairIter {
00082 
00083 public:
00085   SpatialMOPairIter(const Ref<MOIndexSpace>& space_i, const Ref<MOIndexSpace>& space_j) :
00086     MOPairIter(space_i,space_j) {};
00087   ~SpatialMOPairIter() {};
00088 
00090   virtual int nij_aa() const =0;
00092   virtual int nij_ab() const =0;
00095   virtual int ij_aa() const =0;
00097   virtual int ij_ab() const =0;
00099   virtual int ij_ba() const =0;
00100 };
00101 
00105 class SpatialMOPairIter_eq : public SpatialMOPairIter {
00106 
00107   int nij_aa_;
00108   int nij_ab_;
00109   int ij_aa_;
00110   int ij_ab_;
00111   int ji_ab_;
00112 
00113   void init_ij(const int ij) {
00114 
00115     if (ij<0)
00116       throw std::runtime_error("SpatialMOPairIter_eq::start() -- argument ij out of range");
00117 
00118     ij_ = 0;
00119     const int renorm_ij = ij%nij_;
00120 
00121     i_ = (int)floor((sqrt(1.0+8.0*renorm_ij) - 1.0)/2.0);
00122     const int i_off = i_*(i_+1)/2;
00123     j_ = renorm_ij - i_off;
00124 
00125     ij_ab_ = i_*nj_ + j_;
00126     ji_ab_ = j_*ni_ + i_;
00127 
00128     if (i_ != 0) {
00129       const int i_off = i_*(i_-1)/2;
00130       ij_aa_ = i_off + j_;
00131       if (i_ == j_)
00132         ij_aa_--;
00133     }
00134     else {
00135       ij_aa_ = -1;
00136     }
00137   };
00138   
00139   void inc_ij() {
00140     ij_++;
00141     if (ij_ab_ == nij_ab_-1) {
00142       i_ = 0;
00143       j_ = 0;
00144       ij_ab_ = 0;
00145       ji_ab_ = 0;
00146       ij_aa_ = -1;
00147     }
00148     else {
00149       if (i_ == j_) {
00150         i_++;
00151         j_ = 0;
00152         ji_ab_ = i_;
00153         ij_ab_ = i_*nj_;
00154         ij_aa_ += (i_ == j_) ? 0 : 1;
00155       }
00156       else {
00157         j_++;
00158         ji_ab_ += ni_;
00159         ij_ab_++;
00160         ij_aa_ += (i_ == j_) ? 0 : 1;
00161       }
00162     }
00163   };
00164 
00165 public:
00167   SpatialMOPairIter_eq(const Ref<MOIndexSpace>& space1);
00168   ~SpatialMOPairIter_eq();
00169 
00171   void start(const int ij_offset=0)
00172   {
00173     ij_ = 0;
00174     init_ij(ij_offset);
00175   };
00176   
00178   void next() {
00179     inc_ij();
00180   };
00182   operator int() const { return (nij_ > ij_);};
00183 
00185   int nij_aa() const { return nij_aa_; }
00187   int nij_ab() const { return nij_ab_; }
00190   int ij_aa() const { return (i_ == j_) ? -1 : ij_aa_; }
00192   int ij_ab() const { return ij_ab_; }
00194   int ij_ba() const { return ji_ab_; }
00195 };
00196 
00197 
00200 class SpatialMOPairIter_neq : public SpatialMOPairIter {
00201 
00202   int IJ_;
00203 
00204   void init_ij(const int ij) {
00205 
00206     if (ij<0)
00207       throw std::runtime_error("SpatialMOPairIter_neq::start() -- argument ij out of range");
00208 
00209     IJ_ = 0;
00210     const int renorm_ij = ij%nij_;
00211 
00212     i_ = renorm_ij/nj_;
00213     j_ = renorm_ij - i_*nj_;
00214 
00215     IJ_ = i_*nj_ + j_;
00216 
00217   };
00218 
00219   void inc_ij() {
00220     ij_++;
00221     IJ_++;
00222     if (IJ_ == nij_) {
00223       i_ = 0;
00224       j_ = 0;
00225       IJ_ = 0;
00226     }
00227     else {
00228       if (j_ == nj_-1) {
00229         i_++;
00230         j_ = 0;
00231       }
00232       else {
00233         j_++;
00234       }
00235     }
00236   };
00237 
00238 public:
00240   SpatialMOPairIter_neq(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
00241   ~SpatialMOPairIter_neq();
00242 
00244   void start(const int ij_offset=0)
00245   {
00246     ij_ = 0;
00247     init_ij(ij_offset);
00248   };
00249 
00251   void next() {
00252     inc_ij();
00253   };
00255   operator int() const { return (nij_ > ij_);};
00256 
00258   int nij_aa() const { return nij_; }
00260   int nij_ab() const { return nij_; }
00262   int ij_aa() const { return IJ_; }
00264   int ij_ab() const { return IJ_; }
00266   int ij_ba() const { return IJ_; }
00267 };
00268 
00269 
00272 class MOPairIterFactory {
00273 
00274 public:
00275   MOPairIterFactory() {}
00276   ~MOPairIterFactory() {}
00277 
00279   Ref<SpatialMOPairIter> mopairiter(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
00281   RefSCDimension scdim_aa(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
00283   RefSCDimension scdim_ab(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
00284 };
00285 
00286 }
00287   
00288 #endif
00289 
00290 // Local Variables:
00291 // mode: c++
00292 // c-file-style: "ETS"
00293 // End:

Generated at Mon Dec 3 23:23:40 2007 for MPQC 2.3.1 using the documentation package Doxygen 1.5.2.