VMPS++
Loading...
Searching...
No Matches
SuperMatrix.h
Go to the documentation of this file.
1#ifndef SUPERMATRIX
2#define SUPERMATRIX
3
5#include <set>
6#include <boost/multi_array.hpp>
8
9#include "MemCalc.h" // from TOOLS
10//include "DmrgTypedefs.h"
11//include "DmrgHamiltonianTerms.h"
13
14
16template<typename Symmetry, typename Scalar=double>
18{
19typedef SparseMatrix<double,ColMajor,EIGEN_DEFAULT_SPARSE_INDEX_TYPE> MatrixType;
21public:
22
23 OperatorType &operator() (size_t i, size_t j) {return data[i][j];} // write
24 OperatorType operator() (size_t i, size_t j) const {return data[i][j];} // read
25
27 void set (size_t Daux1, size_t Daux2, size_t D)
28 {
29 N_rows = Daux1;
30 N_cols = Daux2;
31 data.resize(boost::extents[Daux1][Daux2]);
33 setZero();
34 }
35
37 void setRowVector (size_t Daux, size_t D)
38 {
39 set(1,Daux,D);
40 }
41
43 void setColVector (size_t Daux, size_t D)
44 {
45 set(Daux,1,D);
46 }
47
49 void setMatrix (size_t Daux, size_t D)
50 {
51 set(Daux,Daux,D);
52 }
53
56 {
58 Mout.setRowVector(N_cols,D()); // instead of auxdim
59 for (size_t j=0; j<N_cols; ++j) // Bug? N_rows
60 {
61 Mout(0,j) = data[i][j];
62 }
63 return Mout;
64 }
65
68 {
70 Mout.setColVector(N_rows,D()); // instead of auxdim
71 for (size_t j=0; j<N_rows; ++j) // Bug? N_cols
72 {
73 Mout(j,0) = data[j][i];
74 }
75 return Mout;
76 }
77
79 void setZero()
80 {
81 for (size_t i=0; i<N_rows; ++i)
82 for (size_t j=0; j<N_cols; ++j)
83 {
84 data[i][j].data.setZero();
85 }
86 }
87
88 inline size_t rows() const {return N_rows;}
89 inline size_t cols() const {return N_cols;}
90
92 inline size_t auxdim() const
93 {
94 assert(N_rows == N_cols and "auxdim called although SuperMatrix is not quadratic");
95 return std::max(N_rows,N_cols);
96 }
97
99 double memory (MEMUNIT memunit=GB) const
100 {
101 double out = 0.;
102
103 for (size_t i=0; i<N_rows; ++i)
104 for (size_t j=0; j<N_cols; ++j)
105 {
106 return out += calc_memory<Scalar>(data[i][j].data, memunit);
107 }
108 return out;
109 }
110
112 size_t D() const
113 {
114 size_t Dres = data[0][0].data.rows();
115 for (size_t i=0; i<N_rows; ++i)
116 for (size_t j=0; j<N_cols; ++j)
117 {
118 assert(data[i][j].data.rows() == Dres);
119 assert(data[i][j].data.cols() == Dres);
120 }
121 return Dres;
122 }
123
124 std::vector<typename Symmetry::qType> calc_qOp() const
125 {
126 std::set<typename Symmetry::qType> qOps;
127 for (size_t i=0; i<N_rows; ++i)
128 for (size_t j=0; j<N_cols; ++j)
129 {
130 qOps.insert(data[i][j].Q);
131 }
132
133 std::vector<typename Symmetry::qType> out(qOps.size());
134 copy(qOps.begin(), qOps.end(), out.begin());
135
136 return out;
137 }
138
139private:
140
141 size_t N_rows;
142 size_t N_cols;
143
144 boost::multi_array<OperatorType,2> data;
145
146 void innerResize (size_t D)
147 {
148 for (size_t i=0; i<N_rows; ++i)
149 for (size_t j=0; j<N_cols; ++j)
150 {
151 data[i][j].data.resize(D,D);
152 }
153 }
154};
155
156template<typename Symmetry, typename Scalar>
158{
159 assert(M1.D() == M2.D());
160
162
163 if (M1.rows() == 1)
164 {
165 Mout.setRowVector(M1.cols()*M2.cols(), M1.D()); // instead of auxdim
166 }
167 else if (M1.cols() == 1)
168 {
169 Mout.setColVector(M1.rows()*M2.rows(), M1.D()); // instead of auxdim
170 }
171 else
172 {
173 Mout.set(M1.rows()*M2.rows(), M1.cols()*M2.cols(), M1.D()); // instead of auxdim
174 }
175
176 for (size_t r1=0; r1<M1.rows(); ++r1)
177 for (size_t c1=0; c1<M1.cols(); ++c1)
178 for (size_t r2=0; r2<M2.rows(); ++r2)
179 for (size_t c2=0; c2<M2.cols(); ++c2)
180 {
181 Mout(r1*M2.rows()+r2, c1*M2.cols()+c2).data = M1(r1,c1).data * M2(r2,c2).data;
182 auto Qsum = Symmetry::reduceSilent(M1(r1,c1).Q, M2(r2,c2).Q);
183 // should be only one term, non-Abelian symmetries have a different code
184 assert(Qsum.size() == 1 and "tensor_product of SuperMatrices called with wrong symmetry!");
185 Mout(r1*M2.rows()+r2, c1*M2.cols()+c2).Q = Qsum[0];
186 }
187
188 return Mout;
189}
190
191template<typename Symmetry, typename Scalar>
193{
195 size_t R;
196 size_t C;
197
198 if (M1.rows()==1 and M2.rows()==1)
199 {
200 Mout.setRowVector(M1.cols()+M2.cols(), M1.D()); // instead of auxdim
201 R = 0;
202 C = M1.cols();
203 }
204 else if (M1.cols()==1 and M2.cols()==1)
205 {
206 Mout.setColVector(M1.rows()+M2.rows(), M1.D()); // instead of auxdim
207 R = M1.rows();
208 C = 0;
209 }
210 else
211 {
212 Mout.set(M1.rows()+M2.rows(), M1.cols()+M2.cols(), M1.D()); // instead of auxdim
213 R = M1.rows();
214 C = M1.cols();
215 }
216
217 for (size_t r1=0; r1<M1.rows(); ++r1)
218 for (size_t c1=0; c1<M1.cols(); ++c1)
219 {
220 Mout(r1,c1) = M1(r1,c1);
221 }
222
223 for (size_t r2=0; r2<M2.rows(); ++r2)
224 for (size_t c2=0; c2<M2.cols(); ++c2)
225 {
226 Mout(R+r2,C+c2) = M2(r2,c2);
227 }
228
229 return Mout;
230}
231
232template<typename Symmetry, typename Scalar>
233std::ostream &operator<< (std::ostream& os, const SuperMatrix<Symmetry,Scalar> &M)
234{
235 os << std::showpos << std::setprecision(1) << std::fixed;
236 for (int i=0; i<M.rows(); ++i)
237 {
238 for (int n=0; n<M.D(); ++n)
239 {
240 for (int j=0; j<M.cols(); ++j)
241 {
242 for (int m=0; m<M.D(); ++m)
243 {
244
245 os << Matrix<Scalar,Dynamic,Dynamic>(M(i,j).data)(n,m);
246 }
247 os << " ";
248 }
249 if (n!=M.D()-1) {os << std::endl;}
250 }
251 if (i!=M.rows()-1) {os << std::endl << std::endl;}
252 }
253 os << noshowpos;
254 return os;
255}
256
257/*template<typename Symmetry, typename Scalar>
258SuperMatrix<Symmetry, Scalar> Generator (const HamiltonianTerms<Symmetry, Scalar> &Terms)
259{
260 typedef SiteOperator<Symmetry,Scalar> OperatorType;
261 size_t Daux = 2 + Terms.tight.size() + 2*Terms.nextn.size();
262
263 std::vector<OperatorType> col;
264 std::vector<OperatorType> row;
265 size_t locdim;
266
267 if (Terms.local.size()>0)
268 {
269 locdim = std::get<1>(Terms.local[0]).data.rows();
270 }
271 else if (Terms.tight.size()>0)
272 {
273 locdim = std::get<1>(Terms.tight[0]).data.rows();
274 }
275 else
276 {
277 locdim = std::get<1>(Terms.nextn[0]).data.rows();
278 }
279
280 OperatorType Id(Matrix<Scalar,Dynamic,Dynamic>::Identity(locdim,locdim).sparseView(),Symmetry::qvacuum());
281 OperatorType Zero(SparseMatrix<Scalar>(locdim,locdim),Symmetry::qvacuum());
282
283 // last row (except corner element)
284 for (size_t i=0; i<Terms.nextn.size(); ++i)
285 {
286 row.push_back(Zero);
287 }
288 for (int i=0; i<Terms.tight.size(); ++i)
289 {
290 row.push_back(std::get<0>(Terms.tight[i]) * std::get<1>(Terms.tight[i]));
291 }
292 for (int i=0; i<Terms.nextn.size(); ++i)
293 {
294 row.push_back(std::get<0>(Terms.nextn[i]) * std::get<1>(Terms.nextn[i]));
295 }
296 row.push_back(Id);
297
298 // first col (except corner element)
299 col.push_back(Id);
300 for (int i=0; i<Terms.nextn.size(); ++i)
301 {
302 col.push_back(std::get<2>(Terms.nextn[i]));
303 }
304 for (int i=0; i<Terms.tight.size(); ++i)
305 {
306 col.push_back(std::get<2>(Terms.tight[i]));
307 }
308 for (size_t i=0; i<Terms.nextn.size(); ++i)
309 {
310 col.push_back(Zero);
311 }
312
313 SuperMatrix<Symmetry,Scalar> Gout;
314 Gout.setMatrix(Daux,locdim);
315 Gout.setZero();
316
317 for (size_t i=0; i<Daux-1; ++i)
318 {
319 Gout(i,0) = col[i];
320 Gout(Daux-1,i+1) = row[i];
321 }
322
323 // corner element : local interaction
324 for (int i=0; i<Terms.local.size(); ++i)
325 {
326 Gout(Daux-1,0) += std::get<0>(Terms.local[i]) * std::get<1>(Terms.local[i]);
327 }
328
329 // nearest-neighbour transfer
330 if (Terms.nextn.size() != 0)
331 {
332 for (size_t i=0; i<Terms.nextn.size(); ++i)
333 {
334 Gout(Daux-1-Terms.nextn.size()+i,1+i) = std::get<3>(Terms.nextn[i]);
335 }
336 }
337
338 return Gout;
339}*/
340
341#endif
SuperMatrix< Symmetry, Scalar > directSum(const SuperMatrix< Symmetry, Scalar > &M1, const SuperMatrix< Symmetry, Scalar > &M2)
Definition: SuperMatrix.h:192
std::ostream & operator<<(std::ostream &os, const SuperMatrix< Symmetry, Scalar > &M)
Definition: SuperMatrix.h:233
SuperMatrix< Symmetry, Scalar > tensor_product(const SuperMatrix< Symmetry, Scalar > &M1, const SuperMatrix< Symmetry, Scalar > &M2)
Definition: SuperMatrix.h:157
size_t N_rows
Definition: SuperMatrix.h:141
boost::multi_array< OperatorType, 2 > data
Definition: SuperMatrix.h:144
void setZero()
Definition: SuperMatrix.h:79
double memory(MEMUNIT memunit=GB) const
Definition: SuperMatrix.h:99
std::vector< typename Symmetry::qType > calc_qOp() const
Definition: SuperMatrix.h:124
size_t D() const
Definition: SuperMatrix.h:112
size_t N_cols
Definition: SuperMatrix.h:142
SuperMatrix< Symmetry, Scalar > row(size_t i)
Definition: SuperMatrix.h:55
size_t auxdim() const
Definition: SuperMatrix.h:92
SiteOperator< Symmetry, Scalar > OperatorType
Definition: SuperMatrix.h:20
OperatorType & operator()(size_t i, size_t j)
Definition: SuperMatrix.h:23
void set(size_t Daux1, size_t Daux2, size_t D)
Definition: SuperMatrix.h:27
void setRowVector(size_t Daux, size_t D)
Definition: SuperMatrix.h:37
size_t rows() const
Definition: SuperMatrix.h:88
void setMatrix(size_t Daux, size_t D)
Definition: SuperMatrix.h:49
void setColVector(size_t Daux, size_t D)
Definition: SuperMatrix.h:43
size_t cols() const
Definition: SuperMatrix.h:89
SparseMatrix< double, ColMajor, EIGEN_DEFAULT_SPARSE_INDEX_TYPE > MatrixType
Definition: SuperMatrix.h:19
void innerResize(size_t D)
Definition: SuperMatrix.h:146
SuperMatrix< Symmetry, Scalar > col(size_t i)
Definition: SuperMatrix.h:67