VMPS++
Loading...
Searching...
No Matches
VumpsMpoTransferMatrix.h
Go to the documentation of this file.
1#ifndef VANILLA_VUMPS_MPO_TRANSFERMATRIX
2#define VANILLA_VUMPS_MPO_TRANSFERMATRIX
3
5#include "termcolor.hpp"
7
9
10//include "tensors/Biped.h"
11//include "tensors/Multipede.h"
12//include "tensors/DmrgContractions.h"
13//include "RandomVector.h"
14
19template<typename Symmetry, typename Scalar>
21{
23
25 const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &Abra_input,
26 const vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > &Aket_input,
27 const Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &LReigen_input,
28 const vector<vector<vector<vector<Biped<Symmetry,SparseMatrix<Scalar> > > > > > &W_input,
29 const vector<vector<qarray<Symmetry::Nq> > > &qloc_input,
30 const vector<vector<qarray<Symmetry::Nq> > > &qOp_input,
31 size_t ab_input,
32 const std::unordered_map<pair<qarray<Symmetry::Nq>,size_t>,size_t> &basis_order_map_input = {},
33 const vector<pair<qarray<Symmetry::Nq>,size_t> > &basis_order_imput={})
34 :DIR(DIR_input), Abra(Abra_input), Aket(Aket_input), LReigen(LReigen_input), W(W_input), qloc(qloc_input), qOp(qOp_input), ab(ab_input), basis_order_map(basis_order_map_input), basis_order(basis_order_imput)
35 {}
36
39
41 vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > Abra;
42 vector<vector<Biped<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > > > Aket;
43 vector<vector<vector<vector<Biped<Symmetry, SparseMatrix<Scalar> > > > > > W;
45
47
48 size_t ab;
49 std::unordered_map<pair<qarray<Symmetry::Nq>,size_t>,size_t> basis_order_map;
50 vector<pair<qarray<Symmetry::Nq>,size_t> > basis_order;
51
52 vector<vector<qarray<Symmetry::Nq> > > qloc;
53 vector<vector<qarray<Symmetry::Nq> > > qOp;
54};
55
60template<typename Symmetry, typename Scalar_>
62{
63 typedef Scalar_ Scalar;
64
66
67 // When called for the VUMPS ground state algorithm, ab_input and LRdotY are set.
68 // When called with StructureFactor, they are equal to zero.
69 MpoTransferVector (const Tripod<Symmetry,Matrix<Scalar,Dynamic,Dynamic> > &T, const pair<qarray<Symmetry::Nq>,size_t> &ab_input, const Scalar &LRdotY=0.)
70 :data(T), ab(ab_input)
71 {
72 if (LRdotY != 0.)
73 {
74 for (size_t q=0; q<data.dim; ++q)
75 {
76 if (data.mid(q) == ab.first)
77 {
78 data.block[q][ab.second][0] -= LRdotY * Matrix<Scalar,Dynamic,Dynamic>::Identity(data.block[q][ab.second][0].rows(), data.block[q][ab.second][0].cols());
79 }
80 }
81 }
82 };
83
85 pair<qarray<Symmetry::Nq>,size_t> ab;
86
88
91 template<typename OtherScalar> MpoTransferVector<Symmetry,Scalar>& operator*= (const OtherScalar &alpha);
92 template<typename OtherScalar> MpoTransferVector<Symmetry,Scalar>& operator/= (const OtherScalar &alpha);
94};
95
98template<typename Symmetry, typename Scalar1, typename Scalar2>
100{
101 Vout = Vin;
102 Vout.data.setZero();
103 size_t Lcell = H.W.size();
104
106 TxV.data.setZero();
107
109 {
112 for (int l=Lcell-1; l>=0; --l)
113 {
114// if (l==0 or l==Lcell-1)
115 if (l==0)
116 {
117 contract_R(R, H.Abra[l], H.W[l], H.Aket[l], H.qloc[l], H.qOp[l], Rnext, false, make_pair(CONTRACT_LR_MODE::FIXED_ROWS,H.ab), H.basis_order_map);
118 }
119 else if (l==Lcell-1)
120 {
121 contract_R(R, H.Abra[l], H.W[l], H.Aket[l], H.qloc[l], H.qOp[l], Rnext, false, make_pair(CONTRACT_LR_MODE::FIXED_COLS,H.ab), H.basis_order_map);
122 }
123 else
124 {
125 contract_R(R, H.Abra[l], H.W[l], H.Aket[l], H.qloc[l], H.qOp[l], Rnext);
126 }
127 R.clear();
128 R = Rnext;
129 Rnext.clear();
130 }
131 TxV.data = R;
132
133// cout << "MpoTransferVector R:" << endl << TxV.data.print(true,13) << endl;
134 }
135 else if (H.DIR == VMPS::DIRECTION::LEFT)
136 {
139 for (size_t l=0; l<Lcell; ++l)
140 {
141// if (l==Lcell-1 or l==0)
142 if (l==Lcell-1)
143 {
144 contract_L(L, H.Abra[l], H.W[l], H.Aket[l], H.qloc[l], H.qOp[l], Lnext, false, make_pair(CONTRACT_LR_MODE::FIXED_COLS,H.ab), H.basis_order_map);
145 }
146 else if (l==0)
147 {
148 contract_L(L, H.Abra[l], H.W[l], H.Aket[l], H.qloc[l], H.qOp[l], Lnext, false, make_pair(CONTRACT_LR_MODE::FIXED_ROWS,H.ab), H.basis_order_map);
149 }
150 else
151 {
152 contract_L(L, H.Abra[l], H.W[l], H.Aket[l], H.qloc[l], H.qOp[l], Lnext);
153 }
154 L.clear();
155 L = Lnext;
156 Lnext.clear();
157 }
158 TxV.data = L;
159
160// cout << "MpoTransferVector L:" << endl << TxV.data.print(true,13) << endl;
161 }
162
163 // find quantum number and inner basis element for H.ab
164 pair<qarray<Symmetry::Nq>,size_t> ab_blocked = H.basis_order[H.ab];
165 Scalar2 LdotR;
167 {
168 LdotR = contract_LR(ab_blocked, H.LReigen, Vin.data);
169 }
170 else if (H.DIR == VMPS::DIRECTION::LEFT)
171 {
172 LdotR = contract_LR(ab_blocked, Vin.data, H.LReigen);
173 }
174
175 for (size_t q=0; q<TxV.data.dim; ++q)
176 {
177 qarray3<Symmetry::Nq> quple = {TxV.data.in(q), TxV.data.out(q), TxV.data.mid(q)};
178 auto it = Vin.data.dict.find(quple);
179
180 Matrix<Scalar2,Dynamic,Dynamic> Mtmp;
181 if (it != Vin.data.dict.end())
182 {
183 Mtmp = Vin.data.block[it->second][ab_blocked.second][0] - TxV.data.block[q][ab_blocked.second][0];
184 Mtmp += LdotR * Matrix<Scalar2,Dynamic,Dynamic>::Identity(Vin.data.block[it->second][ab_blocked.second][0].rows(),
185 Vin.data.block[it->second][ab_blocked.second][0].cols());
186 }
187
188 if (Mtmp.size() != 0)
189 {
190 auto ip = Vout.data.dict.find(quple);
191 if (ip != Vout.data.dict.end())
192 {
193 if (Vout.data.block[ip->second][ab_blocked.second][0].rows() != Mtmp.rows() or
194 Vout.data.block[ip->second][ab_blocked.second][0].cols() != Mtmp.cols())
195 {
196 Vout.data.block[ip->second][ab_blocked.second][0] = Mtmp;
197 }
198 else
199 {
200 Vout.data.block[ip->second][ab_blocked.second][0] += Mtmp;
201 }
202 }
203 else
204 {
205 cout << termcolor::red << "push_back that shouldn't be" << termcolor::reset << endl;
206 boost::multi_array<Matrix<Scalar2,Dynamic,Dynamic>,LEGLIMIT> Mtmpvec(boost::extents[H.W[0][0][0][0].block[0].cols()][1]);
207 Mtmpvec[ab_blocked.second][0] = Mtmp;
208 Vout.data.push_back(quple, Mtmpvec);
209 }
210 }
211 }
212}
213
214template<typename Symmetry, typename Scalar1, typename Scalar2>
216{
218 HxV(H,Vinout,Vtmp);
219 Vinout = Vtmp;
220}
221
222template<typename Symmetry, typename Scalar>
224{
225 return 0;
226}
227
228template<typename Symmetry, typename Scalar>
230{
231 size_t out = 0;
232 for (size_t q=0; q<V.data.dim; ++q)
233 {
234 if (V.data.mid(q) != V.ab.first) {continue;}
235 out += V.data.block[q][V.ab.second][0].size();
236 }
237 return out;
238}
239
240template<typename Symmetry, typename Scalar>
242{
243 return isReal(dot(V,V));
244}
245
246template<typename Symmetry, typename Scalar>
248{
249 return sqrt(squaredNorm(V));
250}
251
252template<typename Symmetry, typename Scalar>
254{
255 V /= norm(V);
256}
257
258template<typename Symmetry, typename Scalar>
260{
261 Scalar res = 0;
262 for (size_t q=0; q<V1.data.size(); ++q)
263 {
264 if (V1.data.mid(q) != V1.ab.first) {continue;}
265 // Note: qmid is not necessarily the vacuum for the structure factor (TransferMatrixSF)!
266 qarray3<Symmetry::Nq> quple = {V1.data.in(q), V1.data.out(q), V1.data.mid(q)};
267 auto it = V2.data.dict.find(quple);
268 if (it != V2.data.dict.end())
269 {
270 if (V2.data.mid(it->second) != V2.ab.first) {continue;}
271 res += (V1.data.block[q][V1.ab.second][0].adjoint() * V2.data.block[it->second][V2.ab.second][0]).trace() * Symmetry::coeff_dot(V2.data.out(q));
272 }
273 }
274 return res;
275}
276
277template<typename Symmetry, typename Scalar>
280{
281 data.addScale(1.,Vrhs.data);
282 return *this;
283
284 // for (size_t q=0; q<Vrhs.data.dim; ++q)
285 // {
286 // qarray3<Symmetry::Nq> quple = {Vrhs.data.in(q), Vrhs.data.out(q), Vrhs.data.mid(q)};
287 // auto it = data.dict.find(quple);
288 // if (it != data.dict.end())
289 // {
290 // data.block[it->second][ab][0] += Vrhs.data.block[q][ab][0];
291 // }
292 // }
293 // return *this;
294}
295
296template<typename Symmetry, typename Scalar>
299{
300 data.addScale(-1.,Vrhs.data);
301 return *this;
302
303 // for (size_t q=0; q<Vrhs.data.dim; ++q)
304 // {
305 // qarray3<Symmetry::Nq> quple = {Vrhs.data.in(q), Vrhs.data.out(q), Vrhs.data.mid(q)};
306 // auto it = data.dict.find(quple);
307 // if (it != data.dict.end())
308 // {
309 // data.block[it->second][ab][0] -= Vrhs.data.block[q][ab][0];
310 // }
311 // }
312 // return *this;
313}
314
315template<typename Symmetry, typename Scalar>
316template<typename OtherScalar>
318operator*= (const OtherScalar &alpha)
319{
320 for (size_t q=0; q<data.dim; ++q)
321 {
322 if (data.mid(q) != ab.first) {continue;}
323 data.block[q][ab.second][0] *= alpha;
324 }
325 return *this;
326}
327
328template<typename Symmetry, typename Scalar>
329template<typename OtherScalar>
331operator/= (const OtherScalar &alpha)
332{
333 for (size_t q=0; q<data.dim; ++q)
334 {
335 if (data.mid(q) != ab.first) {continue;}
336 data.block[q][ab.second][0] /= alpha;
337 }
338 return *this;
339}
340
341template<typename Symmetry, typename Scalar, typename OtherScalar>
343{
344 return V *= alpha;
345}
346
347template<typename Symmetry, typename Scalar, typename OtherScalar>
349{
350 return V /= alpha;
351}
352
353template<typename Symmetry, typename Scalar, typename OtherScalar>
355{
357 Vout.data += V2.data;
358 return Vout;
359}
360
361template<typename Symmetry, typename Scalar, typename OtherScalar>
363{
365 Vout.data -= V2.data;
366 return Vout;
367}
368
369template<typename Symmetry, typename Scalar>
371{
372 V.data.setZero();
373}
374
375template<typename Symmetry, typename Scalar, typename OtherScalar>
376inline void addScale (const OtherScalar alpha, const MpoTransferVector<Symmetry,Scalar> &Vin, MpoTransferVector<Symmetry,Scalar> &Vout)
377{
378 Vout.data.addScale(alpha,Vin.data);
379 // Vout += alpha * Vin;
380}
381
382template<typename Symmetry, typename Scalar>
383struct GaussianRandomVector<MpoTransferVector<Symmetry,Scalar>,Scalar>
384{
385 static void fill (size_t N, MpoTransferVector<Symmetry,Scalar> &Vout)
386 {
387 for (size_t q=0; q<Vout.data.dim; ++q)
388 {
389 if (Vout.data.mid(q) != Vout.ab.first) {continue;}
390 for (size_t i=0; i<Vout.data.block[q][Vout.ab.second][0].rows(); ++i)
391 for (size_t j=0; j<Vout.data.block[q][Vout.ab.second][0].cols(); ++j)
392 {
393 Vout.data.block[q][Vout.ab.second][0](i,j) = threadSafeRandUniform<Scalar>(-1.,1.);
394 }
395 }
396 normalize(Vout);
397 }
398};
399
400#endif
@ FIXED_ROWS
@ FIXED_COLS
void normalize(PivotVector< Symmetry, Scalar_ > &V)
double isReal(double x)
Definition: DmrgTypedefs.h:21
#define LEGLIMIT
Definition: Multipede.h:4
void addScale(const OtherScalar alpha, const MpoTransferVector< Symmetry, Scalar > &Vin, MpoTransferVector< Symmetry, Scalar > &Vout)
MpoTransferVector< Symmetry, Scalar > operator*(const OtherScalar &alpha, MpoTransferVector< Symmetry, Scalar > V)
Scalar dot(const MpoTransferVector< Symmetry, Scalar > &V1, const MpoTransferVector< Symmetry, Scalar > &V2)
double squaredNorm(const MpoTransferVector< Symmetry, Scalar > &V)
MpoTransferVector< Symmetry, Scalar > operator/(MpoTransferVector< Symmetry, Scalar > V, const OtherScalar &alpha)
double norm(const MpoTransferVector< Symmetry, Scalar > &V)
MpoTransferVector< Symmetry, Scalar > operator+(const MpoTransferVector< Symmetry, Scalar > &V1, const MpoTransferVector< Symmetry, Scalar > &V2)
void normalize(MpoTransferVector< Symmetry, Scalar > &V)
void setZero(MpoTransferVector< Symmetry, Scalar > &V)
size_t dim(const MpoTransferMatrix< Symmetry, Scalar > &H)
MpoTransferVector< Symmetry, Scalar > operator-(const MpoTransferVector< Symmetry, Scalar > &V1, const MpoTransferVector< Symmetry, Scalar > &V2)
void contract_R(const Tripod< Symmetry, MatrixType2 > &Rold, const vector< Biped< Symmetry, MatrixType > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, MatrixType > > &Aket, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, Tripod< Symmetry, MatrixType2 > &Rnew, bool RANDOMIZE=false, tuple< CONTRACT_LR_MODE, size_t > MODE_input=make_pair(FULL, 0), const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map={})
void contract_L(const Tripod< Symmetry, MatrixType2 > &Lold, const vector< Biped< Symmetry, MatrixType > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, MatrixType > > &Aket, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp, Tripod< Symmetry, MatrixType2 > &Lnew, bool RANDOMIZE=false, tuple< CONTRACT_LR_MODE, size_t > MODE_input=make_pair(FULL, 0), const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map={})
Scalar contract_LR(const Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &L, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Abra, const vector< vector< vector< Biped< Symmetry, MpoMatrixType > > > > &W, const vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > &Aket, const Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &R, const vector< qarray< Symmetry::Nq > > &qloc, const vector< qarray< Symmetry::Nq > > &qOp)
void HxV(const MpoTransferMatrix< Symmetry, Scalar1 > &H, const MpoTransferVector< Symmetry, Scalar2 > &Vin, MpoTransferVector< Symmetry, Scalar2 > &Vout)
std::array< qarray< Nq >, 3 > qarray3
Definition: qarray.h:52
Definition: Biped.h:64
static void fill(size_t N, MpoTransferVector< Symmetry, Scalar > &Vout)
vector< pair< qarray< Symmetry::Nq >, size_t > > basis_order
vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< Scalar > > > > > > W
vector< vector< qarray< Symmetry::Nq > > > qOp
MpoTransferMatrix(VMPS::DIRECTION::OPTION DIR_input, const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &Abra_input, const vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > &Aket_input, const Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &LReigen_input, const vector< vector< vector< vector< Biped< Symmetry, SparseMatrix< Scalar > > > > > > &W_input, const vector< vector< qarray< Symmetry::Nq > > > &qloc_input, const vector< vector< qarray< Symmetry::Nq > > > &qOp_input, size_t ab_input, const std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > &basis_order_map_input={}, const vector< pair< qarray< Symmetry::Nq >, size_t > > &basis_order_imput={})
VMPS::DIRECTION::OPTION DIR
vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > Abra
std::unordered_map< pair< qarray< Symmetry::Nq >, size_t >, size_t > basis_order_map
vector< vector< qarray< Symmetry::Nq > > > qloc
vector< vector< Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > > > Aket
Biped< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > LReigen
MpoTransferVector< Symmetry, Scalar > & operator-=(const MpoTransferVector< Symmetry, Scalar > &Vrhs)
MpoTransferVector< Symmetry, Scalar > & operator/=(const OtherScalar &alpha)
Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > data
pair< qarray< Symmetry::Nq >, size_t > ab
MpoTransferVector< Symmetry, Scalar > & operator*=(const OtherScalar &alpha)
MpoTransferVector< Symmetry, Scalar > & operator+=(const MpoTransferVector< Symmetry, Scalar > &Vrhs)
MpoTransferVector(const Tripod< Symmetry, Matrix< Scalar, Dynamic, Dynamic > > &T, const pair< qarray< Symmetry::Nq >, size_t > &ab_input, const Scalar &LRdotY=0.)
void clear()
Definition: Multipede.h:409
Definition: qarray.h:26