ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
block_matrix_algorithms.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 BLOCK_MATRIX_ALGORITHMS_H
28 #define BLOCK_MATRIX_ALGORITHMS_H
29 
30 #include "dmrg/utils/logger.h"
31 #include "dmrg/utils/utils.hpp"
32 #include "utils/timings.h"
33 #include "utils/traits.hpp"
34 #include "utils/bindings.hpp"
35 
39 
40 #include <boost/lambda/lambda.hpp>
41 #include <boost/function.hpp>
42 
44 
46  std::size_t bond_dimension; // new bond dimension
47  double truncated_weight; // sum of discarded eigenvalues (square of singuler values)
48  double truncated_fraction; // sum of discarded singular values
49  double smallest_ev; // smallest eigenvalue kept
50 
52 
53  truncation_results(std::size_t m, double tw, double tf, double se)
54  : bond_dimension(m)
55  , truncated_weight(tw)
56  , truncated_fraction(tf)
57  , smallest_ev(se)
58  { }
59 };
60 
61 template<class Matrix1, class Matrix2, class Matrix3, class SymmGroup>
65 {
66  C.clear();
67 
68  typedef typename SymmGroup::charge charge;
69  for (std::size_t k = 0; k < A.n_blocks(); ++k) {
70  std::size_t matched_block = B.left_basis().position(A.right_basis()[k].first);
71 
72  if ( matched_block == B.left_basis().size() )
73  continue;
74 
75  std::size_t new_block = C.insert_block(new Matrix3(num_rows(A[k]), num_cols(B[matched_block])),
76  A.left_basis()[k].first, B.right_basis()[matched_block].first);
77  gemm(A[k], B[matched_block], C[new_block]);
78  }
79 }
80 
81 template<class Matrix1, class Matrix2, class Matrix3, class SymmGroup>
85 {
86  C.clear();
87 
88  typedef typename SymmGroup::charge charge;
89  for (std::size_t k = 0; k < A.n_blocks(); ++k) {
90  std::size_t matched_block = B.left_basis().position(A.right_basis()[k].first);
91 
92  // Match A.right_basis() with B.left_basis()
93  if ( matched_block == B.left_basis().size() )
94  continue;
95 
96  // Also match A.left_basis() with B.left_basis()
97  if ( !B.left_basis().has(A.left_basis()[k].first) )
98  continue;
99 
100  std::size_t new_block = C.insert_block(new Matrix3(num_rows(A[k]), num_cols(B[matched_block])),
101  A.left_basis()[k].first, B.right_basis()[matched_block].first);
102  gemm(A[k], B[matched_block], C[new_block]);
103  }
104 }
105 
106 template<class Matrix1, class Matrix2, class Matrix3, class SymmGroup>
110 {
111  C.clear();
112 
113  typedef typename SymmGroup::charge charge;
114  for (std::size_t k = 0; k < B.n_blocks(); ++k) {
115  std::size_t matched_block = A.right_basis().position(B.left_basis()[k].first);
116 
117  // Match A.right_basis() with B.left_basis()
118  if ( matched_block == A.right_basis().size() )
119  continue;
120 
121  // Also match A.right_basis() with B.right_basis()
122  if ( !A.right_basis().has(B.right_basis()[k].first) )
123  continue;
124 
125  std::size_t new_block = C.insert_block(new Matrix3(num_rows(A[matched_block]), num_cols(B[k])),
126  A.left_basis()[matched_block].first, B.right_basis()[k].first);
127  gemm(A[matched_block], B[k], C[new_block]);
128  }
129 }
130 
131 template<class Matrix, class DiagMatrix, class SymmGroup>
136 {
137  Index<SymmGroup> r = M.left_basis(), c = M.right_basis(), m = M.left_basis();
138  for (std::size_t i = 0; i < M.n_blocks(); ++i)
139  m[i].second = std::min(r[i].second, c[i].second);
140 
144  std::size_t loop_max = M.n_blocks();
145 
146  parallel_for(/*removed...*/, std::size_t k = 0; k < loop_max; ++k)
147  svd(M[k], U[k], V[k], S[k]);
148 }
149 
150 template<class Matrix, class DiagMatrix, class SymmGroup>
154 {
155 
158  std::size_t loop_max = M.n_blocks();
159 
160  parallel_for(/*removed...*/, std::size_t k = 0; k < loop_max; ++k)
161  heev(M[k], evecs[k], evals[k]);
162 }
163 
164 template <class T>
166 {
167  assert( check_real(val) );
168  assert( maquis::real(val) > -1e-10 );
169  return maquis::real(val);
170 }
171 
172 template<class DiagMatrix, class SymmGroup>
174  size_t Mmax, double cutoff, size_t* keeps,
175  double & truncated_fraction, double & truncated_weight, double & smallest_ev)
176 { // to be parallelized later (30.04.2012)
177  typedef typename DiagMatrix::value_type value_type;
178 
179  size_t length = 0;
180  for(std::size_t k = 0; k < evals.n_blocks(); ++k){
181  length += num_rows(evals[k]);
182  }
183 
184  typedef std::vector<typename maquis::traits::real_type<value_type>::type > real_vector_t;
185  real_vector_t allevals(length);
186 
187  std::size_t position = 0;
188  for(std::size_t k = 0; k < evals.n_blocks(); ++k){
189  std::transform(evals[k].diagonal().first, evals[k].diagonal().second, allevals.begin()+position, gather_real_pred<value_type>);
190  position += num_rows(evals[k]);
191  }
192 
193  assert( allevals.size() > 0 );
194  std::sort(allevals.begin(), allevals.end());
195  std::reverse(allevals.begin(), allevals.end());
196 
197  double evalscut = cutoff * allevals[0];
198 
199  if (allevals.size() > Mmax)
200  evalscut = std::max(evalscut, allevals[Mmax]);
201  smallest_ev = evalscut / allevals[0];
202 
203  truncated_fraction = 0.0; truncated_weight = 0.0;
204  for (typename real_vector_t::const_iterator it = std::find_if(allevals.begin(), allevals.end(), boost::lambda::_1 < evalscut);
205  it != allevals.end(); ++it) {
206  truncated_fraction += *it;
207  truncated_weight += (*it)*(*it);
208  }
209  truncated_fraction /= std::accumulate(allevals.begin(), allevals.end(), 0.0);
210  truncated_weight /= std::accumulate(allevals.begin(), allevals.end(), 0.0, boost::lambda::_1 + boost::lambda::_2 *boost::lambda::_2);
211 
212  for(std::size_t k = 0; k < evals.n_blocks(); ++k){
213  real_vector_t evals_k(num_rows(evals[k]));
214  std::transform(evals[k].diagonal().first, evals[k].diagonal().second, evals_k.begin(), gather_real_pred<value_type>);
215  keeps[k] = std::find_if(evals_k.begin(), evals_k.end(), boost::lambda::_1 < evalscut)-evals_k.begin();
216  }
217 }
218 
219 
220 template<class Matrix, class DiagMatrix, class SymmGroup>
225  double rel_tol, std::size_t Mmax,
226  bool verbose = true)
227 {
228  assert( M.left_basis().sum_of_sizes() > 0 && M.right_basis().sum_of_sizes() > 0 );
229  svd(M, U, V, S);
230 
231  Index<SymmGroup> old_basis = S.left_basis();
232  size_t* keeps = new size_t[S.n_blocks()];
233  double truncated_fraction, truncated_weight, smallest_ev;
234  // Given the full SVD in each block (above), remove all singular values and corresponding rows/cols
235  // where the singular value is < rel_tol*max(S), where the maximum is taken over all blocks.
236  // Be careful to update the Index descriptions in the matrices to reflect the reduced block sizes
237  // (remove_rows/remove_cols methods for that)
238  estimate_truncation(S, Mmax, rel_tol, keeps, truncated_fraction, truncated_weight, smallest_ev);
239 
240  for ( int k = S.n_blocks() - 1; k >= 0; --k) // C - we reverse faster and safer ! we avoid bug if keeps[k] = 0
241  {
242  size_t keep = keeps[k];
243 
244  if (keep == 0) {
245  S.remove_block(S.left_basis()[k].first,
246  S.right_basis()[k].first);
247  U.remove_block(U.left_basis()[k].first,
248  U.right_basis()[k].first);
249  V.remove_block(V.left_basis()[k].first,
250  V.right_basis()[k].first);
251  // C- idem heev_truncate --k; // everything gets shifted, to we have to look into the same k again
252  } else {
253  if (keep >= num_rows(S[k])) continue;
254 
255  S.resize_block(S.left_basis()[k].first,
256  S.right_basis()[k].first,
257  keep, keep);
258  U.resize_block(U.left_basis()[k].first,
259  U.right_basis()[k].first,
260  U.left_basis()[k].second,
261  keep);
262  V.resize_block(V.left_basis()[k].first,
263  V.right_basis()[k].first,
264  keep,
265  V.right_basis()[k].second);
266  }
267  }
268 
269  delete[] keeps;
270 
271  std::size_t bond_dimension = S.left_basis().sum_of_sizes();
272  if(verbose){
273  maquis::cout << "Sum: " << old_basis.sum_of_sizes() << " -> " << bond_dimension << std::endl;
274  }
275 
276  // MD: for singuler values we care about summing the square of the discraded
277  // MD: sum of the discarded values is stored elsewhere
278  return truncation_results(bond_dimension, truncated_weight, truncated_fraction, smallest_ev);
279 }
280 
281 // TODO: not yet working properly.
282 template<class Matrix, class DiagMatrix, class SymmGroup>
287  double rel_tol, std::size_t Mmax,
288  bool verbose = true)
289 {
290  assert( M.left_basis().sum_of_sizes() > 0 && M.right_basis().sum_of_sizes() > 0 );
291 
295 
296 // maquis::cout << "M:" << std::endl << M;
297 
298 
300 
301  gemm(M, transpose(Mconj), t);
302  truncation_results res = heev_truncate(t, U, D, rel_tol, Mmax, verbose);
303 
304  gemm(transpose(Mconj), U, t);
305  qr(t, V, R);
306 
307  maquis::cout << "S.n_blocks: " << D.n_blocks() << std::endl;
308  maquis::cout << "S.trace: " << trace(D) << std::endl;
309  maquis::cout << "R.n_blocks: " << R.n_blocks() << std::endl;
310  maquis::cout << "R.trace: " << trace(R) << std::endl;
311 
312 // maquis::cout << "S:" << std::endl << S;
313 // maquis::cout << "R:" << std::endl << R;
314 
315  using std::abs;
316  for (int n=0; n<D.n_blocks(); ++n)
317  for (int i=0; i<num_rows(D[n]); ++i)
318  if ( abs(D[n](i,i) - R[n](i,i)*R[n](i,i)) > 1e-6 )
319  maquis::cout << "n=" << n << ", i=" << i << " broken. D=" << D[n](i,i) << ", td=" << R[n](i,i)*R[n](i,i) << std::endl;
320 
321  S = sqrt(D);
322  S /= trace(S);
323  V.adjoint_inplace();
324 
325  maquis::cout << "U:\n" << U.left_basis() << "\n" << U.right_basis() << std::endl;
326  maquis::cout << "S:\n" << S.left_basis() << "\n" << S.right_basis() << std::endl;
327  maquis::cout << "V:\n" << V.left_basis() << "\n" << V.right_basis() << std::endl;
328 
329 // assert( td == S );
330  return res;
331 }
332 
333 template<class Matrix, class DiagMatrix, class SymmGroup>
337  double cutoff, std::size_t Mmax,
338  bool verbose = true)
339 {
340  assert( M.left_basis().sum_of_sizes() > 0 && M.right_basis().sum_of_sizes() > 0 );
341  heev(M, evecs, evals);
342  Index<SymmGroup> old_basis = evals.left_basis();
343  size_t* keeps = new size_t[evals.n_blocks()];
344  double truncated_fraction, truncated_weight, smallest_ev;
345 
346  estimate_truncation(evals, Mmax, cutoff, keeps, truncated_fraction, truncated_weight, smallest_ev);
347 
348  for ( int k = evals.n_blocks() - 1; k >= 0; --k) // C - we reverse faster and safer ! we avoid bug if keeps[k] = 0
349  {
350  size_t keep = keeps[k];
351 
352  if (keep == 0) {
353  evals.remove_block(evals.left_basis()[k].first,
354  evals.right_basis()[k].first);
355  evecs.remove_block(evecs.left_basis()[k].first,
356  evecs.right_basis()[k].first);
357 // --k; // everything gets shifted, to we have to look into the same k again
358 // C - Tim : I reversed the loop because the new version was incompatible with the keeps array, and created a bug when keeps[k]=0.
359  } else {
360  if(keep >= num_rows(evals[k])) continue;
361 
362  evals.resize_block(evals.left_basis()[k].first,
363  evals.right_basis()[k].first,
364  keep, keep);
365  evecs.resize_block(evecs.left_basis()[k].first,
366  evecs.right_basis()[k].first,
367  evecs.left_basis()[k].second,
368  keep);
369  }
370  }
371  delete[] keeps;
372 
373  std::size_t bond_dimension = evals.left_basis().sum_of_sizes();
374  if(verbose){
375  maquis::cout << "Sum: " << old_basis.sum_of_sizes() << " -> " << bond_dimension << std::endl;
376  }
377 
378  // MD: for eigenvalues we care about summing the discraded
379  return truncation_results(bond_dimension, truncated_fraction, truncated_fraction, smallest_ev);
380 }
381 
382 template<class Matrix, class SymmGroup>
386 {
387  /* thin QR in each block */
388  Index<SymmGroup> m = M.left_basis(), n = M.right_basis(), k = M.right_basis();
389  for (size_t i=0; i<k.size(); ++i)
390  k[i].second = std::min(m[i].second,n[i].second);
391 
394  std::size_t loop_max = M.n_blocks();
395 
396  parallel_for(/*removed...*/, std::size_t k = 0; k < loop_max; ++k)
397  qr(M[k], Q[k], R[k]);
398 
399  assert(Q.right_basis() == R.left_basis());
400  assert(Q.reasonable());
401  assert(R.reasonable());
402 }
403 
404 template<class Matrix, class SymmGroup>
408 {
409  /* thin LQ in each block */
410  Index<SymmGroup> m = M.left_basis(), n = M.right_basis(), k = M.right_basis();
411  for (size_t i=0; i<k.size(); ++i)
412  k[i].second = std::min(m[i].second,n[i].second);
413 
416  std::size_t loop_max = M.n_blocks();
417 
418  parallel_for(/*removed...*/, std::size_t k = 0; k < loop_max; ++k)
419  lq(M[k], L[k], Q[k]);
420 
421  assert(Q.left_basis() == L.right_basis());
422  assert(Q.reasonable());
423  assert(L.reasonable());
424 }
425 
426 template<class Matrix, class SymmGroup>
428 {
430  for(size_t k=0; k<m.n_blocks(); ++k)
431  ret.insert_block(transpose(m[k]), m.right_basis()[k].first, m.left_basis()[k].first);
432  return ret;
433 }
434 
435 template<class Matrix, class SymmGroup>
437 {
438  m.conjugate_inplace();
439  return m;
440 }
441 
442 template<class Matrix, class SymmGroup>
444 {
445  m.adjoint_inplace();
446  return m;
447 }
448 
449 template<class Matrix, class SymmGroup>
451 {
452  return m.trace();
453 }
454 
455 template<class Matrix, class SymmGroup>
456 block_matrix<Matrix, SymmGroup> adjoin(block_matrix<Matrix, SymmGroup> const & m) // error: it should be adjoin_t_
457 {
459  for (std::size_t k = 0; k < m.n_blocks(); ++k)
460  ret.insert_block(m[k],
461  -m.left_basis()[k].first,
462  -m.right_basis()[k].first);
463  return ret;
464 }
465 
466 template<class Matrix, class SymmGroup, class Generator>
468 {
469  m.generate(g);
470 }
471 
472 template<class Matrix, class SymmGroup>
474 {
475  block_matrix<Matrix, SymmGroup> ret(size, size);
476  for (std::size_t k = 0; k < ret.n_blocks(); ++k)
477  ret[k] = Matrix::identity_matrix(size[k].second);
478  return ret;
479 }
480 
481 template<class Matrix, class SymmGroup>
483 {
484  bool ret = true;
485  for (size_t k=0; ret && k < m.n_blocks(); ++k) {
486  if (m.left_basis()[k].second != m.right_basis()[k].second)
487  return false;
488  else if (m.left_basis()[k].first == m.right_basis()[k].first)
489  ret = is_hermitian(m[k]);
490  else if (! m.has_block(m.right_basis()[k].first, m.left_basis()[k].first))
491  return false;
492  else
493  ret = ( m[k] == transpose(conj( m(m.right_basis()[k].first, m.left_basis()[k].first) )) );
494  }
495  return ret;
496 }
497 
498 template<class Matrix, class SymmGroup>
500 {
501  for (std::size_t k = 0; k < m.n_blocks(); ++k)
502  sqrt_inplace(m[k]);
503 
504  return m;
505 }
506 
507 // Is it really useful?
508 //template <class Matrix, class SymmGroup, class A>
509 //block_matrix<Matrix, SymmGroup> exp (block_matrix<Matrix, SymmGroup> const & M, A const & alpha = 1)
510 //{
511 // block_matrix<Matrix, SymmGroup> N, tmp, res;
512 // block_matrix<typename alps::numeric::associated_diagonal_matrix<Matrix>::type, SymmGroup> S;
513 //
514 // heev(M, N, S);
515 // for (std::size_t k = 0; k < S.n_blocks(); ++k)
516 // S[k] = exp(alpha*S[k]);
517 // gemm(N, S, tmp);
518 // gemm(tmp, adjoint(N), res);
519 //
520 // return res;
521 //}
522 
523 template <class Matrix, class SymmGroup, class A>
526  A const & alpha = 1.)
527 {
528  for (typename Index<SymmGroup>::const_iterator it_c = phys.begin(); it_c != phys.end(); it_c++)
529  if (M.has_block(it_c->first, it_c->first))
530  M(it_c->first, it_c->first) = exp_hermitian(M(it_c->first, it_c->first), alpha);
531  else
533  it_c->first, it_c->first);
534  return M;
535 }
536 
537 namespace detail {
538 
539  template <class Matrix>
540  typename boost::enable_if<boost::is_complex<typename Matrix::value_type>, Matrix>::type
541  exp_dispatcher(Matrix const& m, typename Matrix::value_type const& alpha)
542  {
543  return exp(m, alpha);
544  }
545 
546  template <class Matrix>
547  typename boost::disable_if<boost::is_complex<typename Matrix::value_type>, Matrix>::type
548  exp_dispatcher(Matrix const& m, typename Matrix::value_type const& alpha)
549  {
550  throw std::runtime_error("Exponential of non-hermitian real matrices not implemented!");
551  return Matrix();
552  }
553 }
554 
555 template <class Matrix, class SymmGroup, class A>
558  A const & alpha = 1.)
559 {
560  for (typename Index<SymmGroup>::const_iterator it_c = phys.begin(); it_c != phys.end(); it_c++)
561  if (M.has_block(it_c->first, it_c->first))
562  M(it_c->first, it_c->first) = detail::exp_dispatcher(M(it_c->first, it_c->first), alpha);
563  else
565  it_c->first, it_c->first);
566  return M;
567 }
568 
569 template<class Matrix1, class Matrix2, class SymmGroup>
570 void op_kron(Index<SymmGroup> const & phys_A,
571  Index<SymmGroup> const & phys_B,
575 {
577 
578  ProductBasis<SymmGroup> pb_left(phys_A, phys_B);
579  ProductBasis<SymmGroup> const& pb_right = pb_left;
580 
581  for (int i = 0; i < A.n_blocks(); ++i) {
582  for (int j = 0; j < B.n_blocks(); ++j) {
583  typename SymmGroup::charge new_right = SymmGroup::fuse(A.right_basis()[i].first, B.right_basis()[j].first);
584  typename SymmGroup::charge new_left = SymmGroup::fuse(A.left_basis()[i].first, B.left_basis()[j].first);
585 
586 
587  Matrix2 tmp(pb_left.size(A.left_basis()[i].first, B.left_basis()[j].first),
588  pb_right.size(A.right_basis()[i].first, B.right_basis()[j].first),
589  0);
590 
591  maquis::dmrg::detail::op_kron(tmp, B[j], A[i],
592  pb_left(A.left_basis()[i].first, B.left_basis()[j].first),
593  pb_right(A.right_basis()[i].first, B.right_basis()[j].first),
594  A.left_basis()[i].second, B.left_basis()[j].second,
595  A.right_basis()[i].second, B.right_basis()[j].second);
596 
597  C.match_and_add_block(tmp, new_left, new_right);
598  }
599  }
600 }
601 
602 template<class Matrix, class SymmGroup>
608  std::size_t dist,
610 {
611  assert( midx.size() == 2*(dist+1) );
613 
614  for (size_t run=0; run<2; ++run) {
615 
616  if (run == 1)
617  C.allocate_blocks();
618 
619  for (index_product_iterator<SymmGroup> it = midx.begin();
620  it != midx.end(); ++it)
621  {
622  bool has_block = A.has_block((*it)[0].first, (*it)[1].first);
623  has_block = has_block && B.has_block((*it)[2*dist].first, (*it)[2*dist+1].first);
624  for (size_t i=1; has_block && i<dist; ++i)
625  has_block = F.has_block((*it)[2*i].first, (*it)[2*i+1].first);
626 
627  if (!has_block)
628  continue;
629 
630  typename Matrix::value_type val = A((*it)[0], (*it)[1]) * B((*it)[2*dist], (*it)[2*dist+1]);
631  for (size_t i=1; i<dist; ++i)
632  val *= F((*it)[2*i], (*it)[2*i+1]);
633 
634  if (val != 0.) {
635  typename MultiIndex<SymmGroup>::coord_t coord_l, coord_r;
636  boost::tie(coord_l, coord_r) = midx.get_coords(s, *it);
637  if (run == 0)
638  C.reserve(coord_l.first, coord_r.first,
639  midx.left_size(s, coord_l.first), midx.right_size(s, coord_r.first));
640  else
641  C(coord_l, coord_r) += val;
642 
643  }
644  }
645 
646  }
647 
648 }
649 
650 #endif
void conjugate_inplace()
void run(std::string const &chkp1, std::string const &chkp2)
Definition: main.cpp:52
base_t::const_iterator const_iterator
bool is_hermitian(block_matrix< Matrix, SymmGroup > const &m)
void heev(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &evecs, block_matrix< DiagMatrix, SymmGroup > &evals)
iterator begin()
std::size_t set_id
Definition: multi_index.h:150
std::pair< coord_t, coord_t > get_coords(set_id s, key_t const &key) const
Definition: multi_index.h:223
size_type n_blocks() const
std::pair< charge, elem_id > coord_t
Definition: multi_index.h:148
void gemm_trim_left(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
void match_and_add_block(Matrix const &, charge, charge)
declaration of block_matrix class
block_matrix< Matrix, SymmGroup > op_exp(Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > M, A const &alpha=1.)
size_t size(charge pc) const
maquis::traits::real_type< T >::type gather_real_pred(T const &val)
block_matrix< Matrix, SymmGroup > identity_matrix(Index< SymmGroup > const &size)
size_type insert_block(Matrix const &, charge, charge)
std::size_t size_of_block(charge c) const
const_iterator end() const
Definition: multi_index.h:279
void op_kron(Index< SymmGroup > const &phys_A, Index< SymmGroup > const &phys_B, block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix1, SymmGroup > const &B, block_matrix< Matrix2, SymmGroup > &C)
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
block_matrix< Matrix, SymmGroup > adjoint(block_matrix< Matrix, SymmGroup > m)
scalar_type trace() const
size_t right_size(set_id s, charge const &c) const
Definition: multi_index.h:206
truncation_results(std::size_t m, double tw, double tf, double se)
bool check_real(T x)
Definition: utils.hpp:43
block_matrix< Matrix, SymmGroup > sqrt(block_matrix< Matrix, SymmGroup > m)
void resize_block(charge r, charge c, size_type new_r, size_type new_c, bool pretend=false)
void op_kron_long(MultiIndex< SymmGroup > const &midx, typename MultiIndex< SymmGroup >::set_id s, block_matrix< Matrix, SymmGroup > const &A, block_matrix< Matrix, SymmGroup > const &B, block_matrix< Matrix, SymmGroup > const &F, std::size_t dist, block_matrix< Matrix, SymmGroup > &C)
block_matrix< Matrix, SymmGroup >::scalar_type trace(block_matrix< Matrix, SymmGroup > const &m)
maquis::traits::scalar_type< Matrix >::type scalar_type
Definition: block_matrix.h:52
include one of the Index class definitions
truncation_results svd_truncate(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &U, block_matrix< Matrix, SymmGroup > &V, block_matrix< DiagMatrix, SymmGroup > &S, double rel_tol, std::size_t Mmax, bool verbose=true)
block_matrix< Matrix, SymmGroup > adjoin(block_matrix< Matrix, SymmGroup > const &m)
bool reasonable() const
void estimate_truncation(block_matrix< DiagMatrix, SymmGroup > const &evals, size_t Mmax, double cutoff, size_t *keeps, double &truncated_fraction, double &truncated_weight, double &smallest_ev)
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,...)
real_type< typename T::value_type >::type type
Definition: traits.hpp:9
bool has_block(charge r, charge c) const
block_matrix< Matrix, SymmGroup > conjugate(block_matrix< Matrix, SymmGroup > m)
size_t left_size(set_id s, charge const &c) const
Definition: multi_index.h:201
void svd(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &U, block_matrix< Matrix, SymmGroup > &V, block_matrix< DiagMatrix, SymmGroup > &S)
std::size_t num_cols(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:102
void op_kron(Matrix2 &out, const Matrix1 &in, const Matrix1 &alfa, size_t out_y_offset, size_t out_x_offset, size_t ldim1, size_t ldim2, size_t rdim1, size_t rdim2)
Definition: alps_detail.hpp:65
const_iterator begin() const
Definition: multi_index.h:276
Index< SymmGroup > const & right_basis() const
void generate(Generator g)
iterator end()
void remove_block(charge r, charge c)
void adjoint_inplace()
void reserve(charge, charge, std::size_t, std::size_t)
void lq(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &L, block_matrix< Matrix, SymmGroup > &Q)
truncation_results alt_svd_truncate(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &U, block_matrix< Matrix, SymmGroup > &V, block_matrix< DiagMatrix, SymmGroup > &S, double rel_tol, std::size_t Mmax, bool verbose=true)
void generate(block_matrix< Matrix, SymmGroup > &m, Generator &g)
void gemm(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
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)
size_t size() const
Definition: multi_index.h:166
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
Definition: bindings.hpp:44
void allocate_blocks()
block_matrix< Matrix, SymmGroup > op_exp_hermitian(Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > M, A const &alpha=1.)
Index< SymmGroup > const & left_basis() const
boost::enable_if< boost::is_complex< typename Matrix::value_type >, Matrix >::type exp_dispatcher(Matrix const &m, typename Matrix::value_type const &alpha)
alps::numeric::real_type< T >::type real(T f)
Definition: bindings.hpp:38
void qr(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &Q, block_matrix< Matrix, SymmGroup > &R)
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.