ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mps_initializers.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  * 2011-2013 by Bela Bauer <bauerb@phys.ethz.ch>
7  * Michele Dolfi <dolfim@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 MPS_INITIALIZER_H
29 #define MPS_INITIALIZER_H
30 
31 #include <fstream>
32 #include <sstream>
33 #include <algorithm>
34 
35 #include <boost/tokenizer.hpp>
36 
41 
42 #include "dmrg/mp_tensors/mps.h"
44 
45 template<class Matrix, class SymmGroup>
46 struct default_mps_init : public mps_initializer<Matrix, SymmGroup>
47 {
49  std::vector<Index<SymmGroup> > const& phys_dims_,
50  typename SymmGroup::charge right_end_,
51  std::vector<int> const& site_type_)
52  : init_bond_dimension(parms["init_bond_dimension"])
53  , phys_dims(phys_dims_)
54  , right_end(right_end_)
55  , site_type(site_type_)
56  { }
57 
59  {
60  init_sectors(mps, this->init_bond_dimension, true);
61  }
62 
63  void init_sectors(MPS<Matrix, SymmGroup> & mps, size_t Mmax, bool fillrand = true, typename Matrix::value_type val = 0)
64  {
65  std::size_t L = mps.length();
66 
67  maquis::cout << "Right end: " << right_end << std::endl;
68 
69  std::vector<Index<SymmGroup> > allowed = allowed_sectors(site_type, phys_dims, right_end, Mmax);
70 
71  parallel_for(/*removed...*/, std::size_t i = 0; i < L; ++i) {
72  mps[i] = MPSTensor<Matrix, SymmGroup>(phys_dims[site_type[i]], allowed[i], allowed[i+1], fillrand, val);
73  mps[i].divide_by_scalar(mps[i].scalar_norm());
74  }
75 
76 #ifndef NDEBUG
77  maquis::cout << "init norm: " << norm(mps) << std::endl;
78  maquis::cout << mps.description() << std::endl;
79 #endif
80  }
81 
82  std::size_t init_bond_dimension;
83  std::vector<Index<SymmGroup> > phys_dims;
84  typename SymmGroup::charge right_end;
85  std::vector<int> site_type;
86 };
87 
88 template<class Matrix, class SymmGroup>
89 struct const_mps_init : public mps_initializer<Matrix, SymmGroup>
90 {
92  std::vector<Index<SymmGroup> > const& phys_dims,
93  typename SymmGroup::charge right_end,
94  std::vector<int> const& site_type)
95  : di(parms, phys_dims, right_end, site_type)
96  { }
97 
99  {
100  di.init_sectors(mps, di.init_bond_dimension, false, 1.);
101  }
102 
104 };
105 
106 template<class Matrix, class SymmGroup>
107 struct thin_mps_init : public mps_initializer<Matrix, SymmGroup>
108 {
110  std::vector<Index<SymmGroup> > const& phys_dims,
111  typename SymmGroup::charge right_end,
112  std::vector<int> const& site_type)
113  : di(parms, phys_dims, right_end, site_type)
114  { }
115 
117  {
118  di.init_sectors(mps, 5, true);
119  mps = compression::l2r_compress(mps, di.init_bond_dimension, 1e-6);
120  }
121 
123 };
124 
125 template<class Matrix, class SymmGroup>
126 struct thin_const_mps_init : public mps_initializer<Matrix, SymmGroup>
127 {
129  std::vector<Index<SymmGroup> > const& phys_dims,
130  typename SymmGroup::charge right_end,
131  std::vector<int> const& site_type)
132  : di(parms, phys_dims, right_end, site_type)
133  { }
134 
136  {
137  di.init_sectors(mps, 5, false, 1.);
138  mps = compression::l2r_compress(mps, di.init_bond_dimension, 1e-6);
139  }
140 
142 };
143 
144 
145 template<class Matrix, class SymmGroup>
146 struct empty_mps_init : public mps_initializer<Matrix, SymmGroup>
147 {
148  empty_mps_init(std::vector<Index<SymmGroup> > const& phys_dims_,
149  std::vector<int> const& site_type_)
150  : phys_dims(phys_dims_)
151  , site_type(site_type_)
152  { }
153 
155  {
156  std::size_t L = mps.length();
157 
158  Index<SymmGroup> triv;
159  triv.insert( std::make_pair(SymmGroup::IdentityCharge, 1) );
160 
161  for (int i = 0; i < L; ++i)
162  mps[i] = MPSTensor<Matrix, SymmGroup>(phys_dims[site_type[i]], triv, triv);
163  }
164 
165 private:
166  std::vector<Index<SymmGroup> > phys_dims;
167  std::vector<int> site_type;
168 };
169 
170 //template<class Matrix>
171 //struct linear_mps_init : public mps_initializer<Matrix, U1>
172 //{
173 //
174 // void operator()(MPS<Matrix, U1> & mps,
175 // std::size_t Mmax,
176 // Index<U1> const & phys,
177 // U1::charge right_end)
178 // {
179 // init_sectors(mps, Mmax, phys, right_end, true);
180 // }
181 //
182 // void init_sectors(MPS<Matrix, U1> & mps,
183 // std::size_t Mmax,
184 // Index<U1> const & phys,
185 // U1::charge right_end,
186 // bool fillrand = true,
187 // typename Matrix::value_type val = 1.)
188 // {
189 // std::size_t L = mps.length();
190 // int delta = 1;
191 //
192 // Index<U1> physc = phys;
193 // physc.sort();
194 // U1::charge cmax = physc.begin()->first;
195 // U1::charge cmin = physc.rbegin()->first;
196 // if (cmin > cmax) std::swap(cmin, cmax);
197 //
198 // U1::charge cmaxL=U1::IdentityCharge, cminL=U1::IdentityCharge;
199 // for (int i = 1; i < L; ++i) {
200 // cmaxL = U1::fuse(cmaxL, cmax);
201 // cminL = U1::fuse(cminL, cmin);
202 // }
203 //
204 // Index<U1> l_triv, r_triv;
205 // l_triv.insert( std::make_pair(U1::IdentityCharge, 1) );
206 // r_triv.insert( std::make_pair(right_end, 1) );
207 //
208 // std::vector<Index<U1> > left_allowed(L+1), right_allowed(L+1), allowed(L+1);
209 // left_allowed[0] = l_triv;
210 // right_allowed[L] = r_triv;
211 //
212 // for (int i = 1; i < L+1; ++i) {
213 // U1::charge cell_end = ((i-1)*right_end) / L + 1;
214 // int num_site_right = L/right_end - (i-1)%(L/right_end) - 1;
215 // U1::charge cmaxi = num_site_right*cmax;
216 // U1::charge cmini = num_site_right*cmin;
217 //
218 // left_allowed[i] = phys * left_allowed[i-1];
219 // Index<U1>::iterator it = left_allowed[i].begin();
220 // while ( it != left_allowed[i].end() )
221 // {
222 // if (U1::fuse(it->first, cmaxi) +delta < cell_end)
223 // it = left_allowed[i].erase(it);
224 // else if (U1::fuse(it->first, cmini) -delta > cell_end)
225 // it = left_allowed[i].erase(it);
226 // else {
227 // it->second = std::min(Mmax, it->second);
228 // ++it;
229 // }
230 // }
231 // }
232 //
233 // for (int i = L-1; i >= 0; --i) {
234 // U1::charge cell_end = (i*right_end) / L;
235 // int num_site_left = i%(L/right_end);
236 // U1::charge cmaxi = num_site_left*(cmax);
237 // U1::charge cmini = num_site_left*(cmin);
238 //
239 // right_allowed[i] = adjoin(phys) * right_allowed[i+1];
240 // Index<U1>::iterator it = right_allowed[i].begin();
241 // while ( it != right_allowed[i].end() )
242 // {
243 // if (U1::fuse(it->first, -cmaxi) -delta > cell_end)
244 // it = right_allowed[i].erase(it);
245 // else if (U1::fuse(it->first, -cmini) +delta < cell_end)
246 // it = right_allowed[i].erase(it);
247 // else {
248 // it->second = std::min(Mmax, it->second);
249 // ++it;
250 // }
251 // }
252 // }
253 //
254 // for (int i = 0; i < L+1; ++i) {
255 // allowed[i] = common_subset(left_allowed[i], right_allowed[i]);
256 // for (Index<U1>::iterator it = allowed[i].begin();
257 // it != allowed[i].end(); ++it)
258 // it->second = tri_min(Mmax,
259 // left_allowed[i].size_of_block(it->first),
260 // right_allowed[i].size_of_block(it->first));
261 // }
262 //
263 // for (int i = 0; i < L; ++i) {
264 // mps[i] = MPSTensor<Matrix, U1>(phys, allowed[i], allowed[i+1], fillrand, val);
265 // mps[i].divide_by_scalar(mps[i].scalar_norm());
266 // }
267 //
268 //#ifndef NDEBUG
269 // maquis::cout << "init norm: " << norm(mps) << std::endl;
270 // maquis::cout << mps.description() << std::endl;
271 //#endif
272 // }
273 //};
274 
275 template<class Matrix, class SymmGroup>
276 class coherent_mps_init : public mps_initializer<Matrix, SymmGroup>
277 {
278 public:
280  std::vector<Index<SymmGroup> > const& phys_dims_,
281  std::vector<int> const& site_type_)
282  : coeff(params["init_coeff"].as<std::vector<double> >())
283  , phys_dims(phys_dims_)
284  , site_type(site_type_)
285  { }
286 
288  {
289  assert(coeff.size() == mps.length());
290  if (phys_dims[0].size() != 1) throw std::runtime_error("coherent_mps_init only for TrivialGroup.");
291 
292  typedef typename SymmGroup::charge charge;
293 
294  using std::exp; using std::sqrt; using std::pow;
295  using boost::math::factorial;
296 
297  size_t L = coeff.size();
298 
299  Index<SymmGroup> trivial_i;
300  trivial_i.insert(std::make_pair(SymmGroup::IdentityCharge, 1));
301 
302  for (int p=0; p<L; ++p) {
303  int s=0;
304  Matrix m(phys_dims[site_type[p]][s].second, 1, 0.);
305  for (int ss=0; ss<phys_dims[site_type[p]][s].second; ++ss) {
306  m(ss, 0) = pow(coeff[p], ss) * sqrt(factorial<double>(ss)) / factorial<double>(ss);
307  }
309  block.insert_block(m, SymmGroup::IdentityCharge, SymmGroup::IdentityCharge);
310 
311  MPSTensor<Matrix, SymmGroup> t(phys_dims[site_type[p]], trivial_i, trivial_i);
312  t.data() = block;
313 
314  swap(mps[p], t);
315  }
316  }
317 private:
318  std::vector<double> coeff;
319  std::vector<Index<SymmGroup> > phys_dims;
320  std::vector<int> site_type;
321 };
322 
323 template<class Matrix, class SymmGroup>
324 class coherent_dm_mps_init : public mps_initializer<Matrix, SymmGroup>
325 {
326 public:
328  std::vector<Index<SymmGroup> > const& phys_dims_,
329  std::vector<int> const& site_type_)
330  : coeff(params["init_coeff"].as<std::vector<double> >())
331  , phys_rho_dims(phys_dims_)
332  , site_type(site_type_)
333  { }
334 
336  {
337  using std::sqrt;
338 
339  assert(coeff.size() == mps.length());
340  if (phys_rho_dims[0].size() != 1) throw std::runtime_error("coherent_dm_mps_init only for TrivialGroup.");
341 
342  std::vector<Index<SymmGroup> > phys_psi_dims(phys_rho_dims.size());
343  for (int type=0; type<phys_rho_dims.size(); ++type)
344  phys_psi_dims[type].insert( std::make_pair( SymmGroup::IdentityCharge, static_cast<size_t>(sqrt(double(phys_rho_dims[type][0].second))) ) );
345 
346  typedef typename SymmGroup::charge charge;
347 
348  using std::exp; using std::sqrt; using std::pow;
349  using boost::math::factorial;
350 
351  size_t L = coeff.size();
352 
353  Index<SymmGroup> trivial_i;
354  trivial_i.insert(std::make_pair(SymmGroup::IdentityCharge, 1));
355 
356  for (int p=0; p<L; ++p) {
357  int s=0;
358  Matrix m(phys_rho_dims[site_type[p]][s].second, 1, 0.);
359  for (int ss1=0; ss1<phys_psi_dims[site_type[p]][s].second; ++ss1)
360  for (int ss2=0; ss2<phys_psi_dims[site_type[p]][s].second; ++ss2) {
361  m(ss1*phys_psi_dims[site_type[p]][s].second+ss2, 0) = pow(coeff[p], ss1) * sqrt(factorial<double>(ss1)) / factorial<double>(ss1);
362  m(ss1*phys_psi_dims[site_type[p]][s].second+ss2, 0) *= pow(coeff[p], ss2) * sqrt(factorial<double>(ss2)) / factorial<double>(ss2);
363  }
365  block.insert_block(m, SymmGroup::IdentityCharge, SymmGroup::IdentityCharge);
366 
367  MPSTensor<Matrix, SymmGroup> t(phys_rho_dims[site_type[p]], trivial_i, trivial_i);
368  t.data() = block;
369 
370  swap(mps[p], t);
371  }
372  }
373 private:
374  std::vector<double> coeff;
375  std::vector<Index<SymmGroup> > phys_rho_dims;
376  std::vector<int> site_type;
377 };
378 
379 template<class Matrix, class SymmGroup>
380 class basis_mps_init : public mps_initializer<Matrix, SymmGroup>
381 {
382 public:
384  std::vector<Index<SymmGroup> > const& phys_dims_,
385  std::vector<int> const& site_type_)
386 
387  : occupation(params["init_basis_state"].as<std::vector<int> >())
388  , phys_dims(phys_dims_)
389  , site_type(site_type_)
390  { }
391 
393  {
394  assert(occupation.size() == mps.length());
395  if (phys_dims[0].size() != 1) throw std::runtime_error("basis_mps_init only for TrivialGroup.");
396  typedef typename SymmGroup::charge charge;
397  charge C = SymmGroup::IdentityCharge;
398 
399  std::vector<boost::tuple<charge, size_t> > state(mps.length());
400  for (int i=0; i<mps.length(); ++i)
401  state[i] = boost::make_tuple(C, occupation[i]);
402  mps = state_mps<Matrix>(state, phys_dims, site_type);
403  }
404 
405 private:
406  std::vector<int> occupation;
407  std::vector<Index<SymmGroup> > phys_dims;
408  std::vector<int> site_type;
409 };
410 
411 template<class Matrix, class SymmGroup>
412 class basis_dm_mps_init : public mps_initializer<Matrix, SymmGroup>
413 {
414 public:
416  std::vector<Index<SymmGroup> > const& phys_dims_,
417  std::vector<int> const& site_type_)
418  : occupation(params["init_basis_state"].as<std::vector<int> >())
419  , phys_rho_dims(phys_dims_)
420  , site_type(site_type_)
421  { }
422 
424  {
425  assert(occupation.size() == mps.length());
426  if (phys_rho_dims.size() != 1) throw std::runtime_error("basis_dm_mps_init only for unique site basis.");
427  if (phys_rho_dims[0].size() != 1) throw std::runtime_error("basis_dm_mps_init only for TrivialGroup.");
428  typedef typename SymmGroup::charge charge;
429  charge C = SymmGroup::IdentityCharge;
430 
431  using std::sqrt;
432  size_t N = sqrt(double(phys_rho_dims[0][0].second));
433 
434  std::vector<boost::tuple<charge, size_t> > state(mps.length());
435  for (int i=0; i<mps.length(); ++i)
436  state[i] = boost::make_tuple(C, occupation[i] + occupation[i]*N);
437  mps = state_mps<Matrix>(state, phys_rho_dims, site_type);
438  }
439 
440 private:
441  std::vector<int> occupation;
442  std::vector<Index<SymmGroup> > phys_rho_dims;
443  std::vector<int> site_type;
444 };
445 
446 template<class Matrix, class SymmGroup>
447 class basis_mps_init_generic : public mps_initializer<Matrix, SymmGroup>
448 {
449 public:
450  typedef std::vector<boost::tuple<typename SymmGroup::charge, size_t> > state_type;
452  std::vector<Index<SymmGroup> > const& phys_dims_,
453  typename SymmGroup::charge right_end_,
454  std::vector<int> const& site_type_)
455  : basis_index(params["init_basis_state"].as<std::vector<int> >())
456  , phys_dims(phys_dims_)
457  , right_end(right_end_)
458  , site_type(site_type_)
459  { }
460 
462  std::vector<Index<SymmGroup> > const& phys_dims_,
463  typename SymmGroup::charge right_end_,
464  std::vector<int> const& site_type_)
465  : phys_dims(phys_dims_)
466  , right_end(right_end_)
467  , site_type(site_type_)
468  , state(state_)
469  { }
470 
472  {
473  if (state.size() == 0) {
474  assert(basis_index.size() == mps.length());
475  state.resize(mps.length());
476  maquis::cout << "state: ";
477  for (int i=0; i<mps.length(); ++i) {
478  state[i] = phys_dims[site_type[i]].element(basis_index[i]);
479  maquis::cout << boost::get<0>(state[i]) << ":" << boost::get<1>(state[i])<< " ";
480  }
481  maquis::cout << "\n";
482  }
483 
484  mps = state_mps<Matrix>(state, phys_dims, site_type);
485  if (mps[mps.length()-1].col_dim()[0].first != right_end)
486  throw std::runtime_error("Initial state does not satisfy total quantum numbers.");
487  }
488 
489 private:
490  std::vector<int> basis_index;
491  std::vector<Index<SymmGroup> > phys_dims;
492  typename SymmGroup::charge right_end;
493  std::vector<int> site_type;
494  state_type state;
495 };
496 
497 
498 #endif
void operator()(MPS< Matrix, SymmGroup > &mps)
SymmGroup::charge right_end
empty_mps_init(std::vector< Index< SymmGroup > > const &phys_dims_, std::vector< int > const &site_type_)
functions to compress the MPS
void operator()(MPS< Matrix, SymmGroup > &mps)
initialize all allowed quantum number sectors in the MPS
default_mps_init< Matrix, SymmGroup > di
void operator()(MPS< Matrix, SymmGroup > &mps)
basis_mps_init_generic(BaseParameters &params, std::vector< Index< SymmGroup > > const &phys_dims_, typename SymmGroup::charge right_end_, std::vector< int > const &site_type_)
declaration of the MPS class (vector of MPSTensor)
default_mps_init(BaseParameters &parms, std::vector< Index< SymmGroup > > const &phys_dims_, typename SymmGroup::charge right_end_, std::vector< int > const &site_type_)
void swap(MPSTensor< Matrix, SymmGroup > &x, MPSTensor< Matrix, SymmGroup > &y)
convert a basis state into MPS
void init_sectors(MPS< Matrix, SymmGroup > &mps, size_t Mmax, bool fillrand=true, typename Matrix::value_type val=0)
size_type insert_block(Matrix const &, charge, charge)
void operator()(MPS< Matrix, SymmGroup > &mps)
basis_mps_init(BaseParameters &params, std::vector< Index< SymmGroup > > const &phys_dims_, std::vector< int > const &site_type_)
void operator()(MPS< Matrix, SymmGroup > &mps)
basis_mps_init_generic(state_type const &state_, std::vector< Index< SymmGroup > > const &phys_dims_, typename SymmGroup::charge right_end_, std::vector< int > const &site_type_)
block_matrix< Matrix, SymmGroup > sqrt(block_matrix< Matrix, SymmGroup > m)
Index< SymmGroup > const & col_dim(size_t i) const
Definition: mps.h:61
std::vector< boost::tuple< typename SymmGroup::charge, size_t > > state_type
std::vector< Index< SymmGroup > > phys_dims
void operator()(MPS< Matrix, SymmGroup > &mps)
default_mps_init< Matrix, SymmGroup > di
std::size_t init_bond_dimension
std::vector< Index< SymmGroup > > allowed_sectors(std::vector< int > const &site_type, std::vector< Index< SymmGroup > > const &phys_dims, typename SymmGroup::charge right_end, std::size_t Mmax)
Definition: mps_sectors.h:42
Definition: mps.h:40
#define parallel_for(constraint,...)
coherent_mps_init(BaseParameters &params, std::vector< Index< SymmGroup > > const &phys_dims_, std::vector< int > const &site_type_)
functions to operate on MPS and MPO (compute expectation values, etc.)
MPS< Matrix, SymmGroup >::scalar_type norm(MPS< Matrix, SymmGroup > const &mps)
Definition: mps_mpo_ops.h:120
size_t length() const
Definition: mps.h:58
basis_dm_mps_init(BaseParameters &params, std::vector< Index< SymmGroup > > const &phys_dims_, std::vector< int > const &site_type_)
void operator()(MPS< Matrix, SymmGroup > &mps)
std::string description() const
Definition: mps.hpp:35
void operator()(MPS< Matrix, SymmGroup > &mps)
thin_const_mps_init(BaseParameters &parms, std::vector< Index< SymmGroup > > const &phys_dims, typename SymmGroup::charge right_end, std::vector< int > const &site_type)
coherent_dm_mps_init(BaseParameters &params, std::vector< Index< SymmGroup > > const &phys_dims_, std::vector< int > const &site_type_)
std::size_t insert(std::pair< charge, std::size_t > const &x)
const_mps_init(BaseParameters &parms, std::vector< Index< SymmGroup > > const &phys_dims, typename SymmGroup::charge right_end, std::vector< int > const &site_type)
void operator()(MPS< Matrix, SymmGroup > &mps)
block_matrix< Matrix, SymmGroup > & data()
Definition: mpstensor.hpp:423
std::vector< int > site_type
static MPS< Matrix, SymmGroup > l2r_compress(MPS< Matrix, SymmGroup > mps, std::size_t Mmax, double cutoff, bool verbose=false)
Definition: compression.h:101
default_mps_init< Matrix, SymmGroup > di
void operator()(MPS< Matrix, SymmGroup > &mps)
thin_mps_init(BaseParameters &parms, std::vector< Index< SymmGroup > > const &phys_dims, typename SymmGroup::charge right_end, std::vector< int > const &site_type)