ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mps_sectors.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_SECTORS_H
29 #define MPS_SECTORS_H
30 
31 
33 
34 template<class T>
35 T tri_min(T a, T b, T c)
36 {
37  return std::min(std::min(a, b),
38  std::min(a, c));
39 }
40 
41 template <class SymmGroup>
42 inline std::vector<Index<SymmGroup> > allowed_sectors(std::vector<int> const& site_type,
43  std::vector<Index<SymmGroup> > const& phys_dims,
44  typename SymmGroup::charge right_end,
45  std::size_t Mmax)
46 {
47  bool finitegroup = SymmGroup::finite;
48 
49  std::size_t L = site_type.size();
50 
51  typedef typename SymmGroup::subcharge subcharge;
52 
53  std::vector<typename SymmGroup::charge> maximum_charges(phys_dims.size()), minimum_charges(phys_dims.size());
54  for (int type=0; type<phys_dims.size(); ++type) {
55  Index<SymmGroup> physc = phys_dims[type];
56  physc.sort();
57  maximum_charges[type] = physc.begin()->first;
58  minimum_charges[type] = physc.rbegin()->first;
59  if (minimum_charges[type] > maximum_charges[type]) std::swap(maximum_charges[type], minimum_charges[type]);
60  }
61 
62  typename SymmGroup::charge maximum_total_charge=SymmGroup::IdentityCharge, minimum_total_charge=SymmGroup::IdentityCharge;
63  for (int i = 1; i < L; ++i) {
64  maximum_total_charge = SymmGroup::fuse(maximum_total_charge, maximum_charges[site_type[i-1]]);
65  minimum_total_charge = SymmGroup::fuse(minimum_total_charge, minimum_charges[site_type[i-1]]);
66  }
67 
68  Index<SymmGroup> l_triv, r_triv;
69  l_triv.insert( std::make_pair(SymmGroup::IdentityCharge, 1) );
70  r_triv.insert( std::make_pair(right_end, 1) );
71 
72  std::vector<Index<SymmGroup> > left_allowed(L+1), right_allowed(L+1), allowed(L+1);
73  left_allowed[0] = l_triv;
74  right_allowed[L] = r_triv;
75 
76  typename SymmGroup::charge cmaxi=maximum_total_charge, cmini=minimum_total_charge;
77  for (int i = 1; i < L+1; ++i) {
78  left_allowed[i] = phys_dims[site_type[i-1]] * left_allowed[i-1];
79  typename Index<SymmGroup>::iterator it = left_allowed[i].begin();
80  while ( it != left_allowed[i].end() )
81  {
82  if (!finitegroup && SymmGroup::fuse(it->first, cmaxi) < right_end)
83  it = left_allowed[i].erase(it);
84  else if (!finitegroup && SymmGroup::fuse(it->first, cmini) > right_end)
85  it = left_allowed[i].erase(it);
86  else {
87  it->second = std::min(Mmax, it->second);
88  ++it;
89  }
90  }
91  cmaxi = SymmGroup::fuse(cmaxi, -maximum_charges[site_type[i-1]]);
92  cmini = SymmGroup::fuse(cmini, -minimum_charges[site_type[i-1]]);
93  }
94 
95  cmaxi=maximum_total_charge; cmini=minimum_total_charge;
96  for (int i = L-1; i >= 0; --i) {
97  right_allowed[i] = adjoin(phys_dims[site_type[i]]) * right_allowed[i+1];
98 
99  typename Index<SymmGroup>::iterator it = right_allowed[i].begin();
100  while ( it != right_allowed[i].end() )
101  {
102  if (!finitegroup && SymmGroup::fuse(it->first, -cmaxi) > SymmGroup::IdentityCharge)
103  it = right_allowed[i].erase(it);
104  else if (!finitegroup && SymmGroup::fuse(it->first, -cmini) < SymmGroup::IdentityCharge)
105  it = right_allowed[i].erase(it);
106  else {
107  it->second = std::min(Mmax, it->second);
108  ++it;
109  }
110  }
111  cmaxi = SymmGroup::fuse(cmaxi, -maximum_charges[site_type[i]]);
112  cmini = SymmGroup::fuse(cmini, -minimum_charges[site_type[i]]);
113 
114  }
115 
116  for (int i = 0; i < L+1; ++i) {
117  allowed[i] = common_subset(left_allowed[i], right_allowed[i]);
118  for (typename Index<SymmGroup>::iterator it = allowed[i].begin();
119  it != allowed[i].end(); ++it)
120  it->second = tri_min(Mmax,
121  left_allowed[i].size_of_block(it->first),
122  right_allowed[i].size_of_block(it->first));
123  }
124 
125  return allowed;
126 }
127 
128 #endif
void sort()
T tri_min(T a, T b, T c)
Definition: mps_sectors.h:35
iterator begin()
void swap(MPSTensor< Matrix, SymmGroup > &x, MPSTensor< Matrix, SymmGroup > &y)
include one of the Index class definitions
block_matrix< Matrix, SymmGroup > adjoin(block_matrix< Matrix, SymmGroup > const &m)
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
reverse_iterator rbegin()
iterator erase(iterator p)
std::size_t insert(std::pair< charge, std::size_t > const &x)
Index< SymmGroup > common_subset(Index< SymmGroup > &a, Index< SymmGroup > &b)
base_t::iterator iterator
T fuse(const A &ind, T d)
Fuse indices n[i] into one p = n[i] d^i.