ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ts_ops.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  * 2013-2013 by Sebastian Keller <sebkelle@phys.ethz.ch>
7  *
8  *
9  * This software is part of the ALPS Applications, published under the ALPS
10  * Application License; you can use, redistribute it and/or modify it under
11  * the terms of the license, either version 1 or (at your option) any later
12  * version.
13  *
14  * You should have received a copy of the ALPS Application License along with
15  * the ALPS Applications; see the file LICENSE.txt. If not, the license is also
16  * available from http://alps.comp-phys.org/.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  *****************************************************************************/
27 
28 #ifndef MAQUIS_DMRG_TS_OPS_H
29 #define MAQUIS_DMRG_TS_OPS_H
30 
37 
38 template<class MPOMatrix, class MPSMatrix, class SymmGroup>
41  Index<SymmGroup> const & phys_i1,
42  Index<SymmGroup> const & phys_i2,
43  bool global_table)
44 {
46 
47  assert(mpo1.col_dim() == mpo2.row_dim());
48 
49  typedef typename MPOTensor<MPOMatrix, SymmGroup>::index_type index_type;
50  typedef typename MPOTensor<MPOMatrix, SymmGroup>::row_proxy row_proxy;
51  typedef typename MPOTensor<MPOMatrix, SymmGroup>::col_proxy col_proxy;
53  typedef typename OPTable<MPSMatrix, SymmGroup>::op_t op_t;
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;
58 
59 
60  if (global_table) {
61  // Use a separate operator table for every twosite MPO Tensor - too much overhead to globally synchronize
62  // a single table
64  typename MPOTensor<MPOMatrix, SymmGroup>::op_table_ptr op_table = kron_handler.get_operator_table();
65 
66  prempo_t prempo;
67 
68  index_type b1, b2, b3;
69  for (b1=0; b1 < mpo1.row_dim(); ++b1) {
70 
71  op_map out_row;
72  std::set<index_type> non_uniform;
73  op_scale_map uniform_ops;
74 
75  row_proxy row1 = mpo1.row(b1);
76  for (typename row_proxy::const_iterator it1 = row1.begin(); it1 != row1.end(); ++it1) {
77 
78  b2 = it1.index();
79  row_proxy row2 = mpo2.row(b2);
80  for (typename row_proxy::const_iterator it2 = row2.begin(); it2 != row2.end(); ++it2)
81  {
82  b3 = it2.index();
83  assert((mpo1.has(b1, b2) && mpo2.has(b2, b3)));
84  tag_type kron_tag;
85 
86  const_term_descriptor<MPSMatrix, SymmGroup> p1 = mpo1.at(b1,b2), p2 = mpo2.at(b2,b3);
87 
88  // Compute the Kronecker product
89  kron_tag = kron_handler.get_kron_tag(phys_i1, phys_i2, mpo1.tag_number(b1,b2), mpo2.tag_number(b2,b3));
90 
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)
94  {
95  non_uniform.insert(b3);
96  }
97  else {
98  uniform_ops[b3].first = kron_tag;
99  uniform_ops[b3].second = (p1.scale * p2.scale);
100  }
101 
103  tmp_op = kron_handler.get_op(kron_tag);
104  tmp_op *= (p1.scale * p2.scale);
105  out_row[b3] += tmp_op;
106  }
107  }
108 
109  for (b3 = 0; b3 < mpo2.col_dim(); ++b3) {
110  if (non_uniform.count(b3) == 0 && uniform_ops.count(b3) == 0)
111  continue;
112 
113  if (non_uniform.count(b3) > 0) {
114  std::pair<tag_type, value_type> scaled_tag;
115  tag_detail::remove_empty_blocks(out_row[b3]);
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));
118  //tag_type new_tag = kron_handler.get_kronecker_table()->register_op(out_row[b3]);
119  //prempo.push_back(boost::make_tuple(b1, b3, new_tag, 1.0));
120  }
121  else {
122  prempo.push_back(boost::make_tuple(b1, b3, uniform_ops[b3].first, uniform_ops[b3].second));
123  }
124  }
125 
126  /*
127  #ifdef MAQUIS_OPENMP
128  #pragma omp critical
129  #endif
130  for (typename op_map::iterator it = out_row.begin(); it != out_row.end(); ++it) {
131  b3 = it->first;
132  op_t & tmp = it->second;
133  std::pair<tag_type, value_type> scaled_tag = kron_handler.get_kronecker_table()->checked_register(tmp);
134  prempo.push_back(boost::make_tuple(b1, b3, scaled_tag.first, scaled_tag.second));
135  }
136  */
137  }
138 
139 
140 
141  #ifdef MAQUIS_OPENMP
142  #pragma omp critical
143  #endif
144  maquis::cout << "TSMPOTensor: " << mpo1.row_dim() << "x" << mpo2.col_dim() << ", " << prempo.size()
145  << " operators, " << kron_handler.get_kronecker_table()->size() << " tags\n";
146 
147  using boost::tuples::get;
148  MPOTensor<MPSMatrix, SymmGroup> mpo_big_tag(mpo1.row_dim(), mpo2.col_dim(), prempo, kron_handler.get_kronecker_table());
149 
150  return mpo_big_tag;
151 
152  }
153 
154  else {
155  prempo_t prempo;
156 
158 
159  index_type b1, b2, b3;
160  for (b1=0; b1 < mpo1.row_dim(); ++b1) {
161 
162  op_map out_row;
163 
164  row_proxy row1 = mpo1.row(b1);
165  for (typename row_proxy::const_iterator it1 = row1.begin(); it1 != row1.end(); ++it1) {
166 
167  b2 = it1.index();
168  row_proxy row2 = mpo2.row(b2);
169  for (typename row_proxy::const_iterator it2 = row2.begin(); it2 != row2.end(); ++it2)
170  {
171  b3 = it2.index();
172  assert((mpo1.has(b1, b2) && mpo2.has(b2, b3)));
174 
175  const_term_descriptor<MPSMatrix, SymmGroup> p1 = mpo1.at(b1,b2), p2 = mpo2.at(b2,b3);
176 
177  op_kron(phys_i1, phys_i2, p1.op, p2.op, product);
178  product *= (p1.scale * p2.scale);
179  out_row[b3] += product;
180  }
181  }
182 
183  for (typename op_map::iterator it = out_row.begin(); it != out_row.end(); ++it) {
184  b3 = it->first;
185  tag_type new_tag = op_table->register_op(it->second);
186  prempo.push_back(boost::make_tuple(b1, b3, new_tag, 1.0));
187  }
188  }
189 
190  using boost::tuples::get;
191  MPOTensor<MPSMatrix, SymmGroup> mpo_big(mpo1.row_dim(), mpo2.col_dim(), prempo, op_table);
192 
193  return mpo_big;
194  }
195 }
196 
197 template<class MPOMatrix, class MPSMatrix, class SymmGroup>
200 {
201  std::size_t L_ts = mpo_orig.length() - 1;
202  mpo_out.resize(L_ts);
203 
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());
207 
208  parallel_for(/*removed...*/, std::size_t p = 0; p < L_ts; ++p)
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);
211 
212  std::size_t ntags=0;
213  for (int p=0; p<mpo_out.length(); ++p) {
214  ntags += mpo_out[p].get_operator_table()->size();
215  }
216  maquis::cout << "Total number of tags: " << ntags << std::endl;
217 
218 }
219 
220 #endif
index_type row_dim() const
Definition: mpotensor.hpp:179
boost::shared_ptr< OPTable< Matrix, SymmGroup > > get_operator_table()
Definition: op_handler.h:128
tag_detail::tag_type tag_type
Definition: op_handler.h:46
void remove_empty_blocks(block_matrix< Matrix, SymmGroup > &op)
Definition: tag_detail.h:55
op_table_ptr get_operator_table() const
Definition: mpotensor.hpp:173
declaration of block_matrix class
tag_type tag_number(index_type left_index, index_type right_index) const
Definition: mpotensor.hpp:152
row_proxy row(index_type row_i) const
Definition: mpotensor.hpp:139
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: mpo.h:36
include one of the Index class definitions
MPOTensor_detail::const_term_descriptor< Matrix, SymmGroup > at(index_type left_index, index_type right_index) const
Definition: mpotensor.hpp:120
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)
Definition: ts_ops.h:39
std::size_t index_type
Definition: mpotensor.h:52
Definition: mps.h:40
#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)
Definition: ts_ops.h:198
declaration of the MPSTensor class
bool has(index_type left_index, index_type right_index) const
Definition: mpotensor.hpp:95
declaration of MPOTensor object
algorithms for block_matrix (gemm, svd, etc.)
boost::shared_ptr< OPTable< Matrix, SymmGroup > > op_table_ptr
Definition: mpotensor.h:58
boost::numeric::ublas::matrix_column< const CSCMatrix > col_proxy
Definition: mpotensor.h:72
unsigned tag_type
Definition: tag_detail.h:36
index_type col_dim() const
Definition: mpotensor.hpp:185