1 //
2 // BAGEL - Brilliantly Advanced General Electronic Structure Library
3 // Filename: determinants.h
4 // Copyright (C) 2014 Toru Shiozaki
5 //
6 // Author: Toru Shiozaki <shiozaki@northwestern.edu>
7 // Maintainer: Shiozaki group
8 //
9 // This file is part of the BAGEL package.
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program 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 General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 //
24 
25 
26 #ifndef __SRC_CIUTIL_DETERMINANTS_BASE_H
27 #define __SRC_CIUTIL_DETERMINANTS_BASE_H
28 
29 #include <src/ci/ciutil/ciblock.h>
30 #include <src/ci/ciutil/cistringspace.h>
31 
32 namespace bagel {
33 
34 template <class StringType>
35 class Determinants_base {
36   protected:
37     std::vector<std::shared_ptr<const CIBlockInfo<StringType>>> blockinfo_;
38 
39     std::shared_ptr<const CIStringSet<StringType>> alphaspaces_;
40     std::shared_ptr<const CIStringSet<StringType>> betaspaces_;
41 
42     bool compress_;
43     size_t size_;
44 
45     // configuration list i^dagger j compressed
46     std::shared_ptr<const StringMap> phia_;
47     std::shared_ptr<const StringMap> phib_;
48 
49     // configuration list i^dagger j uncompressed
50     std::shared_ptr<const StringMap> phia_uncompressed_;
51     std::shared_ptr<const StringMap> phib_uncompressed_;
52 
53     // configuration list i^dagger
54     std::shared_ptr<const StringMap> phiupa_;
55     std::shared_ptr<const StringMap> phiupb_;
56 
57     // configuration list i
58     std::shared_ptr<const StringMap> phidowna_;
59     std::shared_ptr<const StringMap> phidownb_;
60 
blockinfo(const int i)61     const std::shared_ptr<const CIBlockInfo<StringType>>& blockinfo(const int i) const { return blockinfo_[i]; }
62 
63   private:
64     friend class boost::serialization::access;
65     template<class Archive>
serialize(Archive & ar,const unsigned int)66     void serialize(Archive& ar, const unsigned int) {
67       ar & blockinfo_ & alphaspaces_ & betaspaces_ & phia_ & phib_ & phia_uncompressed_ & phib_uncompressed_
68          & phiupa_ & phiupb_ & phidowna_ & phidownb_;
69     }
70 
71   public:
Determinants_base()72     Determinants_base() { }
~Determinants_base()73     virtual ~Determinants_base() { }
74 
75     // some functions to retrieve members of CIBlockInfo<StringType>
76     // block-independent members
norb()77     int norb() const { return alphaspaces_->norb(); }
nelea()78     int nelea() const { return alphaspaces_->nele(); }
neleb()79     int neleb() const { return betaspaces_->nele(); }
nspin()80     int nspin() const { return nelea() - neleb(); }
81     // block dependent members
lena()82     size_t lena() const { return alphaspaces_->size(); }
lenb()83     size_t lenb() const { return betaspaces_->size(); }
size()84     size_t size() const { return size_; }
85 
86     template<int spin>
sign(const std::bitset<nbit__> & bit,const size_t pos)87     int sign(const std::bitset<nbit__>& bit, const size_t pos) const {
88       auto iter = std::find_if(blockinfo_.begin(), blockinfo_.end(), [](const std::shared_ptr<const CIBlockInfo<StringType>>& o){ return !o->empty(); });
89       return (*iter)->template sign<spin>(bit, pos);
90     }
91 
sign(const std::bitset<nbit__> & bit,const size_t pos0,const size_t pos1)92     static int sign(const std::bitset<nbit__>& bit, const size_t pos0, const size_t pos1) {
93       return CIBlockInfo<StringType>::sign(bit, pos0, pos1);
94     }
95 
96     template <int spin>
lexical_zero(const std::bitset<nbit__> & bit)97     size_t lexical_zero(const std::bitset<nbit__>& bit)   const { return (spin == 0 ? alphaspaces_ : betaspaces_)->lexical_zero(bit); }
98     template <int spin>
lexical_offset(const std::bitset<nbit__> & bit)99     size_t lexical_offset(const std::bitset<nbit__>& bit) const { return (spin == 0 ? alphaspaces_ : betaspaces_)->lexical_offset(bit); }
100 
blockinfo()101     const std::vector<std::shared_ptr<const CIBlockInfo<StringType>>>& blockinfo() const { return blockinfo_; }
blockinfo(std::shared_ptr<const StringType> beta,std::shared_ptr<const StringType> alpha)102     std::shared_ptr<const CIBlockInfo<StringType>> blockinfo(std::shared_ptr<const StringType> beta, std::shared_ptr<const StringType> alpha) const {
103       auto iter = std::find_if(blockinfo_.begin(), blockinfo_.end(),
104         [&alpha, &beta] (const std::shared_ptr<const CIBlockInfo<StringType>>& o) {
105           return (o->empty() ? false :
106             o->stringsa()->matches(alpha) &&
107             o->stringsb()->matches(beta));
108       });
109       return (iter != blockinfo_.end() ? *iter : nullptr);
110     }
stringspacea()111     const std::shared_ptr<const CIStringSet<StringType>>& stringspacea() const { return alphaspaces_; }
stringspaceb()112     const std::shared_ptr<const CIStringSet<StringType>>& stringspaceb() const { return betaspaces_; }
113 
string_bits_a(const size_t i)114     const std::bitset<nbit__>& string_bits_a(const size_t i) const { return alphaspaces_->strings(i); }
string_bits_b(const size_t i)115     const std::bitset<nbit__>& string_bits_b(const size_t i) const { return betaspaces_->strings(i); }
string_bits_a()116     const std::vector<std::bitset<nbit__>>& string_bits_a() const { return alphaspaces_->strings(); }
string_bits_b()117     const std::vector<std::bitset<nbit__>>& string_bits_b() const { return betaspaces_->strings(); }
118 
119     bool operator==(const Determinants_base<StringType>& o) const
120       { return (norb() == o.norb() && nelea() == o.nelea() && neleb() == o.neleb() && compress_ == o.compress_); }
121 
compress()122     bool compress() const { return compress_; }
123 
124     // single index goes to normal versions (compressed based on compress_)
phia(const int i)125     const std::vector<DetMap>& phia(const int i) const { return phia_->data(i); }
phib(const int i)126     const std::vector<DetMap>& phib(const int i) const { return phib_->data(i); }
127 
128     // two indices goes to uncompressed versions
phia(const int i,const int j)129     const std::vector<DetMap>& phia(const int i, const int j) const { return phia_uncompressed_->data(i + j*norb()); }
phib(const int i,const int j)130     const std::vector<DetMap>& phib(const int i, const int j) const { return phib_uncompressed_->data(i + j*norb()); }
131 
phiupa(const int i)132     const std::vector<DetMap>& phiupa(const int i) const { return phiupa_->data(i); }
phiupb(const int i)133     const std::vector<DetMap>& phiupb(const int i) const { return phiupb_->data(i); }
phidowna(const int i)134     const std::vector<DetMap>& phidowna(const int i) const { return phidowna_->data(i); }
phidownb(const int i)135     const std::vector<DetMap>& phidownb(const int i) const { return phidownb_->data(i); }
set_phiupa(std::shared_ptr<const StringMap> o)136     void set_phiupa(std::shared_ptr<const StringMap> o) { phiupa_ = o; }
set_phiupb(std::shared_ptr<const StringMap> o)137     void set_phiupb(std::shared_ptr<const StringMap> o) { phiupb_ = o; }
set_phidowna(std::shared_ptr<const StringMap> o)138     void set_phidowna(std::shared_ptr<const StringMap> o) { phidowna_ = o; }
set_phidownb(std::shared_ptr<const StringMap> o)139     void set_phidownb(std::shared_ptr<const StringMap> o) { phidownb_ = o; }
140 
141 };
142 
link(std::shared_ptr<DetClass> mdet,std::shared_ptr<DetClass> odet)143 template<int spin, typename StringType, class DetClass> void link(std::shared_ptr<DetClass> mdet, std::shared_ptr<DetClass> odet) {
144   std::shared_ptr<DetClass> plusdet;
145   std::shared_ptr<DetClass> det;
146 
147   const int de = spin == 0 ? mdet->nelea() - odet->nelea() : mdet->neleb() - odet->neleb();
148   if      (de ==  1) std::tie(det, plusdet) = std::make_pair(odet, mdet);
149   else if (de == -1) std::tie(det, plusdet) = std::make_pair(mdet, odet);
150   else throw std::logic_error("Determinants::link failed");
151 
152   const int fac = (spin == 1 && (mdet->nelea() & 1)) ? -1 : 1;
153   CIStringSpace<CIStringSet<StringType>> space{spin==0?mdet->stringspacea():mdet->stringspaceb(),
154                                                spin==0?odet->stringspacea():odet->stringspaceb()};
155   space.build_linkage(fac);
156 
157   // finally link
158   if (spin == 0) {
159     plusdet->set_remalpha(det);
160     plusdet->set_phidowna(space.phidown(plusdet->stringspacea()));
161 
162     det->set_addalpha(plusdet);
163     det->set_phiupa(space.phiup(det->stringspacea()));
164   } else {
165     plusdet->set_rembeta(det);
166     plusdet->set_phidownb(space.phidown(plusdet->stringspaceb()));
167 
168     det->set_addbeta(plusdet);
169     det->set_phiupb(space.phiup(det->stringspaceb()));
170   }
171 }
172 
173 }
174 
175 extern template class bagel::Determinants_base<bagel::FCIString>;
176 extern template class bagel::Determinants_base<bagel::RASString>;
177 
178 #include <src/util/archive.h>
179 BOOST_CLASS_EXPORT_KEY(bagel::Determinants_base<bagel::FCIString>)
180 BOOST_CLASS_EXPORT_KEY(bagel::Determinants_base<bagel::RASString>)
181 
182 #endif
183