VMPS++
Loading...
Searching...
No Matches
Biped.h
Go to the documentation of this file.
1#ifndef STRAWBERRY_BIPED
2#define STRAWBERRY_BIPED
3
5#include <unordered_map>
6#include <unordered_set>
8
9#include "termcolor.hpp" // from TOOLS
10
11#include "macros.h" // from TOOLS
12#include "MemCalc.h" // from TOOLS
13#include "RandomVector.h"
14
15//include "DmrgExternal.h"
16#include "symmetry/functions.h"
17#include "DmrgConglutinations.h"
18
19double xlogx (double x)
20{
21 if (x > 0.0)
22 {
23 if (x < 1e-30)
24 {
25 // For very small x, x * log(x) is effectively 0
26 return 0.0;
27 }
28 else
29 {
30 // Direct computation for larger x
31 return x * log(x);
32 }
33 }
34 else if (x == 0.0)
35 {
36 return 0.0; // mathematically, limit of x*log(x) as x approaches 0 is 0
37 }
38 else
39 {
40 return NAN; // log(x) is not defined for negative x
41 }
42}
43
44template<typename Symmetry>
45class Qbasis;
46
47namespace contract {
49}
50
51// using namespace std;
52
62template<typename Symmetry, typename MatrixType_>
63struct Biped
64{
65private:
66 typedef typename Symmetry::qType qType;
67 typedef Eigen::Index Index;
68public:
69 typedef MatrixType_ MatrixType;
70private:
71 typedef typename MatrixType_::Scalar Scalar;
72
73public:
74
75 Biped(){dim=0;}
76
78
82 std::size_t dim;
83 inline std::size_t size() const {return dim;}
84 inline void plusplus() {++dim;}
85
87 std::vector<qType> in;
88
90 std::vector<qType> out;
91
96 std::vector<MatrixType_> block;
98
100
104 std::unordered_map<std::array<qType,2>,std::size_t> dict; // key format: {qin,qout}
105
107
108 Eigen::VectorXi rows(bool FULL=false) const;
110 Eigen::VectorXi cols(bool FULL=false) const;
112 double operatorNorm(bool COLWISE=true) const;
114 double norm() const;
116 Eigen::VectorXd squaredNorm() const;
118
120 std::string formatted () const;
121
127 std::string print (const bool SHOW_MATRICES=false , const std::size_t precision=3 ) const;
128
130 std::string print_dict() const;
131
133 double memory (MEMUNIT memunit=GB) const;
134
136 double overhead (MEMUNIT memunit=MB) const;
138
140
141 void clear();
142
144 void setZero();
145
147 void setRandom();
148
153 void setVacuum();
154
159 void setTarget (qType Qtot);
160
161 void setTarget (vector<qType> Qmulti);
162
163 void setIdentity (const Qbasis<Symmetry> &base1, const Qbasis<Symmetry> &base2, qType Q = Symmetry::qvacuum());
164
165 void setRandom (const Qbasis<Symmetry> &base1, const Qbasis<Symmetry> &base2, qType Q = Symmetry::qvacuum());
166
167 void setZero (const Qbasis<Symmetry> &base1, const Qbasis<Symmetry> &base2, qType Q = Symmetry::qvacuum());
169
171
173
175
181
183
185
193 Biped<Symmetry,MatrixType_> adjustQN (const size_t number_cells);
194
196
197 template<typename EpsScalar>
198 tuple<Biped<Symmetry,MatrixType_>,Biped<Symmetry,MatrixType_>,Biped<Symmetry,MatrixType_> >
199 truncateSVD (size_t minKeep, size_t maxKeep, EpsScalar eps_svd, double &truncWeight, double &entropy, map<qarray<Symmetry::Nq>,Eigen::ArrayXd> &SVspec, bool PRESERVE_MULTIPLETS=true, bool RETURN_SPEC=true) const;
200
201 template<typename EpsScalar>
202 tuple<Biped<Symmetry,MatrixType_>,Biped<Symmetry,MatrixType_>,Biped<Symmetry,MatrixType_> > truncateSVD (size_t minKeep, size_t maxKeep, EpsScalar eps_svd, double &truncWeight, bool PRESERVE_MULTIPLETS=true) const
203 {
204 double S_dumb;
205 map<qarray<Symmetry::Nq>,Eigen::ArrayXd> SVspec_dumb;
206 return truncateSVD(minKeep, maxKeep, eps_svd, truncWeight, S_dumb, SVspec_dumb, PRESERVE_MULTIPLETS, false); //false: Dont return singular value spectrum
207 }
208
209 pair<Biped<Symmetry,MatrixType_>,Biped<Symmetry,MatrixType_> >
210 QR(bool RETURN_LQ=false, bool MAKE_UNIQUE=false) const;
211
217
218 void addScale (const Scalar &factor, const Biped<Symmetry,MatrixType_> &Mrhs, BLOCK_POSITION BP = SAME_PLACE);
219
220 void addScale_extend (const Scalar &factor, const Biped<Symmetry,MatrixType_> &Mrhs);
221
229
231 Scalar trace() const;
232
233 template<typename expScalar>
234 Biped<Symmetry,MatrixType_> exp( const expScalar x ) const;
235
237
241 void push_back (qType qin, qType qout, const MatrixType_ &M);
242
248 void push_back (std::array<qType,2> quple, const MatrixType_ &M);
249
250 void try_push_back (std::array<qType,2> quple, const MatrixType_ &M);
251 void try_push_back (qType qin, qType qout, const MatrixType_ &M);
252
253 void create_block (std::array<qType,2> quple);
254 void try_create_block (std::array<qType,2> quple);
256
257 template<typename OtherMatrixType>
259 {
260 dict = Brhs.dict;
261 in = Brhs.in;
262 out = Brhs.out;
263 dim = Brhs.dim;
264 block.resize(dim);
265 }
266
267 template<typename OtherMatrixType>
269 {
271 Vout.outerResize(*this);
272
273 for (size_t q=0; q<dim; ++q)
274 {
275 Vout.block[q] = block[q].template cast<typename OtherMatrixType::Scalar>();
276 }
277
278 return Vout;
279 }
280
282 {
283 auto in_tmp = in;
284 auto out_tmp = out;
285 auto block_tmp = block;
286 auto dim_tmp = dim;
287
288 in.clear();
289 out.clear();
290 block.clear();
291 dict.clear();
292 dim = 0;
293
294 for (size_t q=0; q<dim_tmp; ++q)
295 {
296// cout << "q=" << ", in=" << in[q]+Q << ", out=" << out[q]+Q << endl;
297 push_back({in[q]+Q, out[q]+Q}, block_tmp[q]);
298 }
299
300// for (size_t q=0; q<dim_tmp; ++q)
301// {
302// auto qnews = Symmetry::reduceSilent(in[q],Q);
303// for (const auto &qnew : qnews)
304// {
305// double factor_cgc = Symmetry::coeff_rightOrtho(qnew,in[q]);
306// auto it = dict.find(qarray2<Symmetry::Nq>{qnew,qnew});
307// if (it != dict.end())
308// {
309// cout << block[it->second].rows() << "x" << block[it->second].cols() << endl;
310// cout << block_tmp[q].rows() << "x" << block_tmp[q].cols() << endl;
311//
312// block[it->second] += factor_cgc*block_tmp[q];
313// }
314// else
315// {
316// push_back({qnew,qnew}, factor_cgc*block_tmp[q]);
317// }
318// }
319// }
320 }
321};
322
323template<typename Symmetry, typename MatrixType_>
325clear()
326{
327 in.clear();
328 out.clear();
329 block.clear();
330 dict.clear();
331 dim = 0;
332}
333
334template<typename Symmetry, typename MatrixType_>
336setZero()
337{
338 for (std::size_t q=0; q<dim; ++q) {block[q].setZero();}
339}
340
341template<typename Symmetry, typename MatrixType_>
343setRandom()
344{
345 for (std::size_t q=0; q<dim; ++q) {block[q].setRandom();}
346}
347
348template<typename Symmetry, typename MatrixType_>
350setVacuum()
351{
352 MatrixType_ Mtmp(1,1); Mtmp << 1.;
353 push_back(Symmetry::qvacuum(), Symmetry::qvacuum(), Mtmp);
354}
355
356template<typename Symmetry, typename MatrixType_>
358setIdentity (const Qbasis<Symmetry> &base1, const Qbasis<Symmetry> &base2, qType Q)
359{
360 for (size_t q1=0; q1<base1.Nq(); ++q1)
361 for (size_t q2=0; q2<base2.Nq(); ++q2)
362 {
363 if (Symmetry::triangle(qarray3<Symmetry::Nq>{base1[q1],Q,base2[q2]}))
364 // if (base1[q1] == base2[q2])
365 {
366 MatrixType Mtmp(base1.inner_dim(base1[q1]), base2.inner_dim(base2[q2]));
367 Mtmp.setIdentity();
368 push_back(base1[q1], base2[q2], Mtmp);
369 }
370 }
371}
372
373template<typename Symmetry, typename MatrixType_>
375setRandom (const Qbasis<Symmetry> &base1, const Qbasis<Symmetry> &base2, qType Q)
376{
377 for (size_t q1=0; q1<base1.Nq(); ++q1)
378 for (size_t q2=0; q2<base2.Nq(); ++q2)
379 {
380 if (Symmetry::triangle(qarray3<Symmetry::Nq>{base1[q1],Q,base2[q2]}))
381 {
382 MatrixType Mtmp(base1.inner_dim(base1[q1]), base2.inner_dim(base2[q2]));
383 for (size_t a1=0; a1<Mtmp.rows(); ++a1)
384 for (size_t a2=0; a2<Mtmp.cols(); ++a2)
385 {
386 Mtmp(a1,a2) = threadSafeRandUniform<typename MatrixType_::Scalar>(-1.,1.);
387 }
388 push_back(base1[q1], base2[q2], Mtmp);
389 }
390 }
391}
392
393template<typename Symmetry, typename MatrixType_>
395setZero (const Qbasis<Symmetry> &base1, const Qbasis<Symmetry> &base2, qType Q)
396{
397 for (size_t q1=0; q1<base1.Nq(); ++q1)
398 for (size_t q2=0; q2<base2.Nq(); ++q2)
399 {
400 if (Symmetry::triangle(qarray3<Symmetry::Nq>{base1[q1],Q,base2[q2]}))
401 {
402 MatrixType Mtmp(base1.inner_dim(base1[q1]), base2.inner_dim(base2[q2]));
403 Mtmp.setZero();
404 // for (size_t a1=0; a1<Mtmp.rows(); ++a1)
405 // for (size_t a2=0; a2<Mtmp.cols(); ++a2)
406 // {
407 // Mtmp(a1,a2) = threadSafeRandUniform<typename MatrixType_::Scalar>(-1.,1.);
408 // }
409 push_back(base1[q1], base2[q2], Mtmp);
410 }
411 }
412}
413
414template<typename Symmetry, typename MatrixType_>
416setTarget (qType Qtot)
417{
418 MatrixType_ Mtmp(1,1);
419 Mtmp << 1.;
420// Mtmp << Symmetry::coeff_dot(Qtot);
421 push_back(Qtot, Qtot, Mtmp);
422}
423
424template<typename Symmetry, typename MatrixType_>
426setTarget (vector<qType> Qmulti)
427{
428 MatrixType_ Mtmp(1,1);
429 Mtmp << 1.;
430// Mtmp << Symmetry::coeff_dot(Qtot);
431 for (const auto &Qtot:Qmulti)
432 {
433 push_back(Qtot, Qtot, Mtmp);
434 }
435}
436
437template<typename Symmetry, typename MatrixType_>
439rows (bool FULL) const
440{
441 std::unordered_set<qType> uniqueControl;
442 Index count=0;
443 for (std::size_t nu=0; nu<size(); nu++)
444 {
445 if(auto it=uniqueControl.find(in[nu]); it == uniqueControl.end()){
446 uniqueControl.insert(in[nu]); count++;
447 }
448 }
449 Eigen::VectorXi Vout(count);
450 count=0;
451 uniqueControl.clear();
452 for (std::size_t nu=0; nu<size(); nu++)
453 {
454 if(auto it=uniqueControl.find(in[nu]) == uniqueControl.end()){
455 uniqueControl.insert(in[nu]);
456 if(FULL) { Vout[count] = Symmetry::degeneracy(in[nu])*block[nu].rows() ; }
457 else { Vout[count] = block[nu].rows(); }
458 count++;
459 }
460 }
461 return Vout;
462}
463
464template<typename Symmetry, typename MatrixType_>
466cols (bool FULL) const
467{
468 std::unordered_set<qType> uniqueControl;
469 Index count=0;
470 for (std::size_t nu=0; nu<size(); nu++)
471 {
472 if(auto it=uniqueControl.find(out[nu]); it == uniqueControl.end()){
473 uniqueControl.insert(out[nu]); count++;
474 }
475 }
476 Eigen::VectorXi Vout(count);
477 count=0;
478 uniqueControl.clear();
479 for (std::size_t nu=0; nu<size(); nu++)
480 {
481 if(auto it=uniqueControl.find(out[nu]) == uniqueControl.end()){
482 uniqueControl.insert(out[nu]);
483 if(FULL) { Vout[count] = Symmetry::degeneracy(out[nu])*block[nu].cols(); }
484 else { Vout[count] = block[nu].cols(); }
485 count++;
486 }
487 }
488
489 return Vout;
490}
491
492template<typename Symmetry, typename MatrixType_>
494operatorNorm (bool COLWISE) const
495{
496 double norm = 0.;
497 for (size_t q=0; q<dim; q++)
498 {
499 if (COLWISE)
500 {
501 if (block[q].cwiseAbs().colwise().sum().maxCoeff() > norm) { norm=block[q].cwiseAbs().colwise().sum().maxCoeff(); }
502 }
503 else { if (block[q].cwiseAbs().rowwise().sum().maxCoeff() > norm) { norm=block[q].cwiseAbs().rowwise().sum().maxCoeff(); } }
504 }
505 return norm;
506}
507
508template<typename Symmetry, typename MatrixType_>
510norm () const
511{
512 return std::sqrt(squaredNorm().sum());
513 // Eigen::VectorXd Vout(size());
514 // for (std::size_t nu=0; nu<size(); nu++) { Vout[nu] = block[nu].norm(); }
515 // return Vout;
516}
517
518template<typename Symmetry, typename MatrixType_>
520squaredNorm () const
521{
522 Eigen::VectorXd Vout(size());
523 for (std::size_t nu=0; nu<size(); nu++) { Vout[nu] = block[nu].squaredNorm() * Symmetry::coeff_dot(in[nu]); }
524 return Vout;
525}
526
527template<typename Symmetry, typename MatrixType_>
529push_back (qType qin, qType qout, const MatrixType_ &M)
530{
531 push_back({qin,qout},M);
532}
533
534template<typename Symmetry, typename MatrixType_>
536push_back (std::array<qType,2> quple, const MatrixType_ &M)
537{
538 assert(dict.find(quple) == dict.end() and "Block already exists in Biped!");
539 in.push_back(quple[0]);
540 out.push_back(quple[1]);
541 block.push_back(M);
542 dict.insert({quple, dim});
543 ++dim;
544}
545
546template<typename Symmetry, typename MatrixType_>
548try_push_back (qType qin, qType qout, const MatrixType_ &M)
549{
550 try_push_back({qin,qout},M);
551}
552
553template<typename Symmetry, typename MatrixType_>
555try_push_back (std::array<qType,2> quple, const MatrixType_ &M)
556{
557 if (dict.find(quple) == dict.end())
558 {
559 in.push_back(quple[0]);
560 out.push_back(quple[1]);
561 block.push_back(M);
562 dict.insert({quple, dim});
563 ++dim;
564 }
565}
566
567template<typename Symmetry, typename MatrixType_>
569create_block (std::array<qType,2> quple)
570{
571 assert(dict.find(quple) == dict.end() and "Block already exists in Biped!");
572 in.push_back(quple[0]);
573 out.push_back(quple[1]);
574 MatrixType_ Mtmp(0,0);
575 block.push_back(Mtmp);
576 dict.insert({quple, dim});
577 ++dim;
578}
579
580template<typename Symmetry, typename MatrixType_>
582try_create_block (std::array<qType,2> quple)
583{
584 if (dict.find(quple) == dict.end())
585 {
586 in.push_back(quple[0]);
587 out.push_back(quple[1]);
588 MatrixType_ Mtmp(0,0);
589 block.push_back(Mtmp);
590 dict.insert({quple, dim});
591 ++dim;
592 }
593}
594
595template<typename Symmetry, typename MatrixType_>
597cleaned() const
598{
600 for (size_t q=0; q<dim; ++q)
601 {
602 if (block[q].size() > 0)
603 {
604 Aout.try_push_back(in[q], out[q], block[q]);
605 }
606 }
607 return Aout;
608}
609
610template<typename Symmetry, typename MatrixType_>
612sorted() const
613{
615 set<qarray2<Symmetry::Nq> > quples;
616 for (size_t q=0; q<dim; ++q)
617 {
618 quples.insert(qarray2<Symmetry::Nq>{in[q], out[q]});
619 }
620 for (const auto &quple:quples)
621 {
622 auto it = dict.find(quple);
623 Aout.push_back(quple, block[it->second]);
624 }
625 return Aout;
626}
627
628template<typename Symmetry, typename MatrixType_>
630adjoint() const
631{
633 Aout.dim = dim;
634 Aout.in = out;
635 Aout.out = in;
636
637 // new dict with reversed keys {qin,qout}->{qout,qin}
638 for (auto it=dict.begin(); it!=dict.end(); ++it)
639 {
640 auto qin = get<0>(it->first);
641 auto qout = get<1>(it->first);
642 Aout.dict.insert({{qout,qin}, it->second});
643 }
644
645 Aout.block.resize(dim);
646 for (std::size_t q=0; q<dim; ++q)
647 {
648 Aout.block[q] = block[q].adjoint();
649 }
650
651 return Aout;
652}
653
654template<typename Symmetry, typename MatrixType_>
656transpose() const
657{
659 Aout.dim = dim;
660 Aout.in = out;
661 Aout.out = in;
662
663 // new dict with reversed keys {qin,qout}->{qout,qin}
664 for (auto it=dict.begin(); it!=dict.end(); ++it)
665 {
666 auto qin = Symmetry::flip(get<0>(it->first));
667 auto qout = Symmetry::flip(get<1>(it->first));
668 Aout.dict.insert({{qout,qin}, it->second});
669 }
670
671 Aout.block.resize(dim);
672 for (std::size_t q=0; q<dim; ++q)
673 {
674 Aout.block[q] = block[q].transpose();
675 }
676
677 return Aout;
678}
679
680template<typename Symmetry, typename MatrixType_>
682conjugate() const
683{
685 Aout.dim = dim;
686 Aout.in = in;
687 Aout.out = out;
688// Aout.in = out;
689// Aout.out = in;
690
691 // new dict with same keys
692 for (auto it=dict.begin(); it!=dict.end(); ++it)
693 {
694 auto qin = get<0>(it->first);
695 auto qout = get<1>(it->first);
696 Aout.dict.insert({{qin,qout}, it->second});
697// Aout.dict.insert({{qout,qin}, it->second});
698 }
699
700 Aout.block.resize(dim);
701 for (std::size_t q=0; q<dim; ++q)
702 {
703 Aout.block[q] = block[q].conjugate();
704 }
705
706 return Aout;
707}
708
709template<typename Symmetry, typename MatrixType_>
711adjustQN (const size_t number_cells)
712{
714 Aout.dim = dim;
715 Aout.block = block;
716 Aout.in.resize(dim);
717 Aout.out.resize(dim);
718 for (std::size_t q=0; q<dim; ++q)
719 {
720 Aout.in[q] = ::adjustQN<Symmetry>(in[q],number_cells);
721 Aout.out[q] = ::adjustQN<Symmetry>(out[q],number_cells);
722 Aout.dict.insert({{Aout.in[q],Aout.out[q]},q});
723 }
724 return Aout;
725}
726
727template<typename Symmetry, typename MatrixType_>
730{
731 res = *this;
732 for (size_t q=0; q<res.dim; q++)
733 {
734 MatrixType Mtmp = res.block[q];
735 Eigen::LLT Jim(Mtmp);
736 res.block[q] = Jim.matrixL();
737 }
738 return;
739}
740
741template<typename Symmetry, typename MatrixType_>
742template<typename EpsScalar>
744truncateSVD (size_t minKeep, size_t maxKeep, EpsScalar eps_truncWeight, double &truncWeight, double &entropy, map<qarray<Symmetry::Nq>,Eigen::ArrayXd> &SVspec, bool PRESERVE_MULTIPLETS, bool RETURN_SPEC) const
745{
746 entropy = 0.;
747 truncWeight = 0;
748 Biped<Symmetry,MatrixType_> U,Vdag,Sigma;
749 Biped<Symmetry,MatrixType_> trunc_U,trunc_Vdag,trunc_Sigma;
750 vector<pair<typename Symmetry::qType, double> > allSV;
751
752 for (size_t q=0; q<dim; ++q)
753 {
754 #ifdef DONT_USE_BDCSVD
755// cout << "JacobiSVD" << endl;
756 JacobiSVD<MatrixType> Jack; // standard SVD
757 #else
758// cout << "BDCSVD" << endl;
759 BDCSVD<MatrixType> Jack; // "Divide and conquer" SVD (only available in Eigen)
760 #endif
761
762// cout << "begin Jack.compute" << endl;
763// cout << "block[q]=" << endl << block[q] << endl;
764// cout << "begin Jack: " << block[q].rows() << "x" << block[q].cols() << endl;
765 Jack.compute(block[q], ComputeThinU|ComputeThinV);
766// cout << "end Jack.compute" << endl;
767// cout << "Jack computation done!" << endl;
768 for (size_t i=0; i<Jack.singularValues().size(); i++) {allSV.push_back(make_pair(in[q],std::real(Jack.singularValues()(i))));}
769 // for (const auto& s:Jack.singularValues()) {allSV.push_back(make_pair(in[q],s));}
770
771 U.push_back(in[q], out[q], Jack.matrixU());
772 Sigma.push_back(in[q], out[q], Jack.singularValues().asDiagonal());
773 Vdag.push_back(in[q], out[q], Jack.matrixV().adjoint());
774 //lout << "q=" << q << ", SV=" << Jack.singularValues().transpose() << endl;
775 }
776 size_t numberOfStates = allSV.size();
777 std::sort(allSV.begin(),allSV.end(),[](const pair<typename Symmetry::qType, double> &sv1, const pair<typename Symmetry::qType, double> &sv2) {return sv1.second > sv2.second;});
778// for (size_t i=maxKeep; i<allSV.size(); i++)
779// {
780// truncWeight += Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
781// }
782
783 //Use eps_svd:
784 /*
785 for (int i=0; i<allSV.size(); ++i)
786 {
787 if (allSV[i].second < eps_svd)
788 {
789 truncWeight += Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
790 }
791 }
792 // std::erase_if(allSV, [eps_svd](const pair<typename Symmetry::qType, Scalar> &sv) { return (sv < eps_svd); }); c++-20 version
793 allSV.erase(std::remove_if(allSV.begin(), allSV.end(), [eps_svd](const pair<typename Symmetry::qType, double> &sv) { return (sv.second < eps_svd); }), allSV.end());
794 */
795
796 // Use eps_truncWeight:
797 int numberOfDiscardedStates = 0;
798 for (int i=allSV.size()-1; i>=0; --i)
799 {
800 double truncWeightIncr = Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
801 //lout << "i=" << i << ", truncWeight=" << truncWeight << ", truncWeightIncr=" << truncWeightIncr << ", numberOfDiscardedStates=" << numberOfDiscardedStates << endl;
802 if (truncWeight+truncWeightIncr < eps_truncWeight)
803 {
804 truncWeight += truncWeightIncr;
805 numberOfDiscardedStates += 1;
806 }
807 }
808 //assert(numberOfDiscardedStates < allSV.size());
809 if (numberOfDiscardedStates >= allSV.size())
810 {
811 numberOfDiscardedStates = 0;
812 truncWeight = 0.;
813 }
814 //lout << "all=" << allSV.size() << ", discarded=" << numberOfDiscardedStates << ", truncWeight=" << truncWeight << ", eps_truncWeight=" << eps_truncWeight << endl;
815 int numberOfKeptStates = allSV.size()-numberOfDiscardedStates;
816
817 if (numberOfKeptStates <= maxKeep and numberOfKeptStates >= min(minKeep,numberOfStates))
818 {
819 allSV.resize(numberOfKeptStates);
820 }
821 else if (numberOfKeptStates <= maxKeep and numberOfKeptStates <= min(minKeep,numberOfStates))
822 {
823 numberOfKeptStates = min(minKeep,numberOfStates);
824 truncWeight = 0;
825 for (int i=allSV.size()-1; i>numberOfKeptStates; --i)
826 {
827 truncWeight += Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
828 }
829 allSV.resize(numberOfKeptStates);
830 }
831 else if (numberOfKeptStates > maxKeep)
832 {
833 numberOfKeptStates = min(maxKeep,numberOfStates);
834 truncWeight = 0;
835 for (int i=allSV.size()-1; i>numberOfKeptStates; --i)
836 {
837 truncWeight += Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
838 }
839 allSV.resize(numberOfKeptStates);
840 }
841 else
842 {
843 lout << "numberOfKeptStates=" << numberOfKeptStates << ", minKeep=" << minKeep << ", maxKeep=" << maxKeep << ", numberOfStates=" << numberOfStates << endl;
844 throw;
845 }
846
847 // cout << "saving sv for expansion to file, #sv=" << allSV.size() << endl;
848 // ofstream Filer("sv_expand");
849 // size_t index=0;
850 // for (const auto & [q,sv]: allSV)
851 // {
852 // Filer << index << "\t" << sv << endl;
853 // index++;
854 // }
855 // Filer.close();
856
857 if (PRESERVE_MULTIPLETS)
858 {
859 //cutLastMultiplet(allSV);
860 int endOfMultiplet=-1;
861 for (int i=allSV.size()-1; i>0; i--)
862 {
863 EpsScalar rel_diff = 2*(allSV[i-1].second-allSV[i].second)/(allSV[i-1].second+allSV[i].second);
864 if (rel_diff > 0.1) {endOfMultiplet = i; break;}
865 }
866 if (endOfMultiplet != -1)
867 {
868 cout << termcolor::red << "Cutting of the last " << allSV.size()-endOfMultiplet << " singular values to preserve the multiplet" << termcolor::reset << endl;
869 allSV.resize(endOfMultiplet);
870 }
871 }
872
873 //cout << "Adding " << allSV.size() << " states from " << numberOfStates << " states" << endl;
874 map<typename Symmetry::qType, vector<Scalar> > qn_orderedSV;
875 for (const auto &[q,s] : allSV)
876 {
877 qn_orderedSV[q].push_back(s);
878 //entropy += -Symmetry::degeneracy(q) * s*s * std::log(s*s);
879 entropy += -Symmetry::degeneracy(q) * xlogx(s*s);
880 }
881 for (const auto & [q,vec_sv]: qn_orderedSV)
882 {
883 size_t Nret = vec_sv.size();
884 // cout << "q=" << q << ", Nret=" << Nret << endl;
885 auto itSigma = Sigma.dict.find({q,q});
886 trunc_Sigma.push_back(q,q,Sigma.block[itSigma->second].diagonal().head(Nret).asDiagonal());
887 if (RETURN_SPEC)
888 {
889 SVspec.insert(make_pair(q, Sigma.block[itSigma->second].diagonal().head(Nret).real()));
890 }
891 auto itU = U.dict.find({q,q});
892 trunc_U.push_back(q, q, U.block[itU->second].leftCols(Nret));
893 auto itVdag = Vdag.dict.find({q,q});
894 trunc_Vdag.push_back(q, q, Vdag.block[itVdag->second].topRows(Nret));
895 }
896 return make_tuple(trunc_U,trunc_Sigma,trunc_Vdag);
897}
898
899template<typename Symmetry, typename MatrixType_>
901QR(bool RETURN_LQ, bool MAKE_UNIQUE) const
902{
904 for (size_t q=0; q<dim; ++q)
905 {
906 HouseholderQR<MatrixType> Quirinus;
907 Quirinus.compute(block[q]);
908
909 MatrixType Qmat, Rmat;
910 if (RETURN_LQ)
911 {
912 Qmat = (Quirinus.householderQ() * MatrixType::Identity(block[q].rows(),block[q].cols())).adjoint();
913 Rmat = (MatrixType::Identity(block[q].cols(),block[q].rows()) * Quirinus.matrixQR().template triangularView<Upper>()).adjoint();
914 }
915 else
916 {
917 Qmat = Quirinus.householderQ() * MatrixType::Identity(block[q].rows(),block[q].cols());
918 Rmat = MatrixType::Identity(block[q].cols(),block[q].rows()) * Quirinus.matrixQR().template triangularView<Upper>();
919 }
920 if (MAKE_UNIQUE)
921 {
922 //make the QR decomposition unique by enforcing the diagonal of R to be positive.
923 DiagonalMatrix<Scalar,Dynamic> Sign = Rmat.diagonal().cwiseSign().matrix().asDiagonal();
924 Rmat = Sign*Rmat;
925 Qmat = Qmat*Sign;
926 }
927
928 Q.push_back(in[q], out[q], Qmat);
929 R.push_back(in[q], out[q], Rmat);
930 }
931 return make_pair(Q,R);
932}
933
934template<typename Symmetry, typename MatrixType_>
935typename MatrixType_::Scalar Biped<Symmetry,MatrixType_>::
936trace() const
937{
938 typename MatrixType_::Scalar res=0.;
939 for (std::size_t nu=0; nu<size(); nu++)
940 {
941 assert(in[nu] == out[nu] and "A trace can only be taken from a matrix");
942 res += block[nu].trace()*Symmetry::coeff_dot(in[nu]);
943 }
944 return res;
945}
946
947template<typename Symmetry, typename MatrixType_>
949{
950 std::vector<std::size_t> addenda;
951
952 for (std::size_t q=0; q<Arhs.dim; ++q)
953 {
954 std::array<qType,2> quple = {Arhs.in[q], Arhs.out[q]};
955 auto it = dict.find(quple);
956
957 if (it != dict.end())
958 {
959 block[it->second] += Arhs.block[q];
960 }
961 else
962 {
963 addenda.push_back(q);
964 }
965 }
966
967 for (size_t q=0; q<addenda.size(); ++q)
968 {
969 push_back(Arhs.in[addenda[q]], Arhs.out[addenda[q]], Arhs.block[addenda[q]]);
970 }
971
972 return *this;
973}
974template<typename Symmetry, typename MatrixType_>
976contract (const Biped<Symmetry,MatrixType_> &A, const contract::MODE MODE) const
977{
979 Scalar factor_cgc;
980 for (std::size_t q1=0; q1<this->size(); ++q1)
981 for (std::size_t q2=0; q2<A.size(); ++q2)
982 {
983 if (this->out[q1] == A.in[q2])
984 {
985 if (this->in[q1] == A.out[q2])
986 {
987 if (this->block[q1].size() != 0 and A.block[q2].size() != 0)
988 {
989 factor_cgc = Scalar(1);
990 if (MODE == contract::MODE::OORR)
991 {
992 // factor_cgc = Symmetry::coeff_rightOrtho(this->out[q1],this->in[q2]);
993 factor_cgc = Symmetry::coeff_rightOrtho(this->out[q1],this->in[q1]);
994 }
995 else if (MODE == contract::MODE::DOT)
996 {
997 factor_cgc = Symmetry::coeff_dot(this->out[q1]);
998 }
999 if (auto it = Ares.dict.find({{this->in[q1],A.out[q2]}}); it == Ares.dict.end())
1000 {
1001 Ares.push_back(this->in[q1], A.out[q2], factor_cgc*this->block[q1]*A.block[q2]);
1002 }
1003 else
1004 {
1005 Ares.block[it->second] += factor_cgc*this->block[q1]*A.block[q2];
1006 }
1007 }
1008 }
1009 }
1010 }
1011 return Ares;
1012}
1013
1014// Note: multiplication of Bipes which are not neccesarily singlets. So on does not have qin = qout.
1015template<typename Symmetry, typename MatrixType_>
1017{
1019 for (std::size_t q1=0; q1<A1.dim; ++q1)
1020 for (std::size_t q2=0; q2<A2.dim; ++q2)
1021 {
1022 if (A1.out[q1] == A2.in[q2] and A1.block[q1].size() != 0 and A2.block[q2].size() != 0)
1023 {
1024 auto it = Ares.dict.find(qarray2<Symmetry::Nq>{A1.in[q1],A2.out[q2]});
1025 if (it != Ares.dict.end())
1026 {
1027// cout << "adding" << endl;
1028// cout << Ares.block[it->second].rows() << "x" << Ares.block[it->second].cols() << endl;
1029// cout << A1.block[q1].rows() << "x" << A1.block[q1].cols() << endl;
1030// cout << A2.block[q2].rows() << "x" << A2.block[q2].cols() << endl;
1031// cout << endl;
1032 Ares.block[it->second] += A1.block[q1]*A2.block[q2];
1033 }
1034 else
1035 {
1036// cout << "pushing" << endl;
1037// cout << A1.block[q1].rows() << "x" << A1.block[q1].cols() << endl;
1038// cout << A2.block[q2].rows() << "x" << A2.block[q2].cols() << endl;
1039// cout << endl;
1040 Ares.push_back(A1.in[q1], A2.out[q2], A1.block[q1]*A2.block[q2]);
1041 }
1042 }
1043 }
1044 return Ares;
1045}
1046
1047template<typename Symmetry, typename MatrixType_, typename Scalar>
1049{
1051 for (std::size_t q=0; q<Ares.dim; ++q)
1052 {
1053 Ares.block[q] *= alpha;
1054 }
1055 return Ares;
1056}
1057
1058// template<typename Symmetry, typename MatrixType_>
1059// Biped<Symmetry,MatrixType_> operator+ (const Biped<Symmetry,MatrixType_> &A1, const Biped<Symmetry,MatrixType_> &A2)
1060// {
1061// Biped<Symmetry,MatrixType_> Ares = A1;
1062// Ares += A2;
1063// return Ares;
1064// }
1065
1066template<typename Symmetry, typename MatrixType_>
1067template<typename expScalar>
1069exp( const expScalar x ) const
1070{
1071 // assert( this->legs[0].getDir() == dir::in and this->legs[1].getDir() == dir::out and "We need a regular matrix for exponentials.");
1073
1074 for (std::size_t nu=0; nu<size(); nu++)
1075 {
1076 MatrixType_ A;
1077 A = block[nu] * x;
1078 MatrixType_ Aexp = A.exp();
1079 Mout.push_back(this->in[nu], this->out[nu], Aexp);
1080 }
1081 return Mout;
1082}
1083
1084template<typename Symmetry, typename MatrixType_>
1086print_dict() const
1087{
1088 std::stringstream ss;
1089 for (auto it=dict.begin(); it!=dict.end(); ++it)
1090 {
1091 ss << "in:" << get<0>(it->first) << "\tout:" << get<1>(it->first) << "\t→\t" << it->second << endl;
1092 }
1093 return ss.str();
1094}
1095
1096template<typename Symmetry, typename MatrixType_>
1098memory (MEMUNIT memunit) const
1099{
1100 double res = 0.;
1101 for (std::size_t q=0; q<dim; ++q)
1102 {
1103 res += calc_memory(block[q], memunit);
1104 }
1105 return res;
1106}
1107
1108template<typename Symmetry, typename MatrixType_>
1110overhead (MEMUNIT memunit) const
1111{
1112 double res = 0.;
1113 res += 2. * 2. * Symmetry::Nq * calc_memory<int>(dim, memunit); // in,out; dict.keys
1114 res += Symmetry::Nq * calc_memory<std::size_t>(dim, memunit); // dict.vals
1115 return res;
1116}
1117
1118template<typename Symmetry, typename MatrixType_>
1120formatted () const
1121{
1122 std::stringstream ss;
1123 ss << "•Biped(" << dim << "):" << endl;
1124 for (std::size_t q=0; q<dim; ++q)
1125 {
1126 ss << " [" << q << "]: " << Sym::format<Symmetry>(in[q]) << "→" << Sym::format<Symmetry>(out[q]);
1127 ss << ":" << endl;
1128 ss << " " << block[q];
1129 if (q!=dim-1) {ss << endl;}
1130 }
1131 return ss.str();
1132}
1133
1134template <typename Symmetry, typename MatrixType_>
1135std::string
1137 const std::size_t precision) const {
1138#ifdef TOOLS_IO_TABLE
1139 std::stringstream out_string;
1140
1141 TextTable t('-', '|', '+');
1142 t.add("ν");
1143 t.add("Q_ν");
1144 t.add("A_ν");
1145 t.endOfRow();
1146 for (std::size_t nu = 0; nu < size(); nu++) {
1147 std::stringstream ss, tt, uu;
1148 ss << nu;
1149 tt << "(" << Sym::format<Symmetry>(in[nu]) << ","
1150 << Sym::format<Symmetry>(out[nu]) << ")";
1151 uu << block[nu].rows() << "x" << block[nu].cols();
1152 t.add(ss.str());
1153 t.add(tt.str());
1154 t.add(uu.str());
1155 t.endOfRow();
1156 }
1157 t.setAlignment(0, TextTable::Alignment::RIGHT);
1158 out_string << t;
1159
1160 if (SHOW_MATRICES) {
1161 out_string << termcolor::blue << termcolor::underline
1162 << "A-tensors:" << termcolor::reset << std::endl;
1163 for (std::size_t nu = 0; nu < dim; nu++) {
1164 out_string << termcolor::blue << "ν=" << nu << termcolor::reset
1165 << std::endl
1166 << std::setprecision(precision) << std::fixed
1167 << termcolor::green << block[nu] << termcolor::reset
1168 << std::endl;
1169 }
1170 }
1171 return out_string.str();
1172#else
1173 return "Can't print. Table Library is missing.";
1174#endif
1175}
1176
1178template<typename Symmetry, typename MatrixType_>
1180{
1181 if (M1.size() < M2.size()) {return M2+M1;}
1182
1183 std::vector<std::size_t> blocks_in_2nd_biped;
1185
1186 for (std::size_t nu=0; nu<M1.size(); nu++)
1187 {
1188 auto it = M2.dict.find({{M1.in[nu], M1.out[nu]}});
1189 if (it != M2.dict.end())
1190 {
1191 blocks_in_2nd_biped.push_back(it->second);
1192 }
1193
1194 MatrixType_ Mtmp;
1195 if (it != M2.dict.end() and M1.block[nu].size() > 0 and M2.block[it->second].size() > 0)
1196 {
1197 Mtmp = M1.block[nu] + M2.block[it->second]; // M1+M2
1198 }
1199 else if (it != M2.dict.end() and M1.block[nu].size() == 0)
1200 {
1201 Mtmp = M2.block[it->second]; // 0+M2
1202 }
1203 else
1204 {
1205 Mtmp = M1.block[nu]; // M1+0
1206 }
1207
1208 if (Mtmp.size() != 0)
1209 {
1210 Mout.push_back({{M1.in[nu], M1.out[nu]}}, Mtmp);
1211 }
1212 }
1213
1214 if (blocks_in_2nd_biped.size() != M2.size())
1215 {
1216 for (std::size_t nu=0; nu<M2.size(); nu++)
1217 {
1218 auto it = std::find(blocks_in_2nd_biped.begin(),blocks_in_2nd_biped.end(),nu);
1219 if (it == blocks_in_2nd_biped.end())
1220 {
1221 if (M2.block[nu].size() != 0)
1222 {
1223 Mout.push_back({{M2.in[nu], M2.out[nu]}}, M2.block[nu]); // 0+M2
1224 }
1225 }
1226 }
1227 }
1228 return Mout;
1229}
1230
1232template<typename Symmetry, typename MatrixType_>
1234{
1235 std::vector<std::size_t> blocks_in_2nd_biped;
1237
1238 for (std::size_t nu=0; nu<M1.size(); nu++)
1239 {
1240 auto it = M2.dict.find({{M1.in[nu], M1.out[nu]}});
1241 if (it != M2.dict.end())
1242 {
1243 blocks_in_2nd_biped.push_back(it->second);
1244 }
1245
1246 MatrixType_ Mtmp;
1247 if (it != M2.dict.end() and M1.block[nu].size() != 0 and M2.block[it->second].size() != 0)
1248 {
1249// cout << "nu=" << nu << ", M1-M2" << endl;
1250 Mtmp = M1.block[nu] - M2.block[it->second]; // M1-M2
1251 }
1252 else if (it != M2.dict.end() and M1.block[nu].size() == 0)
1253 {
1254// cout << "nu=" << nu << ", 0-M2" << endl;
1255 Mtmp = -M2.block[it->second]; // 0-M2
1256 }
1257 else
1258 {
1259// cout << "nu=" << nu << ", M1-0" << endl;
1260 Mtmp = M1.block[nu]; // M1-0
1261 }
1262
1263 if (Mtmp.size() != 0)
1264 {
1265 Mout.push_back({{M1.in[nu], M1.out[nu]}}, Mtmp);
1266 }
1267 }
1268
1269 if (blocks_in_2nd_biped.size() != M2.size())
1270 {
1271 for (std::size_t nu=0; nu<M2.size(); nu++)
1272 {
1273 auto it = std::find(blocks_in_2nd_biped.begin(),blocks_in_2nd_biped.end(),nu);
1274 if (it == blocks_in_2nd_biped.end())
1275 {
1276 if (M2.block[nu].size() != 0)
1277 {
1278// cout << "nu=" << nu << ", 0-M2 and blocks_in_2nd_biped.size() != M2.size()" << endl;
1279 Mout.push_back({{M2.in[nu], M2.out[nu]}}, -M2.block[nu]); // 0-M2
1280 }
1281 }
1282 }
1283 }
1284
1285// cout << "M1:" << endl << M1 << endl;
1286// cout << "M2:" << endl << M2 << endl;
1287// cout << "Mout:" << endl << Mout << endl;
1288
1289 return Mout;
1290}
1291
1293template<typename Symmetry, typename MatrixType_>
1295addScale (const Scalar &factor, const Biped<Symmetry,MatrixType_> &Mrhs, BLOCK_POSITION POS)
1296{
1297 vector<size_t> matching_blocks;
1299
1300 for (size_t q=0; q<dim; ++q)
1301 {
1302 auto it = Mrhs.dict.find({{in[q], out[q]}});
1303 if (it != Mrhs.dict.end())
1304 {
1305 matching_blocks.push_back(it->second);
1306 }
1307
1308 MatrixType_ Mtmp;
1309 if (it != Mrhs.dict.end())
1310 {
1311 if (block[q].size() != 0 and Mrhs.block[it->second].size() != 0)
1312 {
1313 if (POS == SAME_PLACE)
1314 {
1315 Mtmp = block[q] + factor * Mrhs.block[it->second]; // M1+factor*Mrhs
1316 }
1317 else
1318 {
1319 Mtmp = block[q];
1320 addPos(factor * Mrhs.block[it->second], Mtmp, POS);
1321 }
1322 }
1323 else if (block[q].size() == 0 and Mrhs.block[it->second].size() != 0)
1324 {
1325 Mtmp = factor * Mrhs.block[it->second]; // 0+factor*Mrhs
1326 }
1327 else if (block[q].size() != 0 and Mrhs.block[it->second].size() == 0)
1328 {
1329 Mtmp = block[q]; // M1+0
1330 }
1331 // else: block[q].size() == 0 and Mrhs.block[it->second].size() == 0 -> do nothing -> Mtmp.size() = 0
1332 }
1333 else
1334 {
1335 Mtmp = block[q]; // M1+0
1336 }
1337
1338 if (Mtmp.size() != 0)
1339 {
1340 Mout.push_back({{in[q], out[q]}}, Mtmp);
1341 }
1342 }
1343
1344 if (matching_blocks.size() != Mrhs.dim)
1345 {
1346 for (size_t q=0; q<Mrhs.size(); ++q)
1347 {
1348 auto it = find(matching_blocks.begin(), matching_blocks.end(), q);
1349 if (it == matching_blocks.end())
1350 {
1351 if (Mrhs.block[q].size() != 0)
1352 {
1353 Mout.push_back({{Mrhs.in[q], Mrhs.out[q]}}, factor * Mrhs.block[q]); // 0+factor*Mrhs
1354 }
1355 }
1356 }
1357 }
1358
1359 *this = Mout;
1360}
1361
1365template<typename Symmetry, typename MatrixType_>
1367addScale_extend (const Scalar &factor, const Biped<Symmetry,MatrixType_> &Mrhs)
1368{
1369 vector<size_t> matching_blocks;
1371
1372 for (size_t q=0; q<dim; ++q)
1373 {
1374 auto it = Mrhs.dict.find({{in[q], out[q]}});
1375 if (it != Mrhs.dict.end())
1376 {
1377 matching_blocks.push_back(it->second);
1378 }
1379
1380 MatrixType_ Mtmp;
1381 if (it != Mrhs.dict.end())
1382 {
1383 if (block[q].size() != 0 and Mrhs.block[it->second].size() != 0)
1384 {
1385 if (block[q].rows() == Mrhs.block[it->second].rows() and block[q].cols()==Mrhs.block[it->second].cols())
1386 {
1387 Mtmp = block[q] + factor * Mrhs.block[it->second]; // M1+factor*Mrhs
1388 }
1389 else
1390 {
1391 int maxrows = max(block[q].rows(),Mrhs.block[it->second].rows());
1392 int maxcols = max(block[q].cols(),Mrhs.block[it->second].cols());
1393 Mtmp.resize(maxrows,maxcols);
1394 Mtmp.setZero();
1395 Mtmp.topLeftCorner(block[q].rows(),block[q].cols()) = block[q];
1396 Mtmp.topLeftCorner(Mrhs.block[it->second].rows(),Mrhs.block[it->second].cols()) += factor * Mrhs.block[it->second];
1397 }
1398 }
1399 else if (block[q].size() == 0 and Mrhs.block[it->second].size() != 0)
1400 {
1401 Mtmp = factor * Mrhs.block[it->second]; // 0+factor*Mrhs
1402 }
1403 else if (block[q].size() != 0 and Mrhs.block[it->second].size() == 0)
1404 {
1405 Mtmp = block[q]; // M1+0
1406 }
1407 // else: block[q].size() == 0 and Mrhs.block[it->second].size() == 0 -> do nothing -> Mtmp.size() = 0
1408 }
1409 else
1410 {
1411 Mtmp = block[q]; // M1+0
1412 }
1413
1414 if (Mtmp.size() != 0)
1415 {
1416 Mout.push_back({{in[q], out[q]}}, Mtmp);
1417 }
1418 }
1419
1420 if (matching_blocks.size() != Mrhs.dim)
1421 {
1422 for (size_t q=0; q<Mrhs.size(); ++q)
1423 {
1424 auto it = find(matching_blocks.begin(), matching_blocks.end(), q);
1425 if (it == matching_blocks.end())
1426 {
1427 if (Mrhs.block[q].size() != 0)
1428 {
1429 Mout.push_back({{Mrhs.in[q], Mrhs.out[q]}}, factor * Mrhs.block[q]); // 0+factor*Mrhs
1430 }
1431 }
1432 }
1433 }
1434
1435 *this = Mout;
1436}
1437
1438template<typename Symmetry, typename MatrixType_>
1439std::ostream& operator<< (std::ostream& os, const Biped<Symmetry,MatrixType_> &V)
1440{
1441 os << V.print(true,4);
1442 return os;
1443}
1444
1445#endif
Biped< Symmetry, MatrixType_ > operator-(const Biped< Symmetry, MatrixType_ > &M1, const Biped< Symmetry, MatrixType_ > &M2)
Definition: Biped.h:1233
double xlogx(double x)
Definition: Biped.h:19
Biped< Symmetry, MatrixType_ > operator+(const Biped< Symmetry, MatrixType_ > &M1, const Biped< Symmetry, MatrixType_ > &M2)
Definition: Biped.h:1179
std::ostream & operator<<(std::ostream &os, const Biped< Symmetry, MatrixType_ > &V)
Definition: Biped.h:1439
Biped< Symmetry, MatrixType_ > operator*(const Biped< Symmetry, MatrixType_ > &A1, const Biped< Symmetry, MatrixType_ > &A2)
Definition: Biped.h:1016
void addPos(const MatrixType1 &Min, MatrixType2 &Mout, BLOCK_POSITION POS)
BLOCK_POSITION
@ SAME_PLACE
@ FULL
Hamiltonian sum(const Hamiltonian &H1, const Hamiltonian &H2, DMRG::VERBOSITY::OPTION VERBOSITY=DMRG::VERBOSITY::SILENT)
double norm(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
size_t dim(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
double squaredNorm(const PivotVector< Symmetry, Scalar_ > &V)
@ A
Definition: DmrgTypedefs.h:130
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
Definition: Biped.h:47
MODE
Definition: Biped.h:48
@ UNITY
Definition: Biped.h:48
@ OORR
Definition: Biped.h:48
@ DOT
Definition: Biped.h:48
std::array< qarray< Nq >, 2 > qarray2
Definition: qarray.h:51
std::array< qarray< Nq >, 3 > qarray3
Definition: qarray.h:52
Definition: Biped.h:64
Biped< Symmetry, MatrixType_ > adjoint() const
Definition: Biped.h:630
void plusplus()
Definition: Biped.h:84
std::unordered_map< std::array< qType, 2 >, std::size_t > dict
Definition: Biped.h:104
Biped< Symmetry, MatrixType_ > transpose() const
Definition: Biped.h:656
void setTarget(vector< qType > Qmulti)
Definition: Biped.h:426
std::string print_dict() const
Definition: Biped.h:1086
void try_create_block(std::array< qType, 2 > quple)
Definition: Biped.h:582
std::vector< MatrixType_ > block
Definition: Biped.h:96
void create_block(std::array< qType, 2 > quple)
Definition: Biped.h:569
void outerResize(const Biped< Symmetry, OtherMatrixType > Brhs)
Definition: Biped.h:258
void addScale(const Scalar &factor, const Biped< Symmetry, MatrixType_ > &Mrhs, BLOCK_POSITION BP=SAME_PLACE)
Definition: Biped.h:1295
std::size_t size() const
Definition: Biped.h:83
tuple< Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ > > truncateSVD(size_t minKeep, size_t maxKeep, EpsScalar eps_svd, double &truncWeight, bool PRESERVE_MULTIPLETS=true) const
Definition: Biped.h:202
std::vector< qType > in
Definition: Biped.h:87
Biped< Symmetry, MatrixType_ > & operator+=(const Biped< Symmetry, MatrixType_ > &Arhs)
Definition: Biped.h:948
void cholesky(Biped< Symmetry, MatrixType > &res) const
Definition: Biped.h:729
Biped< Symmetry, OtherMatrixType > cast() const
Definition: Biped.h:268
Biped< Symmetry, MatrixType_ > contract(const Biped< Symmetry, MatrixType_ > &A, const contract::MODE MODE=contract::MODE::UNITY) const
Definition: Biped.h:976
Biped< Symmetry, MatrixType_ > conjugate() const
Definition: Biped.h:682
Biped()
Definition: Biped.h:75
MatrixType_::Scalar Scalar
Definition: Biped.h:71
void setRandom(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
Definition: Biped.h:375
void push_back(qType qin, qType qout, const MatrixType_ &M)
Definition: Biped.h:529
Biped< Symmetry, MatrixType_ > adjustQN(const size_t number_cells)
Definition: Biped.h:711
void clear()
Definition: Biped.h:325
double operatorNorm(bool COLWISE=true) const
Definition: Biped.h:494
void setZero(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
Definition: Biped.h:395
pair< Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ > > QR(bool RETURN_LQ=false, bool MAKE_UNIQUE=false) const
Definition: Biped.h:901
double overhead(MEMUNIT memunit=MB) const
Definition: Biped.h:1110
MatrixType_ MatrixType
Definition: Biped.h:69
void setRandom()
Definition: Biped.h:343
Eigen::VectorXi cols(bool FULL=false) const
Definition: Biped.h:466
tuple< Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ > > truncateSVD(size_t minKeep, size_t maxKeep, EpsScalar eps_svd, double &truncWeight, double &entropy, map< qarray< Symmetry::Nq >, Eigen::ArrayXd > &SVspec, bool PRESERVE_MULTIPLETS=true, bool RETURN_SPEC=true) const
Definition: Biped.h:744
double norm() const
Definition: Biped.h:510
void try_push_back(qType qin, qType qout, const MatrixType_ &M)
Definition: Biped.h:548
Symmetry::qType qType
Definition: Biped.h:66
void push_back(std::array< qType, 2 > quple, const MatrixType_ &M)
Definition: Biped.h:536
Scalar trace() const
Definition: Biped.h:936
void try_push_back(std::array< qType, 2 > quple, const MatrixType_ &M)
Definition: Biped.h:555
void setTarget(qType Qtot)
Definition: Biped.h:416
void shift_Qin(const qarray< Symmetry::Nq > &Q)
Definition: Biped.h:281
void addScale_extend(const Scalar &factor, const Biped< Symmetry, MatrixType_ > &Mrhs)
Definition: Biped.h:1367
Biped< Symmetry, MatrixType_ > sorted() const
Definition: Biped.h:612
Eigen::Index Index
Definition: Biped.h:67
void setZero()
Definition: Biped.h:336
std::string print(const bool SHOW_MATRICES=false, const std::size_t precision=3) const
Definition: Biped.h:1136
double memory(MEMUNIT memunit=GB) const
Definition: Biped.h:1098
std::string formatted() const
Definition: Biped.h:1120
std::size_t dim
Definition: Biped.h:82
std::vector< qType > out
Definition: Biped.h:90
Biped< Symmetry, MatrixType_ > exp(const expScalar x) const
Definition: Biped.h:1069
Eigen::VectorXi rows(bool FULL=false) const
Definition: Biped.h:439
Biped< Symmetry, MatrixType_ > cleaned() const
Definition: Biped.h:597
Eigen::VectorXd squaredNorm() const
Definition: Biped.h:520
void setVacuum()
Definition: Biped.h:350
void setIdentity(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
Definition: Biped.h:358
Definition: qarray.h:26