VMPS++
Loading...
Searching...
No Matches
DmrgPivotVector.h
Go to the documentation of this file.
1#ifndef DMRGPIVOTVECTOR
2#define DMRGPIVOTVECTOR
3
4#include "tensors/DmrgContractions.h" // for contract_AA
5#include "termcolor.hpp"
6//include "numeric_limits.h"
7
8template<typename Symmetry, typename Scalar_>
10{
11 typedef Scalar_ Scalar;
12
13 static constexpr std::size_t Nq = Symmetry::Nq;
14
16 {
17 data.resize(1); // needs to be set for 0-site
18 };
19
21 PivotVector (const Biped<Symmetry,Matrix<Scalar_,Dynamic,Dynamic> > &C)
22 {
23 data.resize(1);
24 data[0] = C;
25 }
26
28 PivotVector (const vector<Biped<Symmetry,Matrix<Scalar_,Dynamic,Dynamic> > > &A12)
29 :data(A12)
30 {}
31
33 PivotVector (const vector<Biped<Symmetry,Matrix<Scalar_,Dynamic,Dynamic> > > &A12,
34 const vector<qarray<Symmetry::Nq> > &qloc12,
35 const vector<Biped<Symmetry,Matrix<Scalar_,Dynamic,Dynamic> > > &A34,
36 const vector<qarray<Symmetry::Nq> > &qloc34,
37 const qarray<Symmetry::Nq> &Qtop,
38 const qarray<Symmetry::Nq> &Qbot,
39 bool DRY = false)
40 {
41// contract_AA(A12, qloc12, A34, qloc34, Qtop, Qbot, data, DRY);
42 contract_AA2(A12, qloc12, A34, qloc34, data, DRY);
43
44 Qbasis<Symmetry> loc12; loc12.pullData(qloc12);
45 Qbasis<Symmetry> loc34; loc34.pullData(qloc34);
46 auto loc = loc12.combine(loc34);
47 extend_A(data, loc.qloc());
48 }
49
51 void outerResize (const PivotVector &Vrhs)
52 {
53 data.clear();
54 data.resize(Vrhs.data.size());
55 for (size_t i=0; i<data.size(); ++i)
56 {
57 data[i].in = Vrhs.data[i].in;
58 data[i].out = Vrhs.data[i].out;
59 data[i].dict = Vrhs.data[i].dict;
60 data[i].block.resize(Vrhs.data[i].block.size());
61 data[i].dim = Vrhs.data[i].dim;
62 }
63 }
64
65 void setZero()
66 {
67 for (size_t i=0; i<data.size(); ++i)
68 for (size_t q=0; q<data[i].dim; ++q)
69 {
70 data[i].block[q].setZero();
71 }
72 }
73
74 inline size_t size() const {return data.size();}
75
76 void print_dims() const
77 {
78 map<qarray<Symmetry::Nq>,set<int> > indim;
79 map<qarray<Symmetry::Nq>,set<int> > outdim;
80 for (size_t s1s3=0; s1s3<data.size(); ++s1s3)
81 for (size_t q=0; q<data[s1s3].dim; ++q)
82 {
83 indim[data[s1s3].in[q]].insert(data[s1s3].block[q].rows());
84 outdim[data[s1s3].out[q]].insert(data[s1s3].block[q].cols());
85 }
86 for (auto it=indim.begin(); it!=indim.end(); ++it)
87 {
88 cout << "in=" << it->first << ":";
89 for (auto ip=it->second.begin(); ip!=it->second.end(); ++ip)
90 {
91 cout << *ip << " ";
92 }
93 cout << endl;
94 }
95 for (auto it=outdim.begin(); it!=outdim.end(); ++it)
96 {
97 cout << "out=" << it->first << ":";
98 for (auto ip=it->second.begin(); ip!=it->second.end(); ++ip)
99 {
100 cout << *ip << " ";
101 }
102 cout << endl;
103 }
104 }
105
110
113 template<typename OtherScalar> PivotVector<Symmetry,Scalar_>& operator*= (const OtherScalar &alpha);
114 template<typename OtherScalar> PivotVector<Symmetry,Scalar_>& operator/= (const OtherScalar &alpha);
115
116 vector<Biped<Symmetry,Matrix<Scalar_,Dynamic,Dynamic> > > data;
117};
118//-----------</definitions>-----------
119
120//-----------<vector arithmetics>-----------
121template<typename Symmetry, typename Scalar_>
123{
124// for (std::size_t s=0; s<data.size(); s++)
125// {
134// data[s] = data[s] + Vrhs.data[s];
135// }
136// return *this;
137
138 #ifdef DMRG_PIVOTVECTOR_PARALLELIZE
139 #pragma omp parallel for schedule(dynamic)
140 #endif
141 for (size_t s=0; s<data.size(); s++)
142 for (size_t q=0; q<data[s].dim; ++q)
143 {
144
145// qarray2<Symmetry::Nq> quple = {data[s].in[q], data[s].out[q]};
146// auto it = Vrhs.data[s].dict.find(quple);
147// if (it != Vrhs.data[s].dict.end())
148 {
149// cout << "+=" << endl;
150// print_size(data[s].block[q],"data[s].block[q]");
151// print_size(Vrhs.data[s].block[it->second],"Vrhs.data[s].block[it->second]");
152// cout << endl;
153
154 if (data[s].block[q].size() == 0)
155 {
156 data[s].block[q] = Vrhs.data[s].block[q];
157 }
158 else if (data[s].block[q].size() != 0 and Vrhs.data[s].block[q].size() != 0)
159 {
160// cout << data[s].block[q].rows() << "x" << data[s].block[q].cols() << endl;
161// cout << Vrhs.data[s].block[q].rows() << "x" << Vrhs.data[s].block[q].cols() << endl;
162// cout << endl;
163
164 data[s].block[q] += Vrhs.data[s].block[q];
165 }
166 }
167 }
168 return *this;
169}
170
171template<typename Symmetry, typename Scalar_>
174{
175// for (std::size_t s=0; s<data.size(); s++)
176// {
185// data[s] = data[s] - Vrhs.data[s];
186// }
187// return *this;
188
189 #ifdef DMRG_PIVOTVECTOR_PARALLELIZE
190 #pragma omp parallel for schedule(dynamic)
191 #endif
192 for (size_t s=0; s<data.size(); s++)
193 for (size_t q=0; q<data[s].dim; ++q)
194 {
195// cout << "s=" << s << ", q=" << q << endl;
196// cout << "-= 1=" << data[s].in[q] << ", " << data[s].out[q] << endl;
197// cout << "-= 2=" << Vrhs.data[s].in[q] << ", " << Vrhs.data[s].out[q] << endl;
198// print_size(data[s].block[q],"data[s].block[q]");
199// print_size(Vrhs.data[s].block[q],"Vrhs.data[s].block[q]");
200
201// qarray2<Symmetry::Nq> quple = {data[s].in[q], data[s].out[q]};
202// auto it = Vrhs.data[s].dict.find(quple);
203// if (it != Vrhs.data[s].dict.end())
204 {
205// cout << "-=" << endl;
206// print_size(data[s].block[q],"data[s].block[q]");
207// print_size(Vrhs.data[s].block[it->second],"Vrhs.data[s].block[it->second]");
208// cout << endl;
209
210 if (data[s].block[q].size() == 0)
211 {
212 data[s].block[q] = -Vrhs.data[s].block[q];
213 }
214 else if (data[s].block[q].size() != 0 and Vrhs.data[s].block[q].size() != 0)
215 {
216 data[s].block[q] -= Vrhs.data[s].block[q];
217 }
218 }
219 }
220 return *this;
221}
222
223template<typename Symmetry, typename Scalar_>
224template<typename OtherScalar>
226operator*= (const OtherScalar &alpha)
227{
228 #ifdef DMRG_PIVOTVECTOR_PARALLELIZE
229 #pragma omp parallel for schedule(dynamic)
230 #endif
231 for (size_t s=0; s<data.size(); ++s)
232 for (size_t q=0; q<data[s].dim; ++q)
233 {
234 data[s].block[q] *= alpha;
235 }
236 return *this;
237}
238
239template<typename Symmetry, typename Scalar_>
240template<typename OtherScalar>
242operator/= (const OtherScalar &alpha)
243{
244 #ifdef DMRG_PIVOTVECTOR_PARALLELIZE
245 #pragma omp parallel for schedule(dynamic)
246 #endif
247 for (size_t s=0; s<data.size(); ++s)
248 for (size_t q=0; q<data[s].dim; ++q)
249 {
250 data[s].block[q] /= alpha;
251 }
252 return *this;
253}
254
255template<typename Symmetry, typename Scalar_, typename OtherScalar>
257{
258 return V *= alpha;
259}
260
261template<typename Symmetry, typename Scalar_, typename OtherScalar>
263{
264 return V *= alpha;
265}
266
267template<typename Symmetry, typename Scalar_, typename OtherScalar>
269{
270 return V /= alpha;
271}
272
273template<typename Symmetry, typename Scalar_>
275{
277 Vout += V2;
278 return Vout;
279}
280
281template<typename Symmetry, typename Scalar_>
283{
285 Vout -= V2;
286 return Vout;
287}
288
289template<typename Symmetry, typename Scalar_, typename OtherScalar>
290void addScale (const OtherScalar alpha, const PivotVector<Symmetry,Scalar_> &Vin, PivotVector<Symmetry,Scalar_> &Vout)
291{
292 Vout += alpha * Vin;
293}
294
295//-----------<dot & vector norms>-----------
296template<typename Symmetry, typename Scalar_>
298{
299// cout << "sizes in dot: " << V1.data.size() << ", " << V2.data.size() << endl;
300 Scalar_ res = 0;
301 #ifdef DMRG_PIVOTVECTOR_PARALLELIZE
302 #pragma omp parallel for schedule(dynamic) reduction(+:res)
303 #endif
304 for (size_t s=0; s<V2.data.size(); ++s)
305 for (size_t q=0; q<V2.data[s].dim; ++q)
306 {
307 if (V1.data[s].in[q] != V2.data[s].in[q] or V1.data[s].out[q] != V2.data[s].out[q])
308 {
309 cout << "s=" << s << ", q=" << q << endl;
310 cout << "V1 inout=" << V1.data[s].in[q] << ", " << V1.data[s].out[q] << endl;
311 cout << "V2 inout=" << V2.data[s].in[q] << ", " << V2.data[s].out[q] << endl;
312 print_size(V1.data[s].block[q],"V1.data[s].block[q]");
313 print_size(V2.data[s].block[q],"V2.data[s].block[q]");
314 cout << endl;
315 cout << termcolor::red << "Mismatched blocks in dot(PivotVector)" << termcolor::reset << endl;
316 cout << V1.data[s].print() << endl;
317 cout << V2.data[s].print() << endl;
318 }
319
320 if (V1.data[s].block[q].size() > 0 and
321 V2.data[s].block[q].size() > 0)
322 {
323 res += (V1.data[s].block[q].adjoint() * V2.data[s].block[q]).trace() * Symmetry::coeff_dot(V1.data[s].out[q]);
324 }
325
326// qarray2<Symmetry::Nq> quple = {V2.data[s].in[q], V2.data[s].out[q]};
327// auto it = V1.data[s].dict.find(quple);
328// if (it != V1.data[s].dict.end())
329// {
335// res += (V1.data[s].block[it->second].adjoint() * V2.data[s].block[q]).trace() * Symmetry::coeff_dot(V1.data[s].out[it->second]);
336// }
337 }
338 return res;
339}
340
341template<typename Symmetry, typename Scalar_>
343{
344 double res = isReal(dot(V,V));
345 return res;
346}
347
348template<typename Symmetry, typename Scalar_>
349inline double norm (const PivotVector<Symmetry,Scalar_> &V)
350{
351 return sqrt(squaredNorm(V));
352}
353
354template<typename Symmetry, typename Scalar_>
356{
357 V /= norm(V);
358}
359
360template<typename Symmetry, typename Scalar_>
361inline size_t dim (const PivotVector<Symmetry,Scalar_> &V)
362{
363 size_t out = 0;
364 for (size_t s=0; s<V.data.size(); ++s)
365 for (size_t q=0; q<V.data[s].dim; ++q)
366 {
367 out += V.data[s].block[q].size();
368 }
369 return out;
370}
371
372template<typename Symmetry, typename Scalar_>
374{
375 double res = 0.;
376 for (size_t s=0; s<V1.data.size(); ++s)
377 {
378 auto Mtmp = V1.data[s] - V2.data[s];
379 for (size_t q=0; q<Mtmp.dim; ++q)
380 {
381 double tmp = Mtmp.block[q].template lpNorm<Eigen::Infinity>();
382 if (tmp>res) {res = tmp;}
383 }
384 }
385 return res;
386}
387
388template<typename Symmetry, typename Scalar_>
390{
391// for (size_t s=0; s<V1.data.size(); ++s)
392// {
393// V1.data[s].block.swap(V2.data[s].block);
394// }
395 swap(V1.data, V2.data);
396}
397
398template<typename Symmetry, typename Scalar_>
400{
401 for (size_t s=0; s<V.data.size(); ++s)
402 for (size_t q=0; q<V.data[s].dim; ++q)
403 {
404 V.data[s].block[q].setZero();
405 }
406};
407
408#include "RandomVector.h"
409
410template<typename Symmetry, typename Scalar_>
411struct GaussianRandomVector<PivotVector<Symmetry,Scalar_>,Scalar_>
412{
413 static void fill (size_t N, PivotVector<Symmetry,Scalar_> &Vout)
414 {
415 for (size_t s=0; s<Vout.data.size(); ++s)
416 for (size_t q=0; q<Vout.data[s].dim; ++q)
417 for (size_t a1=0; a1<Vout.data[s].block[q].rows(); ++a1)
418 for (size_t a2=0; a2<Vout.data[s].block[q].cols(); ++a2)
419 {
420 Vout.data[s].block[q](a1,a2) = threadSafeRandUniform<Scalar_>(-1.,1.);
421 }
422 normalize(Vout);
423 }
424};
425
426#endif
void contract_AA2(const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &A1, const vector< qarray< Symmetry::Nq > > &qloc1, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &A2, const vector< qarray< Symmetry::Nq > > &qloc2, vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Apair, bool DRY=false)
vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > extend_A(const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &A, const vector< qarray< Symmetry::Nq > > &qloc)
void print_size(const MatrixType &M, string label)
Definition: DmrgExternal.h:184
size_t dim(const PivotVector< Symmetry, Scalar_ > &V)
PivotVector< Symmetry, Scalar_ > operator-(const PivotVector< Symmetry, Scalar_ > &V1, const PivotVector< Symmetry, Scalar_ > &V2)
double infNorm(const PivotVector< Symmetry, Scalar_ > &V1, const PivotVector< Symmetry, Scalar_ > &V2)
double squaredNorm(const PivotVector< Symmetry, Scalar_ > &V)
double norm(const PivotVector< Symmetry, Scalar_ > &V)
void swap(PivotVector< Symmetry, Scalar_ > &V1, PivotVector< Symmetry, Scalar_ > &V2)
PivotVector< Symmetry, Scalar_ > operator+(const PivotVector< Symmetry, Scalar_ > &V1, const PivotVector< Symmetry, Scalar_ > &V2)
void normalize(PivotVector< Symmetry, Scalar_ > &V)
void addScale(const OtherScalar alpha, const PivotVector< Symmetry, Scalar_ > &Vin, PivotVector< Symmetry, Scalar_ > &Vout)
PivotVector< Symmetry, Scalar_ > operator*(const OtherScalar &alpha, PivotVector< Symmetry, Scalar_ > V)
PivotVector< Symmetry, Scalar_ > operator/(PivotVector< Symmetry, Scalar_ > V, const OtherScalar &alpha)
void setZero(PivotVector< Symmetry, Scalar_ > &V)
Scalar_ dot(const PivotVector< Symmetry, Scalar_ > &V1, const PivotVector< Symmetry, Scalar_ > &V2)
double isReal(double x)
Definition: DmrgTypedefs.h:21
Definition: Qbasis.h:39
Qbasis< Symmetry > combine(const Qbasis< Symmetry > &other, bool FLIP=false) const
Definition: Qbasis.h:686
void pullData(const vector< Biped< Symmetry, MatrixType > > &A, const Eigen::Index &leg)
Definition: Qbasis.h:486
Definition: Biped.h:64
static void fill(size_t N, PivotVector< Symmetry, Scalar_ > &Vout)
PivotVector< Symmetry, Scalar_ > & operator+=(const PivotVector< Symmetry, Scalar_ > &Vrhs)
PivotVector< Symmetry, Scalar_ > & operator-=(const PivotVector< Symmetry, Scalar_ > &Vrhs)
PivotVector(const vector< Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > > &A12)
static constexpr std::size_t Nq
Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > & operator[](size_t i)
PivotVector< Symmetry, Scalar_ > & operator*=(const OtherScalar &alpha)
Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > & operator()(size_t i)
size_t size() const
PivotVector(const Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > &C)
void outerResize(const PivotVector &Vrhs)
PivotVector< Symmetry, Scalar_ > & operator/=(const OtherScalar &alpha)
vector< Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > > data
void print_dims() const
PivotVector(const vector< Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > > &A12, const vector< qarray< Symmetry::Nq > > &qloc12, const vector< Biped< Symmetry, Matrix< Scalar_, Dynamic, Dynamic > > > &A34, const vector< qarray< Symmetry::Nq > > &qloc34, const qarray< Symmetry::Nq > &Qtop, const qarray< Symmetry::Nq > &Qbot, bool DRY=false)
Scalar_ Scalar
Definition: qarray.h:26