1 //
2 // BAGEL - Brilliantly Advanced General Electronic Structure Library
3 // Filename: reldvec.cc
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 #include <numeric>
26 #include <src/ci/zfci/reldvec.h>
27 
28 using namespace std;
29 using namespace bagel;
30 
31 template<typename DataType>
RelDvector(shared_ptr<const Space_base> space,const size_t ij)32 RelDvector<DataType>::RelDvector(shared_ptr<const Space_base> space, const size_t ij) : space_(space) {
33   for (auto& isp : space->detmap())
34     dvecs_.emplace(make_pair(isp.second->nelea(), isp.second->neleb()),
35                    make_shared<Dvector<DataType>>(isp.second, ij));
36 }
37 
38 
39 template<typename DataType>
RelDvector(const RelDvector<DataType> & o)40 RelDvector<DataType>::RelDvector(const RelDvector<DataType>& o) : space_(o.space_) {
41   for (auto& i : o.dvecs_)
42     dvecs_.emplace(i.first, i.second->copy());
43 }
44 
45 
46 template<typename DataType>
RelDvector(const vector<shared_ptr<RelDvector<DataType>>> & o)47 RelDvector<DataType>::RelDvector(const vector<shared_ptr<RelDvector<DataType>>>& o) : space_(o.front()->space_) {
48   for (auto& isp : space_->detmap())
49     dvecs_.emplace(make_pair(isp.second->nelea(), isp.second->neleb()), make_shared<Dvector<DataType>>(isp.second, o.size()));
50   int j = 0;
51   for (auto& i : o)
52     set_data(j++, i);
53 }
54 
55 
56 template<typename DataType>
clone() const57 shared_ptr<RelDvector<DataType>> RelDvector<DataType>::clone() const {
58   return make_shared<RelDvector<DataType>>(space_, dvecs_.begin()->second->ij());
59 }
60 
61 
62 template<typename DataType>
copy() const63 shared_ptr<RelDvector<DataType>> RelDvector<DataType>::copy() const {
64   return make_shared<RelDvector<DataType>>(*this);
65 }
66 
67 
68 template<typename DataType>
extract_state(const vector<int> input) const69 shared_ptr<RelDvector<DataType>> RelDvector<DataType>::extract_state(const vector<int> input) const {
70   MapType newdvec;
71   for (auto& i : dvecs_)
72     newdvec.emplace(i.first, i.second->extract_state(input));
73   return make_shared<RelDvector<DataType>>(newdvec, space_);
74 }
75 
76 
77 template<typename DataType>
set_data(const int istate,shared_ptr<const RelDvector<DataType>> o)78 void RelDvector<DataType>::set_data(const int istate, shared_ptr<const RelDvector<DataType>> o) {
79   assert(space_ == o->space_ || o->dvecs_.begin()->second->ij() == 1);
80   auto j = o->dvecs_.begin();
81   for (auto& i : dvecs_) {
82     *i.second->data(istate) = *j->second->data(0);
83     ++j;
84   }
85 }
86 
87 
88 template<typename DataType>
zero()89 void RelDvector<DataType>::zero() {
90   for_each(dvecs_.begin(), dvecs_.end(), [](EleType i) { i.second->zero(); });
91 }
92 
93 
94 template<typename DataType>
size() const95 size_t RelDvector<DataType>::size() const {
96   return accumulate(dvecs_.begin(), dvecs_.end(), 0ull, [](size_t i, const EleType& o) { return i+o.second->size(); });
97 }
98 
99 
100 template<typename DataType>
dot_product(const RelDvector<DataType> & o) const101 DataType RelDvector<DataType>::dot_product(const RelDvector<DataType>& o) const {
102   return inner_product(dvecs_.begin(), dvecs_.end(), o.dvecs_.begin(), DataType(0.0), plus<DataType>(),
103                             [](const EleType& i, const EleType& j) { return i.second->dot_product(*j.second); });
104 }
105 
106 
107 template<typename DataType>
ax_plus_y(const DataType a,const RelDvector<DataType> & o)108 void RelDvector<DataType>::ax_plus_y(const DataType a, const RelDvector<DataType>& o) {
109   auto iter = o.dvecs_.begin();
110   for (auto& i : dvecs_) {
111     assert(i.first == iter->first);
112     i.second->ax_plus_y(a, *iter->second);
113     ++iter;
114   }
115 }
116 
117 
118 template<typename DataType>
split(const int nstart,const int nend) const119 vector<shared_ptr<const RelDvector<DataType>>> RelDvector<DataType>::split(const int nstart, const int nend) const {
120   vector<shared_ptr<const RelDvector<DataType>>> out;
121   for (int i = nstart; i != nend; ++i) {
122     MapType tmp;
123     // copy construct each of them
124     for (auto& j : dvecs_) {
125       vector<shared_ptr<Civector<DataType>>> tmp1 { make_shared<Civector<DataType>>(*j.second->data(i)) };
126       tmp.emplace(j.first, make_shared<Dvector<DataType>>(tmp1));
127     }
128     out.push_back(make_shared<RelDvector<DataType>>(tmp, space_));
129   }
130   return out;
131 }
132 
133 
134 template<typename DataType>
dvec(const vector<int> & conv) const135 vector<shared_ptr<const RelDvector<DataType>>> RelDvector<DataType>::dvec(const vector<int>& conv) const {
136   vector<shared_ptr<const RelDvector<DataType>>> sp = split();
137   vector<shared_ptr<const RelDvector<DataType>>> out;
138   auto c = conv.begin();
139   for (auto& i : sp)
140     if (*c++ == 0) out.push_back(i);
141     else out.push_back(nullptr);
142   return out;
143 }
144 
145 
146 template<typename DataType>
scale(const DataType & a)147 void RelDvector<DataType>::scale(const DataType& a) {
148   for_each(dvecs_.begin(), dvecs_.end(), [&a](EleType i) { i.second->scale(a); });
149 }
150 
151 
152 template<typename DataType>
orthog(list<shared_ptr<const RelDvector<DataType>>> c)153 double RelDvector<DataType>::orthog(list<shared_ptr<const RelDvector<DataType>>> c) {
154   for (auto& iter : c)
155     project_out(iter);
156   return normalize();
157 }
158 
159 
160 template<typename DataType>
orthog(shared_ptr<const RelDvector<DataType>> o)161 double RelDvector<DataType>::orthog(shared_ptr<const RelDvector<DataType>> o) {
162   return orthog(list<shared_ptr<const RelDvector<DataType>>>{o});
163 }
164 
165 
166 template<typename DataType>
normalize()167 double RelDvector<DataType>::normalize() {
168   const double norm = this->norm();
169   const double scal = (norm*norm<1.0e-60 ? 0.0 : 1.0/norm);
170   scale(DataType(scal));
171   return norm;
172 }
173 
174 
175 template<typename DataType>
print(double thresh) const176 void RelDvector<DataType>::print(double thresh) const {
177   for (auto& i : dvecs_)
178     i.second->print(thresh);
179 }
180 
181 
182 template<typename DataType>
synchronize()183 void RelDvector<DataType>::synchronize() {
184 #ifdef HAVE_MPI_H
185   for (auto& i : dvecs_)
186     i.second->synchronize();
187 #endif
188 }
189 
190 
191 template class bagel::RelDvector<double>;
192 template class bagel::RelDvector<complex<double>>;
193 
194 BOOST_CLASS_EXPORT_IMPLEMENT(RelDvector<double>)
195 BOOST_CLASS_EXPORT_IMPLEMENT(RelDvector<complex<double>>)
196