1#ifndef STRAWBERRY_BIPED
2#define STRAWBERRY_BIPED
5#include <unordered_map>
6#include <unordered_set>
9#include "termcolor.hpp"
13#include "RandomVector.h"
44template<
typename Symmetry>
62template<
typename Symmetry,
typename MatrixType_>
66 typedef typename Symmetry::qType
qType;
71 typedef typename MatrixType_::Scalar
Scalar;
83 inline std::size_t
size()
const {
return dim;}
87 std::vector<qType>
in;
90 std::vector<qType>
out;
104 std::unordered_map<std::array<qType,2>,std::size_t>
dict;
127 std::string
print (
const bool SHOW_MATRICES=
false ,
const std::size_t precision=3 )
const;
133 double memory (MEMUNIT memunit=GB)
const;
197 template<
typename EpsScalar>
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;
201 template<
typename EpsScalar>
205 map<qarray<Symmetry::Nq>,Eigen::ArrayXd> SVspec_dumb;
206 return truncateSVD(minKeep, maxKeep, eps_svd, truncWeight, S_dumb, SVspec_dumb, PRESERVE_MULTIPLETS,
false);
210 QR(
bool RETURN_LQ=
false,
bool MAKE_UNIQUE=
false)
const;
233 template<
typename expScalar>
248 void push_back (std::array<qType,2> quple,
const MatrixType_ &M);
257 template<
typename OtherMatrixType>
267 template<
typename OtherMatrixType>
273 for (
size_t q=0; q<
dim; ++q)
275 Vout.
block[q] =
block[q].template cast<typename OtherMatrixType::Scalar>();
285 auto block_tmp =
block;
294 for (
size_t q=0; q<dim_tmp; ++q)
323template<
typename Symmetry,
typename MatrixType_>
334template<
typename Symmetry,
typename MatrixType_>
338 for (std::size_t q=0; q<
dim; ++q) {block[q].setZero();}
341template<
typename Symmetry,
typename MatrixType_>
345 for (std::size_t q=0; q<
dim; ++q) {block[q].setRandom();}
348template<
typename Symmetry,
typename MatrixType_>
352 MatrixType_ Mtmp(1,1); Mtmp << 1.;
353 push_back(Symmetry::qvacuum(), Symmetry::qvacuum(), Mtmp);
356template<
typename Symmetry,
typename MatrixType_>
360 for (
size_t q1=0; q1<base1.
Nq(); ++q1)
361 for (
size_t q2=0; q2<base2.
Nq(); ++q2)
368 push_back(base1[q1], base2[q2], Mtmp);
373template<
typename Symmetry,
typename MatrixType_>
377 for (
size_t q1=0; q1<base1.
Nq(); ++q1)
378 for (
size_t q2=0; q2<base2.
Nq(); ++q2)
383 for (
size_t a1=0; a1<Mtmp.rows(); ++a1)
384 for (
size_t a2=0; a2<Mtmp.cols(); ++a2)
386 Mtmp(a1,a2) = threadSafeRandUniform<typename MatrixType_::Scalar>(-1.,1.);
388 push_back(base1[q1], base2[q2], Mtmp);
393template<
typename Symmetry,
typename MatrixType_>
397 for (
size_t q1=0; q1<base1.
Nq(); ++q1)
398 for (
size_t q2=0; q2<base2.
Nq(); ++q2)
409 push_back(base1[q1], base2[q2], Mtmp);
414template<
typename Symmetry,
typename MatrixType_>
418 MatrixType_ Mtmp(1,1);
421 push_back(Qtot, Qtot, Mtmp);
424template<
typename Symmetry,
typename MatrixType_>
428 MatrixType_ Mtmp(1,1);
431 for (
const auto &Qtot:Qmulti)
433 push_back(Qtot, Qtot, Mtmp);
437template<
typename Symmetry,
typename MatrixType_>
441 std::unordered_set<qType> uniqueControl;
443 for (std::size_t nu=0; nu<size(); nu++)
445 if(
auto it=uniqueControl.find(in[nu]); it == uniqueControl.end()){
446 uniqueControl.insert(in[nu]); count++;
449 Eigen::VectorXi Vout(count);
451 uniqueControl.clear();
452 for (std::size_t nu=0; nu<size(); nu++)
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(); }
464template<
typename Symmetry,
typename MatrixType_>
468 std::unordered_set<qType> uniqueControl;
470 for (std::size_t nu=0; nu<size(); nu++)
472 if(
auto it=uniqueControl.find(out[nu]); it == uniqueControl.end()){
473 uniqueControl.insert(out[nu]); count++;
476 Eigen::VectorXi Vout(count);
478 uniqueControl.clear();
479 for (std::size_t nu=0; nu<size(); nu++)
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(); }
492template<
typename Symmetry,
typename MatrixType_>
497 for (
size_t q=0; q<
dim; q++)
501 if (block[q].cwiseAbs().colwise().
sum().maxCoeff() >
norm) {
norm=block[q].cwiseAbs().colwise().sum().maxCoeff(); }
503 else {
if (block[q].cwiseAbs().rowwise().
sum().maxCoeff() >
norm) {
norm=block[q].cwiseAbs().rowwise().sum().maxCoeff(); } }
508template<
typename Symmetry,
typename MatrixType_>
518template<
typename Symmetry,
typename MatrixType_>
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]); }
527template<
typename Symmetry,
typename MatrixType_>
531 push_back({qin,qout},M);
534template<
typename Symmetry,
typename MatrixType_>
536push_back (std::array<qType,2> quple,
const MatrixType_ &M)
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]);
542 dict.insert({quple,
dim});
546template<
typename Symmetry,
typename MatrixType_>
550 try_push_back({qin,qout},M);
553template<
typename Symmetry,
typename MatrixType_>
555try_push_back (std::array<qType,2> quple,
const MatrixType_ &M)
557 if (dict.find(quple) == dict.end())
559 in.push_back(quple[0]);
560 out.push_back(quple[1]);
562 dict.insert({quple,
dim});
567template<
typename Symmetry,
typename MatrixType_>
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});
580template<
typename Symmetry,
typename MatrixType_>
584 if (dict.find(quple) == dict.end())
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});
595template<
typename Symmetry,
typename MatrixType_>
600 for (
size_t q=0; q<
dim; ++q)
602 if (block[q].size() > 0)
610template<
typename Symmetry,
typename MatrixType_>
615 set<qarray2<Symmetry::Nq> > quples;
616 for (
size_t q=0; q<
dim; ++q)
620 for (
const auto &quple:quples)
622 auto it = dict.find(quple);
623 Aout.
push_back(quple, block[it->second]);
628template<
typename Symmetry,
typename MatrixType_>
638 for (
auto it=dict.begin(); it!=dict.end(); ++it)
640 auto qin = get<0>(it->first);
641 auto qout = get<1>(it->first);
642 Aout.
dict.insert({{qout,qin}, it->second});
646 for (std::size_t q=0; q<
dim; ++q)
648 Aout.
block[q] = block[q].adjoint();
654template<
typename Symmetry,
typename MatrixType_>
664 for (
auto it=dict.begin(); it!=dict.end(); ++it)
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});
672 for (std::size_t q=0; q<
dim; ++q)
674 Aout.
block[q] = block[q].transpose();
680template<
typename Symmetry,
typename MatrixType_>
692 for (
auto it=dict.begin(); it!=dict.end(); ++it)
694 auto qin = get<0>(it->first);
695 auto qout = get<1>(it->first);
696 Aout.
dict.insert({{qin,qout}, it->second});
701 for (std::size_t q=0; q<
dim; ++q)
703 Aout.
block[q] = block[q].conjugate();
709template<
typename Symmetry,
typename MatrixType_>
718 for (std::size_t q=0; q<
dim; ++q)
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});
727template<
typename Symmetry,
typename MatrixType_>
732 for (
size_t q=0; q<res.
dim; q++)
735 Eigen::LLT Jim(Mtmp);
736 res.
block[q] = Jim.matrixL();
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
750 vector<pair<typename Symmetry::qType, double> > allSV;
752 for (
size_t q=0; q<
dim; ++q)
754 #ifdef DONT_USE_BDCSVD
756 JacobiSVD<MatrixType> Jack;
759 BDCSVD<MatrixType> Jack;
765 Jack.compute(block[q], ComputeThinU|ComputeThinV);
768 for (
size_t i=0; i<Jack.singularValues().size(); i++) {allSV.
push_back(make_pair(in[q],std::real(Jack.singularValues()(i))));}
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());
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;});
797 int numberOfDiscardedStates = 0;
798 for (
int i=allSV.size()-1; i>=0; --i)
800 double truncWeightIncr = Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
802 if (truncWeight+truncWeightIncr < eps_truncWeight)
804 truncWeight += truncWeightIncr;
805 numberOfDiscardedStates += 1;
809 if (numberOfDiscardedStates >= allSV.size())
811 numberOfDiscardedStates = 0;
815 int numberOfKeptStates = allSV.size()-numberOfDiscardedStates;
817 if (numberOfKeptStates <= maxKeep and numberOfKeptStates >= min(minKeep,numberOfStates))
819 allSV.resize(numberOfKeptStates);
821 else if (numberOfKeptStates <= maxKeep and numberOfKeptStates <= min(minKeep,numberOfStates))
823 numberOfKeptStates = min(minKeep,numberOfStates);
825 for (
int i=allSV.size()-1; i>numberOfKeptStates; --i)
827 truncWeight += Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
829 allSV.resize(numberOfKeptStates);
831 else if (numberOfKeptStates > maxKeep)
833 numberOfKeptStates = min(maxKeep,numberOfStates);
835 for (
int i=allSV.size()-1; i>numberOfKeptStates; --i)
837 truncWeight += Symmetry::degeneracy(allSV[i].first) * std::pow(std::abs(allSV[i].second),2.);
839 allSV.resize(numberOfKeptStates);
843 lout <<
"numberOfKeptStates=" << numberOfKeptStates <<
", minKeep=" << minKeep <<
", maxKeep=" << maxKeep <<
", numberOfStates=" << numberOfStates << endl;
857 if (PRESERVE_MULTIPLETS)
860 int endOfMultiplet=-1;
861 for (
int i=allSV.size()-1; i>0; i--)
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;}
866 if (endOfMultiplet != -1)
868 cout << termcolor::red <<
"Cutting of the last " << allSV.size()-endOfMultiplet <<
" singular values to preserve the multiplet" << termcolor::reset << endl;
869 allSV.resize(endOfMultiplet);
874 map<typename Symmetry::qType, vector<Scalar> > qn_orderedSV;
875 for (
const auto &[q,s] : allSV)
877 qn_orderedSV[q].push_back(s);
879 entropy += -Symmetry::degeneracy(q) *
xlogx(s*s);
881 for (
const auto & [q,vec_sv]: qn_orderedSV)
883 size_t Nret = vec_sv.size();
885 auto itSigma = Sigma.
dict.find({q,q});
886 trunc_Sigma.
push_back(q,q,Sigma.
block[itSigma->second].diagonal().head(Nret).asDiagonal());
889 SVspec.insert(make_pair(q, Sigma.
block[itSigma->second].diagonal().head(Nret).real()));
891 auto itU = U.
dict.find({q,q});
893 auto itVdag = Vdag.
dict.find({q,q});
894 trunc_Vdag.
push_back(q, q, Vdag.
block[itVdag->second].topRows(Nret));
896 return make_tuple(trunc_U,trunc_Sigma,trunc_Vdag);
899template<
typename Symmetry,
typename MatrixType_>
901QR(
bool RETURN_LQ,
bool MAKE_UNIQUE)
const
904 for (
size_t q=0; q<
dim; ++q)
906 HouseholderQR<MatrixType> Quirinus;
907 Quirinus.compute(block[q]);
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();
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>();
923 DiagonalMatrix<Scalar,Dynamic> Sign = Rmat.diagonal().cwiseSign().matrix().asDiagonal();
931 return make_pair(Q,R);
934template<
typename Symmetry,
typename MatrixType_>
938 typename MatrixType_::Scalar res=0.;
939 for (std::size_t nu=0; nu<size(); nu++)
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]);
947template<
typename Symmetry,
typename MatrixType_>
950 std::vector<std::size_t> addenda;
952 for (std::size_t q=0; q<Arhs.
dim; ++q)
954 std::array<qType,2> quple = {Arhs.
in[q], Arhs.
out[q]};
955 auto it = dict.find(quple);
957 if (it != dict.end())
959 block[it->second] += Arhs.
block[q];
963 addenda.push_back(q);
967 for (
size_t q=0; q<addenda.size(); ++q)
969 push_back(Arhs.
in[addenda[q]], Arhs.
out[addenda[q]], Arhs.
block[addenda[q]]);
974template<
typename Symmetry,
typename MatrixType_>
980 for (std::size_t q1=0; q1<this->size(); ++q1)
981 for (std::size_t q2=0; q2<
A.size(); ++q2)
983 if (this->out[q1] ==
A.in[q2])
985 if (this->in[q1] ==
A.out[q2])
987 if (this->block[q1].size() != 0 and
A.block[q2].size() != 0)
993 factor_cgc = Symmetry::coeff_rightOrtho(this->out[q1],this->in[q1]);
997 factor_cgc = Symmetry::coeff_dot(this->out[q1]);
999 if (
auto it = Ares.
dict.find({{this->in[q1],A.out[q2]}}); it == Ares.
dict.end())
1001 Ares.
push_back(this->in[q1],
A.out[q2], factor_cgc*this->block[q1]*
A.block[q2]);
1005 Ares.
block[it->second] += factor_cgc*this->block[q1]*
A.block[q2];
1015template<
typename Symmetry,
typename MatrixType_>
1019 for (std::size_t q1=0; q1<A1.
dim; ++q1)
1020 for (std::size_t q2=0; q2<A2.
dim; ++q2)
1022 if (A1.
out[q1] == A2.
in[q2] and A1.
block[q1].size() != 0 and A2.
block[q2].size() != 0)
1025 if (it != Ares.
dict.end())
1047template<
typename Symmetry,
typename MatrixType_,
typename Scalar>
1051 for (std::size_t q=0; q<Ares.
dim; ++q)
1053 Ares.
block[q] *= alpha;
1066template<
typename Symmetry,
typename MatrixType_>
1067template<
typename expScalar>
1069exp(
const expScalar x )
const
1074 for (std::size_t nu=0; nu<size(); nu++)
1078 MatrixType_ Aexp =
A.exp();
1079 Mout.
push_back(this->in[nu], this->out[nu], Aexp);
1084template<
typename Symmetry,
typename MatrixType_>
1088 std::stringstream ss;
1089 for (
auto it=dict.begin(); it!=dict.end(); ++it)
1091 ss <<
"in:" << get<0>(it->first) <<
"\tout:" << get<1>(it->first) <<
"\t→\t" << it->second << endl;
1096template<
typename Symmetry,
typename MatrixType_>
1098memory (MEMUNIT memunit)
const
1101 for (std::size_t q=0; q<
dim; ++q)
1103 res += calc_memory(block[q], memunit);
1108template<
typename Symmetry,
typename MatrixType_>
1113 res += 2. * 2. * Symmetry::Nq * calc_memory<int>(
dim, memunit);
1114 res += Symmetry::Nq * calc_memory<std::size_t>(
dim, memunit);
1118template<
typename Symmetry,
typename MatrixType_>
1122 std::stringstream ss;
1123 ss <<
"•Biped(" <<
dim <<
"):" << endl;
1124 for (std::size_t q=0; q<
dim; ++q)
1126 ss <<
" [" << q <<
"]: " << Sym::format<Symmetry>(in[q]) <<
"→" << Sym::format<Symmetry>(out[q]);
1128 ss <<
" " << block[q];
1129 if (q!=
dim-1) {ss << endl;}
1134template <
typename Symmetry,
typename MatrixType_>
1137 const std::size_t precision)
const {
1138#ifdef TOOLS_IO_TABLE
1139 std::stringstream out_string;
1141 TextTable t(
'-',
'|',
'+');
1146 for (std::size_t nu = 0; nu < size(); nu++) {
1147 std::stringstream ss, tt, uu;
1149 tt <<
"(" << Sym::format<Symmetry>(in[nu]) <<
","
1150 << Sym::format<Symmetry>(out[nu]) <<
")";
1151 uu << block[nu].rows() <<
"x" << block[nu].cols();
1157 t.setAlignment(0, TextTable::Alignment::RIGHT);
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
1166 << std::setprecision(precision) << std::fixed
1167 << termcolor::green << block[nu] << termcolor::reset
1171 return out_string.str();
1173 return "Can't print. Table Library is missing.";
1178template<
typename Symmetry,
typename MatrixType_>
1181 if (M1.
size() < M2.
size()) {
return M2+M1;}
1183 std::vector<std::size_t> blocks_in_2nd_biped;
1186 for (std::size_t nu=0; nu<M1.
size(); nu++)
1188 auto it = M2.
dict.find({{M1.
in[nu], M1.
out[nu]}});
1189 if (it != M2.
dict.end())
1191 blocks_in_2nd_biped.push_back(it->second);
1195 if (it != M2.
dict.end() and M1.
block[nu].size() > 0 and M2.
block[it->second].size() > 0)
1199 else if (it != M2.
dict.end() and M1.
block[nu].size() == 0)
1201 Mtmp = M2.
block[it->second];
1205 Mtmp = M1.
block[nu];
1208 if (Mtmp.size() != 0)
1214 if (blocks_in_2nd_biped.size() != M2.
size())
1216 for (std::size_t nu=0; nu<M2.
size(); nu++)
1218 auto it = std::find(blocks_in_2nd_biped.begin(),blocks_in_2nd_biped.end(),nu);
1219 if (it == blocks_in_2nd_biped.end())
1221 if (M2.
block[nu].size() != 0)
1232template<
typename Symmetry,
typename MatrixType_>
1235 std::vector<std::size_t> blocks_in_2nd_biped;
1238 for (std::size_t nu=0; nu<M1.
size(); nu++)
1240 auto it = M2.
dict.find({{M1.
in[nu], M1.
out[nu]}});
1241 if (it != M2.
dict.end())
1243 blocks_in_2nd_biped.push_back(it->second);
1247 if (it != M2.
dict.end() and M1.
block[nu].size() != 0 and M2.
block[it->second].size() != 0)
1252 else if (it != M2.
dict.end() and M1.
block[nu].size() == 0)
1255 Mtmp = -M2.
block[it->second];
1260 Mtmp = M1.
block[nu];
1263 if (Mtmp.size() != 0)
1269 if (blocks_in_2nd_biped.size() != M2.
size())
1271 for (std::size_t nu=0; nu<M2.
size(); nu++)
1273 auto it = std::find(blocks_in_2nd_biped.begin(),blocks_in_2nd_biped.end(),nu);
1274 if (it == blocks_in_2nd_biped.end())
1276 if (M2.
block[nu].size() != 0)
1293template<
typename Symmetry,
typename MatrixType_>
1297 vector<size_t> matching_blocks;
1300 for (
size_t q=0; q<
dim; ++q)
1302 auto it = Mrhs.
dict.find({{in[q], out[q]}});
1303 if (it != Mrhs.
dict.end())
1305 matching_blocks.push_back(it->second);
1309 if (it != Mrhs.
dict.end())
1311 if (block[q].size() != 0 and Mrhs.
block[it->second].size() != 0)
1315 Mtmp = block[q] + factor * Mrhs.
block[it->second];
1320 addPos(factor * Mrhs.
block[it->second], Mtmp, POS);
1323 else if (block[q].size() == 0 and Mrhs.
block[it->second].size() != 0)
1325 Mtmp = factor * Mrhs.
block[it->second];
1327 else if (block[q].size() != 0 and Mrhs.
block[it->second].size() == 0)
1338 if (Mtmp.size() != 0)
1340 Mout.
push_back({{in[q], out[q]}}, Mtmp);
1344 if (matching_blocks.size() != Mrhs.
dim)
1346 for (
size_t q=0; q<Mrhs.
size(); ++q)
1348 auto it = find(matching_blocks.begin(), matching_blocks.end(), q);
1349 if (it == matching_blocks.end())
1351 if (Mrhs.
block[q].size() != 0)
1365template<
typename Symmetry,
typename MatrixType_>
1369 vector<size_t> matching_blocks;
1372 for (
size_t q=0; q<
dim; ++q)
1374 auto it = Mrhs.
dict.find({{in[q], out[q]}});
1375 if (it != Mrhs.
dict.end())
1377 matching_blocks.push_back(it->second);
1381 if (it != Mrhs.
dict.end())
1383 if (block[q].size() != 0 and Mrhs.
block[it->second].size() != 0)
1385 if (block[q].rows() == Mrhs.
block[it->second].rows() and block[q].cols()==Mrhs.
block[it->second].cols())
1387 Mtmp = block[q] + factor * Mrhs.
block[it->second];
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);
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];
1399 else if (block[q].size() == 0 and Mrhs.
block[it->second].size() != 0)
1401 Mtmp = factor * Mrhs.
block[it->second];
1403 else if (block[q].size() != 0 and Mrhs.
block[it->second].size() == 0)
1414 if (Mtmp.size() != 0)
1416 Mout.
push_back({{in[q], out[q]}}, Mtmp);
1420 if (matching_blocks.size() != Mrhs.
dim)
1422 for (
size_t q=0; q<Mrhs.
size(); ++q)
1424 auto it = find(matching_blocks.begin(), matching_blocks.end(), q);
1425 if (it == matching_blocks.end())
1427 if (Mrhs.
block[q].size() != 0)
1438template<
typename Symmetry,
typename MatrixType_>
1441 os << V.
print(
true,4);
Biped< Symmetry, MatrixType_ > operator-(const Biped< Symmetry, MatrixType_ > &M1, const Biped< Symmetry, MatrixType_ > &M2)
Biped< Symmetry, MatrixType_ > operator+(const Biped< Symmetry, MatrixType_ > &M1, const Biped< Symmetry, MatrixType_ > &M2)
std::ostream & operator<<(std::ostream &os, const Biped< Symmetry, MatrixType_ > &V)
Biped< Symmetry, MatrixType_ > operator*(const Biped< Symmetry, MatrixType_ > &A1, const Biped< Symmetry, MatrixType_ > &A2)
void addPos(const MatrixType1 &Min, MatrixType2 &Mout, BLOCK_POSITION POS)
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)
Eigen::Index inner_dim(const Eigen::Index &num_in) const
std::array< qarray< Nq >, 2 > qarray2
std::array< qarray< Nq >, 3 > qarray3
Biped< Symmetry, MatrixType_ > adjoint() const
std::unordered_map< std::array< qType, 2 >, std::size_t > dict
Biped< Symmetry, MatrixType_ > transpose() const
void setTarget(vector< qType > Qmulti)
std::string print_dict() const
void try_create_block(std::array< qType, 2 > quple)
std::vector< MatrixType_ > block
void create_block(std::array< qType, 2 > quple)
void outerResize(const Biped< Symmetry, OtherMatrixType > Brhs)
void addScale(const Scalar &factor, const Biped< Symmetry, MatrixType_ > &Mrhs, BLOCK_POSITION BP=SAME_PLACE)
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
Biped< Symmetry, MatrixType_ > & operator+=(const Biped< Symmetry, MatrixType_ > &Arhs)
void cholesky(Biped< Symmetry, MatrixType > &res) const
Biped< Symmetry, OtherMatrixType > cast() const
Biped< Symmetry, MatrixType_ > contract(const Biped< Symmetry, MatrixType_ > &A, const contract::MODE MODE=contract::MODE::UNITY) const
Biped< Symmetry, MatrixType_ > conjugate() const
MatrixType_::Scalar Scalar
void setRandom(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
void push_back(qType qin, qType qout, const MatrixType_ &M)
Biped< Symmetry, MatrixType_ > adjustQN(const size_t number_cells)
double operatorNorm(bool COLWISE=true) const
void setZero(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())
pair< Biped< Symmetry, MatrixType_ >, Biped< Symmetry, MatrixType_ > > QR(bool RETURN_LQ=false, bool MAKE_UNIQUE=false) const
double overhead(MEMUNIT memunit=MB) const
Eigen::VectorXi cols(bool FULL=false) const
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
void try_push_back(qType qin, qType qout, const MatrixType_ &M)
void push_back(std::array< qType, 2 > quple, const MatrixType_ &M)
void try_push_back(std::array< qType, 2 > quple, const MatrixType_ &M)
void setTarget(qType Qtot)
void shift_Qin(const qarray< Symmetry::Nq > &Q)
void addScale_extend(const Scalar &factor, const Biped< Symmetry, MatrixType_ > &Mrhs)
Biped< Symmetry, MatrixType_ > sorted() const
std::string print(const bool SHOW_MATRICES=false, const std::size_t precision=3) const
double memory(MEMUNIT memunit=GB) const
std::string formatted() const
Biped< Symmetry, MatrixType_ > exp(const expScalar x) const
Eigen::VectorXi rows(bool FULL=false) const
Biped< Symmetry, MatrixType_ > cleaned() const
Eigen::VectorXd squaredNorm() const
void setIdentity(const Qbasis< Symmetry > &base1, const Qbasis< Symmetry > &base2, qType Q=Symmetry::qvacuum())