28 #ifndef MAQUIS_DMRG_TS_OPS_H
29 #define MAQUIS_DMRG_TS_OPS_H
38 template<
class MPOMatrix,
class MPSMatrix,
class SymmGroup>
54 typedef typename MPSMatrix::value_type value_type;
55 typedef std::map<index_type, op_t> op_map;
56 typedef std::map<index_type, std::pair<tag_type, value_type> > op_scale_map;
57 typedef std::vector<boost::tuple<index_type, index_type, tag_type, value_type> > prempo_t;
68 index_type b1, b2, b3;
69 for (b1=0; b1 < mpo1.
row_dim(); ++b1) {
72 std::set<index_type> non_uniform;
73 op_scale_map uniform_ops;
75 row_proxy row1 = mpo1.
row(b1);
76 for (
typename row_proxy::const_iterator it1 = row1.begin(); it1 != row1.end(); ++it1) {
79 row_proxy row2 = mpo2.
row(b2);
80 for (
typename row_proxy::const_iterator it2 = row2.begin(); it2 != row2.end(); ++it2)
83 assert((mpo1.
has(b1, b2) && mpo2.
has(b2, b3)));
86 const_term_descriptor<MPSMatrix, SymmGroup> p1 = mpo1.
at(b1,b2), p2 = mpo2.
at(b2,b3);
89 kron_tag = kron_handler.get_kron_tag(phys_i1, phys_i2, mpo1.
tag_number(b1,b2), mpo2.
tag_number(b2,b3));
91 if (!kron_handler.is_uniform(mpo1.
tag_number(b1,b2)) ||
92 !kron_handler.is_uniform(mpo2.
tag_number(b2,b3)) ||
93 uniform_ops.count(b3) > 0)
95 non_uniform.insert(b3);
98 uniform_ops[b3].first = kron_tag;
99 uniform_ops[b3].second = (p1.scale * p2.scale);
103 tmp_op = kron_handler.get_op(kron_tag);
104 tmp_op *= (p1.scale * p2.scale);
105 out_row[b3] += tmp_op;
109 for (b3 = 0; b3 < mpo2.
col_dim(); ++b3) {
110 if (non_uniform.count(b3) == 0 && uniform_ops.count(b3) == 0)
113 if (non_uniform.count(b3) > 0) {
114 std::pair<tag_type, value_type> scaled_tag;
116 scaled_tag = kron_handler.get_kronecker_table()->checked_register(out_row[b3]);
117 prempo.push_back(boost::make_tuple(b1, b3, scaled_tag.first, scaled_tag.second));
122 prempo.push_back(boost::make_tuple(b1, b3, uniform_ops[b3].first, uniform_ops[b3].second));
144 maquis::cout <<
"TSMPOTensor: " << mpo1.
row_dim() <<
"x" << mpo2.
col_dim() <<
", " << prempo.size()
145 <<
" operators, " << kron_handler.get_kronecker_table()->size() <<
" tags\n";
147 using boost::tuples::get;
159 index_type b1, b2, b3;
160 for (b1=0; b1 < mpo1.
row_dim(); ++b1) {
164 row_proxy row1 = mpo1.
row(b1);
165 for (
typename row_proxy::const_iterator it1 = row1.begin(); it1 != row1.end(); ++it1) {
168 row_proxy row2 = mpo2.
row(b2);
169 for (
typename row_proxy::const_iterator it2 = row2.begin(); it2 != row2.end(); ++it2)
172 assert((mpo1.
has(b1, b2) && mpo2.
has(b2, b3)));
175 const_term_descriptor<MPSMatrix, SymmGroup> p1 = mpo1.
at(b1,b2), p2 = mpo2.
at(b2,b3);
177 op_kron(phys_i1, phys_i2, p1.op, p2.op, product);
178 product *= (p1.scale * p2.scale);
179 out_row[b3] += product;
183 for (
typename op_map::iterator it = out_row.begin(); it != out_row.end(); ++it) {
185 tag_type new_tag = op_table->register_op(it->second);
186 prempo.push_back(boost::make_tuple(b1, b3, new_tag, 1.0));
190 using boost::tuples::get;
197 template<
class MPOMatrix,
class MPSMatrix,
class SymmGroup>
201 std::size_t L_ts = mpo_orig.length() - 1;
202 mpo_out.resize(L_ts);
204 bool global_table =
true;
205 for (
int p=0; p<L_ts && global_table; ++p)
206 global_table = (mpo_orig[p].get_operator_table() == mpo_orig[0].get_operator_table());
209 mpo_out[p] = make_twosite_mpo<MPOMatrix, MPSMatrix>(mpo_orig[p], mpo_orig[p+1],
210 mps[p].site_dim(), mps[p+1].site_dim(), global_table);
213 for (
int p=0; p<mpo_out.length(); ++p) {
214 ntags += mpo_out[p].get_operator_table()->size();
216 maquis::cout <<
"Total number of tags: " << ntags << std::endl;
index_type row_dim() const
boost::shared_ptr< OPTable< Matrix, SymmGroup > > get_operator_table()
tag_detail::tag_type tag_type
void remove_empty_blocks(block_matrix< Matrix, SymmGroup > &op)
op_table_ptr get_operator_table() const
declaration of block_matrix class
tag_type tag_number(index_type left_index, index_type right_index) const
row_proxy row(index_type row_i) const
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)
include one of the Index class definitions
MPOTensor_detail::const_term_descriptor< Matrix, SymmGroup > at(index_type left_index, index_type right_index) const
MPOTensor< MPSMatrix, SymmGroup > make_twosite_mpo(MPOTensor< MPOMatrix, SymmGroup > const &mpo1, MPOTensor< MPOMatrix, SymmGroup > const &mpo2, Index< SymmGroup > const &phys_i1, Index< SymmGroup > const &phys_i2, bool global_table)
#define parallel_for(constraint,...)
void make_ts_cache_mpo(MPO< MPOMatrix, SymmGroup > const &mpo_orig, MPO< MPSMatrix, SymmGroup > &mpo_out, MPS< MPSMatrix, SymmGroup > const &mps)
declaration of the MPSTensor class
bool has(index_type left_index, index_type right_index) const
declaration of MPOTensor object
algorithms for block_matrix (gemm, svd, etc.)
boost::shared_ptr< OPTable< Matrix, SymmGroup > > op_table_ptr
boost::numeric::ublas::matrix_column< const CSCMatrix > col_proxy
index_type col_dim() const