ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
reshapes.h
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * ALPS MPS DMRG Project
4  *
5  * Copyright (C) 2013 Institute for Theoretical Physics, ETH Zurich
6  * 2011-2011 by Bela Bauer <bauerb@phys.ethz.ch>
7  *
8  * This software is part of the ALPS Applications, published under the ALPS
9  * Application License; you can use, redistribute it and/or modify it under
10  * the terms of the license, either version 1 or (at your option) any later
11  * version.
12  *
13  * You should have received a copy of the ALPS Application License along with
14  * the ALPS Applications; see the file LICENSE.txt. If not, the license is also
15  * available from http://alps.comp-phys.org/.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  *
25  *****************************************************************************/
26 
27 #ifndef RESHAPE_H
28 #define RESHAPE_H
29 
30 #include <map>
32 
33 template<class Matrix, class SymmGroup>
35  Index<SymmGroup> left_i,
36  Index<SymmGroup> right_i,
39 {
40 
42 
43  typedef std::size_t size_t;
44  typedef typename SymmGroup::charge charge;
45 
46  ProductBasis<SymmGroup> in_left(physical_i, left_i);
47  ProductBasis<SymmGroup> out_right(physical_i, right_i,
48  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
49  -boost::lambda::_1, boost::lambda::_2));
50 
51  for (int run = 0; run < 2; ++run) {
52  if (run == 1)
53  m2.allocate_blocks();
54 
55  for (size_t block = 0; block < m1.n_blocks(); ++block)
56  {
57  for (size_t s = 0; s < physical_i.size(); ++s)
58  {
59  size_t r = right_i.position(m1.right_basis()[block].first);
60  if(r == right_i.size()) continue;
61  size_t l = left_i.position(SymmGroup::fuse(m1.left_basis()[block].first,
62  -physical_i[s].first));
63  if(l == left_i.size()) continue;
64 
65  {
66  bool pretend = (run == 0);
67 
68  charge in_l_charge = SymmGroup::fuse(physical_i[s].first, left_i[l].first);
69  charge in_r_charge = right_i[r].first;
70  charge out_l_charge = left_i[l].first;
71  charge out_r_charge = SymmGroup::fuse(-physical_i[s].first, right_i[r].first);
72 
73  if (! m1.has_block(in_l_charge, in_r_charge) )
74  continue;
75 
76  size_t in_left_offset = in_left(physical_i[s].first, left_i[l].first);
77  size_t out_right_offset = out_right(physical_i[s].first, right_i[r].first);
78 
79  if (!pretend){
80  Matrix const & in_block = m1(in_l_charge, in_r_charge);
81  Matrix & out_block = m2(out_l_charge, out_r_charge);
82 
83  maquis::dmrg::detail::reshape_l2r(in_block, out_block, in_left_offset, out_right_offset,
84  physical_i[s].second, left_i[l].second, right_i[r].second);
85  }
86 
87  if (pretend)
88  m2.reserve(out_l_charge, out_r_charge,
89  left_i[l].second, out_right_offset + physical_i[s].second * right_i[r].second);
90  }
91  }
92  }
93  }
94 
95 
96 // assert(m2.left_basis() == left_i);
97 }
98 
99 /*
100  pseudo-code kernel
101 
102  std::map<std::pair<charge, charge>, std::list<size_t> > block_requirements;
103 
104  for (s = 0; s < physical_i.size(); ++s)
105  for (l = 0; ...)
106  for (r = 0; ...) {
107  charge in_l_charge = SymmGroup::fuse(physical_i[s].first, left_i[l].first);
108  charge in_r_charge = right_i[r].first;
109 
110  charge out_l_charge = left_i[l].first;
111  charge out_r_charge = SymmGroup::fuse(-physical_i[s].first, right_i[r].first);
112 
113  block_requirements[make_pair(out_l_charge, out_r_charge)].push_back(m1.position(in_l_charge, in_r_charge);
114  }
115 
116  A: logistics kernel
117 
118  // on the node that creates (l,r) in the final block_matrix,
119  // get block_requirements[(l,r)] from other nodes
120 
121  B: compute kernel
122 
123  */
124 
125 
126 template<class Matrix, class SymmGroup>
128  Index<SymmGroup> left_i,
129  Index<SymmGroup> right_i,
132 {
133 // assert(m1.left_basis() == left_i);
134 
135 
137 
138  typedef std::size_t size_t;
139  typedef typename SymmGroup::charge charge;
140 
141  ProductBasis<SymmGroup> in_right(physical_i, right_i,
142  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
143  -boost::lambda::_1, boost::lambda::_2));
144  ProductBasis<SymmGroup> out_left(physical_i, left_i);
145 
146  for (int run = 0; run < 2; ++run) {
147 
148  if (run == 1)
149  m2.allocate_blocks();
150 
151  for (size_t block = 0; block < m1.n_blocks(); ++block)
152  {
153  for (size_t s = 0; s < physical_i.size(); ++s)
154  {
155  size_t l = left_i.position(m1.left_basis()[block].first);
156  if(l == left_i.size()) continue;
157  size_t r = right_i.position(SymmGroup::fuse(m1.right_basis()[block].first,
158  physical_i[s].first));
159  if(r == right_i.size()) continue;
160 
161  {
162  bool pretend = (run == 0);
163 
164  charge in_l_charge = left_i[l].first;
165  charge in_r_charge = SymmGroup::fuse(-physical_i[s].first, right_i[r].first);
166  charge out_l_charge = SymmGroup::fuse(physical_i[s].first, left_i[l].first);
167  charge out_r_charge = right_i[r].first;
168 
169  if (! m1.has_block(in_l_charge, in_r_charge) )
170  continue;
171 
172  size_t in_right_offset = in_right(physical_i[s].first, right_i[r].first);
173  size_t out_left_offset = out_left(physical_i[s].first, left_i[l].first);
174 
175  if (!pretend) {
176  Matrix const & in_block = m1(in_l_charge, in_r_charge);
177  Matrix & out_block = m2(out_l_charge, out_r_charge);
178  maquis::dmrg::detail::reshape_r2l(out_block, in_block, out_left_offset, in_right_offset,
179  physical_i[s].second, left_i[l].second, right_i[r].second);
180  }
181 
182  if (pretend)
183  m2.reserve(out_l_charge, out_r_charge,
184  out_left_offset + physical_i[s].second * left_i[l].second, right_i[r].second);
185  }
186  }
187  }
188  }
189 
190 
191 // assert(m2.right_basis() == right_i);
192 }
193 
194 // Moving physical index from left to right
195 // [(phys_i, left_i), right_i] --> [left_i, (-phys_i, right_i)]
196 template<class Matrix, class OtherMatrix, class SymmGroup>
198  Index<SymmGroup> left_i,
199  Index<SymmGroup> right_i,
202 {
204 
205  typedef std::size_t size_t;
206  typedef typename SymmGroup::charge charge;
207 
208  ProductBasis<SymmGroup> in_left(physical_i, left_i);
209  ProductBasis<SymmGroup> out_right(physical_i, right_i,
210  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
211  -boost::lambda::_1, boost::lambda::_2));
212 
213  for (size_t block = 0; block < m1.n_blocks(); ++block)
214  {
215  size_t r = right_i.position(m1.right_basis()[block].first);
216  if(r == right_i.size()) continue;
217  charge in_r_charge = right_i[r].first;
218  charge in_l_charge = m1.left_basis()[block].first;
219 
220  for (size_t s = 0; s < physical_i.size(); ++s)
221  {
222  size_t l = left_i.position(SymmGroup::fuse(m1.left_basis()[block].first, -physical_i[s].first));
223  if(l == left_i.size()) continue;
224 
225  charge out_l_charge = left_i[l].first;
226  charge out_r_charge = SymmGroup::fuse(-physical_i[s].first, in_r_charge);
227 
228  if(!m2.has_block(out_l_charge, out_r_charge))
229  m2.insert_block(Matrix(left_i[l].second, out_right.size(out_r_charge), 0),
230  out_l_charge, out_r_charge);
231 
232  size_t in_left_offset = in_left(physical_i[s].first, left_i[l].first);
233  size_t out_right_offset = out_right(physical_i[s].first, in_r_charge);
234 
235  OtherMatrix const & in_block = m1[block];
236  Matrix & out_block = m2(out_l_charge, out_r_charge);
237 
238  maquis::dmrg::detail::reshape_l2r(in_block, out_block, in_left_offset, out_right_offset,
239  physical_i[s].second, left_i[l].second, right_i[r].second);
240  }
241  }
242 }
243 
244 template<class Matrix, class SymmGroup>
246  Index<SymmGroup> in_left_i,
247  Index<SymmGroup> in_right_i,
248  Index<SymmGroup> out_left_i,
249  Index<SymmGroup> out_right_i,
252 {
253  m2 *= 0;
254 
255  typedef std::size_t size_t;
256  typedef typename SymmGroup::charge charge;
257 
258  ProductBasis<SymmGroup> in_left(physical_i, in_left_i);
259  ProductBasis<SymmGroup> out_left(physical_i, out_left_i);
260 
261  for (size_t block = 0; block < m1.n_blocks(); ++block)
262  {
263  for (size_t s = 0; s < physical_i.size(); ++s)
264  {
265  size_t r = in_right_i.position(m1.right_basis()[block].first);
266  if(r == in_right_i.size()) continue;
267 
268  size_t l = in_left_i.position(SymmGroup::fuse(m1.left_basis()[block].first,
269  -physical_i[s].first));
270  if(l == in_left_i.size()) continue;
271 
272  {
273  charge l_charge = SymmGroup::fuse(physical_i[s].first, in_left_i[l].first);
274  charge r_charge = in_right_i[r].first;
275 
276  if (! out_left_i.has(in_left_i[l].first)) continue;
277  if (! m1.has_block(l_charge, r_charge) ) continue;
278  if (! m2.has_block(l_charge, r_charge) ) continue;
279 
280  size_t in_left_offset = in_left(physical_i[s].first, in_left_i[l].first);
281  size_t out_left_offset = out_left(physical_i[s].first, in_left_i[l].first);
282 
283  Matrix const & in_block = m1(l_charge, r_charge);
284  Matrix & out_block = m2(l_charge, r_charge);
285 
286  for (size_t ss = 0; ss < physical_i[s].second; ++ss)
287  for (size_t rr = 0; rr < in_right_i[r].second; ++rr)
288  for (size_t ll = 0; ll < in_left_i[l].second; ++ll)
289  out_block(out_left_offset + ss*in_left_i[l].second+ll, rr)
290  = in_block(in_left_offset + ss*in_left_i[l].second+ll, rr);
291  }
292  }
293  }
294 
295 
296  // assert(m2.left_basis() == left_i);
297 }
298 
299 // MD: here we reshape without the `pretend` loop. This way i) we are faster, ii) we avoid the bug that the size is not correct.
300 // example for ii): the output is going to be multiplied with a left_i containing more elements, than the size of some blocks
301 // might be wrong. Such a situation originates in overlap() if right_i and left_i are very different: the block_matrix will contain
302 // only diagonal blocks.
303 // Moving physical index from right to left
304 // [left_i, (-phys_i, right_i)] --> [(phys_i, left_i), right_i]
305 template<class Matrix, class OtherMatrix, class SymmGroup>
307  Index<SymmGroup> left_i,
308  Index<SymmGroup> right_i,
311 {
312  // assert(m1.left_basis() == left_i);
313 
314 
316 
317  typedef std::size_t size_t;
318  typedef typename SymmGroup::charge charge;
319 
320  ProductBasis<SymmGroup> in_right(physical_i, right_i,
321  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
322  -boost::lambda::_1, boost::lambda::_2));
323  ProductBasis<SymmGroup> out_left(physical_i, left_i);
324 
325  for (size_t block = 0; block < m1.n_blocks(); ++block)
326  {
327  size_t l = left_i.position(m1.left_basis()[block].first);
328  if(l == left_i.size()) continue;
329  charge in_l_charge = left_i[l].first;
330  charge in_r_charge = m1.right_basis()[block].first;
331 
332  for (size_t s = 0; s < physical_i.size(); ++s)
333  {
334  size_t r = right_i.position(SymmGroup::fuse(m1.right_basis()[block].first,
335  physical_i[s].first));
336  if(r == right_i.size()) continue;
337 
338  charge out_l_charge = SymmGroup::fuse(physical_i[s].first, in_l_charge);
339  charge out_r_charge = right_i[r].first;
340  if (! m2.has_block(out_l_charge, out_r_charge))
341  m2.insert_block(Matrix(out_left.size(physical_i[s].first, in_l_charge), right_i[r].second, 0),
342  out_l_charge, out_r_charge);
343 
344  size_t in_right_offset = in_right(physical_i[s].first, out_r_charge);
345  size_t out_left_offset = out_left(physical_i[s].first, in_l_charge);
346 
347  OtherMatrix const & in_block = m1[block];
348  Matrix & out_block = m2(out_l_charge, out_r_charge);
349 
350  maquis::dmrg::detail::reshape_r2l(out_block, in_block, out_left_offset, in_right_offset,
351  physical_i[s].second, left_i[l].second, right_i[r].second);
352  }
353  }
354 }
355 
356 // Moving two auxiliary indexes to the right
357 // [(phys_i, left_i), right_i] --> [phys_i, (-left_i, right_i)]
358 template<class Matrix, class SymmGroup>
361  Index<SymmGroup> left_i,
362  Index<SymmGroup> right_i,
364 {
366 
367  typedef std::size_t size_t;
368  typedef typename SymmGroup::charge charge;
369 
370  ProductBasis<SymmGroup> in_left(physical_i, left_i);
371  ProductBasis<SymmGroup> out_right(left_i, right_i,
372  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
373  -boost::lambda::_1, boost::lambda::_2));
374 
375  for (size_t block = 0; block < m1.n_blocks(); ++block)
376  {
377  for (size_t s = 0; s < physical_i.size(); ++s)
378  {
379  size_t r = right_i.position(m1.right_basis()[block].first);
380  if(r == right_i.size()) continue;
381  size_t l = left_i.position(SymmGroup::fuse(m1.left_basis()[block].first,
382  -physical_i[s].first));
383  if(l == left_i.size()) continue;
384 
385  {
386  charge in_l_charge = SymmGroup::fuse(physical_i[s].first, left_i[l].first);
387  charge in_r_charge = right_i[r].first;
388  charge out_l_charge = physical_i[s].first;
389  charge out_r_charge = SymmGroup::fuse(-left_i[l].first, right_i[r].first);
390 
391  if (! m1.has_block(in_l_charge, in_r_charge) )
392  continue;
393 
394  if (! m2.has_block(out_l_charge, out_r_charge) )
395  m2.insert_block(Matrix(physical_i[s].second, out_right.size(out_r_charge), 0),
396  out_l_charge, out_r_charge);
397 
398  size_t in_left_offset = in_left(physical_i[s].first, left_i[l].first);
399  size_t out_right_offset = out_right(left_i[l].first, right_i[r].first);
400 
401  Matrix const & in_block = m1(in_l_charge, in_r_charge);
402  Matrix & out_block = m2(out_l_charge, out_r_charge);
403 
404  for (size_t ss = 0; ss < physical_i[s].second; ++ss)
405  for (size_t rr = 0; rr < right_i[r].second; ++rr)
406  for (size_t ll = 0; ll < left_i[l].second; ++ll)
407  out_block(ss, out_right_offset + ll*right_i[r].second+rr) = in_block(in_left_offset + ss*left_i[l].second+ll, rr);
408  }
409  }
410  }
411 
412  return m2;
413 }
414 
415 
416 template<class Matrix, class SymmGroup>
419 { // only for the dense matrices in MPO (30.04.2012 / scalar / value types discussion)
420  // TODO: (scatter alps::numeric::matrix during building of MPO)
421  typedef typename SymmGroup::charge charge;
423 
424  ProductBasis<SymmGroup> pb(phys1, phys2);
425  ProductBasis<SymmGroup> pb_out_left(phys1, adjoin(phys1));
426  ProductBasis<SymmGroup> pb_out_right(phys2, adjoin(phys2));
427 
428  /// s1 \in phys1, input of op on site1
429  /// s2 \in phys2, input of op on site2
430  /// s3 \in phys1, output of op on site1
431  /// s4 \in phys2, output of op on site2
432 
433  typedef typename Index<SymmGroup>::basis_iterator bi_t;
434  for (bi_t s1 = phys1.basis_begin(); !s1.end(); ++s1)
435  for (bi_t s2 = phys2.basis_begin(); !s2.end(); ++s2)
436  for (bi_t s3 = phys1.basis_begin(); !s3.end(); ++s3)
437  for (bi_t s4 = phys2.basis_begin(); !s4.end(); ++s4)
438  {
439  charge in_left_c = SymmGroup::fuse(s1->first, s2->first);
440  charge in_right_c = SymmGroup::fuse(s3->first, s4->first);
441 
442  if (!A.has_block(in_left_c, in_right_c))
443  continue;
444 
445  charge out_left_c = SymmGroup::fuse(s1->first, -s3->first);
446  charge out_right_c = SymmGroup::fuse(s4->first, -s2->first);
447 
448  if (!ret.has_block(out_left_c, out_right_c))
449  ret.insert_block(new Matrix(pb_out_left.size(s1->first, -s3->first),
450  pb_out_right.size(s4->first, -s2->first),
451  0),
452  out_left_c, out_right_c);
453 
454  std::size_t in_left_offset = pb(s1->first, s2->first);
455  std::size_t in_right_offset = pb(s3->first, s4->first);
456 
457  std::size_t out_left_offset = pb_out_left(s1->first, -s3->first);
458  std::size_t out_right_offset = pb_out_right(s4->first, -s2->first);
459 
460  ret(std::make_pair(out_left_c, out_left_offset + s1->second*phys1.size_of_block(s3->first)+s3->second),
461  std::make_pair(out_right_c, out_right_offset + s2->second*phys2.size_of_block(s4->first)+s4->second))
462  = A(std::make_pair(in_left_c, in_left_offset + s1->second*phys2.size_of_block(s2->first) + s2->second),
463  std::make_pair(in_right_c, in_right_offset + s3->second*phys2.size_of_block(s4->first) + s4->second));
464 
465  }
466 
467  // Removing empty blocks
468  Index<SymmGroup> out_left = phys1*adjoin(phys1);
469  Index<SymmGroup> out_right = phys2*adjoin(phys2);
470  for (typename Index<SymmGroup>::const_iterator it1 = out_left.begin(); it1 != out_left.end(); it1++)
471  {
472  for (typename Index<SymmGroup>::const_iterator it2 = out_right.begin(); it2 != out_right.end(); it2++)
473  {
474  bool empty = true;
475 
476  if (!ret.has_block(it1->first, it2->first)) continue;
477 
478  Matrix tmp = ret(it1->first, it2->first);
479  for (int i=0; i<num_rows(tmp); ++i)
480  {
481  for (int j=0; j<num_cols(tmp); ++j)
482  if (tmp(i,j) != typename Matrix::value_type()) {
483  empty=false;
484  break;
485  }
486  if (!empty) break;
487  }
488 
489  if (empty)
490  ret.remove_block(it1->first, it2->first);
491  }
492  }
493 
494  return ret;
495 }
496 
497 template<class Matrix, class SymmGroup>
498 std::vector<block_matrix<Matrix, SymmGroup> > reshape_right_to_list (Index<SymmGroup> const & phys,
500 {
501  typedef typename SymmGroup::charge charge;
502  std::vector<block_matrix<Matrix, SymmGroup> > ret;
503 
504  Index<SymmGroup> aux_i = A.right_basis();
505  ProductBasis<SymmGroup> pb(phys, adjoin(phys));
506 
507  typedef typename Index<SymmGroup>::basis_iterator bi_t;
508  for (bi_t b = aux_i.basis_begin(); !b.end(); ++b)
509  {
511  for (bi_t s1 = phys.basis_begin(); !s1.end(); ++s1)
512  for (bi_t s2 = phys.basis_begin(); !s2.end(); ++s2)
513  {
514  charge in_left_c = SymmGroup::fuse(s1->first, -s2->first);
515  charge in_right_c = b->first;
516 
517  if (!A.has_block(in_left_c, in_right_c))
518  continue;
519 
520  charge out_left_c = s1->first;
521  charge out_right_c = s2->first;
522 
523  if (!Ai.has_block(out_left_c, out_right_c))
524  Ai.insert_block(new Matrix(phys.size_of_block(s1->first),
525  phys.size_of_block(s2->first),
526  0),
527  out_left_c, out_right_c);
528 
529  std::size_t in_left_offset = pb(s1->first, -s2->first);
530  std::size_t in_right_offset = 0;
531 
532  std::size_t out_left_offset = 0;
533  std::size_t out_right_offset = 0;
534 
535  Ai(*s1, *s2)
536  = A(std::make_pair(in_left_c, in_left_offset + s1->second*phys.size_of_block(s2->first) + s2->second),
537  *b);
538 
539  }
540 
541  // Removing empty blocks
542  for (int n=0; n<Ai.n_blocks(); ++n)
543  {
544  bool empty = true;
545  for (int i=0; i<num_rows(Ai[n]) && empty; ++i)
546  for (int j=0; j<num_cols(Ai[n]) && empty; ++j)
547  if (Ai[n](i,j) != typename Matrix::value_type())
548  empty=false;
549 
550  if (empty)
551  Ai.remove_block(n);
552  }
553 
554  ret.push_back(Ai);
555  }
556  assert( ret.size() == aux_i.sum_of_sizes() );
557 
558  return ret;
559 }
560 
561 template<class Matrix, class SymmGroup>
562 std::vector<block_matrix<Matrix, SymmGroup> > reshape_left_to_list (Index<SymmGroup> const & phys,
564 {
565  typedef typename SymmGroup::charge charge;
566  std::vector<block_matrix<Matrix, SymmGroup> > ret;
567 
568  Index<SymmGroup> aux_i = A.left_basis();
569  ProductBasis<SymmGroup> pb(phys, adjoin(phys));
570 
571  typedef typename Index<SymmGroup>::basis_iterator bi_t;
572  for (bi_t b = aux_i.basis_begin(); !b.end(); ++b)
573  {
575  for (bi_t s1 = phys.basis_begin(); !s1.end(); ++s1)
576  for (bi_t s2 = phys.basis_begin(); !s2.end(); ++s2)
577  {
578  charge in_right_c = SymmGroup::fuse(s2->first, -s1->first);
579  charge in_left_c = b->first;
580 
581  if (!A.has_block(in_left_c, in_right_c))
582  continue;
583 
584  charge out_left_c = s1->first;
585  charge out_right_c = s2->first;
586 
587  if (!Ai.has_block(out_left_c, out_right_c))
588  Ai.insert_block(new Matrix(phys.size_of_block(s1->first),
589  phys.size_of_block(s2->first),
590  0),
591  out_left_c, out_right_c);
592 
593  std::size_t in_left_offset = 0;
594  std::size_t in_right_offset = pb(s2->first, -s1->first);
595 
596  std::size_t out_left_offset = 0;
597  std::size_t out_right_offset = 0;
598 
599  Ai(std::make_pair(out_left_c, out_left_offset + s1->second),
600  std::make_pair(out_right_c, out_right_offset + s2->second))
601  = A(std::make_pair(in_left_c, in_left_offset + b->second),
602  std::make_pair(in_right_c, in_right_offset + s1->second*phys.size_of_block(s2->first) + s2->second));
603 
604  }
605 
606  // Removing empty blocks
607  for (int n=0; n<Ai.n_blocks(); ++n)
608  {
609  bool empty = true;
610  for (int i=0; i<num_rows(Ai[n]) && empty; ++i)
611  for (int j=0; j<num_cols(Ai[n]) && empty; ++j)
612  if (Ai[n](i,j) != typename Matrix::value_type())
613  empty=false;
614 
615  if (empty)
616  Ai.remove_block(n);
617  }
618 
619  ret.push_back(Ai);
620  }
621  assert( ret.size() == aux_i.sum_of_sizes() );
622 
623  return ret;
624 }
625 
626 
627 #endif /* RESHAPE_H */
628 
void run(std::string const &chkp1, std::string const &chkp2)
Definition: main.cpp:52
void reshape_l2r(const alps::numeric::matrix< T, A1 > &left, alps::numeric::matrix< T, A2 > &right, size_t left_offset, size_t right_offset, size_t sdim, size_t ldim, size_t rdim)
bool end() const
base_t::const_iterator const_iterator
block_matrix< Matrix, SymmGroup > reshape_left_to_physleft(Index< SymmGroup > physical_i, Index< SymmGroup > left_i, Index< SymmGroup > right_i, block_matrix< Matrix, SymmGroup > const &m1)
Definition: reshapes.h:360
iterator begin()
size_type n_blocks() const
void reshape_right_to_left_new(Index< SymmGroup > physical_i, Index< SymmGroup > left_i, Index< SymmGroup > right_i, block_matrix< OtherMatrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
Definition: reshapes.h:306
bool has(charge c) const
basis_iterator basis_begin() const
size_t size(charge pc) const
size_type insert_block(Matrix const &, charge, charge)
std::size_t size_of_block(charge c) const
std::vector< block_matrix< Matrix, SymmGroup > > reshape_right_to_list(Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > const &A)
Definition: reshapes.h:498
block_matrix< Matrix, SymmGroup > reshape_2site_op(Index< SymmGroup > const &phys1, Index< SymmGroup > const &phys2, block_matrix< Matrix, SymmGroup > const &A)
Definition: reshapes.h:417
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
include one of the Index class definitions
block_matrix< Matrix, SymmGroup > adjoin(block_matrix< Matrix, SymmGroup > const &m)
std::vector< block_matrix< Matrix, SymmGroup > > reshape_left_to_list(Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > const &A)
Definition: reshapes.h:562
void reshape_right_to_left(Index< SymmGroup > physical_i, Index< SymmGroup > left_i, Index< SymmGroup > right_i, block_matrix< Matrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
Definition: reshapes.h:127
bool has_block(charge r, charge c) const
std::size_t num_cols(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:102
Index< SymmGroup > const & right_basis() const
iterator end()
void remove_block(charge r, charge c)
std::size_t position(charge c) const
void reserve(charge, charge, std::size_t, std::size_t)
void reshape_r2l(alps::numeric::matrix< T, A1 > &left, const alps::numeric::matrix< T, A2 > &right, size_t left_offset, size_t right_offset, size_t sdim, size_t ldim, size_t rdim)
void reshape_left_to_right_new(Index< SymmGroup > physical_i, Index< SymmGroup > left_i, Index< SymmGroup > right_i, block_matrix< OtherMatrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
Definition: reshapes.h:197
void allocate_blocks()
Index< SymmGroup > const & left_basis() const
void reshape_left_to_right(Index< SymmGroup > physical_i, Index< SymmGroup > left_i, Index< SymmGroup > right_i, block_matrix< Matrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
Definition: reshapes.h:34
std::size_t size() const
void reshape_and_pad_left(Index< SymmGroup > physical_i, Index< SymmGroup > in_left_i, Index< SymmGroup > in_right_i, Index< SymmGroup > out_left_i, Index< SymmGroup > out_right_i, block_matrix< Matrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
Definition: reshapes.h:245
std::size_t sum_of_sizes() const
T fuse(const A &ind, T d)
Fuse indices n[i] into one p = n[i] d^i.