32 #include <alps/type_traits/is_complex.hpp>
34 #include <boost/serialization/serialization.hpp>
35 #include <boost/ptr_container/serialize_ptr_vector.hpp>
37 template<
class Matrix,
class SymmGroup>
42 template<
class Matrix,
class SymmGroup>
48 assert(rows_.size() == cols_.size());
49 for (
size_type k = 0; k < rows_.size(); ++k)
50 data_.push_back(
new Matrix(rows_[k].second, cols_[k].second));
53 template<
class Matrix,
class SymmGroup>
55 : rows_(rhs.left_basis())
56 , cols_(rhs.right_basis())
60 template<
class Matrix,
class SymmGroup>
61 template <
class OtherMatrix>
63 : rows_(rhs.left_basis())
64 , cols_(rhs.right_basis())
68 data_.push_back(
new Matrix(rhs[k]));
71 template<
class Matrix,
class SymmGroup>
78 template<
class Matrix,
class SymmGroup>
79 template<
class OtherMatrix>
84 data_.resize(rhs.data_.size());
85 for(
int k = 0; k < data_.size(); k++){
87 data_[k] = rhs.data_[k];
101 template<
class Matrix,
class SymmGroup>
106 charge rhs_rc = rhs.rows_[k].first;
107 charge rhs_cc = rhs.cols_[k].first;
108 if (this->has_block(rhs_rc, rhs_cc))
109 (*
this)(rhs_rc, rhs_cc) += rhs.data_[k];
111 this->insert_block(rhs.data_[k], rhs_rc, rhs_cc);
116 template<
class Matrix,
class SymmGroup>
121 charge rhs_rc = rhs.rows_[k].first;
122 charge rhs_cc = rhs.cols_[k].first;
123 if (this->has_block(rhs_rc, rhs_cc))
124 (*
this)(rhs_rc, rhs_cc) -= rhs.data_[k];
126 this->insert_block(-1*rhs.data_[k], rhs_rc, rhs_cc);
131 template<
class Matrix,
class SymmGroup>
134 assert( !has_block(c1, c2) );
136 std::pair<charge, size_type>
137 p1 = std::make_pair(c1,
num_rows(mtx)),
138 p2 = std::make_pair(c2,
num_cols(mtx));
141 cols_.insert(i1, p2);
142 Matrix* block =
new Matrix(mtx);
143 data_.insert(data_.begin() + i1, block);
151 template<
class Matrix,
class SymmGroup>
154 assert( !has_block(c1, c2) );
156 std::pair<charge, size_type>
157 p1 = std::make_pair(c1,
num_rows(*mtx)),
158 p2 = std::make_pair(c2,
num_cols(*mtx));
161 cols_.insert(i1, p2);
162 data_.insert(data_.begin() + i1, mtx);
167 template<
class Matrix,
class SymmGroup>
170 template<
class Matrix,
class SymmGroup>
173 template<
class Matrix,
class SymmGroup>
176 template<
class Matrix,
class SymmGroup>
179 std::ostringstream oss;
180 oss << rows_ << cols_;
184 template<
class Matrix,
class SymmGroup>
191 template<
class Matrix,
class SymmGroup>
194 template<
class Matrix,
class SymmGroup>
197 template<
class Matrix,
class SymmGroup>
200 std::size_t p1 = rows_.position(r);
201 std::size_t p2 = cols_.position(c);
203 if (p1 == p2 && p1 != rows_.size())
return p1;
204 else return n_blocks();
207 template<
class Matrix,
class SymmGroup>
210 std::size_t p1 = rows_.position(r);
211 if (p1 == rows_.size())
return false;
212 std::size_t p2 = cols_.position(c);
213 if (p2 == cols_.size())
return false;
217 template<
class Matrix,
class SymmGroup>
219 std::pair<charge, size_type>
const & c)
const
221 return has_block(r.first, c.first);
224 template<
class Matrix,
class SymmGroup>
226 std::pair<charge, size_type>
const & c)
228 assert( rows_.position(r.first) == cols_.position(c.first) );
229 return data_[rows_.position(r.first)](r.second, c.second);
232 template<
class Matrix,
class SymmGroup>
234 std::pair<charge, size_type>
const & c)
const
236 assert( rows_.position(r.first) == cols_.position(c.first) );
237 return data_[rows_.position(r.first)](r.second, c.second);
255 template<
class Matrix,
class SymmGroup>
263 template<
class Matrix,
class SymmGroup>
272 template<
class Matrix,
class SymmGroup>
275 std::vector<scalar_type> vt; vt.reserve(data_.size());
276 std::transform(data_.begin(), data_.end(), back_inserter(vt), utils::functor_trace());
280 template<
class Matrix,
class SymmGroup>
283 std::vector<real_type> vt; vt.reserve(data_.size());
284 semi_parallel_for(, std::size_t k = 0; k < n_blocks(); ++k) vt.push_back(norm_square(data_[k]));
288 template<
class Matrix,
class SymmGroup>
291 std::for_each(data_.begin(), data_.end(), utils::functor_transpose_inplace());
295 template<
class Matrix,
class SymmGroup>
298 std::for_each(data_.begin(), data_.end(), utils::functor_conj_inplace());
301 template<
class Matrix,
class SymmGroup>
304 std::for_each(data_.begin(), data_.end(), utils::functor_adjoint_inplace());
310 template<
class Matrix,
class Generator>
315 template<
class Matrix,
class SymmGroup>
316 template<
class Generator>
322 template<
class Matrix,
class SymmGroup>
330 template<
class Matrix,
class SymmGroup>
331 std::ostream& operator<<(std::ostream& os, block_matrix<Matrix, SymmGroup>
const & m)
333 os <<
"Left HS: " << m.left_basis() << std::endl;
334 os <<
"Right HS: " << m.right_basis() << std::endl;
335 for (std::size_t k = 0; k < m.n_blocks(); ++k)
336 os <<
"Block (" << m.left_basis()[k].first <<
"," << m.right_basis()[k].first <<
"):\n" << m[k] << std::endl;
341 template<
class Matrix,
class SymmGroup>
345 if (this->has_block(c1, c2))
349 (*this)(c1, c2) += mtx;
354 (*this)(c1, c2) += mtx;
356 std::size_t maxrows = std::max(
num_rows(mtx),
358 std::size_t maxcols = std::max(
num_cols(mtx),
363 resize_block(c1, c2, maxrows, maxcols);
364 resize(cpy, maxrows, maxcols);
366 (*this)(c1, c2) += cpy;
369 insert_block(mtx, c1, c2);
372 template<
class Matrix,
class SymmGroup>
378 resize((*
this)(r,c), new_r, new_c);
379 rows_[rows_.position(r)].second = new_r;
380 cols_[cols_.position(c)].second = new_c;
383 template<
class Matrix,
class SymmGroup>
386 assert( has_block(r, c) );
387 assert( rows_.position(r) == cols_.position(c) );
389 std::size_t which = rows_.position(r);
391 rows_.erase(rows_.begin() + which);
392 cols_.erase(cols_.begin() + which);
393 data_.erase(data_.begin() + which);
395 template<
class Matrix,
class SymmGroup>
398 assert( which < data_.size() );
400 rows_.erase(rows_.begin() + which);
401 cols_.erase(cols_.begin() + which);
402 data_.erase(data_.begin() + which);
405 template<
class Matrix,
class SymmGroup>
406 template<
class Archive>
409 ar[
"rows_"] >> rows_;
410 ar[
"cols_"] >> cols_;
413 if (alps::is_complex<typename Matrix::value_type>() && !ar.is_complex(
"data_"))
416 std::vector<LoadMatrix> tmp;
418 for(
typename std::vector<LoadMatrix>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
419 data_.push_back(
new Matrix(maquis::bindings::matrix_cast<Matrix>(*it)));
421 std::vector<Matrix> tmp;
424 for(
typename std::vector<Matrix>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
425 data_.push_back(
new Matrix(*it));
429 template<
class Matrix,
class SymmGroup>
430 template<
class Archive>
433 ar[
"rows_"] << rows_;
434 ar[
"cols_"] << cols_;
436 std::vector<Matrix> tmp(data_.begin(), data_.end());
440 template<
class Matrix,
class SymmGroup>
441 template <
class Archive>
444 ar & rows_ & cols_ & data_;
447 template<
class Matrix,
class SymmGroup>
449 std::size_t r, std::size_t c)
451 if (this->has_block(c1, c2))
453 std::size_t maxrows = std::max(rows_[rows_.position(c1)].second, r);
454 std::size_t maxcols = std::max(cols_[cols_.position(c2)].second, c);
456 rows_[rows_.position(c1)].second = maxrows;
457 cols_[cols_.position(c2)].second = maxcols;
459 std::pair<charge, size_type>
460 p1 = std::make_pair(c1, r),
461 p2 = std::make_pair(c2, c);
463 assert(rows_.size() == cols_.size());
464 assert(rows_.size() == data_.size());
467 cols_.insert(i1, p2);
468 Matrix* block =
new Matrix(1,1);
469 data_.insert(data_.begin() + i1, block);
471 assert( this->has_block(c1,c2) );
474 template<
class Matrix,
class SymmGroup>
476 std::size_t ri, std::size_t ci)
477 { reserve(c1, c2, ri+1, ci+1); }
480 template<
class Matrix,
class SymmGroup>
483 for (std::size_t k = 0; k < n_blocks(); ++k)
484 resize(data_[k], rows_[k].second, cols_[k].second);
487 template<
class Matrix,
class SymmGroup>
490 for (
size_t k=0; k<n_blocks(); ++k)
491 if (
num_rows((*
this)[k]) != rows_[k].second ||
num_cols((*
this)[k]) != cols_[k].second)
496 template<
class Matrix,
class SymmGroup>
500 for (
size_t k = 0; k < n_blocks(); ++k)
void generate_impl(Matrix &m, Generator g)
size_type n_blocks() const
std::size_t num_elements() const
void match_and_add_block(Matrix const &, charge, charge)
value_type & operator()(std::pair< charge, size_type > const &r, std::pair< charge, size_type > const &c)
void serialize(Archive &ar, const unsigned int version)
void swap(MPSTensor< Matrix, SymmGroup > &x, MPSTensor< Matrix, SymmGroup > &y)
declaration of block_matrix class
size_type insert_block(Matrix const &, charge, charge)
std::string description() const
void shift_basis(charge diff)
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
scalar_type trace() const
#define semi_parallel_for(constraint,...)
Matrix & operator[](size_type c)
void resize_block(charge r, charge c, size_type new_r, size_type new_c, bool pretend=false)
maquis::traits::scalar_type< Matrix >::type scalar_type
bool has_block(charge r, charge c) const
std::size_t num_cols(maquis::dmrg::one_matrix< T > const &m)
block_matrix const & operator/=(const scalar_type &v)
Index< SymmGroup > const & right_basis() const
void generate(Generator g)
void remove_block(charge r, charge c)
block_matrix & operator+=(block_matrix const &rhs)
void reserve(charge, charge, std::size_t, std::size_t)
maquis::traits::real_type< Matrix >::type real_type
void generate(block_matrix< Matrix, SymmGroup > &m, Generator &g)
void save(Archive &ar) const
size_type find_block(charge r, charge c) const
block_matrix & operator-=(block_matrix const &rhs)
void reserve_pos(charge, charge, std::size_t, std::size_t)
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
Index< SymmGroup > const & left_basis() const
block_matrix const & operator*=(const scalar_type &v)
block_matrix & operator=(block_matrix rhs)
Matrix::size_type size_type