VMPS++
Loading...
Searching...
No Matches
Blocker.h
Go to the documentation of this file.
1#ifndef BLOCKER_H_
2#define BLOCKER_H_
3
9template<typename Symmetry, typename Scalar=double>
11{
12private:
13 typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> MatrixType;
14 static constexpr size_t Nq = Symmetry::Nq;
15
16public:
17 Blocker() {};
18
19 Blocker(vector<Biped<Symmetry,MatrixType> > &A_in, const vector<qarray<Nq> > &qloc_in, const Qbasis<Symmetry> &inbase_in, const Qbasis<Symmetry> &outbase_in)
20 :A(A_in), qloc(qloc_in), inbase(inbase_in), outbase(outbase_in) {};
21
23
24 vector<Biped<Symmetry,MatrixType> > reblock(const Biped<Symmetry,MatrixType> &B, DMRG::DIRECTION::OPTION DIR);
25
27
29
30private:
31 vector<Biped<Symmetry,MatrixType> > &A;
32 vector<qarray<Nq> > qloc;
34
36
37 bool HAS_BLOCKED=false;
38
39 void block_left();
40 void block_right();
41
42 vector<Biped<Symmetry,MatrixType> > reblock_left(const Biped<Symmetry,MatrixType> &B);
43 vector<Biped<Symmetry,MatrixType> > reblock_right(const Biped<Symmetry,MatrixType> &B);
44};
45
46template<typename Symmetry, typename Scalar>
49{
50 if (HAS_BLOCKED) {return;}
51 if (DIR == DMRG::DIRECTION::LEFT) {block_left();}
52 else if (DIR == DMRG::DIRECTION::RIGHT) {block_right();}
53 HAS_BLOCKED = true;
54}
55
56template<typename Symmetry, typename Scalar>
57vector<Biped<Symmetry,Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> > > Blocker<Symmetry,Scalar>::
59{
60 assert (HAS_BLOCKED and "Only can reblock if the A-tensor got blocked before.");
61 if (DIR == DMRG::DIRECTION::LEFT) {return reblock_left(B);}
62 else if (DIR == DMRG::DIRECTION::RIGHT) {return reblock_right(B);}
63 else {exit(1);} //avoid stupid warning for no return
64}
65
66template<typename Symmetry, typename Scalar>
69{
70 Aclump_.clear();
71 for (size_t qin=0; qin<inbase.Nq(); ++qin)
72 {
73 // determine how many A's to glue together
74 vector<size_t> svec, qvec, Ncolsvec;
75 for (size_t s=0; s<qloc.size(); ++s)
76 for (size_t q=0; q<A[s].dim; ++q)
77 {
78 if (A[s].in[q] == inbase[qin])
79 {
80 svec.push_back(s);
81 qvec.push_back(q);
82 Ncolsvec.push_back(A[s].block[q].cols());
83 }
84 }
85
86 if (Ncolsvec.size() > 0)
87 {
88 // do the glue
89 size_t Nrows = A[svec[0]].block[qvec[0]].rows();
90 for (size_t i=1; i<svec.size(); ++i)
91 {
92 assert(A[svec[i]].block[qvec[i]].rows() == Nrows);
93 }
94 size_t Ncols = accumulate(Ncolsvec.begin(), Ncolsvec.end(), 0);
95
96 MatrixType Mtmp(Nrows,Ncols);
97 Mtmp.setZero();
98 size_t stitch = 0;
99 for (size_t i=0; i<svec.size(); ++i)
100 {
101 Mtmp.block(0,stitch, Nrows,Ncolsvec[i]) = A[svec[i]].block[qvec[i]]* Symmetry::coeff_leftSweep(A[svec[i]].out[qvec[i]],
102 A[svec[i]].in[qvec[i]]);
103 stitch += Ncolsvec[i];
104 }
105 Aclump_.push_back(inbase[qin], inbase[qin], Mtmp);
106 }
107 }
108}
109
110template<typename Symmetry, typename Scalar>
113{
114 Aclump_.clear();
115 for (size_t qout=0; qout<outbase.Nq(); ++qout)
116 {
117 // determine how many A's to glue together
118 vector<size_t> svec, qvec, Nrowsvec;
119 for (size_t s=0; s<qloc.size(); ++s)
120 for (size_t q=0; q<A[s].dim; ++q)
121 {
122 if (A[s].out[q] == outbase[qout])
123 {
124 svec.push_back(s);
125 qvec.push_back(q);
126 Nrowsvec.push_back(A[s].block[q].rows());
127 }
128 }
129
130 if (Nrowsvec.size() > 0)
131 {
132 // do the glue
133 size_t Ncols = A[svec[0]].block[qvec[0]].cols();
134 for (size_t i=1; i<svec.size(); ++i)
135 {
136 if (A[svec[i]].block[qvec[i]].cols() != Ncols)
137 {
138 cout << "A[svec[i]].block[qvec[i]].cols()=" << A[svec[i]].block[qvec[i]].cols() << ", Ncols=" << Ncols << endl;
139 }
140 }
141 for (size_t i=1; i<svec.size(); ++i) {assert(A[svec[i]].block[qvec[i]].cols() == Ncols);}
142 size_t Nrows = accumulate(Nrowsvec.begin(),Nrowsvec.end(),0);
143
144 MatrixType Mtmp(Nrows,Ncols);
145 Mtmp.setZero();
146 size_t stitch = 0;
147 for (size_t i=0; i<svec.size(); ++i)
148 {
149 Mtmp.block(stitch,0, Nrowsvec[i],Ncols) = A[svec[i]].block[qvec[i]];
150 stitch += Nrowsvec[i];
151 }
152 Aclump_.push_back(outbase[qout], outbase[qout], Mtmp);
153 }
154 }
155}
156
157template<typename Symmetry, typename Scalar>
158vector<Biped<Symmetry,Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> > > Blocker<Symmetry,Scalar>::
160{
161 vector<Biped<Symmetry,MatrixType> > Aout(qloc.size());
162
163 for (size_t qout=0; qout<outbase.Nq(); ++qout)
164 {
165 auto it = B.dict.find({outbase[qout], outbase[qout]});
166 if (it == B.dict.end()) {continue;}
167 // assert(it != B.dict.end());
168 size_t qB = it->second;
169
170 // determine how many A's to glue together
171 vector<size_t> svec, qvec, Nrowsvec;
172 for (size_t s=0; s<qloc.size(); ++s)
173 for (size_t q=0; q<A[s].dim; ++q)
174 {
175 if (A[s].out[q] == outbase[qout])
176 {
177 svec.push_back(s);
178 qvec.push_back(q);
179 Nrowsvec.push_back(A[s].block[q].rows());
180 }
181 }
182
183 size_t stitch = 0;
184 for (size_t i=0; i<svec.size(); ++i)
185 {
186 MatrixType Mtmp;
187 Mtmp = B.block[qB].block(stitch,0, Nrowsvec[i],B.block[qB].cols());
188
189 if (Mtmp.size() != 0)
190 {
191 Aout[svec[i]].push_back(A[svec[i]].in[qvec[i]], A[svec[i]].out[qvec[i]], Mtmp);
192 }
193 stitch += Nrowsvec[i];
194 }
195 }
196 return Aout;
197}
198
199template<typename Symmetry, typename Scalar>
200vector<Biped<Symmetry,Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> > > Blocker<Symmetry,Scalar>::
202{
203 vector<Biped<Symmetry,MatrixType> > Aout(qloc.size());
204
205 for (size_t qin=0; qin<inbase.Nq(); ++qin)
206 {
207 auto it = B.dict.find({inbase[qin], inbase[qin]});
208 if (it == B.dict.end()) {continue;}
209 size_t qB = it->second;
210
211 // determine how many A's to glue together
212 vector<size_t> svec, qvec, Ncolsvec;
213 for (size_t s=0; s<qloc.size(); ++s)
214 for (size_t q=0; q<A[s].dim; ++q)
215 {
216 if (A[s].in[q] == inbase[qin])
217 {
218 svec.push_back(s);
219 qvec.push_back(q);
220 Ncolsvec.push_back(A[s].block[q].cols());
221 }
222 }
223
224 size_t stitch = 0;
225 for (size_t i=0; i<svec.size(); ++i)
226 {
227 MatrixType Mtmp;
228 Mtmp = B.block[qB].block(0,stitch, B.block[qB].rows(),Ncolsvec[i])*Symmetry::coeff_leftSweep(A[svec[i]].in[qvec[i]],
229 A[svec[i]].out[qvec[i]]);
230
231 if (Mtmp.size() != 0)
232 {
233 Aout[svec[i]].push_back(A[svec[i]].in[qvec[i]], A[svec[i]].out[qvec[i]], Mtmp);
234 }
235 stitch += Ncolsvec[i];
236 }
237 }
238 return Aout;
239}
240
241#endif //BLOCKER_H_
@ B
Definition: DmrgTypedefs.h:130
@ A
Definition: DmrgTypedefs.h:130
void block_right()
Definition: Blocker.h:68
Blocker()
Definition: Blocker.h:17
void block(DMRG::DIRECTION::OPTION DIR)
Definition: Blocker.h:48
Biped< Symmetry, MatrixType > Aclump(DMRG::DIRECTION::OPTION DIR)
Definition: Blocker.h:26
vector< Biped< Symmetry, MatrixType > > reblock_right(const Biped< Symmetry, MatrixType > &B)
Definition: Blocker.h:201
Qbasis< Symmetry > inbase
Definition: Blocker.h:33
vector< Biped< Symmetry, MatrixType > > & A
Definition: Blocker.h:31
Biped< Symmetry, MatrixType > Aclump_
Definition: Blocker.h:35
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixType
Definition: Blocker.h:13
bool HAS_BLOCKED
Definition: Blocker.h:37
static constexpr size_t Nq
Definition: Blocker.h:14
void FORCE_NEW_BLOCKING()
Definition: Blocker.h:28
Blocker(vector< Biped< Symmetry, MatrixType > > &A_in, const vector< qarray< Nq > > &qloc_in, const Qbasis< Symmetry > &inbase_in, const Qbasis< Symmetry > &outbase_in)
Definition: Blocker.h:19
vector< Biped< Symmetry, MatrixType > > reblock_left(const Biped< Symmetry, MatrixType > &B)
Definition: Blocker.h:159
void block_left()
Definition: Blocker.h:112
vector< Biped< Symmetry, MatrixType > > reblock(const Biped< Symmetry, MatrixType > &B, DMRG::DIRECTION::OPTION DIR)
Definition: Blocker.h:58
vector< qarray< Nq > > qloc
Definition: Blocker.h:32
Qbasis< Symmetry > outbase
Definition: Blocker.h:33
Definition: Qbasis.h:39
Definition: Biped.h:64
Definition: qarray.h:26