ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ts_optimize.hpp
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 Bela Bauer <bauerb@phys.ethz.ch>
7  * Sebastian Keller <sebkelle@phys.ethz.ch>
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 TS_OPTIMIZE_H
29 #define TS_OPTIMIZE_H
30 
31 #include "dmrg/optimize/optimize.h"
32 
35 
36 #include <boost/tuple/tuple.hpp>
37 
38 
39 template<class Matrix, class SymmGroup, class Storage>
40 class ts_optimize : public optimizer_base<Matrix, SymmGroup, Storage>
41 {
42 public:
43 
45  using base::mpo;
46  using base::mps;
47  using base::left_;
48  using base::right_;
49  using base::parms;
51  using base::stop_callback;
52 
54  MPO<Matrix, SymmGroup> const & mpo_,
55  BaseParameters & parms_,
56  boost::function<bool ()> stop_callback_,
57  int initial_site_ = 0)
58  : base(mps_, mpo_, parms_, stop_callback_, to_site(mps_.length(), initial_site_))
59  , initial_site((initial_site_ < 0) ? 0 : initial_site_)
60  {
61  locale_shared l; // cache twosite mpo
62  make_ts_cache_mpo(mpo, ts_cache_mpo, mps);
63  }
64 
65  inline int to_site(const int L, const int i) const
66  {
67  if (i < 0) return 0;
68  /// i, or (L-1) - (i - (L-1))
69  return (i < L-1) ? i : 2*L - 2 - i;
70  }
72  {
73  boost::chrono::high_resolution_clock::time_point sweep_now = boost::chrono::high_resolution_clock::now();
74 
76 
77  std::size_t L = mps.length();
78 
79  int _site = 0, site = 0;
80  if (initial_site != -1) {
81  _site = initial_site;
82  site = to_site(L, _site);
83  }
84 
85  if (_site < L-1) {
86  Storage::prefetch(left_[site]);
87  Storage::prefetch(right_[site+2]);
88  } else {
89  Storage::prefetch(left_[site-1]);
90  Storage::prefetch(right_[site+1]);
91  }
92 
93 #ifndef NDEBUG
94  maquis::cout << mps.description() << std::endl;
95 #endif
96  for (; _site < 2*L-2; ++_site) {
97  /* (0,1), (1,2), ... , (L-1,L), (L-1,L), (L-2, L-1), ... , (0,1)
98  | | |
99  site 1 |
100  | left to right | right to left, lr = -1
101  site 2 | */
102 
103  int lr, site1, site2;
104  if (_site < L-1) {
105  site = to_site(L, _site);
106  lr = 1;
107  site1 = site;
108  site2 = site+1;
109  ts_cache_mpo[site1].placement_l = mpo[site1].placement_l;
110  ts_cache_mpo[site1].placement_r = get_right_placement(ts_cache_mpo[site1], mpo[site1].placement_l, mpo[site2].placement_r);
111  } else {
112  site = to_site(L, _site);
113  lr = -1;
114  site1 = site-1;
115  site2 = site;
116  ts_cache_mpo[site1].placement_l = get_left_placement(ts_cache_mpo[site1], mpo[site1].placement_l, mpo[site2].placement_r);
117  ts_cache_mpo[site1].placement_r = mpo[site2].placement_r;
118  }
119 
120  //if (lr == +1) mps.canonize(site1);
121  //else mps.canonize(site2);
122 
123  maquis::cout << std::endl;
124  maquis::cout << "Sweep " << sweep << ", optimizing sites " << site1 << " and " << site2 << std::endl;
125 
126  // MD: some changes needed to re-enable it.
127 // if (parms.template get<bool>("beta_mode")) {
128 // if (sweep == 0 && lr == 1) {
129 // mpo = zero_after(mpo_orig, 0);
130 // if (site == 0)
131 // this->init_left_right(mpo, 0);
132 // } else if (sweep == 0 && lr == -1 && site == L-1) {
133 // mpo = mpo_orig;
134 // }
135 // }
136 
137  if (_site != L-1)
138  {
139  Storage::fetch(left_[site1]);
140  Storage::fetch(right_[site2+1]);
141  }
142 
143  if (lr == +1) {
144  if (site2+2 < right_.size()){
145  Storage::prefetch(right_[site2+2]);
146  }
147  } else {
148  if (site1 > 0){
149  Storage::prefetch(left_[site1-1]);
150  }
151  }
152 
153 
154  boost::chrono::high_resolution_clock::time_point now, then;
155 
156  // Create TwoSite objects
157  TwoSiteTensor<Matrix, SymmGroup> tst(mps[site1], mps[site2]);
158  MPSTensor<Matrix, SymmGroup> twin_mps = tst.make_mps();
159  SiteProblem<Matrix, SymmGroup> sp(left_[site1], right_[site2+1], ts_cache_mpo[site1]);
160 
161  /// Compute orthogonal vectors
162  std::vector<MPSTensor<Matrix, SymmGroup> > ortho_vecs(base::northo);
163  for (int n = 0; n < base::northo; ++n) {
165  ortho_vecs[n] = contraction::site_ortho_boundaries(twin_mps, ts_ortho.make_mps(),
166  base::ortho_left_[n][site1], base::ortho_right_[n][site2+1]);
167  }
168 
169  std::pair<double, MPSTensor<Matrix, SymmGroup> > res;
170 
171  if (d == Both ||
172  (d == LeftOnly && lr == -1) ||
173  (d == RightOnly && lr == +1))
174  {
175  if (parms["eigensolver"] == std::string("IETL")) {
176  BEGIN_TIMING("IETL")
177  res = solve_ietl_lanczos(sp, twin_mps, parms);
178  END_TIMING("IETL")
179  } else if (parms["eigensolver"] == std::string("IETL_JCD")) {
180  BEGIN_TIMING("JCD")
181  res = solve_ietl_jcd(sp, twin_mps, parms, ortho_vecs);
182  END_TIMING("JCD")
183  } else {
184  throw std::runtime_error("I don't know this eigensolver.");
185  }
186 
187  tst << res.second;
188  }
189 
190 #ifndef NDEBUG
191  // Caution: this is an O(L) operation, so it really should be done only in debug mode
192  for (int n = 0; n < base::northo; ++n)
193  maquis::cout << "MPS overlap: " << overlap(mps, base::ortho_mps[n]) << std::endl;
194 #endif
195 
196  maquis::cout << "Energy " << lr << " " << res.first << std::endl;
197  iteration_results_["Energy"] << res.first;
198 
199  double cutoff = this->get_cutoff(sweep);
200  std::size_t Mmax = this->get_Mmax(sweep);
201  truncation_results trunc;
202 
203  if (lr == +1)
204  {
205  // Write back result from optimization
206  boost::tie(mps[site1], mps[site2], trunc) = tst.split_mps_l2r(Mmax, cutoff);
207 
209 
210  //t = mps[site1].normalize_left(DefaultSolver());
211  //mps[site2].multiply_from_left(t);
212  //mps[site2].divide_by_scalar(mps[site2].scalar_norm());
213 
214  t = mps[site2].normalize_left(DefaultSolver());
215  // MD: DEBUGGING OUTPUT
216  maquis::cout << "Propagating t with norm " << t.norm() << std::endl;
217  if (site2 < L-1) mps[site2+1].multiply_from_left(t);
218 
219  if (site1 != L-2)
220  Storage::drop(right_[site2+1]);
221 
222  this->boundary_left_step(mpo, site1); // creating left_[site2]
223 
224  if (site1 != L-2){
225  Storage::evict(mps[site1]);
226  Storage::evict(left_[site1]);
227  }
228  }
229  if (lr == -1){
230  // Write back result from optimization
231  boost::tie(mps[site1], mps[site2], trunc) = tst.split_mps_r2l(Mmax, cutoff);
232 
234 
235  //t = mps[site2].normalize_right(DefaultSolver());
236  //mps[site1].multiply_from_right(t);
237  //mps[site1].divide_by_scalar(mps[site1].scalar_norm());
238 
239  t = mps[site1].normalize_right(DefaultSolver());
240  // MD: DEBUGGING OUTPUT
241  maquis::cout << "Propagating t with norm " << t.norm() << std::endl;
242  if (site1 > 0) mps[site1-1].multiply_from_right(t);
243 
244  if(site1 != 0)
245  Storage::drop(left_[site1]);
246 
247  this->boundary_right_step(mpo, site2); // creating right_[site2]
248 
249  if(site1 != 0){
250  Storage::evict(mps[site2]);
251  Storage::evict(right_[site2+1]);
252  }
253  }
254 
255  iteration_results_["BondDimension"] << trunc.bond_dimension;
256  iteration_results_["TruncatedWeight"] << trunc.truncated_weight;
257  iteration_results_["TruncatedFraction"] << trunc.truncated_fraction;
258  iteration_results_["SmallestEV"] << trunc.smallest_ev;
259 
260 
261  boost::chrono::high_resolution_clock::time_point sweep_then = boost::chrono::high_resolution_clock::now();
262  double elapsed = boost::chrono::duration<double>(sweep_then - sweep_now).count();
263  maquis::cout << "Sweep has been running for " << elapsed << " seconds." << std::endl;
264 
265  if (stop_callback())
266  throw dmrg::time_limit(sweep, _site+1);
267 
268  } // for sites
269  initial_site = -1;
270  } // sweep
271 
272 private:
273  int initial_site;
274  MPO<Matrix, SymmGroup> ts_cache_mpo;
275 };
276 
277 #endif
std::size_t get_Mmax(int sweep) const
Definition: optimize.h:212
BaseParameters & parms
Definition: optimize.h:232
void sweep(int sweep, OptimizeDirection d=Both)
Definition: ts_optimize.hpp:71
std::pair< double, MPSTensor< Matrix, SymmGroup > > solve_ietl_lanczos(SiteProblem< Matrix, SymmGroup > &sp, MPSTensor< Matrix, SymmGroup > const &initial, BaseParameters &params)
MPSTensor< Matrix, SymmGroup > make_mps() const
std::vector< Boundary< typename storage::constrained< Matrix >::type, SymmGroup > > left_
Definition: optimize.h:235
int to_site(const int L, const int i) const
Definition: ts_optimize.hpp:65
Definition: optimize.h:84
static MPSTensor< Matrix, SymmGroup > site_ortho_boundaries(MPSTensor< Matrix, SymmGroup > const &mps, MPSTensor< Matrix, SymmGroup > const &ortho_mps, block_matrix< OtherMatrix, SymmGroup > const &ortho_left, block_matrix< OtherMatrix, SymmGroup > const &ortho_right)
Definition: contractions.h:479
ts_optimize(MPS< Matrix, SymmGroup > &mps_, MPO< Matrix, SymmGroup > const &mpo_, BaseParameters &parms_, boost::function< bool()> stop_callback_, int initial_site_=0)
Definition: ts_optimize.hpp:53
std::vector< std::vector< block_matrix< typename storage::constrained< Matrix >::type, SymmGroup > > > ortho_left_
Definition: optimize.h:239
std::vector< int > get_right_placement(const MPOTensor< Matrix, SymmGroup > &mpo, const std::vector< int > &placement_l, const std::vector< int > &placement_r_old)
Definition: placement.h:85
Definition: mpo.h:36
utility functions for the MPO
results_collector iteration_results_
Definition: optimize.h:227
optimization base class
MPS< Matrix, SymmGroup >::scalar_type overlap(MPS< Matrix, SymmGroup > const &mps1, MPS< Matrix, SymmGroup > const &mps2)
Definition: mps_mpo_ops.h:136
std::size_t locale_shared
declaration of the TwoSiteTensor class
std::vector< std::vector< block_matrix< typename storage::constrained< Matrix >::type, SymmGroup > > > ortho_right_
Definition: optimize.h:239
Definition: mps.h:40
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
OptimizeDirection
Definition: optimize.h:84
std::pair< double, MPSTensor< Matrix, SymmGroup > > solve_ietl_jcd(SiteProblem< Matrix, SymmGroup > &sp, MPSTensor< Matrix, SymmGroup > const &initial, BaseParameters &params, std::vector< MPSTensor< Matrix, SymmGroup > > ortho_vecs=std::vector< MPSTensor< Matrix, SymmGroup > >())
boost::function< bool()> stop_callback
Definition: optimize.h:233
MPO< Matrix, SymmGroup > const & mpo
Definition: optimize.h:230
boost::tuple< MPSTensor< Matrix, SymmGroup >, MPSTensor< Matrix, SymmGroup >, truncation_results > split_mps_l2r(std::size_t Mmax, double cutoff) const
MPS< Matrix, SymmGroup > & mps
Definition: optimize.h:229
double get_cutoff(int sweep) const
Definition: optimize.h:202
unsigned int northo
Definition: optimize.h:238
optimizer_base< Matrix, SymmGroup, Storage > base
Definition: ts_optimize.hpp:44
real_type norm() const
#define BEGIN_TIMING(name)
#define END_TIMING(name)
std::vector< Boundary< typename storage::constrained< Matrix >::type, SymmGroup > > right_
Definition: optimize.h:235
boost::tuple< MPSTensor< Matrix, SymmGroup >, MPSTensor< Matrix, SymmGroup >, truncation_results > split_mps_r2l(std::size_t Mmax, double cutoff) const
void boundary_right_step(MPO< Matrix, SymmGroup > const &mpo, int site)
Definition: optimize.h:144
std::vector< MPS< Matrix, SymmGroup > > ortho_mps
Definition: optimize.h:240
std::vector< int > get_left_placement(const MPOTensor< Matrix, SymmGroup > &mpo, const std::vector< int > &placement_l_old, const std::vector< int > &placement_r)
Definition: placement.h:69
void boundary_left_step(MPO< Matrix, SymmGroup > const &mpo, int site)
Definition: optimize.h:135