ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Classes | Namespaces | Functions
block_matrix_algorithms.h File Reference
#include "dmrg/utils/logger.h"
#include "dmrg/utils/utils.hpp"
#include "utils/timings.h"
#include "utils/traits.hpp"
#include "utils/bindings.hpp"
#include "dmrg/block_matrix/block_matrix.h"
#include "dmrg/block_matrix/indexing.h"
#include "dmrg/block_matrix/multi_index.h"
#include <boost/lambda/lambda.hpp>
#include <boost/function.hpp>
#include "dmrg/utils/parallel_for.hpp"

Go to the source code of this file.

Classes

struct  truncation_results
 

Namespaces

 detail
 

Functions

template<class Matrix1 , class Matrix2 , class Matrix3 , class SymmGroup >
void gemm (block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
 
template<class Matrix1 , class Matrix2 , class Matrix3 , class SymmGroup >
void gemm_trim_left (block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
 
template<class Matrix1 , class Matrix2 , class Matrix3 , class SymmGroup >
void gemm_trim_right (block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
 
template<class Matrix , class DiagMatrix , class SymmGroup >
void svd (block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &U, block_matrix< Matrix, SymmGroup > &V, block_matrix< DiagMatrix, SymmGroup > &S)
 
template<class Matrix , class DiagMatrix , class SymmGroup >
void heev (block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &evecs, block_matrix< DiagMatrix, SymmGroup > &evals)
 
template<class T >
maquis::traits::real_type< T >
::type 
gather_real_pred (T const &val)
 
template<class DiagMatrix , class SymmGroup >
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)
 
template<class Matrix , class DiagMatrix , class SymmGroup >
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)
 
template<class Matrix , class DiagMatrix , class SymmGroup >
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)
 
template<class Matrix , class DiagMatrix , class SymmGroup >
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)
 
template<class Matrix , class SymmGroup >
void qr (block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &Q, block_matrix< Matrix, SymmGroup > &R)
 
template<class Matrix , class SymmGroup >
void lq (block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &L, block_matrix< Matrix, SymmGroup > &Q)
 
template<class Matrix , class SymmGroup >
block_matrix< typename
maquis::traits::transpose_view
< Matrix >::type, SymmGroup > 
transpose (block_matrix< Matrix, SymmGroup > const &m)
 
template<class Matrix , class SymmGroup >
block_matrix< Matrix, SymmGroup > conjugate (block_matrix< Matrix, SymmGroup > m)
 
template<class Matrix , class SymmGroup >
block_matrix< Matrix, SymmGroup > adjoint (block_matrix< Matrix, SymmGroup > m)
 
template<class Matrix , class SymmGroup >
block_matrix< Matrix,
SymmGroup >::scalar_type 
trace (block_matrix< Matrix, SymmGroup > const &m)
 
template<class Matrix , class SymmGroup >
block_matrix< Matrix, SymmGroup > adjoin (block_matrix< Matrix, SymmGroup > const &m)
 
template<class Matrix , class SymmGroup , class Generator >
void generate (block_matrix< Matrix, SymmGroup > &m, Generator &g)
 
template<class Matrix , class SymmGroup >
block_matrix< Matrix, SymmGroup > identity_matrix (Index< SymmGroup > const &size)
 
template<class Matrix , class SymmGroup >
bool is_hermitian (block_matrix< Matrix, SymmGroup > const &m)
 
template<class Matrix , class SymmGroup >
block_matrix< Matrix, SymmGroup > sqrt (block_matrix< Matrix, SymmGroup > m)
 
template<class Matrix , class SymmGroup , class A >
block_matrix< Matrix, SymmGroup > op_exp_hermitian (Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > M, A const &alpha=1.)
 
template<class Matrix >
boost::enable_if
< boost::is_complex< typename
Matrix::value_type >, Matrix >
::type 
detail::exp_dispatcher (Matrix const &m, typename Matrix::value_type const &alpha)
 
template<class Matrix >
boost::disable_if
< boost::is_complex< typename
Matrix::value_type >, Matrix >
::type 
detail::exp_dispatcher (Matrix const &m, typename Matrix::value_type const &alpha)
 
template<class Matrix , class SymmGroup , class A >
block_matrix< Matrix, SymmGroup > op_exp (Index< SymmGroup > const &phys, block_matrix< Matrix, SymmGroup > M, A const &alpha=1.)
 
template<class Matrix1 , class Matrix2 , class SymmGroup >
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)
 
template<class Matrix , class SymmGroup >
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)
 

Function Documentation

template<class Matrix , class SymmGroup >
block_matrix<Matrix, SymmGroup> adjoin ( block_matrix< Matrix, SymmGroup > const &  m)

Definition at line 456 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
size_type insert_block(Matrix const &, charge, charge)
Index< SymmGroup > const & right_basis() const
Index< SymmGroup > const & left_basis() const
template<class Matrix , class SymmGroup >
block_matrix<Matrix, SymmGroup> adjoint ( block_matrix< Matrix, SymmGroup >  m)

Definition at line 443 of file block_matrix_algorithms.h.

444 {
445  m.adjoint_inplace();
446  return m;
447 }
void adjoint_inplace()
template<class Matrix , class DiagMatrix , class SymmGroup >
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 
)

Definition at line 283 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
block_matrix< Matrix, SymmGroup > sqrt(block_matrix< Matrix, SymmGroup > m)
block_matrix< Matrix, SymmGroup >::scalar_type trace(block_matrix< Matrix, SymmGroup > const &m)
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)
block_matrix< Matrix, SymmGroup > conjugate(block_matrix< Matrix, SymmGroup > m)
Index< SymmGroup > const & right_basis() const
void adjoint_inplace()
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)
Index< SymmGroup > const & left_basis() const
void qr(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &Q, block_matrix< Matrix, SymmGroup > &R)
template<class Matrix , class SymmGroup >
block_matrix<Matrix, SymmGroup> conjugate ( block_matrix< Matrix, SymmGroup >  m)

Definition at line 436 of file block_matrix_algorithms.h.

437 {
438  m.conjugate_inplace();
439  return m;
440 }
void conjugate_inplace()
template<class DiagMatrix , class SymmGroup >
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 
)

Definition at line 173 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
Definition: bindings.hpp:44
template<class T >
maquis::traits::real_type<T>::type gather_real_pred ( T const &  val)

Definition at line 165 of file block_matrix_algorithms.h.

166 {
167  assert( check_real(val) );
168  assert( maquis::real(val) > -1e-10 );
169  return maquis::real(val);
170 }
bool check_real(T x)
Definition: utils.hpp:43
alps::numeric::real_type< T >::type real(T f)
Definition: bindings.hpp:38
template<class Matrix1 , class Matrix2 , class Matrix3 , class SymmGroup >
void gemm ( block_matrix< Matrix1, SymmGroup > const &  A,
block_matrix< Matrix2, SymmGroup > const &  B,
block_matrix< Matrix3, SymmGroup > &  C 
)

Definition at line 62 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
size_type insert_block(Matrix const &, charge, charge)
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
std::size_t num_cols(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:102
Index< SymmGroup > const & right_basis() const
void gemm(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
Index< SymmGroup > const & left_basis() const
template<class Matrix1 , class Matrix2 , class Matrix3 , class SymmGroup >
void gemm_trim_left ( block_matrix< Matrix1, SymmGroup > const &  A,
block_matrix< Matrix2, SymmGroup > const &  B,
block_matrix< Matrix3, SymmGroup > &  C 
)

Definition at line 82 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
size_type insert_block(Matrix const &, charge, charge)
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
std::size_t num_cols(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:102
Index< SymmGroup > const & right_basis() const
void gemm(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
Index< SymmGroup > const & left_basis() const
template<class Matrix1 , class Matrix2 , class Matrix3 , class SymmGroup >
void gemm_trim_right ( block_matrix< Matrix1, SymmGroup > const &  A,
block_matrix< Matrix2, SymmGroup > const &  B,
block_matrix< Matrix3, SymmGroup > &  C 
)

Definition at line 107 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
size_type insert_block(Matrix const &, charge, charge)
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
std::size_t num_cols(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:102
Index< SymmGroup > const & right_basis() const
void gemm(block_matrix< Matrix1, SymmGroup > const &A, block_matrix< Matrix2, SymmGroup > const &B, block_matrix< Matrix3, SymmGroup > &C)
Index< SymmGroup > const & left_basis() const
template<class Matrix , class SymmGroup , class Generator >
void generate ( block_matrix< Matrix, SymmGroup > &  m,
Generator &  g 
)

Definition at line 467 of file block_matrix_algorithms.h.

468 {
469  m.generate(g);
470 }
void generate(Generator g)
template<class Matrix , class DiagMatrix , class SymmGroup >
void heev ( block_matrix< Matrix, SymmGroup > const &  M,
block_matrix< Matrix, SymmGroup > &  evecs,
block_matrix< DiagMatrix, SymmGroup > &  evals 
)

Definition at line 151 of file block_matrix_algorithms.h.

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 }
void heev(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &evecs, block_matrix< DiagMatrix, SymmGroup > &evals)
size_type n_blocks() const
#define parallel_for(constraint,...)
Index< SymmGroup > const & right_basis() const
Index< SymmGroup > const & left_basis() const
template<class Matrix , class DiagMatrix , class SymmGroup >
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 
)

Definition at line 334 of file block_matrix_algorithms.h.

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 }
void heev(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &evecs, block_matrix< DiagMatrix, SymmGroup > &evals)
size_type n_blocks() const
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
void resize_block(charge r, charge c, size_type new_r, size_type new_c, bool pretend=false)
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)
Index< SymmGroup > const & right_basis() const
void remove_block(charge r, charge c)
Index< SymmGroup > const & left_basis() const
std::size_t sum_of_sizes() const
template<class Matrix , class SymmGroup >
block_matrix<Matrix, SymmGroup> identity_matrix ( Index< SymmGroup > const &  size)

Definition at line 473 of file block_matrix_algorithms.h.

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 }
block_matrix< Matrix, SymmGroup > identity_matrix(Index< SymmGroup > const &size)
template<class Matrix , class SymmGroup >
bool is_hermitian ( block_matrix< Matrix, SymmGroup > const &  m)

Definition at line 482 of file block_matrix_algorithms.h.

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 }
bool is_hermitian(block_matrix< Matrix, SymmGroup > const &m)
size_type n_blocks() const
bool has_block(charge r, charge c) const
Index< SymmGroup > const & right_basis() const
block_matrix< typename maquis::traits::transpose_view< Matrix >::type, SymmGroup > transpose(block_matrix< Matrix, SymmGroup > const &m)
Index< SymmGroup > const & left_basis() const
template<class Matrix , class SymmGroup >
void lq ( block_matrix< Matrix, SymmGroup > const &  M,
block_matrix< Matrix, SymmGroup > &  L,
block_matrix< Matrix, SymmGroup > &  Q 
)

Definition at line 405 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
bool reasonable() const
#define parallel_for(constraint,...)
Index< SymmGroup > const & right_basis() const
void lq(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &L, block_matrix< Matrix, SymmGroup > &Q)
Index< SymmGroup > const & left_basis() const
template<class Matrix , class SymmGroup , class A >
block_matrix<Matrix, SymmGroup> op_exp ( Index< SymmGroup > const &  phys,
block_matrix< Matrix, SymmGroup >  M,
A const &  alpha = 1. 
)

Definition at line 556 of file block_matrix_algorithms.h.

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 }
base_t::const_iterator const_iterator
iterator begin()
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
bool has_block(charge r, charge c) const
iterator end()
boost::enable_if< boost::is_complex< typename Matrix::value_type >, Matrix >::type exp_dispatcher(Matrix const &m, typename Matrix::value_type const &alpha)
template<class Matrix , class SymmGroup , class A >
block_matrix<Matrix, SymmGroup> op_exp_hermitian ( Index< SymmGroup > const &  phys,
block_matrix< Matrix, SymmGroup >  M,
A const &  alpha = 1. 
)

Definition at line 524 of file block_matrix_algorithms.h.

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 }
base_t::const_iterator const_iterator
iterator begin()
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
bool has_block(charge r, charge c) const
iterator end()
template<class Matrix1 , class Matrix2 , class SymmGroup >
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 
)

Definition at line 570 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
void match_and_add_block(Matrix const &, charge, charge)
size_t size(charge pc) const
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
Index< SymmGroup > const & right_basis() const
Index< SymmGroup > const & left_basis() const
T fuse(const A &ind, T d)
Fuse indices n[i] into one p = n[i] d^i.
template<class Matrix , class SymmGroup >
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 
)

Definition at line 603 of file block_matrix_algorithms.h.

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 }
void run(std::string const &chkp1, std::string const &chkp2)
Definition: main.cpp:52
std::pair< coord_t, coord_t > get_coords(set_id s, key_t const &key) const
Definition: multi_index.h:223
std::pair< charge, elem_id > coord_t
Definition: multi_index.h:148
const_iterator end() const
Definition: multi_index.h:279
size_t right_size(set_id s, charge const &c) const
Definition: multi_index.h:206
bool has_block(charge r, charge c) const
size_t left_size(set_id s, charge const &c) const
Definition: multi_index.h:201
const_iterator begin() const
Definition: multi_index.h:276
void reserve(charge, charge, std::size_t, std::size_t)
size_t size() const
Definition: multi_index.h:166
void allocate_blocks()
template<class Matrix , class SymmGroup >
void qr ( block_matrix< Matrix, SymmGroup > const &  M,
block_matrix< Matrix, SymmGroup > &  Q,
block_matrix< Matrix, SymmGroup > &  R 
)

Definition at line 383 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
bool reasonable() const
#define parallel_for(constraint,...)
Index< SymmGroup > const & right_basis() const
Index< SymmGroup > const & left_basis() const
void qr(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &Q, block_matrix< Matrix, SymmGroup > &R)
template<class Matrix , class SymmGroup >
block_matrix<Matrix, SymmGroup> sqrt ( block_matrix< Matrix, SymmGroup >  m)

Definition at line 499 of file block_matrix_algorithms.h.

500 {
501  for (std::size_t k = 0; k < m.n_blocks(); ++k)
502  sqrt_inplace(m[k]);
503 
504  return m;
505 }
size_type n_blocks() const
template<class Matrix , class DiagMatrix , class SymmGroup >
void svd ( block_matrix< Matrix, SymmGroup > const &  M,
block_matrix< Matrix, SymmGroup > &  U,
block_matrix< Matrix, SymmGroup > &  V,
block_matrix< DiagMatrix, SymmGroup > &  S 
)

Definition at line 132 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
#define parallel_for(constraint,...)
void svd(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &U, block_matrix< Matrix, SymmGroup > &V, block_matrix< DiagMatrix, SymmGroup > &S)
Index< SymmGroup > const & right_basis() const
Index< SymmGroup > const & left_basis() const
template<class Matrix , class DiagMatrix , class SymmGroup >
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 
)

Definition at line 221 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
void resize_block(charge r, charge c, size_type new_r, size_type new_c, bool pretend=false)
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)
void svd(block_matrix< Matrix, SymmGroup > const &M, block_matrix< Matrix, SymmGroup > &U, block_matrix< Matrix, SymmGroup > &V, block_matrix< DiagMatrix, SymmGroup > &S)
Index< SymmGroup > const & right_basis() const
void remove_block(charge r, charge c)
Index< SymmGroup > const & left_basis() const
std::size_t sum_of_sizes() const
template<class Matrix , class SymmGroup >
block_matrix<Matrix, SymmGroup>::scalar_type trace ( block_matrix< Matrix, SymmGroup > const &  m)

Definition at line 450 of file block_matrix_algorithms.h.

451 {
452  return m.trace();
453 }
scalar_type trace() const
template<class Matrix , class SymmGroup >
block_matrix<typename maquis::traits::transpose_view<Matrix>::type, SymmGroup> transpose ( block_matrix< Matrix, SymmGroup > const &  m)

Definition at line 427 of file block_matrix_algorithms.h.

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 }
size_type n_blocks() const
size_type insert_block(Matrix const &, charge, charge)
Index< SymmGroup > const & right_basis() const
block_matrix< typename maquis::traits::transpose_view< Matrix >::type, SymmGroup > transpose(block_matrix< Matrix, SymmGroup > const &m)
Index< SymmGroup > const & left_basis() const