VMPS++
Loading...
Searching...
No Matches
Multipede.h
Go to the documentation of this file.
1#ifndef STRAWBERRY_MULTIPEDE
2#define STRAWBERRY_MULTIPEDE
3
4#define LEGLIMIT 2
5
7#include <unordered_map>
8
9#include "boost/multi_array.hpp"
11
12
13#include "MemCalc.h" // from TOOLS
14#include "symmetry/functions.h"
15#include "HDF5Interface.h"
16
17//include "symmetry/qarray.h"
18//include "DmrgExternal.h"
19
31template<size_t Nlegs, typename Symmetry, typename MatrixType>
33{
34typedef typename Symmetry::qType qType;
35typedef typename MatrixType::Scalar Scalar;
36
38
43 explicit Multipede (const Biped<Symmetry,MatrixType> &B, qType Q = Symmetry::qvacuum())
44 {
45 assert(Nlegs == 3);
46 for (size_t q=0; q<B.dim; ++q)
47 {
48 // assert(B.in[q] == B.out[q]);
49 if (Symmetry::triangle(qarray3<Symmetry::Nq>{B.in[q], Q, B.out[q]}))
50 {
51 boost::multi_array<MatrixType,LEGLIMIT> Mtmpvec(boost::extents[1][1]);
52 Mtmpvec[0][0] = B.block[q];
53 push_back(qarray3<Symmetry::Nq>{B.in[q], B.out[q], Q}, Mtmpvec);
54 }
55 }
56 }
57
59 inline constexpr size_t rank() const {return Nlegs;}
60
62
66 size_t dim = 0;
67 inline std::size_t size() const {return dim;}
68
77 vector<std::array<qType,Nlegs> > index;
78
88 vector<boost::multi_array<MatrixType,LEGLIMIT> > block;
89
95 unordered_map<std::array<qType,Nlegs>,size_t> dict; // key format: {qin,qout,qmid}
97
99
100 double memory (MEMUNIT memunit=GB) const;
101
103 double overhead (MEMUNIT memunit=MB) const;
104
106 string dict_info() const;
107
108 string print (const bool &SHOW_MATRICES=false, const size_t &precision=3) const;
109// void rebuild_dict();
111
113
114 void clear();
115
117 void setZero();
118
123 void setVacuum();
124
129 void setTarget (std::array<qType,Nlegs> Q);
130
131 void setTarget (vector<std::array<qType,Nlegs> > Q);
132
133 /***/
134 void setIdentity (size_t Drows, size_t Dcols, size_t amax=1, size_t bmax=1);
135
136 void setIdentity (size_t amax, size_t bmax, const Qbasis<Symmetry> &base, const qarray<Symmetry::Nq> &Q=Symmetry::qvacuum());
137
138 void addScale (const Scalar &factor, const Multipede<Nlegs,Symmetry,MatrixType> &Mrhs);
140
142 void save (string filename, bool PRINT=false) const;
143
144 void load (string filename, bool PRINT=false);
146
148
152 inline qType in (size_t q) const {return index[q][0];}
153 inline qType out (size_t q) const {return index[q][1];}
154 inline qType mid (size_t q) const {return index[q][2];}
155
156 inline qType bot (size_t q) const {return index[q][2];}
157 inline qType top (size_t q) const {return index[q][3];}
159
161
165 void push_back (std::array<qType,Nlegs> quple, const boost::multi_array<MatrixType,LEGLIMIT> &M);
166
172 void push_back (std::initializer_list<qType> qlist, const boost::multi_array<MatrixType,LEGLIMIT> &M);
173
174 void insert (std::pair<qType,size_t> ab, const Multipede<Nlegs,Symmetry,MatrixType> &Trhs);
176
178
179 template<typename OtherMatrixType>
181 {
183
184 Vout.dict = dict;
185 Vout.block.clear();
186 Vout.block.resize(block.size());
187 Vout.index = index;
188 Vout.dim = dim;
189
190 for (size_t q=0; q<dim; ++q)
191 {
192 Vout.block[q].resize(boost::extents[block[q].shape()[0]][block[q].shape()[1]]);
193 for (size_t a=0; a<block[q].shape()[0]; ++a)
194 for (size_t b=0; b<block[q].shape()[1]; ++b)
195 {
196 Vout.block[q][a][b] = block[q][a][b].template cast<typename OtherMatrixType::Scalar>();
197 }
198 }
199
200 return Vout;
201 }
202
203 // deprecated, can be deleted later:
205// void shift_Qin (const qarray<Symmetry::Nq> &Q);
207// void shift_Qmid (const qarray<Symmetry::Nq> &Q);
208
210
212 Biped<Symmetry,MatrixType> BipedSliceQmid (qType qslice = Symmetry::qvacuum()) const;
214
215 // Needs to be implemented explicitly because multi_array doesn't resize when assigning A=B.
217 {
218 dict = Vin.dict;
219 block.clear();
220 block.resize(Vin.block.size());
221 index = Vin.index;
222 dim = Vin.dim;
223
224 for (size_t q=0; q<dim; ++q)
225 {
226 block[q].resize(boost::extents[Vin.block[q].shape()[0]][Vin.block[q].shape()[1]]);
227 for (size_t a=0; a<block[q].shape()[0]; ++a)
228 for (size_t b=0; b<block[q].shape()[1]; ++b)
229 {
230 block[q][a][b] = Vin.block[q][a][b];
231 }
232 }
233
234 return *this;
235 }
236};
237
238template<size_t Nlegs, typename Symmetry, typename MatrixType>
240{
242 for (size_t q=0; q<M1.dim; ++q)
243 {
244 qarray3<Symmetry::Nq> quple = {M1.in(q), M1.out(q), M1.mid(q)};
245 auto it = M2.dict.find(quple);
246 boost::multi_array<MatrixType,LEGLIMIT> Mtmpvec(boost::extents[M1.block[q].shape()[0]][1]);
247 for (size_t a=0; a<M1.block[q].shape()[0]; ++a)
248 {
249 Mtmpvec[a][0] = M1.block[q][a][0]-M2.block[it->second][a][0];
250 }
251 Mout.push_back(quple, Mtmpvec);
252 }
253 return Mout;
254}
255
256template<size_t Nlegs, typename Symmetry, typename MatrixType>
258addScale (const Scalar &factor, const Multipede<Nlegs,Symmetry,MatrixType> &Mrhs)
259{
260 if (abs(factor) < 1.e-14) {return;}
261 vector<qarray3<Symmetry::Nq> > matching_blocks;
263
264 for (size_t q=0; q<dim; ++q)
265 {
266 qarray3<Symmetry::Nq> quple = {in(q), out(q), mid(q)};
267 auto it = Mrhs.dict.find(quple);
268 if (it != Mrhs.dict.end())
269 {
270 matching_blocks.push_back(quple);
271 }
272
273 for (size_t a=0; a<block[q].shape()[0]; ++a)
274 {
275 MatrixType Mtmp;
276 if (it != Mrhs.dict.end())
277 {
278 assert(block[q].shape()[0] == Mrhs.block[it->second].shape()[0]);
279
280 if (block[q][a][0].size() != 0 and Mrhs.block[it->second][a][0].size() != 0)
281 {
282// cout << "M1+factor*Mrhs" << endl;
283 Mtmp = block[q][a][0] + factor * Mrhs.block[it->second][a][0]; // M1+factor*Mrhs
284 }
285 else if (block[q][a][0].size() == 0 and Mrhs.block[it->second][a][0].size() != 0)
286 {
287// cout << "0+factor*Mrhs" << endl;
288 Mtmp = factor * Mrhs.block[it->second][a][0]; // 0+factor*Mrhs
289 }
290 else if (block[q].size() != 0 and Mrhs.block[it->second][a][0].size() == 0)
291 {
292// cout << "M1+0" << endl;
293 Mtmp = block[q][a][0]; // M1+0
294 }
295 // else: block[q].size() == 0 and Mrhs.block[it->second][a][0].size() == 0 -> do nothing -> Mtmp.size() = 0
296 }
297 else
298 {
299// cout << "M1+0" << endl;
300 Mtmp = block[q][a][0]; // M1+0
301 }
302
303 if (Mtmp.size() != 0)
304 {
305 auto ip = Mout.dict.find(quple);
306 if (ip != Mout.dict.end())
307 {
308 assert(1==0 and "Error in Multipede::addScale, block already exists!");
309 }
310 else
311 {
312 boost::multi_array<MatrixType,LEGLIMIT> Mtmpvec(boost::extents[block[q].shape()[0]][1]);
313 Mtmpvec[a][0] = Mtmp;
314 Mout.push_back(quple, Mtmpvec);
315 }
316 }
317 }
318 }
319
320 // Mrhs has additional blocks which are not in *this
321 if (matching_blocks.size() != Mrhs.dim)
322 {
323 for (size_t qrhs=0; qrhs<Mrhs.size(); ++qrhs)
324 {
325 qarray3<Symmetry::Nq> quple = {Mrhs.in(qrhs), Mrhs.out(qrhs), Mrhs.mid(qrhs)};
326 auto it = find(matching_blocks.begin(), matching_blocks.end(), quple);
327 if (it == matching_blocks.end())
328 {
329 for (size_t a=0; a<Mrhs.block[qrhs].shape()[0]; ++a)
330 {
331 if (Mrhs.block[qrhs][a][0].size() != 0)
332 {
333 MatrixType Mtmp = factor * Mrhs.block[qrhs][a][0]; // 0+factor*Mrhs
334
335 auto ip = Mout.dict.find(quple);
336 if (ip != Mout.dict.end())
337 {
338 assert(1==0 and "Error in Multipede::addScale, block already exists!");
339 }
340 else
341 {
342 boost::multi_array<MatrixType,LEGLIMIT> Mtmpvec(boost::extents[Mrhs.block[qrhs].shape()[0]][1]);
343 Mtmpvec[a][0] = Mtmp;
344 Mout.push_back(quple, Mtmpvec);
345 }
346 }
347 }
348 }
349 }
350 }
351
352 *this = Mout;
353}
354
355template<typename Symmetry, typename MatrixType> using Tripod = Multipede<3,Symmetry,MatrixType>;
356template<typename Symmetry, typename MatrixType> using Quadruped = Multipede<4,Symmetry,MatrixType>;
357
358template<size_t Nlegs, typename Symmetry, typename MatrixType>
360dict_info() const
361{
362 stringstream ss;
363 for (auto it=dict.begin(); it!=dict.end(); ++it)
364 {
365 if (Nlegs==2) {ss << "in: " << it->first[0] << ", out: " << it->first[1];}
366 if (Nlegs==3) {ss << "in: " << it->first[0] << ", out: " << it->first[1] << ", mid:" << it->first[2];}
367 if (Nlegs==4) {ss << "in: " << it->first[0] << ", out: " << it->first[1] << ", bot:" << it->first[2] << ", top:" << it->first[3];}
368 ss << "\t→\t" << it->second << endl;
369 }
370 return ss.str();
371}
372
373template<size_t Nlegs, typename Symmetry, typename MatrixType>
375memory (MEMUNIT memunit) const
376{
377 double res = 0.;
378 for (size_t q=0; q<dim; ++q)
379 for (auto B=block[q].data(); B!=block[q].data()+block[q].num_elements(); ++B)
380 {
381 res += calc_memory(*B, memunit);
382 }
383 return res;
384}
385
386template<size_t Nlegs, typename Symmetry, typename MatrixType>
388overhead (MEMUNIT memunit) const
389{
390 double res = 0.;
391 res += 2. * Nlegs * Symmetry::Nq * calc_memory<int>(dim, memunit); // in,out,mid; dict.keys
392 res += Symmetry::Nq * calc_memory<size_t>(dim, memunit); // dict.vals
393 return res;
394}
395
396template<size_t Nlegs, typename Symmetry, typename MatrixType>
398setZero()
399{
400 for (size_t q=0; q<dim; ++q)
401 for (auto B=block[q].data(); B!=block[q].data()+block[q].num_elements(); ++B)
402 {
403 B->setZero();
404 }
405}
406
407template<size_t Nlegs, typename Symmetry, typename MatrixType>
409clear()
410{
411// for (size_t leg=0; leg<Nlegs; ++leg)
412// {
413// index[leg].clear();
414// }
415 index.clear();
416 block.clear();
417 dict.clear();
418 dim = 0;
419}
420
421//template<size_t Nlegs, typename Symmetry, typename MatrixType>
422//void Multipede<Nlegs,Symmetry,MatrixType>::
423//rebuild_dict()
424//{
425// dict.clear();
426// for (size_t q=0; q<dim; ++q)
427// {
428// std::array<qType,Nlegs> quple;
429// for (size_t leg=0; leg<Nlegs; ++leg)
430// {
431// quple[leg][q] = index[leg][q];
432// }
433// dict.insert({quple,q});
434// }
435//}
436
437template<size_t Nlegs, typename Symmetry, typename MatrixType>
439push_back (std::array<qType,Nlegs> quple, const boost::multi_array<MatrixType,LEGLIMIT> &M)
440{
441// for (size_t leg=0; leg<Nlegs; ++leg)
442// {
443// index[leg].push_back(quple[leg]);
444// }
445 index.push_back(quple);
446 block.push_back(M);
447 dict.insert({quple, dim});
448 ++dim;
449}
450
451template<size_t Nlegs, typename Symmetry, typename MatrixType>
453push_back (std::initializer_list<qType> qlist, const boost::multi_array<MatrixType,LEGLIMIT> &M)
454{
455 assert(qlist.size() == Nlegs);
456 std::array<qType,Nlegs> quple;
457 copy(qlist.begin(), qlist.end(), quple.data());
458 push_back(quple,M);
459}
460
461template<size_t Nlegs, typename Symmetry, typename MatrixType>
463setVacuum()
464{
465 MatrixType Mtmp(1,1); Mtmp << 1.;
466 boost::multi_array<MatrixType,LEGLIMIT> Mtmparray(boost::extents[1][1]);
467 Mtmparray[0][0] = Mtmp;
468
469 std::array<qType,Nlegs> quple;
470 for (size_t leg=0; leg<Nlegs; ++leg)
471 {
472 quple[leg] = Symmetry::qvacuum();
473 }
474
475 push_back(quple, Mtmparray);
476}
477
478template<size_t Nlegs, typename Symmetry, typename MatrixType>
480setTarget (std::array<qType,Nlegs> Q)
481{
482 MatrixType Mtmp(1,1);
483 Mtmp << 1.;
484
485 boost::multi_array<MatrixType,LEGLIMIT> Mtmparray(boost::extents[1][1]);
486 Mtmparray[0][0] = Mtmp;
487
488 push_back(Q,Mtmparray);
489}
490
491template<size_t Nlegs, typename Symmetry, typename MatrixType>
493setTarget (vector<std::array<qType,Nlegs> > Q)
494{
495 MatrixType Mtmp(1,1);
496 Mtmp << 1.;
497
498 boost::multi_array<MatrixType,LEGLIMIT> Mtmparray(boost::extents[1][1]);
499 Mtmparray[0][0] = Mtmp;
500
501 for (const auto &Qval:Q)
502 {
503 push_back(Qval,Mtmparray);
504 }
505}
506
507template<size_t Nlegs, typename Symmetry, typename MatrixType>
509setIdentity (size_t Drows, size_t Dcols, size_t amax, size_t bmax)
510{
511 boost::multi_array<MatrixType,LEGLIMIT> Mtmparray(boost::extents[amax][bmax]);
512 for (size_t a=0; a<amax; ++a)
513 for (size_t b=0; b<bmax; ++b)
514 {
515 MatrixType Mtmp(Drows,Dcols);
516 Mtmp.setIdentity();
517 Mtmparray[a][b] = Mtmp;
518 }
519
520 std::array<qType,Nlegs> quple;
521 for (size_t leg=0; leg<Nlegs; ++leg)
522 {
523 quple[leg] = Symmetry::qvacuum();
524 }
525 push_back(quple, Mtmparray);
526}
527
528template<size_t Nlegs, typename Symmetry, typename MatrixType>
530setIdentity (size_t amax, size_t bmax, const Qbasis<Symmetry> &base, const qarray<Symmetry::Nq> &Q)
531{
532 static_assert(Nlegs == 3);
533 if (amax == 0 or bmax ==0) {return;}
534
535 for (size_t q=0; q<base.Nq(); ++q)
536 {
537 qarray3<Symmetry::Nq> quple = {base[q], base[q], Q};
538// cout << "quple=" << quple[0] << ", " << quple[1] << ", " << quple[2] << endl;
539// qarray3<Symmetry::Nq> checkquple = {base[q], Q, base[q]};
540// if (!Symmetry::triangle(checkquple)) {continue;}
541
542 boost::multi_array<MatrixType,LEGLIMIT> Mtmparray(boost::extents[amax][bmax]);
543 for (size_t a=0; a<amax; ++a)
544 for (size_t b=0; b<bmax; ++b)
545 {
546 MatrixType Mtmp(base.inner_dim(base[q]), base.inner_dim(base[q]));
547 Mtmp.setIdentity();
548 Mtmparray[a][b] = Mtmp;
549 }
550 push_back(quple, Mtmparray);
551 }
552}
553
554template<size_t Nlegs, typename Symmetry, typename MatrixType>
556insert (std::pair<qType,size_t> ab, const Multipede<Nlegs,Symmetry,MatrixType> &Trhs)
557{
558 static_assert(Nlegs == 3);
559
560 for (size_t q=0; q<Trhs.dim; ++q)
561 {
562 if (Trhs.mid(q) != ab.first) {continue;}
563
564 if (Trhs.block[q][ab.second][0].size() == 0) {continue;}
565 qarray3<Symmetry::Nq> quple = {Trhs.in(q), Trhs.out(q), Trhs.mid(q)};
566
567 auto it = dict.find(quple);
568 if (it != dict.end())
569 {
570 if (block[it->second][ab.second][0].rows() == Trhs.block[q][ab.second][0].rows() and
571 block[it->second][ab.second][0].cols() == Trhs.block[q][ab.second][0].cols())
572 {
573// cout << termcolor::green << "operator+= in insert" << termcolor::reset << endl;
574 block[it->second][ab.second][0] += Trhs.block[q][ab.second][0];
575 }
576 else
577 {
578// cout << termcolor::blue << "operator= in insert" << termcolor::reset << "\t" << block[it->second][ab][0].rows() << "x" << block[it->second][ab][0].cols() << endl;
579 block[it->second][ab.second][0] = Trhs.block[q][ab.second][0];
580 }
581 }
582 else
583 {
584// cout << termcolor::red << "push_back in insert" << termcolor::reset << endl;
585 boost::multi_array<MatrixType,LEGLIMIT> Mtmparray(boost::extents[Trhs.block[q].shape()[0]][1]);
586 Mtmparray[ab.second][0] = Trhs.block[q][ab.second][0];
587 push_back(quple, Mtmparray);
588 }
589 }
590}
591
592template<size_t Nlegs, typename Symmetry, typename MatrixType>
594print (const bool &SHOW_MATRICES, const std::size_t &precision) const
595{
596 #ifndef HELPERS_IO_TABLE
597 std::stringstream out;
598 out << "Texttable library is missing. -> no output" << std::endl;
599 return out.str();
600 #else //Use TextTable library for nicer output.
601 std::stringstream out;
602
603 TextTable t( '-', '|', '+' );
604 t.add("ν");
605 t.add("Q_ν");
606 t.add("A_ν");
607 t.endOfRow();
608 for (std::size_t nu=0; nu<dim; nu++)
609 {
610 std::stringstream ss,tt,uu,vv;
611 ss << nu;
612 tt << "(";
613 for (std::size_t q=0; q<index[nu].size(); q++)
614 {
615 tt << Sym::format<Symmetry>(index[nu][q]);
616 if (q==index[nu].size()-1) {tt << ")";} else {tt << ",";}
617 }
618 uu << block[nu].shape()[0] << ":[";
619 // uu << block[nu][0][0].cols() << "x" << block[nu][0][0].rows() << "x" << block[nu].shape()[0];
620 for (std::size_t q=0; q<block[nu].shape()[0]; q++)
621 {
622// if(block[nu][q][0].cols() != 0 or block[nu][q][0].rows() != 0)
623 {
624 uu << "(" << block[nu][q][0].cols() << "x" << block[nu][q][0].rows() << ")";
625 if(q==block[nu].shape()[0]-1) {uu << "";} else {uu << ",";}
626 }
627 }
628 uu << "]";
629 t.add(ss.str());
630 t.add(tt.str());
631 t.add(uu.str());
632 t.endOfRow();
633 }
634 t.setAlignment( 0, TextTable::Alignment::RIGHT );
635 out << t;
636
637 if (SHOW_MATRICES)
638 {
639 out << termcolor::blue << termcolor::underline << "A-tensors:" << termcolor::reset << std::endl;
640 for (std::size_t nu=0; nu<dim; nu++)
641 {
642 out << termcolor::blue << "ν=" << nu << std::endl;
643 for (std::size_t q=0; q<block[nu].shape()[0]; q++)
644 {
645 if(block[nu][q][0].size() == 0) {continue;}
646 out << termcolor::green << "q=" << q << endl << std::setprecision(precision) << std::fixed << block[nu][q][0] << std::endl;
647 }
648 }
649 }
650
651 return out.str();
652#endif
653}
654
655//template<size_t Nlegs, typename Symmetry, typename MatrixType>
656//void Multipede<Nlegs,Symmetry,MatrixType>::
657//shift_Qin (const qarray<Symmetry::Nq> &Q)
658//{
659// assert(Nlegs == 3);
660//
661// auto index_tmp = index;
662// auto block_tmp = block;
663// auto dim_tmp = dim;
664//
665// index.clear();
666// block.clear();
667// dict.clear();
668// dim = 0;
669//
670// for (size_t q=0; q<dim_tmp; ++q)
671// {
672// push_back({index_tmp[q][0]+Q, index_tmp[q][1]+Q, index_tmp[q][2]}, block_tmp[q]);
673// }
674//}
675
676//template<size_t Nlegs, typename Symmetry, typename MatrixType>
677//void Multipede<Nlegs,Symmetry,MatrixType>::
678//shift_Qmid (const qarray<Symmetry::Nq> &Q)
679//{
680// assert(Nlegs == 3);
681//
682// auto index_tmp = index;
683// auto block_tmp = block;
684// auto dim_tmp = dim;
685//
686// index.clear();
687// block.clear();
688// dict.clear();
689// dim = 0;
690//
691// for (size_t q=0; q<dim_tmp; ++q)
692// {
693// push_back({index_tmp[q][0], index_tmp[q][1]+Q, index_tmp[q][2]+Q}, block_tmp[q]);
694// }
695//}
696
697template<size_t Nlegs, typename Symmetry, typename MatrixType>
698typename MatrixType::Scalar Multipede<Nlegs,Symmetry,MatrixType>::
700{
701 double res = 0;
702 for (size_t q=0; q<dim; ++q)
703 {
704 qarray3<Symmetry::Nq> quple = {in(q), out(q), mid(q)};
705 auto it = Mrhs.dict.find(quple);
706 if (it == Mrhs.dict.end()) {return std::numeric_limits<typename MatrixType::Scalar>::infinity();}
707 for (size_t a=0; a<block[q].shape()[0]; ++a)
708 {
709 res += (block[q][a][0]-Mrhs.block[it->second][a][0]).norm();
710 }
711 }
712 return res;
713}
714
715template<size_t Nlegs, typename Symmetry, typename MatrixType>
717BipedSliceQmid (qType qslice) const
718{
719 assert(Nlegs == 3);
720
722 for (size_t q=0; q<dim; ++q)
723 for (size_t a=0; a<block[q].shape()[0]; ++a)
724 {
725 if (mid(q) == qslice)
726 {
727 Bout.push_back(in(q), out(q), block[q][a][0]);
728 }
729 }
730 return Bout;
731}
732
733template<size_t Nlegs, typename Symmetry, typename MatrixType>
735save (string filename, bool PRINT) const
736{
737 //cout << "saving Multipede to: " << filename << endl;
738
739 filename += ".h5";
740 if (PRINT) lout << termcolor::green << "Saving Multipede to: " << filename << termcolor::reset << std::endl;
741 remove(filename.c_str());
742 HDF5Interface target(filename, WRITE);
743
744 target.save_scalar<size_t>(dim, "dim", "");
745
746 for (size_t q=0; q<dim; ++q)
747 {
748 target.save_scalar<size_t>(block[q].shape()[0], make_string("dima_q=",q), "");
749 target.save_scalar<size_t>(block[q].shape()[1], make_string("dimb_q=",q), "");
750 }
751
752 for (size_t q=0; q<dim; ++q)
753 for (size_t a=0; a<block[q].shape()[0]; ++a)
754 for (size_t b=0; b<block[q].shape()[1]; ++b)
755 {
756 if constexpr (std::is_same<typename MatrixType::Scalar,complex<double>>::value)
757 {
758 MatrixXd Re = block[q][a][b].real();
759 MatrixXd Im = block[q][a][b].imag();
760 string label = make_string("block_q=",q,"_a=",a,"_b=",b);
761 target.save_matrix(Re,label+"Re","");
762 target.save_matrix(Im,label+"Im","");
763 }
764 else
765 {
766 target.save_matrix(block[q][a][b], make_string("block_q=",q,"_a=",a,"_b=",b), "");
767 }
768 }
769
770 MatrixXi Min(dim,Symmetry::Nq);
771 MatrixXi Mout(dim,Symmetry::Nq);
772 MatrixXi Mmid(dim,Symmetry::Nq);
773
774 for (int i=0; i<dim; ++i)
775 for (int q=0; q<Symmetry::Nq; ++q)
776 {
777 Min(i,q) = in(i)[q];
778 Mout(i,q) = out(i)[q];
779 Mmid(i,q) = mid(i)[q];
780 }
781/* lout << "Min=" << endl << Min.transpose() << endl;*/
782/* lout << "Mout=" << endl << Mout.transpose() << endl;*/
783/* lout << "Mmid=" << endl << Mmid.transpose() << endl;*/
784/* lout << "Min.rows()=" << Min.rows() << endl;*/
785 //assert(Min.rows() != 0);
786
787 target.save_matrix<int>(Min, "in", "");
788 target.save_matrix<int>(Mout, "out", "");
789 target.save_matrix<int>(Mmid, "mid", "");
790
791 target.close();
792
793 print();
794}
795
796template<size_t Nlegs, typename Symmetry, typename MatrixType>
798load (string filename, bool PRINT)
799{
800 //cout << "loading Multipede from: " << filename << endl;
801
802 filename += ".h5";
803 if (PRINT) lout << termcolor::green << "Loading Multipede from: " << filename << termcolor::reset << std::endl;
804 HDF5Interface source(filename, READ);
805
806 source.load_scalar<size_t>(dim, "dim", "");
807
808 block.clear();
809 block.resize(dim);
810
811 for (size_t q=0; q<dim; ++q)
812 {
813 size_t dima, dimb;
814 source.load_scalar<size_t>(dima, make_string("dima_q=",q), "");
815 source.load_scalar<size_t>(dimb, make_string("dimb_q=",q), "");
816 block[q].resize(boost::extents[dima][dimb]);
817 //cout << "q=" << q << ", dima=" << dima << ", dimb=" << dimb << endl;
818 }
819
820 for (size_t q=0; q<dim; ++q)
821 for (size_t a=0; a<block[q].shape()[0]; ++a)
822 for (size_t b=0; b<block[q].shape()[1]; ++b)
823 {
824 if constexpr (std::is_same<typename MatrixType::Scalar,complex<double>>::value)
825 {
826 MatrixXd Re, Im;
827 string label = make_string("block_q=",q,"_a=",a,"_b=",b);
828 source.load_matrix(Re, label+"Re", "");
829 source.load_matrix(Im, label+"Im", "");
830 block[q][a][b] = Re+1.i*Im;
831 }
832 else
833 {
834 source.load_matrix(block[q][a][b], make_string("block_q=",q,"_a=",a,"_b=",b), "");
835 }
836 }
837
838 MatrixXi Min, Mout, Mmid;
839 source.load_matrix<int>(Min, "in", "");
840 source.load_matrix<int>(Mout, "out", "");
841 source.load_matrix<int>(Mmid, "mid", "");
842 //cout << in.rows() << "\t" << out.rows() << "\t" << mid.rows() << "\t" << L.dim << endl;
843 assert(Min.rows() != 0);
844
845 index.clear();
846 index.resize(dim);
847 dict.clear();
848
849 for (int i=0; i<dim; ++i)
850 {
851 std::array<qType,Nlegs> quple;
852 for (int q=0; q<Symmetry::Nq; ++q)
853 {
854 quple[0][q] = Min(i,q);
855 quple[1][q] = Mout(i,q);
856 quple[2][q] = Mmid(i,q);
857 }
858 index[i] = quple;
859 dict.insert({quple,i});
860 }
861
862 source.close();
863
864 print();
865}
866
867#endif
double norm(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
size_t dim(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
@ B
Definition: DmrgTypedefs.h:130
Multipede< Nlegs, Symmetry, MatrixType > operator-(const Multipede< Nlegs, Symmetry, MatrixType > &M1, const Multipede< Nlegs, Symmetry, MatrixType > &M2)
Definition: Multipede.h:239
Definition: Qbasis.h:39
std::size_t Nq() const
Definition: Qbasis.h:92
Eigen::Index inner_dim(const Eigen::Index &num_in) const
Definition: Qbasis.h:391
std::array< qarray< Nq >, 3 > qarray3
Definition: qarray.h:52
Definition: Biped.h:64
void push_back(qType qin, qType qout, const MatrixType_ &M)
Definition: Biped.h:529
void save(string filename, bool PRINT=false) const
Definition: Multipede.h:735
Biped< Symmetry, MatrixType > BipedSliceQmid(qType qslice=Symmetry::qvacuum()) const
Definition: Multipede.h:717
void setIdentity(size_t amax, size_t bmax, const Qbasis< Symmetry > &base, const qarray< Symmetry::Nq > &Q=Symmetry::qvacuum())
Definition: Multipede.h:530
Multipede()
Definition: Multipede.h:37
vector< std::array< qType, Nlegs > > index
Definition: Multipede.h:77
void setTarget(vector< std::array< qType, Nlegs > > Q)
Definition: Multipede.h:493
void clear()
Definition: Multipede.h:409
unordered_map< std::array< qType, Nlegs >, size_t > dict
Definition: Multipede.h:95
void setVacuum()
Definition: Multipede.h:463
std::size_t size() const
Definition: Multipede.h:67
void insert(std::pair< qType, size_t > ab, const Multipede< Nlegs, Symmetry, MatrixType > &Trhs)
Definition: Multipede.h:556
qType mid(size_t q) const
Definition: Multipede.h:154
double memory(MEMUNIT memunit=GB) const
Definition: Multipede.h:375
constexpr size_t rank() const
Definition: Multipede.h:59
void push_back(std::initializer_list< qType > qlist, const boost::multi_array< MatrixType, LEGLIMIT > &M)
Definition: Multipede.h:453
void setTarget(std::array< qType, Nlegs > Q)
Definition: Multipede.h:480
string dict_info() const
Definition: Multipede.h:360
size_t dim
Definition: Multipede.h:66
string print(const bool &SHOW_MATRICES=false, const size_t &precision=3) const
Definition: Multipede.h:594
qType top(size_t q) const
Definition: Multipede.h:157
void setZero()
Definition: Multipede.h:398
double overhead(MEMUNIT memunit=MB) const
Definition: Multipede.h:388
qType out(size_t q) const
Definition: Multipede.h:153
Multipede< Nlegs, Symmetry, MatrixType > & operator=(const Multipede< Nlegs, Symmetry, MatrixType > &Vin)
Definition: Multipede.h:216
qType in(size_t q) const
Definition: Multipede.h:152
void push_back(std::array< qType, Nlegs > quple, const boost::multi_array< MatrixType, LEGLIMIT > &M)
Definition: Multipede.h:439
MatrixType::Scalar Scalar
Definition: Multipede.h:35
vector< boost::multi_array< MatrixType, LEGLIMIT > > block
Definition: Multipede.h:88
Multipede(const Biped< Symmetry, MatrixType > &B, qType Q=Symmetry::qvacuum())
Definition: Multipede.h:43
Scalar compare(const Multipede< Nlegs, Symmetry, MatrixType > &Mrhs) const
Definition: Multipede.h:699
Symmetry::qType qType
Definition: Multipede.h:34
void load(string filename, bool PRINT=false)
Definition: Multipede.h:798
Multipede< Nlegs, Symmetry, OtherMatrixType > cast() const
Definition: Multipede.h:180
qType bot(size_t q) const
Definition: Multipede.h:156
void addScale(const Scalar &factor, const Multipede< Nlegs, Symmetry, MatrixType > &Mrhs)
Definition: Multipede.h:258
void setIdentity(size_t Drows, size_t Dcols, size_t amax=1, size_t bmax=1)
Definition: Multipede.h:509
Definition: qarray.h:26