ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
contractions.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 CONTRACTIONS_H
28 #define CONTRACTIONS_H
29 
32 
35 
36 struct contraction {
37 
38  // output/input: left_i for bra_tensor, right_i for ket_tensor
39  template<class Matrix, class OtherMatrix, class SymmGroup>
42  MPSTensor<Matrix, SymmGroup> const & ket_tensor,
44  block_matrix<OtherMatrix, SymmGroup> * localop = NULL)
45  {
46  if (localop != NULL)
47  throw std::runtime_error("Not implemented!");
48 
49  assert(ket_tensor.phys_i == bra_tensor.phys_i);
50 
51  bra_tensor.make_left_paired();
52 
55  ket_tensor.make_right_paired();
56  gemm(left, ket_tensor.data(), t1);
57 
58  reshape_right_to_left_new(ket_tensor.site_dim(), bra_tensor.row_dim(), ket_tensor.col_dim(),
59  t1, t3);
60  gemm(transpose(conjugate(bra_tensor.data())), t3, t1);
61  return t1;
62 
63  // original:
64  // t3 = transpose(t3);
65  // gemm(t3, t2, t1);
66  // return transpose(t1);
67  }
68 
69  template<class Matrix, class OtherMatrix, class SymmGroup>
72  MPSTensor<Matrix, SymmGroup> const & ket_tensor,
74  block_matrix<OtherMatrix, SymmGroup> * localop = NULL)
75  {
76  if (localop != NULL)
77  throw std::runtime_error("Not implemented!");
78 
79  assert(ket_tensor.phys_i == bra_tensor.phys_i);
80 
81  bra_tensor.make_right_paired();
82  ket_tensor.make_left_paired();
83 
86  gemm(ket_tensor.data(), transpose(right), t1);
87  reshape_left_to_right_new(ket_tensor.site_dim(), ket_tensor.row_dim(), bra_tensor.col_dim(), t1, t3);
88  gemm(conjugate(bra_tensor.data()), transpose(t3), t1);
89 
90  return t1;
91  }
92 
93  // SK: New version which generates same output but uses right-paired input.
94  // The charge delta optimization is indepent from the changes needed to
95  // skip the preceding reshapes.
96  template<class Matrix, class OtherMatrix, class SymmGroup>
98  lbtm_kernel(size_t b2,
100  std::vector<block_matrix<Matrix, SymmGroup> > const & left_mult_mps,
101  MPOTensor<Matrix, SymmGroup> const & mpo,
102  Index<SymmGroup> const & physical_i,
103  Index<SymmGroup> const & right_i,
104  Index<SymmGroup> const & out_left_i,
105  ProductBasis<SymmGroup> const & in_right_pb,
106  ProductBasis<SymmGroup> const & out_left_pb)
107  {
108  typedef typename MPOTensor<OtherMatrix, SymmGroup>::index_type index_type;
109  typedef typename MPOTensor<OtherMatrix, SymmGroup>::row_proxy row_proxy;
110  typedef typename MPOTensor<OtherMatrix, SymmGroup>::col_proxy col_proxy;
111 
112  typedef typename SymmGroup::charge charge;
113  typedef std::size_t size_t;
114 
116  col_proxy col_b2 = mpo.column(b2);
117  for (typename col_proxy::const_iterator col_it = col_b2.begin(); col_it != col_b2.end(); ++col_it) {
118  index_type b1 = col_it.index();
119 
120  block_matrix<Matrix, SymmGroup> const & T = left_mult_mps[b1];
121  if (T.n_blocks() == 0) continue;
123  block_matrix<Matrix, SymmGroup> const & W = access.op;
124  if (W.n_blocks() == 0) continue;
125 
126  // charge deltas are constant for all blocks
127  charge operator_delta = SymmGroup::fuse(W.right_basis()[0].first, -W.left_basis()[0].first);
128  charge T_delta = SymmGroup::fuse(T.right_basis()[0].first, -T.left_basis()[0].first);
129  charge total_delta = SymmGroup::fuse(operator_delta, -T_delta);
130 
131  for (size_t r = 0; r < right_i.size(); ++r)
132  {
133  charge out_r_charge = right_i[r].first;
134  charge out_l_charge = SymmGroup::fuse(out_r_charge, total_delta);
135  size_t r_size = right_i[r].second;
136 
137  if (!out_left_i.has(out_l_charge)) continue;
138 
139  size_t o = ret.find_block(out_l_charge, out_r_charge);
140  if ( o == ret.n_blocks() ) {
141  o = ret.insert_block(Matrix(1,1), out_l_charge, out_r_charge);
142  ret.resize_block(out_l_charge, out_r_charge, out_left_i.size_of_block(out_l_charge), r_size);
143  }
144 
145  for (size_t w_block = 0; w_block < W.n_blocks(); ++w_block)
146  {
147  charge phys_c1 = W.left_basis()[w_block].first;
148  charge phys_c2 = W.right_basis()[w_block].first;
149 
150  charge in_r_charge = SymmGroup::fuse(out_r_charge, -phys_c1);
151  size_t t_block = T.right_basis().position(in_r_charge);
152  if (t_block == T.right_basis().size()) continue;
153 
154  charge in_l_charge = T.left_basis()[t_block].first;
155 
156  size_t in_right_offset = in_right_pb(phys_c1, out_r_charge);
157  size_t out_left_offset = out_left_pb(phys_c2, in_l_charge);
158 
159  size_t phys_s1 = W.left_basis()[w_block].second;
160  size_t phys_s2 = W.right_basis()[w_block].second;
161  Matrix const & wblock = W[w_block];
162  Matrix const & iblock = T[t_block];
163  Matrix & oblock = ret[o];
164 
165  maquis::dmrg::detail::lb_tensor_mpo(oblock, iblock, wblock,
166  out_left_offset, in_right_offset,
167  phys_s1, phys_s2, T.left_basis()[t_block].second, r_size, access.scale);
168  }
169  } // right index block
170  } // b1
171  return ret;
172  }
173 
174  template<class Matrix, class OtherMatrix, class SymmGroup>
176  rbtm_kernel(size_t b1,
177  Boundary<OtherMatrix, SymmGroup> const & right,
178  std::vector<block_matrix<Matrix, SymmGroup> > const & right_mult_mps,
179  MPOTensor<Matrix, SymmGroup> const & mpo,
180  Index<SymmGroup> const & physical_i,
181  Index<SymmGroup> const & left_i,
182  Index<SymmGroup> const & right_i,
183  Index<SymmGroup> const & out_right_i,
184  ProductBasis<SymmGroup> const & in_left_pb,
185  ProductBasis<SymmGroup> const & out_right_pb)
186  {
187  typedef typename MPOTensor<OtherMatrix, SymmGroup>::index_type index_type;
188  typedef typename MPOTensor<OtherMatrix, SymmGroup>::row_proxy row_proxy;
189  typedef typename MPOTensor<OtherMatrix, SymmGroup>::col_proxy col_proxy;
190 
191  typedef typename SymmGroup::charge charge;
192  typedef std::size_t size_t;
193 
195 
196  row_proxy row_b1 = mpo.row(b1);
197  for (typename row_proxy::const_iterator row_it = row_b1.begin(); row_it != row_b1.end(); ++row_it) {
198  index_type b2 = row_it.index();
199 
200  block_matrix<Matrix, SymmGroup> const & T = right_mult_mps[b2];
201  if (T.n_blocks() == 0) continue;
203  block_matrix<Matrix, SymmGroup> const & W = access.op;
204  if (W.n_blocks() == 0) continue;
205 
206  // charge deltas are constant for all blocks
207  charge operator_delta = SymmGroup::fuse(W.right_basis()[0].first, -W.left_basis()[0].first);
208  charge T_delta = SymmGroup::fuse(T.right_basis()[0].first, -T.left_basis()[0].first);
209  charge total_delta = SymmGroup::fuse(operator_delta, -T_delta);
210 
211  for (size_t l = 0; l < left_i.size(); ++l)
212  {
213  charge out_l_charge = left_i[l].first;
214  size_t l_size = left_i[l].second;
215  charge out_r_charge = SymmGroup::fuse(out_l_charge, -total_delta);
216 
217  if (!out_right_i.has(out_r_charge)) continue;
218 
219  size_t o = ret.find_block(out_l_charge, out_r_charge);
220  if ( o == ret.n_blocks() ) {
221  o = ret.insert_block(Matrix(1,1), out_l_charge, out_r_charge);
222  ret.resize_block(out_l_charge, out_r_charge, l_size, out_right_i.size_of_block(out_r_charge));
223  }
224 
225  for (size_t w_block = 0; w_block < W.n_blocks(); ++w_block)
226  {
227  charge phys_c1 = W.left_basis()[w_block].first;
228  charge phys_c2 = W.right_basis()[w_block].first;
229 
230  charge in_l_charge = SymmGroup::fuse(out_l_charge, phys_c1);
231  size_t t_block = T.left_basis().position(in_l_charge);
232  if (t_block == T.left_basis().size()) continue;
233 
234  charge in_r_charge = T.right_basis()[t_block].first;
235  assert(right_i.has(in_r_charge));
236 
237  size_t in_left_offset = in_left_pb(phys_c1, out_l_charge);
238  size_t out_right_offset = out_right_pb(phys_c2, in_r_charge);
239  size_t phys_s1 = W.left_basis()[w_block].second;
240  size_t phys_s2 = W.right_basis()[w_block].second;
241  const Matrix & wblock = W[w_block];
242  const Matrix & iblock = T[t_block];
243  Matrix & oblock = ret[o];
244 
245  maquis::dmrg::detail::rb_tensor_mpo(oblock, iblock, wblock,
246  out_right_offset, in_left_offset,
247  phys_s1, phys_s2,
248  l_size, T.right_basis()[t_block].second, access.scale);
249 
250  }
251  }
252  }
253  return ret;
254  }
255 
256  // note: this function changes the internal structure of Boundary,
257  // each block is transposed
258  template<class Matrix, class OtherMatrix, class SymmGroup>
262  MPOTensor<Matrix, SymmGroup> const & mpo,
263  Index<SymmGroup> const * in_low = NULL)
264  {
265  typedef typename SymmGroup::charge charge;
266  typedef std::size_t size_t;
267 
268  if (in_low == NULL)
269  in_low = &mps.row_dim();
270 
271  mps.make_right_paired();
272  std::vector<block_matrix<Matrix, SymmGroup> > t(left.aux_dim());
273  size_t loop_max = left.aux_dim();
274 
275  parallel_for(/*removed...*/, std::size_t b = 0; b < loop_max; ++b){
276  gemm_trim_left(transpose(left[b]), mps.data(), t[b]);
277  }
278 
279  Index<SymmGroup> physical_i = mps.site_dim(), left_i = *in_low, right_i = mps.col_dim(),
280  out_left_i = physical_i * left_i;
281  ProductBasis<SymmGroup> out_left_pb(physical_i, left_i);
282  ProductBasis<SymmGroup> in_right_pb(physical_i, right_i,
283  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
284  -boost::lambda::_1, boost::lambda::_2));
285 
287  ret.resize(mpo.col_dim());
288 
289  loop_max = mpo.col_dim();
290 
291  parallel_for(l/*removed...*/, std::size_t b2 = 0; b2 < loop_max; ++b2) {
292  ret[b2] = lbtm_kernel(b2, left, t, mpo, physical_i, right_i, out_left_i, in_right_pb, out_left_pb);
293  }
294 
295  return ret;
296  }
297 
298  template<class Matrix, class OtherMatrix, class SymmGroup>
301  Boundary<OtherMatrix, SymmGroup> const & right,
302  MPOTensor<Matrix, SymmGroup> const & mpo,
303  Index<SymmGroup> const * in_low = NULL)
304  {
305  typedef typename SymmGroup::charge charge;
306  typedef std::size_t size_t;
307 
308  if (in_low == NULL)
309  in_low = &mps.col_dim();
310 
311  mps.make_left_paired();
312  std::vector<block_matrix<Matrix, SymmGroup> > t(right.aux_dim());
313  size_t loop_max = right.aux_dim();
314 
315  parallel_for(/*removed...*/, std::size_t b = 0; b < loop_max; ++b){
316  gemm_trim_right(mps.data(), right[b], t[b]);
317  }
318 
319  Index<SymmGroup> physical_i = mps.site_dim(), left_i = mps.row_dim(), right_i = *in_low,
320  out_right_i = adjoin(physical_i) * right_i;
321 
322  ProductBasis<SymmGroup> in_left_pb(physical_i, left_i);
323  ProductBasis<SymmGroup> out_right_pb(physical_i, right_i,
324  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
325  -boost::lambda::_1, boost::lambda::_2));
327  ret.resize(mpo.row_dim());
328 
329  loop_max = mpo.row_dim();
330 
331  parallel_for(l/*removed...*/, std::size_t b1 = 0; b1 < loop_max; ++b1) {
332  ret[b1] = rbtm_kernel(b1, right, t, mpo, physical_i, left_i, right_i, out_right_i, in_left_pb, out_right_pb);
333  }
334 
335  return ret;
336  }
337 
338  template<class Matrix, class OtherMatrix, class SymmGroup>
341  MPSTensor<Matrix, SymmGroup> const & ket_tensor,
343  MPOTensor<Matrix, SymmGroup> const & mpo)
344  {
345  typedef typename SymmGroup::charge charge;
346 
347  std::vector<block_matrix<Matrix, SymmGroup> > t(left.aux_dim());
348  {
349  // Make a copy of ket_tensor to avoid reshaping back to left
350  MPSTensor<Matrix, SymmGroup> ket_cpy = ket_tensor;
351  ket_cpy.make_right_paired();
352  std::size_t loop_max = left.aux_dim();
353 
354  parallel_for(/*locale::scatter(mpo.placement_l)*/, std::size_t b = 0; b < loop_max; ++b) {
355  gemm_trim_left(transpose(left[b]), ket_cpy.data(), t[b]);
356  }
357  }
358 
359  Index<SymmGroup> const & left_i = bra_tensor.row_dim();
360  Index<SymmGroup> const & right_i = ket_tensor.col_dim();
361  Index<SymmGroup> out_left_i = ket_tensor.site_dim() * left_i;
362  ProductBasis<SymmGroup> out_left_pb(ket_tensor.site_dim(), left_i);
363  ProductBasis<SymmGroup> in_right_pb(ket_tensor.site_dim(), right_i,
364  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
365  -boost::lambda::_1, boost::lambda::_2));
366 
368  ret.resize(mpo.col_dim());
369 
370  //ket_tensor.make_left_paired();
371  std::size_t loop_max = mpo.col_dim();
372 
373  bra_tensor.make_left_paired();
374  block_matrix<Matrix, SymmGroup> bra_conj = conjugate(bra_tensor.data());
375  parallel_for(/*locale::scatter(mpo.placement_r)*/, std::size_t b2 = 0; b2 < loop_max; ++b2) {
377  tmp = lbtm_kernel(b2, left, t, mpo, ket_tensor.site_dim(), right_i, out_left_i, in_right_pb, out_left_pb);
378  gemm(transpose(tmp), bra_conj, ret[b2]);
379  }
380 
381  return ret;
382  }
383 
384  template<class Matrix, class OtherMatrix, class SymmGroup>
387  MPSTensor<Matrix, SymmGroup> const & ket_tensor,
388  Boundary<OtherMatrix, SymmGroup> const & right,
389  MPOTensor<Matrix, SymmGroup> const & mpo)
390  {
391  typedef typename SymmGroup::charge charge;
392 
393  std::vector<block_matrix<Matrix, SymmGroup> > t(right.aux_dim());
394  {
395  // Make a copy of ket_tensor to avoid reshaping back to right
396  MPSTensor<Matrix, SymmGroup> ket_cpy = ket_tensor;
397  ket_cpy.make_left_paired();
398  std::size_t loop_max = right.aux_dim();
399 
400  parallel_for(/*locale::scatter(mpo.placement_r)*/, std::size_t b = 0; b < loop_max; ++b){
401  gemm_trim_right(ket_cpy.data(), right[b], t[b]);
402  }
403  }
404 
405  Index<SymmGroup> const & left_i = ket_tensor.row_dim();
406  Index<SymmGroup> const & right_i = bra_tensor.col_dim();
407  Index<SymmGroup> out_right_i = adjoin(ket_tensor.site_dim()) * right_i;
408  ProductBasis<SymmGroup> in_left_pb(ket_tensor.site_dim(), left_i);
409  ProductBasis<SymmGroup> out_right_pb(ket_tensor.site_dim(), right_i,
410  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
411  -boost::lambda::_1, boost::lambda::_2));
413  ret.resize(mpo.row_dim());
414 
415  //ket_tensor.make_right_paired();
416  std::size_t loop_max = mpo.row_dim();
417 
418  bra_tensor.make_right_paired();
419  block_matrix<Matrix, SymmGroup> bra_conj = conjugate(bra_tensor.data());
420  parallel_for(/*locale::scatter(mpo.placement_l)*/, std::size_t b1 = 0; b1 < loop_max; ++b1) {
422  tmp = rbtm_kernel(b1, right, t, mpo, ket_tensor.site_dim(), left_i, right_i, out_right_i, in_left_pb, out_right_pb);
423  gemm(tmp, transpose(bra_conj), ret[b1]);
424  }
425 
426  return ret;
427  }
428 
429  template<class Matrix, class OtherMatrix, class SymmGroup>
433  Boundary<OtherMatrix, SymmGroup> const & right,
434  MPOTensor<Matrix, SymmGroup> const & mpo)
435  {
436  typedef typename SymmGroup::charge charge;
437 
439 
440  ket_tensor.make_right_paired();
441 
442  std::vector<block_matrix<Matrix, SymmGroup> > t(left.aux_dim());
443  std::size_t loop_max = left.aux_dim();
444 
445  parallel_for(/*locale::scatter(mpo.placement_l)*/, std::size_t b = 0; b < loop_max; ++b) {
446  gemm_trim_left(transpose(left[b]), ket_tensor.data(), t[b]);
447  }
448 
449  Index<SymmGroup> const & physical_i = ket_tensor.site_dim(),
450  & left_i = ket_tensor.row_dim(),
451  & right_i = ket_tensor.col_dim(),
452  out_left_i = physical_i * left_i;
453  ProductBasis<SymmGroup> out_left_pb(physical_i, left_i);
454  ProductBasis<SymmGroup> in_right_pb(physical_i, right_i,
455  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
456  -boost::lambda::_1, boost::lambda::_2));
457 
458  loop_max = mpo.col_dim();
459 
460  parallel_for(/*locale::scatter(mpo.placement_r)*/, std::size_t b2 = 0; b2 < loop_max; ++b2) {
461 
462  block_matrix<Matrix, SymmGroup> contr_column = lbtm_kernel(b2, left, t, mpo, physical_i,
463  right_i, out_left_i, in_right_pb, out_left_pb);
465  gemm(contr_column, right[b2], tmp);
466  #ifdef MAQUIS_OPENMP
467  #pragma omp critical
468  #endif
469  for (std::size_t k = 0; k < tmp.n_blocks(); ++k)
470  ret.data().match_and_add_block(tmp[k], tmp.left_basis()[k].first, tmp.right_basis()[k].first);
471  }
472 
473  ret.phys_i = ket_tensor.site_dim(); ret.left_i = ket_tensor.row_dim(); ret.right_i = ket_tensor.col_dim();
474  return ret;
475  }
476 
477  template<class Matrix, class OtherMatrix, class SymmGroup>
480  MPSTensor<Matrix, SymmGroup> const & ortho_mps,
481  block_matrix<OtherMatrix, SymmGroup> const & ortho_left,
482  block_matrix<OtherMatrix, SymmGroup> const & ortho_right)
483  {
484  ortho_mps.make_right_paired();
486  gemm(ortho_left, ortho_mps.data(), t);
488  ortho_left.left_basis(), ortho_mps.col_dim(),
489  t, t2);
490  gemm(t2, transpose(ortho_right), t3);
491 
492  mps.make_left_paired();
493  t = mps.data();
495  ortho_left.left_basis(), ortho_right.left_basis(),
496  mps.row_dim(), mps.col_dim(),
497  t3, t);
498 
500  mps.row_dim(), mps.col_dim(),
501  t, LeftPaired);
502  return t4;
503  }
504 
505  template<class Matrix, class OtherMatrix, class SymmGroup>
506  static std::pair<MPSTensor<Matrix, SymmGroup>, truncation_results>
508  MPOTensor<Matrix, SymmGroup> const & mpo,
510  Boundary<OtherMatrix, SymmGroup> const & right,
511  double alpha, double cutoff, std::size_t Mmax)
512  {
513  mps.make_left_paired();
515  gemm(mps.data(), transpose(conjugate(mps.data())), dm);
516 
517  Boundary<Matrix, SymmGroup> half_dm = left_boundary_tensor_mpo(mps, left, mpo);
518 
519  mps.make_left_paired();
520  for (std::size_t b = 0; b < half_dm.aux_dim(); ++b)
521  {
523  gemm(half_dm[b], transpose(conjugate(half_dm[b])), tdm);
524 
525 
526  tdm *= alpha;
527  for (std::size_t k = 0; k < tdm.n_blocks(); ++k) {
528  if (mps.data().left_basis().has(tdm.left_basis()[k].first))
529  dm.match_and_add_block(tdm[k],
530  tdm.left_basis()[k].first,
531  tdm.right_basis()[k].first);
532  }
533  }
534  mps.make_left_paired();
535  assert( weak_equal(dm.left_basis(), mps.data().left_basis()) );
536 
539  truncation_results trunc = heev_truncate(dm, U, S, cutoff, Mmax);
540 
542  ret.replace_left_paired(U);
543  return std::make_pair(ret, trunc);
544  }
545 
546  template<class Matrix, class SymmGroup>
549  MPSTensor<Matrix, SymmGroup> const & psi,
551  {
552  psi.make_left_paired();
553  A.make_left_paired();
554 
556  gemm(transpose(conjugate(A.data())), psi.data(), tmp);
557  B.multiply_from_left(tmp);
558 
559  return B;
560  }
561 
562  template<class Matrix, class OtherMatrix, class SymmGroup>
563  static std::pair<MPSTensor<Matrix, SymmGroup>, truncation_results>
565  MPOTensor<Matrix, SymmGroup> const & mpo,
567  Boundary<OtherMatrix, SymmGroup> const & right,
568  double alpha, double cutoff, std::size_t Mmax)
569  {
570  mps.make_right_paired();
572  gemm(transpose(conjugate(mps.data())), mps.data(), dm);
573 
574  Boundary<Matrix, SymmGroup> half_dm = right_boundary_tensor_mpo(mps, right, mpo);
575 
576  mps.make_right_paired();
577  for (std::size_t b = 0; b < half_dm.aux_dim(); ++b)
578  {
580  gemm(transpose(conjugate(half_dm[b])), half_dm[b], tdm);
581 
582  tdm *= alpha;
583  for (std::size_t k = 0; k < tdm.n_blocks(); ++k) {
584  if (mps.data().right_basis().has(tdm.right_basis()[k].first))
585  dm.match_and_add_block(tdm[k],
586  tdm.left_basis()[k].first,
587  tdm.right_basis()[k].first);
588  }
589  }
590 
591  mps.make_right_paired();
592  assert( weak_equal(dm.right_basis(), mps.data().right_basis()) );
593 
596  truncation_results trunc = heev_truncate(dm, U, S, cutoff, Mmax);
597 
600  return std::make_pair(ret, trunc);
601  }
602 
603  template<class Matrix, class SymmGroup>
606  MPSTensor<Matrix, SymmGroup> const & psi,
608  {
609  psi.make_right_paired();
610  A.make_right_paired();
611 
613  gemm(psi.data(), transpose(conjugate(A.data())), tmp);
614 
615  B.multiply_from_right(tmp);
616 
617  return B;
618  }
619 
620  template<class Matrix, class SymmGroup>
624  Index<SymmGroup> const & left_i,
625  Index<SymmGroup> const & right_i,
626  Index<SymmGroup> const & phys_i)
627  {
628  typedef typename SymmGroup::charge charge;
629 
630  Index<SymmGroup> l_index = phys_i * left_i, r_index = adjoin(phys_i) * right_i;
631  common_subset(l_index, r_index);
633 
634  ProductBasis<SymmGroup> left_pb(phys_i, left_i);
635  ProductBasis<SymmGroup> right_pb(phys_i, right_i,
636  boost::lambda::bind(static_cast<charge(*)(charge, charge)>(SymmGroup::fuse),
637  -boost::lambda::_1, boost::lambda::_2));
638  ProductBasis<SymmGroup> phys_pb(phys_i, phys_i);
639 
640  for (size_t ls = 0; ls < left_i.size(); ++ls)
641  for (size_t rs = 0; rs < right_i.size(); ++rs)
642  for (size_t lps = 0; lps < phys_i.size(); ++lps)
643  for (size_t rps = 0; rps < phys_i.size(); ++rps)
644  for (size_t ilps = 0; ilps < phys_i.size(); ++ilps)
645  for (size_t irps = 0; irps < phys_i.size(); ++irps)
646  {
647  charge lc = left_i[ls].first, rc = right_i[rs].first;
648  charge lpc = phys_i[lps].first, rpc = phys_i[rps].first;
649  charge ilpc = phys_i[ilps].first, irpc = phys_i[irps].first;
650 
651  charge left_vec_charge = SymmGroup::fuse(ilpc, lc);
652  charge right_vec_charge = SymmGroup::fuse(-irpc, rc);
653 
654  charge left_out_charge = SymmGroup::fuse(lpc, lc);
655  charge right_out_charge = SymmGroup::fuse(-rpc, rc);
656 
657  if (left_out_charge != right_out_charge)
658  continue;
659  if (left_vec_charge != right_vec_charge)
660  continue;
661  if (! vec.has_block(left_vec_charge, right_vec_charge) )
662  continue;
663  if (SymmGroup::fuse(lpc, rpc) != SymmGroup::fuse(ilpc, irpc))
664  continue;
665 
666  if (! ret.has_block(left_out_charge, right_out_charge))
667  ret.insert_block(Matrix(l_index.size_of_block(left_out_charge), r_index.size_of_block(right_out_charge), 0),
668  left_out_charge, right_out_charge);
669 
670  charge both_charge = SymmGroup::fuse(lpc, rpc);
671 
672  assert( op.has_block(both_charge, both_charge) );
673 
674  maquis::dmrg::detail::mwt(ret(left_out_charge, right_out_charge),
675  vec(left_vec_charge, right_vec_charge),
676  op(both_charge, both_charge),
677  left_pb(lpc, lc), right_pb(rpc, rc),
678  left_pb(ilpc, lc), right_pb(irpc, rc),
679  phys_pb(ilpc, irpc), phys_pb(lpc, rpc),
680  left_i[ls].second, right_i[rs].second,
681  phys_i[lps].second, phys_i[rps].second,
682  phys_i[ilps].second, phys_i[irps].second);
683  }
684 
685  return ret;
686  }
687 
688  template<class Matrix, class SymmGroup>
691  {
692  typedef typename SymmGroup::charge charge;
693 
694  mps.make_left_paired();
695  block_matrix<Matrix, SymmGroup> const & vec = mps.data();
696 
697  Index<SymmGroup> const& phys_i = mps.site_dim();
698  Index<SymmGroup> const& left_i = mps.row_dim();
699  Index<SymmGroup> const& right_i = mps.col_dim();
700 
701  ProductBasis<SymmGroup> left_pb(phys_i, left_i);
702 
704  Index<SymmGroup> out_left_i;
705 
706  for (size_t ls = 0; ls < left_i.size(); ++ls)
707  for (size_t rs = 0; rs < right_i.size(); ++rs)
708  for (size_t s1 = 0; s1 < phys_i.size(); ++s1)
709  for (size_t s2 = 0; s2 < phys_i.size(); ++s2) {
710 
711  charge lc = left_i[ls].first, rc = right_i[rs].first;
712  charge s1c = phys_i[s1].first, s2c = phys_i[s2].first;
713 
714  if (! op.has_block(s1c, s2c) )
715  continue;
716 
717  charge phys_diff = SymmGroup::fuse(s2c, -s1c);
718 
719  charge left_vec_charge = SymmGroup::fuse(s1c, lc);
720  charge right_vec_charge = rc;
721 
722  if (! vec.has_block(left_vec_charge, right_vec_charge) )
723  continue;
724 
725  if (! out_left_i.has(lc))
726  out_left_i.insert(left_i[ls]);
727 
728  charge left_out_charge = SymmGroup::fuse(s2c, lc);
729  charge right_out_charge = SymmGroup::fuse(rc, phys_diff);
730 
731  if (! ret_vec.has_block(left_out_charge, right_out_charge) )
732  ret_vec.insert_block(new Matrix(left_pb.size(s2c, lc), right_i[rs].second, 0), left_out_charge, right_out_charge);
733 
734  Matrix & oblock = ret_vec(left_out_charge, right_out_charge);
735  Matrix const & iblock = vec(left_vec_charge, right_vec_charge);
736  Matrix const & op_block = op(s1c, s2c);
737 
738  size_t i_l_offset = left_pb(s1c, lc);
739  size_t i_r_offset = 0;
740  size_t l_offset = left_pb(s2c, lc);
741  size_t r_offset = 0;
742  size_t i_op_offset = 0;
743  size_t op_offset = 0;
744 
745  for (size_t ss1 = 0; ss1 < phys_i[s1].second; ++ss1) {
746  for (size_t ss2 = 0; ss2 < phys_i[s2].second; ++ss2) {
747  size_t o_l_start = l_offset + ss2*left_i[ls].second;
748  size_t o_r_start = r_offset;
749 
750  size_t i_l_start = i_l_offset + ss1*left_i[ls].second;
751  size_t i_r_start = i_r_offset;
752 
753  typename Matrix::value_type const & op_val = op_block(i_op_offset + ss1, op_offset + ss2);
754 
755  // TODO: replace by kernel
756  for (size_t rr = 0; rr < right_i[rs].second; ++rr) {
757  for (size_t ll = 0; ll < left_i[ls].second; ++ll) {
758  oblock(o_l_start+ll, o_r_start+rr) += iblock(i_l_start+ll, i_r_start+rr) * op_val;
759  }
760  }
761  }
762  }
763  }
764 
765 
766  MPSTensor<Matrix, SymmGroup> ret(phys_i, out_left_i, ret_vec.right_basis(), ret_vec, LeftPaired);
767  assert( ret.reasonable() );
768  return ret;
769  }
770 
771  // tested only for diagonal operator
772  template<class Matrix, class SymmGroup>
776  {
777  typedef typename SymmGroup::charge charge;
778 
779  mps.make_left_paired();
780  block_matrix<Matrix, SymmGroup> const & vec = mps.data();
781 
782  Index<SymmGroup> phys_i = mps.site_dim();
783  Index<SymmGroup> left_i = mps.row_dim();
784  Index<SymmGroup> right_i = mps.col_dim();
785 
786  ProductBasis<SymmGroup> left_pb(phys_i, left_i);
787 
788  MPSTensor<Matrix, SymmGroup> ret(phys_i, left_i, right_i, false);
789  block_matrix<Matrix, SymmGroup> & ret_vec = ret.data();
790 
791  for (size_t ls = 0; ls < left_i.size(); ++ls)
792  for (size_t rs = 0; rs < right_i.size(); ++rs)
793  for (size_t s1 = 0; s1 < phys_i.size(); ++s1)
794  for (size_t s2 = 0; s2 < phys_i.size(); ++s2) {
795 
796  charge lc = left_i[ls].first, rc = right_i[rs].first;
797  charge s1c = phys_i[s1].first, s2c = phys_i[s2].first;
798 
799  charge left_vec_charge = SymmGroup::fuse(s1c, lc);
800  charge right_vec_charge = rc;
801  charge left_out_charge = SymmGroup::fuse(s2c, lc);
802  charge right_out_charge = right_vec_charge;
803 
804  if (! vec.has_block(left_vec_charge, right_vec_charge) )
805  continue;
806  if (! op.has_block(s1c, s2c) )
807  continue;
808  if (! ret_vec.has_block(left_out_charge, right_out_charge) )
809  ret_vec.insert_block(new Matrix(left_pb.size(s2c, lc), right_i[rs].second, 0), left_out_charge, right_out_charge);
810 
811  Matrix & oblock = ret_vec(left_out_charge, right_out_charge);
812  Matrix const & iblock = vec(left_vec_charge, right_vec_charge);
813  Matrix const & op_block = op(s1c, s2c);
814 
815  size_t i_l_offset = left_pb(s1c, lc);
816  size_t i_r_offset = 0;
817  size_t l_offset = left_pb(s2c, lc);
818  size_t r_offset = 0;
819  size_t i_op_offset = 0;
820  size_t op_offset = 0;
821 
822  for (size_t ll = 0; ll < left_i[ls].second; ++ll)
823  for (size_t rr = 0; rr < right_i[rs].second; ++rr)
824  for (size_t ss1 = 0; ss1 < phys_i[s1].second; ++ss1)
825  for (size_t ss2 = 0; ss2 < phys_i[s2].second; ++ss2) {
826 #ifndef NDEBUG
827  oblock(l_offset + ss2*left_i[ls].second + ll,
828  r_offset + rr);
829  iblock(i_l_offset + ss1*left_i[ls].second + ll,
830  i_r_offset + rr);
831  op_block(i_op_offset + ss1,
832  op_offset + ss2);
833 #endif
834  oblock(l_offset + ss2*left_i[ls].second + ll,
835  r_offset + rr) +=
836  iblock(i_l_offset + ss1*left_i[ls].second + ll,
837  i_r_offset + rr) *
838  op_block(i_op_offset + ss1,
839  op_offset + ss2);
840 
841  }
842  }
843 
844 
845  assert( ret.reasonable() );
846  return ret;
847  }
848 
849  template<class Matrix, class SymmGroup>
852  MPSTensor<Matrix, SymmGroup> const & ket_tensor)
853  {
854  typedef typename SymmGroup::charge charge;
855 
856  assert( bra_tensor.row_dim() == ket_tensor.row_dim() );
857  assert( bra_tensor.col_dim() == ket_tensor.col_dim() );
858  assert( bra_tensor.site_dim() == ket_tensor.site_dim() );
859 
860  bra_tensor.make_left_paired();
861  ket_tensor.make_left_paired();
862 
863  Index<SymmGroup> phys_i = ket_tensor.site_dim();
864  Index<SymmGroup> left_i = ket_tensor.row_dim();
865  Index<SymmGroup> right_i = ket_tensor.col_dim();
866 
867  ProductBasis<SymmGroup> left_pb(phys_i, left_i);
868 
869  block_matrix<Matrix, SymmGroup> const & bra_vec = bra_tensor.data();
870  block_matrix<Matrix, SymmGroup> const & ket_vec = ket_tensor.data();
871 
872  block_matrix<Matrix, SymmGroup> ret(phys_i, phys_i);
873 
874  for (size_t ls = 0; ls < left_i.size(); ++ls)
875  for (size_t rs = 0; rs < right_i.size(); ++rs)
876  for (size_t s1 = 0; s1 < phys_i.size(); ++s1)
877  for (size_t s2 = 0; s2 < phys_i.size(); ++s2) {
878 
879  charge lc = left_i[ls].first, rc = right_i[rs].first;
880  charge s1c = phys_i[s1].first, s2c = phys_i[s2].first;
881 
882  charge left_ket_charge = SymmGroup::fuse(s1c, lc);
883  charge left_bra_charge = SymmGroup::fuse(s2c, lc);
884  charge right_charge = rc;
885 
886  if (! ket_vec.has_block(left_ket_charge, right_charge) )
887  continue;
888  if (! bra_vec.has_block(left_bra_charge, right_charge) )
889  continue;
890  if (! ret.has_block(s1c, s2c) )
891  ret.insert_block(new Matrix(phys_i[s1].second, phys_i[s2].second, 0), s1c, s2c);
892 
893  Matrix & oblock = ret(s1c, s2c);
894  Matrix const & ket_block = ket_vec(left_ket_charge, right_charge);
895  Matrix const & bra_block = bra_vec(left_bra_charge, right_charge);
896 
897  size_t l_ket_offset = left_pb(s1c, lc);
898  size_t l_bra_offset = left_pb(s2c, lc);
899 
900  for (size_t ll = 0; ll < left_i[ls].second; ++ll)
901  for (size_t rr = 0; rr < right_i[rs].second; ++rr)
902  for (size_t ss1 = 0; ss1 < phys_i[s1].second; ++ss1)
903  for (size_t ss2 = 0; ss2 < phys_i[s2].second; ++ss2) {
904 
905  oblock(ss1, ss2) +=
906  utils::conj(bra_block(l_bra_offset + ss2*left_i[ls].second + ll, rr)) *
907  ket_block(l_ket_offset + ss1*left_i[ls].second + ll, rr);
908 
909  }
910  }
911  return ret;
912  }
913 
914  template<class Matrix, class SymmGroup>
917  MPSTensor<Matrix, SymmGroup> const & ket_tensor)
918  {
919  typedef typename SymmGroup::charge charge;
920 
921  assert( bra_tensor.row_dim() == ket_tensor.row_dim() );
922  assert( bra_tensor.col_dim() == ket_tensor.col_dim() );
923  assert( bra_tensor.site_dim() == ket_tensor.site_dim() );
924 
925  bra_tensor.make_left_paired();
926  ket_tensor.make_left_paired();
927 
928  Index<SymmGroup> phys_i = ket_tensor.site_dim();
929  Index<SymmGroup> left_i = ket_tensor.row_dim();
930  Index<SymmGroup> right_i = ket_tensor.col_dim();
931 
932  block_matrix<Matrix, SymmGroup> ket_mat = reshape_left_to_physleft(phys_i, left_i, right_i, ket_tensor.data());
933  block_matrix<Matrix, SymmGroup> bra_mat = reshape_left_to_physleft(phys_i, left_i, right_i, bra_tensor.data());
934 
936  gemm(ket_mat, transpose(conjugate(bra_mat)), dm);
937 
938  return dm;
939  }
940 
941 };
942 
943 #endif
static Boundary< Matrix, SymmGroup > right_boundary_tensor_mpo(MPSTensor< Matrix, SymmGroup > mps, Boundary< OtherMatrix, SymmGroup > const &right, MPOTensor< Matrix, SymmGroup > const &mpo, Index< SymmGroup > const *in_low=NULL)
Definition: contractions.h:300
void make_left_paired() const
Definition: mpstensor.hpp:173
static MPSTensor< Matrix, SymmGroup > predict_lanczos_l2r_sweep(MPSTensor< Matrix, SymmGroup > B, MPSTensor< Matrix, SymmGroup > const &psi, MPSTensor< Matrix, SymmGroup > const &A)
Definition: contractions.h:548
Index< SymmGroup > const & col_dim() const
Definition: mpstensor.hpp:161
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
void make_right_paired() const
Definition: mpstensor.hpp:188
index_type row_dim() const
Definition: mpotensor.hpp:179
size_type n_blocks() const
void mwt(alps::numeric::matrix< T1, A1 > &out, const alps::numeric::matrix< T2, A2 > &in, const alps::numeric::matrix< T3, A3 > &alfa, size_t out_y_offset, size_t out_x_offset, size_t in_y_offset, size_t in_x_offset, size_t alfa_y_offset, size_t alfa_x_offset, size_t ldim, size_t rdim, size_t lpdim, size_t rpdim, size_t ilpdim, size_t irpdim)
void resize(size_t n)
Definition: boundary.h:76
static MPSTensor< Matrix, SymmGroup > local_op(MPSTensor< Matrix, SymmGroup > const &mps, block_matrix< Matrix, SymmGroup > const &op)
Definition: contractions.h:774
void gemm_trim_left(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
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
void match_and_add_block(Matrix const &, charge, charge)
static block_matrix< OtherMatrix, SymmGroup > overlap_right_step(MPSTensor< Matrix, SymmGroup > const &bra_tensor, MPSTensor< Matrix, SymmGroup > const &ket_tensor, block_matrix< OtherMatrix, SymmGroup > const &right, block_matrix< OtherMatrix, SymmGroup > *localop=NULL)
Definition: contractions.h:71
size_t size(charge pc) const
static MPSTensor< Matrix, SymmGroup > site_ortho_boundaries(MPSTensor< Matrix, SymmGroup > const &mps, MPSTensor< Matrix, SymmGroup > const &ortho_mps, block_matrix< OtherMatrix, SymmGroup > const &ortho_left, block_matrix< OtherMatrix, SymmGroup > const &ortho_right)
Definition: contractions.h:479
static MPSTensor< Matrix, SymmGroup > site_hamil2(MPSTensor< Matrix, SymmGroup > ket_tensor, Boundary< OtherMatrix, SymmGroup > const &left, Boundary< OtherMatrix, SymmGroup > const &right, MPOTensor< Matrix, SymmGroup > const &mpo)
Definition: contractions.h:431
static block_matrix< Matrix, SymmGroup > density_matrix_2(MPSTensor< Matrix, SymmGroup > const &bra_tensor, MPSTensor< Matrix, SymmGroup > const &ket_tensor)
Definition: contractions.h:916
size_type insert_block(Matrix const &, charge, charge)
std::size_t size_of_block(charge c) const
void lb_tensor_mpo(alps::numeric::matrix< T1, A1 > &out, const alps::numeric::matrix< T2, A2 > &in, const alps::numeric::matrix< T3, A3 > &alfa, size_t out_offset, size_t in_offset, size_t sdim1, size_t sdim2, size_t ldim, size_t rdim, T2 alfa_scale)
row_proxy row(index_type row_i) const
Definition: mpotensor.hpp:139
static Boundary< OtherMatrix, SymmGroup > overlap_mpo_right_step(MPSTensor< Matrix, SymmGroup > const &bra_tensor, MPSTensor< Matrix, SymmGroup > const &ket_tensor, Boundary< OtherMatrix, SymmGroup > const &right, MPOTensor< Matrix, SymmGroup > const &mpo)
Definition: contractions.h:386
Index< SymmGroup > const & row_dim() const
Definition: mpstensor.hpp:155
static block_matrix< Matrix, SymmGroup > density_matrix(MPSTensor< Matrix, SymmGroup > const &bra_tensor, MPSTensor< Matrix, SymmGroup > const &ket_tensor)
Definition: contractions.h:851
block_matrix< Matrix, SymmGroup > adjoint(block_matrix< Matrix, SymmGroup > m)
static block_matrix< Matrix, SymmGroup > lbtm_kernel(size_t b2, Boundary< OtherMatrix, SymmGroup > const &left, std::vector< block_matrix< Matrix, SymmGroup > > const &left_mult_mps, MPOTensor< Matrix, SymmGroup > const &mpo, Index< SymmGroup > const &physical_i, Index< SymmGroup > const &right_i, Index< SymmGroup > const &out_left_i, ProductBasis< SymmGroup > const &in_right_pb, ProductBasis< SymmGroup > const &out_left_pb)
Definition: contractions.h:98
static block_matrix< OtherMatrix, SymmGroup > overlap_left_step(MPSTensor< Matrix, SymmGroup > const &bra_tensor, MPSTensor< Matrix, SymmGroup > const &ket_tensor, block_matrix< OtherMatrix, SymmGroup > const &left, block_matrix< OtherMatrix, SymmGroup > *localop=NULL)
Definition: contractions.h:41
void resize_block(charge r, charge c, size_type new_r, size_type new_c, bool pretend=false)
void multiply_from_left(block_matrix< Matrix, SymmGroup > const &)
Definition: mpstensor.hpp:305
include one of the Index class definitions
void rb_tensor_mpo(alps::numeric::matrix< T1, A1 > &out, const alps::numeric::matrix< T2, A2 > &in, const alps::numeric::matrix< T3, A3 > &alfa, size_t out_offset, size_t in_offset, size_t sdim1, size_t sdim2, size_t ldim, size_t rdim, T2 alfa_scale)
MPOTensor_detail::const_term_descriptor< Matrix, SymmGroup > at(index_type left_index, index_type right_index) const
Definition: mpotensor.hpp:120
block_matrix< Matrix, SymmGroup > adjoin(block_matrix< Matrix, SymmGroup > const &m)
static std::pair< MPSTensor< Matrix, SymmGroup >, truncation_results > predict_new_state_l2r_sweep(MPSTensor< Matrix, SymmGroup > const &mps, MPOTensor< Matrix, SymmGroup > const &mpo, Boundary< OtherMatrix, SymmGroup > const &left, Boundary< OtherMatrix, SymmGroup > const &right, double alpha, double cutoff, std::size_t Mmax)
Definition: contractions.h:507
Index< SymmGroup > phys_i
Definition: mpstensor.h:141
void replace_left_paired(block_matrix< Matrix, SymmGroup > const &, Indicator=Unorm)
Definition: mpstensor.hpp:113
static Boundary< Matrix, SymmGroup > left_boundary_tensor_mpo(MPSTensor< Matrix, SymmGroup > mps, Boundary< OtherMatrix, SymmGroup > const &left, MPOTensor< Matrix, SymmGroup > const &mpo, Index< SymmGroup > const *in_low=NULL)
Definition: contractions.h:260
std::size_t index_type
Definition: mpotensor.h:52
static block_matrix< Matrix, SymmGroup > multiply_with_twosite(block_matrix< Matrix, SymmGroup > const &vec, block_matrix< Matrix, SymmGroup > const &op, Index< SymmGroup > const &left_i, Index< SymmGroup > const &right_i, Index< SymmGroup > const &phys_i)
Definition: contractions.h:622
bool weak_equal(Index< SymmGroup > const &a, Index< SymmGroup > const &b)
truncation_results heev_truncate(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &evecs, block_matrix< DiagMatrix, SymmGroup > &evals, double cutoff, std::size_t Mmax, bool verbose=true)
#define parallel_for(constraint,...)
declaration of the MPSTensor class
bool has_block(charge r, charge c) const
block_matrix< Matrix, SymmGroup > conjugate(block_matrix< Matrix, SymmGroup > m)
static MPSTensor< Matrix, SymmGroup > multiply_with_op(MPSTensor< Matrix, SymmGroup > const &mps, block_matrix< Matrix, SymmGroup > const &op)
Definition: contractions.h:690
static std::pair< MPSTensor< Matrix, SymmGroup >, truncation_results > predict_new_state_r2l_sweep(MPSTensor< Matrix, SymmGroup > const &mps, MPOTensor< Matrix, SymmGroup > const &mpo, Boundary< OtherMatrix, SymmGroup > const &left, Boundary< OtherMatrix, SymmGroup > const &right, double alpha, double cutoff, std::size_t Mmax)
Definition: contractions.h:564
declaration of MPOTensor object
Index< SymmGroup > const & right_basis() const
static Boundary< OtherMatrix, SymmGroup > overlap_mpo_left_step(MPSTensor< Matrix, SymmGroup > const &bra_tensor, MPSTensor< Matrix, SymmGroup > const &ket_tensor, Boundary< OtherMatrix, SymmGroup > const &left, MPOTensor< Matrix, SymmGroup > const &mpo)
Definition: contractions.h:340
void multiply_from_right(block_matrix< Matrix, SymmGroup > const &)
Definition: mpstensor.hpp:294
std::size_t aux_dim() const
Definition: boundary.h:72
Index< SymmGroup > const & site_dim() const
Definition: mpstensor.hpp:149
static block_matrix< Matrix, SymmGroup > rbtm_kernel(size_t b1, Boundary< OtherMatrix, SymmGroup > const &right, std::vector< block_matrix< Matrix, SymmGroup > > const &right_mult_mps, MPOTensor< Matrix, SymmGroup > const &mpo, Index< SymmGroup > const &physical_i, Index< SymmGroup > const &left_i, Index< SymmGroup > const &right_i, Index< SymmGroup > const &out_right_i, ProductBasis< SymmGroup > const &in_left_pb, ProductBasis< SymmGroup > const &out_right_pb)
Definition: contractions.h:176
Index< SymmGroup > left_i
Definition: mpstensor.h:141
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
col_proxy column(index_type col_i) const
Definition: mpotensor.hpp:145
std::size_t insert(std::pair< charge, std::size_t > const &x)
functions to reshape the representation of data in MPSTensor
void gemm(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
size_type find_block(charge r, charge c) const
boost::numeric::ublas::matrix_column< const CSCMatrix > col_proxy
Definition: mpotensor.h:72
Index< SymmGroup > right_i
Definition: mpstensor.h:141
block_matrix< typename maquis::traits::transpose_view< Matrix >::type, SymmGroup > transpose(block_matrix< Matrix, SymmGroup > const &m)
void gemm_trim_right(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
static MPSTensor< Matrix, SymmGroup > predict_lanczos_r2l_sweep(MPSTensor< Matrix, SymmGroup > B, MPSTensor< Matrix, SymmGroup > const &psi, MPSTensor< Matrix, SymmGroup > const &A)
Definition: contractions.h:605
Index< SymmGroup > const & left_basis() const
index_type col_dim() const
Definition: mpotensor.hpp:185
block_matrix< Matrix, SymmGroup > & data()
Definition: mpstensor.hpp:423
std::size_t size() const
void replace_right_paired(block_matrix< Matrix, SymmGroup > const &, Indicator=Unorm)
Definition: mpstensor.hpp:131
Index< SymmGroup > common_subset(Index< SymmGroup > &a, Index< SymmGroup > &b)
bool reasonable() const
Definition: mpstensor.hpp:547
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
T fuse(const A &ind, T d)
Fuse indices n[i] into one p = n[i] d^i.