VMPS++
Loading...
Searching...
No Matches
Qbasis.h
Go to the documentation of this file.
1#ifndef QBASIS_H_
2#define QBASIS_H_
3
5#include <unordered_set>
6#include <set>
7#include <unordered_map>
8#include <numeric>
9
10#include <Eigen/Eigen>
12
13#include "macros.h"
14
15//include "DmrgTypedefs.h"
16#include "tensors/Basis.h"
17#include "symmetry/functions.h"
18//include "symmetry/qarray.h"
19// #include "tensors/Biped.h"
20
21template<typename Symmetry, typename MatrixType_> struct Biped;
22
37template<typename Symmetry>
38class Qbasis
39{
40 typedef typename Symmetry::qType qType;
41
42public:
43
45 Qbasis() {};
46
50 template<typename Container>
51 Qbasis (const Container &qins, const Eigen::Index &dim)
52 {
53 for (const auto &qin:qins)
54 {
55 push_back(qin,dim);
56 }
57 }
58
62 Qbasis (const vector<qarray<Symmetry::Nq> > &base_input)
63 {
64 map<qarray<Symmetry::Nq>,size_t> counter;
65 for (const auto &b:base_input)
66 {
67 counter[b]++;
68 }
69 for (const auto &[val,count]:counter)
70 {
71 push_back(val,count);
72 }
73 }
74
76
77 std::size_t size() const { std::size_t out = 0; for(const auto& [qVal,num,plain] : data_) { out+=plain.size();} return out; }
78
80 std::size_t M() const { return size(); }
81
86 std::size_t fullM() const { std::size_t out = 0; for(const auto& [qVal,num,plain] : data_) { out+=plain.size()*Symmetry::degeneracy(qVal);} return out; }
87
89 std::size_t Dmax() const;
90
92 std::size_t Nq() const { return data_.size(); }
94
96
97 const std::vector<qType> qloc() const;
98
100 const std::vector<qType> qs() const;
101
103 const std::unordered_set<qType> unordered_qs() const;
105
107
108 qType operator[] ( const std::size_t index ) const { return std::get<0>(data_[index]); }
109 qType& operator[] ( const std::size_t index ) { return std::get<0>(data_[index]); }
111
116 qType find( const std::string& ident ) const;
117
122 qType find( const Eigen::Index& num ) const;
124 bool find( const qType& q ) const;
125
126 Eigen::Index inner_num( const Eigen::Index& outer_num ) const;
127 Eigen::Index location( const std::string& ident ) const;
128
129 Eigen::Index inner_dim( const Eigen::Index& num_in ) const;
130 Eigen::Index inner_dim( const qType& q ) const;
131
132 Eigen::Index outer_num( const qType& q ) const;
133
134 Eigen::Index leftAmount( const qType& qnew, const std::array<qType,2>& qold ) const;
135 Eigen::Index leftOffset( const qType& qnew, const std::array<qType,2>& qold, const std::array<Eigen::Index,2>& plain_old ) const;
136 Eigen::Index rightAmount( const qType& qnew, const std::array<qType,2>& qold ) const;
137 // Eigen::Index outer_num( const qType& qnew, const std::array<qType,2>& qold ) const;
138
140
141 void push_back( const std::tuple<qType,Eigen::Index,std::vector<std::string> >& state );
142 void push_back( const qType& q_number, const Eigen::Index& inner_dim);
143 void push_back( const qType& q_number, const Eigen::Index& inner_dim, const std::vector<std::string>& idents);
145
147 void clear() {data_.clear(); history.clear(); curr_dim=0;}
148
153 template<typename MatrixType>
154 void pullData (const vector<Biped<Symmetry,MatrixType> >& A, const Eigen::Index& leg);
155
156 template<typename MatrixType>
157 void pullData (const vector<vector<vector<Biped<Symmetry,MatrixType>>> > &W, const Eigen::Index &leg);
158
159 void pullData (const std::vector<std::array<qType,3> > &qvec, const std::size_t& leg, const Eigen::Index &inner_dim_in);
160
161 void pullData (const std::vector<qarray<Symmetry::Nq> > &qs);
162
167 Qbasis<Symmetry> combine (const Qbasis<Symmetry>& other, bool FLIP=false) const;
168
173 void setHistoryEntry (const qType& Qval, const qType &Q1, const qType &Q2, Eigen::Index dim);
174
177
179 std::string print() const;
180
182 std::string printHistory() const;
183
184 bool operator== (const Qbasis<Symmetry>& other) const;
185
186 typename std::vector<std::tuple<qType,Eigen::Index,Basis> >::iterator begin() {return data_.begin();}
187 typename std::vector<std::tuple<qType,Eigen::Index,Basis> >::iterator end() {return data_.end();}
188
189 typename std::vector<std::tuple<qType,Eigen::Index,Basis> >::const_iterator cbegin() const {return data_.cbegin();}
190 typename std::vector<std::tuple<qType,Eigen::Index,Basis> >::const_iterator cend() const {return data_.cend();}
191
193 void swap (Qbasis<Symmetry> &other) { this->data.swap(other.data()); }
194
195 void sort ();
196
197//private:
198 struct fuseData
199 {
200 Eigen::Index dim;
201 std::array<qType,2> source;
203 };
204
205 //vector with entry: {Quantumnumber (QN), state number of the first plain state for this QN, all plain states for this QN in a Basis object.}
206 //[{q1,0,plain_q1}, {q2,dim(plain_q1),plain_q2}, {q3,dim(plain_q1)+dim(plain_q2),plain_q3}, ..., {qi, sum_j^(i-1)dim(plain_qj), plain_qi}]
207 std::vector<std::tuple<qType,Eigen::Index,Basis> > data_;
208 Eigen::Index curr_dim=0;
209 std::unordered_map<qType,std::vector<fuseData> > history;
210};
211
212template<typename Symmetry>
214push_back(const std::tuple<qType,Eigen::Index,std::vector<std::string> >& state)
215{
216 auto [ q_number, inner_dim, ident ] = state;
217 push_back(q_number, inner_dim, ident);
218}
219
220template<typename Symmetry>
222push_back(const qType& q_number, const Eigen::Index& inner_dim)
223{
224 std::vector<std::string> dummy_idents(inner_dim,"");
225 push_back(q_number, inner_dim, dummy_idents);
226}
227
228template<typename Symmetry>
230push_back(const qType& q_number, const Eigen::Index& inner_dim, const std::vector<std::string>& idents)
231{
232 // search if the quantum number is already in the Qbasis.
233 auto it = std::find_if(data_.begin(), data_.end(), [&q_number] (const tuple<qType,Eigen::Index,Basis> &entry) {return std::get<0>(entry) == q_number;});
234 // insert quantum number if it is not there
235 if (it == data_.end()) // ATTENTION: workaround for ZN symmetries (e.g. Hubbard basis has parity 0,1,1,0 and 4 states)
236 {
237 Basis plain_basis(idents,inner_dim);
238 auto entry = std::make_tuple(q_number,curr_dim,plain_basis);
239 data_.push_back(entry);
240 }
241 else // append to quantum number if it is there
242 {
243 // I'm not sure this works...
244 // Better to give the correct ident=1,2,3... from the Site class.
245 // (Roman)
246 std::get<2>(*it).push_back(idents);
247 for (auto loop=it++; loop==data_.end(); loop++)
248 {
249 std::get<1>(*loop) += inner_dim;
250 }
251 }
252 curr_dim += inner_dim;
253}
254
255template<typename Symmetry>
257Dmax() const
258{
259 std::size_t out = 0;
260 for (const auto& entry : data_)
261 {
262 auto [qVal,num,plain] = entry;
263 if (plain.size() > out) {out = plain.size();}
264 }
265 return out;
266}
267
268template<typename Symmetry>
269const std::vector<typename Symmetry::qType> Qbasis<Symmetry>::
270qloc() const
271{
272 std::vector<qType> out;
273 for(const auto& [q,num,plain] : data_) { for(std::size_t c=0; c<plain.size(); c++) {out.push_back(q);} }
274 return out;
275}
276
277template<typename Symmetry>
278const std::vector<typename Symmetry::qType> Qbasis<Symmetry>::
279qs() const
280{
281 std::vector<qType> out;
282 for(const auto& [q,num,plain] : data_) { out.push_back(q); }
283 return out;
284}
285
286template<typename Symmetry>
287const std::unordered_set<typename Symmetry::qType> Qbasis<Symmetry>::
288unordered_qs() const
289{
290 std::unordered_set<qType> out;
291 for(const auto& [q,num,plain] : data_) { out.insert(q); }
292 return out;
293}
294
295template<typename Symmetry>
296typename Symmetry::qType Qbasis<Symmetry>::
297find(const std::string& ident) const
298{
299 for (const auto& q : data_ )
300 {
301 auto [qVal,num,basis] = q;
302 if(basis.find(ident)) {return qVal;}
303 }
304 assert(1!=1 and "The ident is not in the basis");
305}
306
307template<typename Symmetry>
308typename Symmetry::qType Qbasis<Symmetry>::
309find(const Eigen::Index& num_in ) const
310{
311 assert( num_in < size() and "The number is larger than the size of this basis." );
312 Eigen::Index check = num_in;
313 for (const auto& q : data_)
314 {
315 auto [qVal,num,basis] = q;
316 if (check < num+basis.size()) { return qVal; }
317 }
318 assert(false and "Something went wrong in Qbasis::find(Eigen::Index num_in)");
319}
320
321template<typename Symmetry>
323find (const qType& q ) const
324{
325 for (const auto& entry : data_)
326 {
327 auto [qVal,num,basis] = entry;
328 if (qVal == q) {return true;}
329 }
330 return false;
331}
332
333template<typename Symmetry>
335inner_num(const Eigen::Index& outer_num) const
336{
337 assert( outer_num < size() and "The number larger than the size of this basis." );
338 Eigen::Index check = outer_num;
339 for (const auto& q : data_)
340 {
341 auto [qVal,num,plain] = q;
342 for (const auto& elem : plain)
343 {
344 auto [ident,inner_num] = elem;
345 if (check == num+inner_num) { return inner_num; }
346 }
347 }
348 assert(false and "Something went wrong in Qbasis::inner_num");
349}
350
351template<typename Symmetry>
353location(const std::string& ident) const
354{
355 for(const auto& elem : data_)
356 {
357 auto [qVal,num,plain] = elem;
358 if(plain.location(ident) != std::numeric_limits<Eigen::Index>::max()) {return plain.location(ident);}
359 }
360 assert( 1!=1 and "The ident is not in the basis" );
361}
362
363template<typename Symmetry>
365inner_dim(const qType& q) const
366{
367 for(const auto& elem : data_)
368 {
369 auto [qVal,num,plain] = elem;
370 if (qVal == q) {return plain.size();}
371 }
372 return 0;
373 // assert( 1!=1 and "The qType is not in the basis" );
374}
375
376template<typename Symmetry>
378outer_num(const qType& q) const
379{
380 for(const auto& elem : data_)
381 {
382 auto [qVal,num,plain] = elem;
383 if (qVal == q) {return num;}
384 }
385 // return 0;
386 assert( 1!=1 and "The qType is not in the basis" );
387}
388
389template<typename Symmetry>
391inner_dim(const Eigen::Index& num_in) const
392{
393 for(const auto& elem : data_)
394 {
395 auto [qVal,num,plain] = elem;
396 if (num == num_in) {return plain.size();}
397 }
398 assert( 1!=1 and "This number is not in the basis" );
399}
400
401template<typename Symmetry>
403rightAmount(const qType& qnew, const std::array<qType,2>& qold) const
404{
405 assert( history.size() == data_.size() and "The history for this basis is not defined properly");
406 auto it = history.find(qnew);
407 assert( it != history.end() and "The history for this basis is not defined properly");
408
409 Eigen::Index out=0;
410 bool SCHALTER=false;
411 for( const auto& i: it->second )
412 {
413 if(i.source != qold and SCHALTER==true) { out+=i.dim; }
414 if(i.source == qold) { SCHALTER = true; }
415 }
416 return out;
417}
418
419template<typename Symmetry>
421leftAmount(const qType& qnew, const std::array<qType,2>& qold) const
422{
423 assert( history.size() == data_.size() and "The history for this basis is not defined properly");
424
425 auto it = history.find(qnew);
426 assert( it != history.end() and "The history for this basis is not defined properly");
427
428 Eigen::Index out=0;
429 bool SCHALTER=false;
430 for( const auto& i: it->second )
431 {
432 if(i.source != qold and SCHALTER==false) { out+=i.dim; }
433 if(i.source == qold) { break; }// SCHALTER = true;
434 }
435 return out;
436}
437
438template<typename Symmetry>
440leftOffset(const qType& qnew, const std::array<qType,2>& qold, const std::array<Eigen::Index,2>& plain_old) const
441{
442 assert( history.size() == data_.size() and "The history for this basis is not defined properly");
443
444 auto it = history.find(qnew);
445 assert( it != history.end() and "The history for this basis is not defined properly");
446
447 Eigen::Index out=0;
448
449 for( const auto& i: it->second )
450 {
451 if(i.source != qold) { out+=i.dim; }
452 if(i.source == qold)
453 {
454 for (size_t j=0; j<i.plainHistory.dim1*i.plainHistory.dim2; j++)
455 {
456 if(i.plainHistory.source(j) != plain_old) { out+=1; }
457 if(i.plainHistory.source(j) == plain_old) { break; }
458 }
459 break;
460 }
461 }
462 return out;
463}
464// template<typename Symmetry>
465// Eigen::Index Qbasis<Symmetry>::
466// outer_num(const qType& qnew, const std::array<qType,2>& qold) const
467// {
468// assert( history.size() == data_.size() and "The history for this basis is not defined properly");
469
470// auto it = history.find(qnew);
471// assert( it != history.end() and "The history for this basis is not defined properly");
472
473// Eigen::Index out=0;
474// bool SCHALTER=false;
475// for( const auto& i: it->second )
476// {
477// if(i.source != qold and SCHALTER==false) { out+=i.dim; }
478// if(i.source == qold) { break; }// SCHALTER = true;
479// }
480// return out;
481// }
482
483template<typename Symmetry>
484template<typename MatrixType>
486pullData (const vector<Biped<Symmetry,MatrixType> > &A, const Eigen::Index &leg)
487{
488 std::unordered_set<qType> unique_controller;
489 for (std::size_t s=0; s<A.size(); s++)
490 for (std::size_t q=0; q<A[s].size(); q++)
491 {
492 if(leg==0)
493 {
494 auto it = unique_controller.find(A[s].in[q]);
495 if( it==unique_controller.end() )
496 {
497 qType q_number = A[s].in[q];
498 Eigen::Index inner_dim = A[s].block[q].rows();
499 push_back(q_number,inner_dim);
500 unique_controller.insert(q_number);
501 }
502 }
503 else if(leg==1)
504 {
505 auto it = unique_controller.find(A[s].out[q]);
506 if( it==unique_controller.end() )
507 {
508 qType q_number = A[s].out[q];
509 Eigen::Index inner_dim = A[s].block[q].cols();
510 push_back(q_number,inner_dim);
511 unique_controller.insert(q_number);
512 }
513 }
514 }
515}
516
517template<typename Symmetry>
518template<typename MatrixType>
520pullData (const vector<vector<vector<Biped<Symmetry,MatrixType>>> > &W, const Eigen::Index &leg)
521{
522 std::unordered_set<qType> unique_controller;
523 for (std::size_t s1=0; s1<W.size(); s1++)
524 for(std::size_t s2=0; s2<W[s1].size(); s2++)
525 for(std::size_t k=0; k<W[s1][s2].size(); k++)
526 for (std::size_t q=0; q<W[s1][s2][k].size(); q++)
527 {
528 if(leg==0)
529 {
530 auto it = unique_controller.find(W[s1][s2][k].in[q]);
531 if( it==unique_controller.end() )
532 {
533 qType q_number = W[s1][s2][k].in[q];
534 Eigen::Index inner_dim = W[s1][s2][k].block[q].rows();
535 push_back(q_number,inner_dim);
536 unique_controller.insert(q_number);
537 }
538 }
539 else if(leg==1)
540 {
541 auto it = unique_controller.find(W[s1][s2][k].out[q]);
542 if( it==unique_controller.end() )
543 {
544 qType q_number = W[s1][s2][k].out[q];
545 Eigen::Index inner_dim = W[s1][s2][k].block[q].cols();
546 push_back(q_number,inner_dim);
547 unique_controller.insert(q_number);
548 }
549 }
550 }
551}
552
553template<typename Symmetry>
555pullData (const std::vector<std::array<qType,3> > &qvec, const std::size_t &leg, const Eigen::Index &inner_dim_in)
556{
557 std::unordered_set<qType> unique_controller;
558 Eigen::Index inner_dim = inner_dim_in;
559 for (std::size_t nu=0; nu<qvec.size(); nu++)
560 {
561 auto it = unique_controller.find(qvec[nu][leg]);
562 if( it==unique_controller.end() )
563 {
564 qType q_number = qvec[nu][leg];
565 push_back(q_number,inner_dim);
566 unique_controller.insert(q_number);
567 }
568 }
569}
570
571template<typename Symmetry>
573pullData (const std::vector<qarray<Symmetry::Nq> > &qs)
574{
575// if (ORDERED)
576 {
577 for (const auto & q : qs)
578 {
579 push_back(q,1);
580 }
581 return;
582 }
583// std::unordered_map<qType,size_t> qmap;
584// for (std::size_t s=0; s<qs.size(); s++)
585// {
586// auto it = qmap.find(qs[s]);
587// if( it==qmap.end() )
588// {
589// qmap[qs[s]] = 1;
590// }
591// else
592// {
593// qmap[qs[s]]++;
594// }
595// }
596// for (const auto &[q,dim]:qmap) {push_back(q,dim);}
597}
598
599template<typename Symmetry>
601sort ()
602{
603
604 std::vector<std::size_t> index_sort(data_.size());
605 std::iota(index_sort.begin(),index_sort.end(),0);
606 std::sort (index_sort.begin(), index_sort.end(),
607 [&] (std::size_t n1, std::size_t n2)
608 {
609 qarray<Symmetry::Nq> q1 = std::get<0>(data_[n1]);
610 qarray<Symmetry::Nq> q2 = std::get<0>(data_[n2]);
611 return Symmetry::compare(std::array{q1},std::array{q2});
612 }
613 );
614 auto new_data_ = data_;
615 for (std::size_t i=0; i<data_.size(); i++)
616 {
617 new_data_[i] = data_[index_sort[i]];
618 }
619 std::get<1>(new_data_[0]) = 0;
620 for (std::size_t i=1; i<data_.size(); i++)
621 {
622 std::get<1>(new_data_[i]) = 0;
623 for (std::size_t j=0; j<i; j++)
624 {
625 std::get<1>(new_data_[i]) += std::get<2>(new_data_[j]).size();
626 }
627 }
628 data_ = new_data_;
629}
630
631template<typename Symmetry>
633operator==( const Qbasis<Symmetry>& other ) const
634{
635 return (this->data_ == other.data_);
636}
637
638template<typename Symmetry>
640add( const Qbasis<Symmetry>& other ) const
641{
642 // cout << termcolor::red << termcolor::bold << "Using function Qbasis::add" << termcolor::reset << endl;
643 std::unordered_set<qType> uniqueController;
644 Qbasis out;
645 for(const auto& [q1,num1,plain1] : this->data_)
646 {
647 auto qtmp = q1;
648 auto it_other = std::find_if(other.data_.begin(), other.data_.end(), [qtmp] (std::tuple<qType,Eigen::Index,Basis> entry) { return std::get<0>(entry) == qtmp; });
649 if (it_other != other.data_.end())
650 {
651 out.push_back(q1,plain1.add(std::get<2>(*it_other)).size());
652 }
653 else
654 {
655 out.push_back(q1,plain1.size());
656 }
657 }
658
659 for(const auto& [q2,num2,plain2] : other.data_)
660 {
661 auto qtmp = q2;
662 auto it_this = std::find_if(data_.begin(), data_.end(), [qtmp] (std::tuple<qType,Eigen::Index,Basis> entry) { return std::get<0>(entry) == qtmp; });
663 if (it_this == data_.end())
664 {
665 out.push_back(q2,plain2.size());
666 }
667 }
668 out.sort();
669 return out;
670}
671
672template<typename Symmetry>
674setHistoryEntry( const qType &Qval, const qType &Q1, const qType &Q2, Eigen::Index dim )
675{
676 vector<fuseData> history_;
677 fuseData entry;
678 entry.source = {Q1,Q2};
679 entry.dim = dim;
680 history_.push_back(entry);
681 history.insert(std::make_pair(Qval,history_));
682}
683
684template<typename Symmetry>
686combine (const Qbasis<Symmetry>& other, bool FLIP) const
687{
688 Qbasis out;
689 //build the history of the combination. Data is relevant for MultipedeQ contractions which include a fuse of two leg.
690 for(const auto& elem1 : this->data_)
691 {
692 auto [q1,num1,plain1] = elem1;
693 for(const auto& elem2 : other.data_)
694 {
695 auto [q2,num2,plain2] = elem2;
696 if (FLIP)
697 {
698 q2 = Symmetry::flip(q2);
699 }
700 auto plain = plain1.combine(plain2);
701 auto qVec = Symmetry::reduceSilent(q1,q2);
702 for (const auto& q: qVec)
703 {
704 auto it = out.history.find(q);
705 if( it==out.history.end() )
706 {
707 std::vector<fuseData> history_;
708 fuseData entry;
709 entry.source = {q1,q2};
710 entry.dim = plain1.size() * plain2.size();
711 // std::vector<Basis::fuseData> plainHistory(entry.dim);
712 // for (Eigen::Index i=0; i<plain1.size(); i++)
713 // for (Eigen::Index j=0; j<plain2.size(); j++)
714 // {
715 // Basis::fuseData plain_entry = {{i,j}};
716 // // plainHistory[i+plain1.size()*j] = plain_entry;
717 // plainHistory[j+plain2.size()*i] = plain_entry;
718 // }
719 entry.plainHistory = plain.history;
720 history_.push_back(entry);
721 out.history.insert(std::make_pair(q,history_));
722 }
723 else
724 {
725 bool DONT_COUNT=false;
726 for( const auto& entry: it->second )
727 {
728 std::array<qType,2> tmp = {q1,q2};
729 if ( entry.source == tmp )
730 {
731 DONT_COUNT = true;
732 }
733 }
734 if ( DONT_COUNT == false )
735 {
736 fuseData entry;
737 entry.source = {q1,q2};
738 entry.dim = plain1.size() * plain2.size();
739 // std::vector<Basis::fuseData> plainHistory(entry.dim);
740 // for (Eigen::Index i=0; i<plain1.size(); i++)
741 // for (Eigen::Index j=0; j<plain2.size(); j++)
742 // {
743 // Basis::fuseData plain_entry = {{i,j}};
744 // // plainHistory[i+plain1.size()*j] = plain_entry;
745 // plainHistory[j+plain2.size()*i] = plain_entry;
746 // }
747 entry.plainHistory = plain.history;
748 (it->second).push_back(entry);
749 }
750 }
751 }
752 }
753 }
754
755 //sort the history on the basis of Symmetry::compare()
756 for ( auto it=out.history.begin(); it!=out.history.end(); it++ )
757 {
758 std::vector<std::size_t> index_sort((it->second).size());
759 std::iota(index_sort.begin(),index_sort.end(),0);
760 std::sort (index_sort.begin(), index_sort.end(),
761 [&] (std::size_t n1, std::size_t n2)
762 {
763 return Symmetry::compare((it->second)[n1].source,(it->second)[n2].source);
764 }
765 );
766 std::vector<fuseData> entry2 = it->second;
767 for (std::size_t i=0; i<entry2.size(); i++)
768 {
769 (it->second)[i] = entry2[index_sort[i]];
770 }
771 }
772
773 //build up the new basis
774 for ( auto it=out.history.begin(); it!=out.history.end(); it++ )
775 {
776 Eigen::Index inner_dim = 0;
777 std::vector<string> idents;
778 for(const auto& i: it->second)
779 {
780 // qType q1 = i.source[0];
781 // qType q2 = i.source[1];
782 // for (Eigen::Index plain=0; plain<i.plainHistory.size(); plain++)
783 // {
784 // Eigen::Index plain1 = i.plainHistory[plain].source[0];
785 // Eigen::Index plain2 = i.plainHistory[plain].source[1];
786 // auto pos_1 = std::find_if(this->data_.begin(), this->data_.end(), [q1](auto t) {return std::get<0>(t) == q1;});
787 // auto pos_2 = std::find_if(other.data_.begin(), other.data_.end(), [q2](auto t) {return std::get<0>(t) == q2;});
788 // std::string label1 = std::get<0>(std::get<2>(*pos_1).data_[plain1]);
789 // std::string label2 = std::get<0>(std::get<2>(*pos_2).data_[plain2]);
790 // idents.push_back(label1+"⊗"+label2);
791 // }
792 inner_dim+=i.dim;
793 }
794 out.push_back(it->first,inner_dim);
795 }
796 out.sort();
797 return out;
798}
799
800template<typename Symmetry>
802print() const
803{
804 std::stringstream out;
805 #ifdef TOOLS_IO_TABLE
806 TextTable t( '-', '|', '+' );
807 t.add("Q");
808 t.add("Dim(Q)");
809 t.add("idents");
810 t.endOfRow();
811 for(const auto& entry : data_)
812 {
813 auto [q_Phys,curr_num,plain] = entry;
814 std::stringstream ss, tt, uu;
815 ss << Sym::format<Symmetry>(q_Phys);
816
817 //ss << q_Phys;
818 tt << plain.size();
819
820 uu << curr_num;
821 // uu << "(";
822 // for (auto it = plain.cbegin(); it != plain.cend(); it++)
823 // // for (const auto & [ident, num] : plain)
824 // {
825 // auto [ident,num] = *it;
826 // if (std::distance(it,plain.cend()) == 1)
827 // uu << ident << "(" << num << ")";
828 // else
829 // uu << ident << "(" << num << ")" << ", ";
830 // }
831 // uu << ")";
832 t.add(ss.str());
833 t.add(tt.str());
834 t.add(uu.str());
835 t.endOfRow();
836 }
837 out << t;
838 #else
839 out << "The stream operator for Qbasis needs the TextTable library.";
840 #endif
841 return out.str();
842}
843
844template<typename Symmetry>
846printHistory() const
847{
848 std::stringstream out;
849 for(auto it=history.begin(); it!=history.end(); it++)
850 {
851 out << it->second.size() << " quantumnumber pair(s) merge to Q=" << it->first << std::endl;
852 for(const auto& i: it->second)
853 {
854 out << i.source[0] << "," << i.source[1] << "\t→\t" << it->first << ": dim=" << i.dim << std::endl;
855 assert(i.dim == i.plainHistory.dim1*i.plainHistory.dim2);
856 for (std::size_t j=0; j<i.dim; j++)
857 {
858 out << "j=" << j << " results from(" << i.plainHistory.source(j)[0] << "," << i.plainHistory.source(j)[1] << ")" << std::endl;
859 }
860 out << std::endl;
861 }
862 out << std::endl;
863 }
864 return out.str();
865}
866
867template<typename Symmetry>
868std::ostream& operator<<(std::ostream& os, const Qbasis<Symmetry> &basis)
869{
870 os << basis.print();
871 return os;
872}
873
874#endif
size_t dim(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
@ A
Definition: DmrgTypedefs.h:130
std::ostream & operator<<(std::ostream &os, const Qbasis< Symmetry > &basis)
Definition: Qbasis.h:868
Definition: Basis.h:12
Definition: Qbasis.h:39
void pullData(const std::vector< std::array< qType, 3 > > &qvec, const std::size_t &leg, const Eigen::Index &inner_dim_in)
Definition: Qbasis.h:555
void push_back(const std::tuple< qType, Eigen::Index, std::vector< std::string > > &state)
Definition: Qbasis.h:214
void push_back(const qType &q_number, const Eigen::Index &inner_dim, const std::vector< std::string > &idents)
Definition: Qbasis.h:230
Eigen::Index inner_dim(const qType &q) const
Definition: Qbasis.h:365
Eigen::Index leftAmount(const qType &qnew, const std::array< qType, 2 > &qold) const
Definition: Qbasis.h:421
std::size_t Nq() const
Definition: Qbasis.h:92
const std::vector< qType > qs() const
Definition: Qbasis.h:279
std::vector< std::tuple< qType, Eigen::Index, Basis > >::iterator end()
Definition: Qbasis.h:187
qType operator[](const std::size_t index) const
Definition: Qbasis.h:108
Eigen::Index rightAmount(const qType &qnew, const std::array< qType, 2 > &qold) const
Definition: Qbasis.h:403
void push_back(const qType &q_number, const Eigen::Index &inner_dim)
Definition: Qbasis.h:222
std::string printHistory() const
Definition: Qbasis.h:846
void sort()
Definition: Qbasis.h:601
std::size_t Dmax() const
Definition: Qbasis.h:257
std::size_t fullM() const
Definition: Qbasis.h:86
qType find(const std::string &ident) const
Definition: Qbasis.h:297
Eigen::Index inner_num(const Eigen::Index &outer_num) const
Definition: Qbasis.h:335
Qbasis< Symmetry > combine(const Qbasis< Symmetry > &other, bool FLIP=false) const
Definition: Qbasis.h:686
Qbasis(const vector< qarray< Symmetry::Nq > > &base_input)
Definition: Qbasis.h:62
Eigen::Index location(const std::string &ident) const
Definition: Qbasis.h:353
std::vector< std::tuple< qType, Eigen::Index, Basis > >::const_iterator cbegin() const
Definition: Qbasis.h:189
Qbasis< Symmetry > add(const Qbasis< Symmetry > &other) const
Definition: Qbasis.h:640
Eigen::Index leftOffset(const qType &qnew, const std::array< qType, 2 > &qold, const std::array< Eigen::Index, 2 > &plain_old) const
Definition: Qbasis.h:440
Qbasis(const Container &qins, const Eigen::Index &dim)
Definition: Qbasis.h:51
void pullData(const vector< Biped< Symmetry, MatrixType > > &A, const Eigen::Index &leg)
Definition: Qbasis.h:486
bool operator==(const Qbasis< Symmetry > &other) const
Definition: Qbasis.h:633
void setHistoryEntry(const qType &Qval, const qType &Q1, const qType &Q2, Eigen::Index dim)
Definition: Qbasis.h:674
std::size_t M() const
Definition: Qbasis.h:80
void swap(Qbasis< Symmetry > &other)
Definition: Qbasis.h:193
std::vector< std::tuple< qType, Eigen::Index, Basis > > data_
Definition: Qbasis.h:207
const std::vector< qType > qloc() const
Definition: Qbasis.h:270
std::vector< std::tuple< qType, Eigen::Index, Basis > >::const_iterator cend() const
Definition: Qbasis.h:190
Eigen::Index curr_dim
Definition: Qbasis.h:208
Symmetry::qType qType
Definition: Qbasis.h:40
bool find(const qType &q) const
Definition: Qbasis.h:323
void pullData(const vector< vector< vector< Biped< Symmetry, MatrixType > > > > &W, const Eigen::Index &leg)
Definition: Qbasis.h:520
qType find(const Eigen::Index &num) const
Definition: Qbasis.h:309
std::string print() const
Definition: Qbasis.h:802
const std::unordered_set< qType > unordered_qs() const
Definition: Qbasis.h:288
std::vector< std::tuple< qType, Eigen::Index, Basis > >::iterator begin()
Definition: Qbasis.h:186
std::size_t size() const
Definition: Qbasis.h:77
std::unordered_map< qType, std::vector< fuseData > > history
Definition: Qbasis.h:209
Qbasis()
Definition: Qbasis.h:45
void pullData(const std::vector< qarray< Symmetry::Nq > > &qs)
Definition: Qbasis.h:573
void clear()
Definition: Qbasis.h:147
Eigen::Index outer_num(const qType &q) const
Definition: Qbasis.h:378
Eigen::Index inner_dim(const Eigen::Index &num_in) const
Definition: Qbasis.h:391
Definition: Biped.h:64
Eigen::Index dim
Definition: Qbasis.h:200
std::array< qType, 2 > source
Definition: Qbasis.h:201
Basis::fuseData plainHistory
Definition: Qbasis.h:202
Definition: qarray.h:26