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