| [0b990d] | 1 | //
 | 
|---|
 | 2 | // pairiter.h
 | 
|---|
 | 3 | //
 | 
|---|
 | 4 | // Copyright (C) 2004 Edward Valeev
 | 
|---|
 | 5 | //
 | 
|---|
 | 6 | // Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
 | 
|---|
 | 7 | // Maintainer: EV
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | // This file is part of the SC Toolkit.
 | 
|---|
 | 10 | //
 | 
|---|
 | 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
 | 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
 | 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
 | 14 | // any later version.
 | 
|---|
 | 15 | //
 | 
|---|
 | 16 | // The SC Toolkit is distributed in the hope that it will be useful,
 | 
|---|
 | 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
 | 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
 | 19 | // GNU Library General Public License for more details.
 | 
|---|
 | 20 | //
 | 
|---|
 | 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
 | 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
 | 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
 | 24 | //
 | 
|---|
 | 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
 | 26 | //
 | 
|---|
 | 27 | 
 | 
|---|
 | 28 | #ifndef _chemistry_qc_mbptr12_pairiter_h
 | 
|---|
 | 29 | #define _chemistry_qc_mbptr12_pairiter_h
 | 
|---|
 | 30 | 
 | 
|---|
 | 31 | #ifdef __GNUC__
 | 
|---|
 | 32 | #pragma interface
 | 
|---|
 | 33 | #endif
 | 
|---|
 | 34 | 
 | 
|---|
 | 35 | #include <stdexcept>
 | 
|---|
 | 36 | #include <chemistry/qc/mbptr12/moindexspace.h>
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 | namespace sc {
 | 
|---|
 | 39 | 
 | 
|---|
 | 40 | /** MOPairIter gives the ordering of orbital pairs */
 | 
|---|
 | 41 | class MOPairIter : public RefCount {
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 |   protected:
 | 
|---|
 | 44 |     bool i_eq_j_;
 | 
|---|
 | 45 |     int ni_;
 | 
|---|
 | 46 |     int nj_;
 | 
|---|
 | 47 |     int i_;
 | 
|---|
 | 48 |     int j_;
 | 
|---|
 | 49 |     int nij_;
 | 
|---|
 | 50 |     int ij_;
 | 
|---|
 | 51 | 
 | 
|---|
 | 52 |   public:
 | 
|---|
 | 53 |     /// Initialize an iterator for the given MO spaces.
 | 
|---|
 | 54 |     MOPairIter(const Ref<MOIndexSpace>& space_i, const Ref<MOIndexSpace>& space_j);
 | 
|---|
 | 55 |     virtual ~MOPairIter();
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 |     /// Start the iteration.
 | 
|---|
 | 58 |     virtual void start(const int first_ij =0) =0;
 | 
|---|
 | 59 |     /// Move to the next pair.
 | 
|---|
 | 60 |     virtual void next() =0;
 | 
|---|
 | 61 |     /// Returns nonzero if the iterator currently hold valid data.
 | 
|---|
 | 62 |     virtual operator int() const =0;
 | 
|---|
 | 63 | 
 | 
|---|
 | 64 |     /// Returns the number of functions in space i.
 | 
|---|
 | 65 |     int ni() const { return ni_; }
 | 
|---|
 | 66 |     /// Returns the number of functions in space j.
 | 
|---|
 | 67 |     int nj() const { return nj_; }
 | 
|---|
 | 68 |     /// Returns index i.
 | 
|---|
 | 69 |     int i() const { return i_; }
 | 
|---|
 | 70 |     /// Returns index j.
 | 
|---|
 | 71 |     int j() const { return j_; }
 | 
|---|
 | 72 |     /// Returns the number of pair combinations for this iterator
 | 
|---|
 | 73 |     int nij() const { return nij_; }
 | 
|---|
 | 74 |     /// Returns the current iteration
 | 
|---|
 | 75 |     int ij() const { return ij_; }
 | 
|---|
 | 76 | };
 | 
|---|
 | 77 | 
 | 
|---|
 | 78 | 
 | 
|---|
 | 79 | /** SpatialMOPairIter gives the ordering of pairs of spatial orbitals.
 | 
|---|
 | 80 |     Different spin cases appear. */
 | 
|---|
 | 81 | class SpatialMOPairIter : public MOPairIter {
 | 
|---|
 | 82 | 
 | 
|---|
 | 83 | public:
 | 
|---|
 | 84 |   /// Initialize a spatial pair iterator for the given MO spaces.
 | 
|---|
 | 85 |   SpatialMOPairIter(const Ref<MOIndexSpace>& space_i, const Ref<MOIndexSpace>& space_j) :
 | 
|---|
 | 86 |     MOPairIter(space_i,space_j) {};
 | 
|---|
 | 87 |   ~SpatialMOPairIter() {};
 | 
|---|
 | 88 | 
 | 
|---|
 | 89 |   /// Returns the number of functions in alpha-alpha space.
 | 
|---|
 | 90 |   virtual int nij_aa() const =0;
 | 
|---|
 | 91 |   /// Returns the number of functions in alpha-beta space.
 | 
|---|
 | 92 |   virtual int nij_ab() const =0;
 | 
|---|
 | 93 |   /** Returns compound index ij for alpha-alpha case. If the combintaion is
 | 
|---|
 | 94 |       not allowed then return -1 */
 | 
|---|
 | 95 |   virtual int ij_aa() const =0;
 | 
|---|
 | 96 |   /// Returns compound index ij for alpha-beta case
 | 
|---|
 | 97 |   virtual int ij_ab() const =0;
 | 
|---|
 | 98 |   /// Returns compound index ij for beta-alpha case
 | 
|---|
 | 99 |   virtual int ij_ba() const =0;
 | 
|---|
 | 100 | };
 | 
|---|
 | 101 | 
 | 
|---|
 | 102 | /** SpatialMOPairIter_eq gives the ordering of same-spin and different-spin orbital pairs
 | 
|---|
 | 103 |     if both orbitals of the pairs are from the same space.
 | 
|---|
 | 104 |     It iterates over all i >= j combinations (total of (ni_+1)*(ni_+2)/2 pairs). */
 | 
|---|
 | 105 | class SpatialMOPairIter_eq : public SpatialMOPairIter {
 | 
|---|
 | 106 | 
 | 
|---|
 | 107 |   int nij_aa_;
 | 
|---|
 | 108 |   int nij_ab_;
 | 
|---|
 | 109 |   int ij_aa_;
 | 
|---|
 | 110 |   int ij_ab_;
 | 
|---|
 | 111 |   int ji_ab_;
 | 
|---|
 | 112 | 
 | 
|---|
 | 113 |   void init_ij(const int ij) {
 | 
|---|
 | 114 | 
 | 
|---|
 | 115 |     if (ij<0)
 | 
|---|
 | 116 |       throw std::runtime_error("SpatialMOPairIter_eq::start() -- argument ij out of range");
 | 
|---|
 | 117 | 
 | 
|---|
 | 118 |     ij_ = 0;
 | 
|---|
 | 119 |     const int renorm_ij = ij%nij_;
 | 
|---|
 | 120 | 
 | 
|---|
 | 121 |     i_ = (int)floor((sqrt(1.0+8.0*renorm_ij) - 1.0)/2.0);
 | 
|---|
 | 122 |     const int i_off = i_*(i_+1)/2;
 | 
|---|
 | 123 |     j_ = renorm_ij - i_off;
 | 
|---|
 | 124 | 
 | 
|---|
 | 125 |     ij_ab_ = i_*nj_ + j_;
 | 
|---|
 | 126 |     ji_ab_ = j_*ni_ + i_;
 | 
|---|
 | 127 | 
 | 
|---|
 | 128 |     if (i_ != 0) {
 | 
|---|
 | 129 |       const int i_off = i_*(i_-1)/2;
 | 
|---|
 | 130 |       ij_aa_ = i_off + j_;
 | 
|---|
 | 131 |       if (i_ == j_)
 | 
|---|
 | 132 |         ij_aa_--;
 | 
|---|
 | 133 |     }
 | 
|---|
 | 134 |     else {
 | 
|---|
 | 135 |       ij_aa_ = -1;
 | 
|---|
 | 136 |     }
 | 
|---|
 | 137 |   };
 | 
|---|
 | 138 |   
 | 
|---|
 | 139 |   void inc_ij() {
 | 
|---|
 | 140 |     ij_++;
 | 
|---|
 | 141 |     if (ij_ab_ == nij_ab_-1) {
 | 
|---|
 | 142 |       i_ = 0;
 | 
|---|
 | 143 |       j_ = 0;
 | 
|---|
 | 144 |       ij_ab_ = 0;
 | 
|---|
 | 145 |       ji_ab_ = 0;
 | 
|---|
 | 146 |       ij_aa_ = -1;
 | 
|---|
 | 147 |     }
 | 
|---|
 | 148 |     else {
 | 
|---|
 | 149 |       if (i_ == j_) {
 | 
|---|
 | 150 |         i_++;
 | 
|---|
 | 151 |         j_ = 0;
 | 
|---|
 | 152 |         ji_ab_ = i_;
 | 
|---|
 | 153 |         ij_ab_ = i_*nj_;
 | 
|---|
 | 154 |         ij_aa_ += (i_ == j_) ? 0 : 1;
 | 
|---|
 | 155 |       }
 | 
|---|
 | 156 |       else {
 | 
|---|
 | 157 |         j_++;
 | 
|---|
 | 158 |         ji_ab_ += ni_;
 | 
|---|
 | 159 |         ij_ab_++;
 | 
|---|
 | 160 |         ij_aa_ += (i_ == j_) ? 0 : 1;
 | 
|---|
 | 161 |       }
 | 
|---|
 | 162 |     }
 | 
|---|
 | 163 |   };
 | 
|---|
 | 164 | 
 | 
|---|
 | 165 | public:
 | 
|---|
 | 166 |   /// Initialize an iterator for the given MO spaces.
 | 
|---|
 | 167 |   SpatialMOPairIter_eq(const Ref<MOIndexSpace>& space1);
 | 
|---|
 | 168 |   ~SpatialMOPairIter_eq();
 | 
|---|
 | 169 | 
 | 
|---|
 | 170 |   /// Initialize the iterator assuming that iteration will start with pair ij_offset
 | 
|---|
 | 171 |   void start(const int ij_offset=0)
 | 
|---|
 | 172 |   {
 | 
|---|
 | 173 |     ij_ = 0;
 | 
|---|
 | 174 |     init_ij(ij_offset);
 | 
|---|
 | 175 |   };
 | 
|---|
 | 176 |   
 | 
|---|
 | 177 |   /// Move to the next pair.
 | 
|---|
 | 178 |   void next() {
 | 
|---|
 | 179 |     inc_ij();
 | 
|---|
 | 180 |   };
 | 
|---|
 | 181 |   /// Returns nonzero if the iterator currently hold valid data.
 | 
|---|
 | 182 |   operator int() const { return (nij_ > ij_);};
 | 
|---|
 | 183 | 
 | 
|---|
 | 184 |   /// Returns the number of functions in alpha-alpha space.
 | 
|---|
 | 185 |   int nij_aa() const { return nij_aa_; }
 | 
|---|
 | 186 |   /// Returns the number of functions in alpha-beta space.
 | 
|---|
 | 187 |   int nij_ab() const { return nij_ab_; }
 | 
|---|
 | 188 |   /** Returns compound index ij for alpha-alpha case. The i == j
 | 
|---|
 | 189 |       combination doesn't make sense, so ij_aa() will return -1 for such pairs. */
 | 
|---|
 | 190 |   int ij_aa() const { return (i_ == j_) ? -1 : ij_aa_; }
 | 
|---|
 | 191 |   /// Returns compound index ij for alpha-beta case
 | 
|---|
 | 192 |   int ij_ab() const { return ij_ab_; }
 | 
|---|
 | 193 |   /// Returns compound index ij for beta-alpha case
 | 
|---|
 | 194 |   int ij_ba() const { return ji_ab_; }
 | 
|---|
 | 195 | };
 | 
|---|
 | 196 | 
 | 
|---|
 | 197 | 
 | 
|---|
 | 198 | /** SpatialMOPairIter_neq gives the ordering of pairs of spatial orbitals from different spaces.
 | 
|---|
 | 199 |     It iterates over all ij combinations (total of ni_*nj_ pairs). */
 | 
|---|
 | 200 | class SpatialMOPairIter_neq : public SpatialMOPairIter {
 | 
|---|
 | 201 | 
 | 
|---|
 | 202 |   int IJ_;
 | 
|---|
 | 203 | 
 | 
|---|
 | 204 |   void init_ij(const int ij) {
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 |     if (ij<0)
 | 
|---|
 | 207 |       throw std::runtime_error("SpatialMOPairIter_neq::start() -- argument ij out of range");
 | 
|---|
 | 208 | 
 | 
|---|
 | 209 |     IJ_ = 0;
 | 
|---|
 | 210 |     const int renorm_ij = ij%nij_;
 | 
|---|
 | 211 | 
 | 
|---|
 | 212 |     i_ = renorm_ij/nj_;
 | 
|---|
 | 213 |     j_ = renorm_ij - i_*nj_;
 | 
|---|
 | 214 | 
 | 
|---|
 | 215 |     IJ_ = i_*nj_ + j_;
 | 
|---|
 | 216 | 
 | 
|---|
 | 217 |   };
 | 
|---|
 | 218 | 
 | 
|---|
 | 219 |   void inc_ij() {
 | 
|---|
 | 220 |     ij_++;
 | 
|---|
 | 221 |     IJ_++;
 | 
|---|
 | 222 |     if (IJ_ == nij_) {
 | 
|---|
 | 223 |       i_ = 0;
 | 
|---|
 | 224 |       j_ = 0;
 | 
|---|
 | 225 |       IJ_ = 0;
 | 
|---|
 | 226 |     }
 | 
|---|
 | 227 |     else {
 | 
|---|
 | 228 |       if (j_ == nj_-1) {
 | 
|---|
 | 229 |         i_++;
 | 
|---|
 | 230 |         j_ = 0;
 | 
|---|
 | 231 |       }
 | 
|---|
 | 232 |       else {
 | 
|---|
 | 233 |         j_++;
 | 
|---|
 | 234 |       }
 | 
|---|
 | 235 |     }
 | 
|---|
 | 236 |   };
 | 
|---|
 | 237 | 
 | 
|---|
 | 238 | public:
 | 
|---|
 | 239 |   /// Initialize an iterator for the given MO spaces.
 | 
|---|
 | 240 |   SpatialMOPairIter_neq(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
 | 
|---|
 | 241 |   ~SpatialMOPairIter_neq();
 | 
|---|
 | 242 | 
 | 
|---|
 | 243 |   /// Initialize the iterator assuming that iteration will start with pair ij_offset
 | 
|---|
 | 244 |   void start(const int ij_offset=0)
 | 
|---|
 | 245 |   {
 | 
|---|
 | 246 |     ij_ = 0;
 | 
|---|
 | 247 |     init_ij(ij_offset);
 | 
|---|
 | 248 |   };
 | 
|---|
 | 249 | 
 | 
|---|
 | 250 |   /// Move to the next pair.
 | 
|---|
 | 251 |   void next() {
 | 
|---|
 | 252 |     inc_ij();
 | 
|---|
 | 253 |   };
 | 
|---|
 | 254 |   /// Returns nonzero if the iterator currently hold valid data.
 | 
|---|
 | 255 |   operator int() const { return (nij_ > ij_);};
 | 
|---|
 | 256 | 
 | 
|---|
 | 257 |   /// Returns the number of functions in alpha-alpha space.
 | 
|---|
 | 258 |   int nij_aa() const { return nij_; }
 | 
|---|
 | 259 |   /// Returns the number of functions in alpha-beta space.
 | 
|---|
 | 260 |   int nij_ab() const { return nij_; }
 | 
|---|
 | 261 |   /// Returns compound index ij for alpha-alpha case
 | 
|---|
 | 262 |   int ij_aa() const { return IJ_; }
 | 
|---|
 | 263 |   /// Returns compound index ij for alpha-beta case
 | 
|---|
 | 264 |   int ij_ab() const { return IJ_; }
 | 
|---|
 | 265 |   /// Returns compound index ij for beta-alpha case
 | 
|---|
 | 266 |   int ij_ba() const { return IJ_; }
 | 
|---|
 | 267 | };
 | 
|---|
 | 268 | 
 | 
|---|
 | 269 | 
 | 
|---|
 | 270 |   /** This class produces MOPairIter objects */
 | 
|---|
 | 271 | 
 | 
|---|
 | 272 | class MOPairIterFactory {
 | 
|---|
 | 273 | 
 | 
|---|
 | 274 | public:
 | 
|---|
 | 275 |   MOPairIterFactory() {}
 | 
|---|
 | 276 |   ~MOPairIterFactory() {}
 | 
|---|
 | 277 | 
 | 
|---|
 | 278 |   /// Constructs an appropriate MOPairIter object
 | 
|---|
 | 279 |   Ref<SpatialMOPairIter> mopairiter(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
 | 
|---|
 | 280 |   /// Constructs an appropriate RefSCDimension object for same-spin pair
 | 
|---|
 | 281 |   RefSCDimension scdim_aa(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
 | 
|---|
 | 282 |   /// Constructs an appropriate RefSCDimension object for different-spin pair
 | 
|---|
 | 283 |   RefSCDimension scdim_ab(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
 | 
|---|
 | 284 | };
 | 
|---|
 | 285 | 
 | 
|---|
 | 286 | }
 | 
|---|
 | 287 |   
 | 
|---|
 | 288 | #endif
 | 
|---|
 | 289 | 
 | 
|---|
 | 290 | // Local Variables:
 | 
|---|
 | 291 | // mode: c++
 | 
|---|
 | 292 | // c-file-style: "ETS"
 | 
|---|
 | 293 | // End:
 | 
|---|