ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
basis_sector_iterators.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 Michele Dolfi <dolfim@phys.ethz.ch>
7  *
8  * This software is part of the ALPS Applications, published under the ALPS
9  * Application License; you can use, redistribute it and/or modify it under
10  * the terms of the license, either version 1 or (at your option) any later
11  * version.
12  *
13  * You should have received a copy of the ALPS Application License along with
14  * the ALPS Applications; see the file LICENSE.txt. If not, the license is also
15  * available from http://alps.comp-phys.org/.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  *
25  *****************************************************************************/
26 
27 #ifndef MAQUIS_DMRG_BASIS_SECTOR_ITERATOR_H
28 #define MAQUIS_DMRG_BASIS_SECTOR_ITERATOR_H
29 
31 
32 #include <boost/operators.hpp>
33 #include <boost/tuple/tuple.hpp>
34 #include <boost/tuple/tuple_comparison.hpp>
35 
36 
37 template <class SymmGroup>
39 : public boost::forward_iterator_helper<
40  basis_sector_iterator_<SymmGroup>
41  , std::vector<boost::tuple<typename SymmGroup::charge, std::size_t> >
42  , std::ptrdiff_t
43  , std::vector<boost::tuple<typename SymmGroup::charge, std::size_t> > *
44  , std::vector<boost::tuple<typename SymmGroup::charge, std::size_t> > &
45  >
46 
47 {
48  typedef typename SymmGroup::charge charge;
49  typedef std::size_t size_t;
50  typedef boost::tuple<charge, size_t> local_state;
51  typedef typename std::vector<local_state>::const_iterator states_iterator;
52 
53  typedef const charge& (*get0_fn_t)(const boost::tuples::cons<charge, boost::tuples::cons<size_t, boost::tuples::null_type> >&);
54 
55 public:
57  : valid(false)
58  { }
59 
60  basis_sector_iterator_(size_t L_, Index<SymmGroup> const& phys, charge initc_)
61  : valid(true)
62  , L(L_)
63  , initc(initc_)
64  , it(L, 0)
65  , state(L)
66  {
67  getter_fn = &boost::tuples::get<0, charge, boost::tuples::cons<size_t, boost::tuples::null_type> >;
68 
69  for (size_t i=0; i<phys.size(); ++i)
70  for (size_t j=0; j<phys[i].second; ++j)
71  alllocal.push_back( local_state(phys[i].first, j) );
72 
73  for (size_t i=0; i<L; ++i) {
74  state[i] = alllocal[it[i]];
75  }
76 
77  if (total_charge() != initc)
78  advance();
79  }
80 
81  std::vector<local_state> const& operator*() const
82  {
83  return state;
84  }
85 
86  void operator++()
87  {
88  advance();
89  }
90 
92  {
93  if (valid != rhs.valid)
94  return false;
95  if (!valid)
96  return true;
97 
98  return (L == rhs.L) && (initc == rhs.initc) && (alllocal == rhs.alllocal) && std::equal(state.begin(), state.end(), rhs.state.begin());
99  }
100 
101 private:
102 
103  charge total_charge() const
104  {
105  return std::accumulate(state.begin(), state.end(), SymmGroup::IdentityCharge,
106  boost::bind(static_cast<charge(*)(charge,charge)>(&SymmGroup::fuse), _1, boost::bind(getter_fn, _2)) );
107  }
108 
109  void advance()
110  {
111  do {
112  ++it[L-1];
113  for (int i=L-1; (i > 0) && (it[i] == alllocal.size()); --i) {
114  it[i] = 0;
115  ++it[i-1];
116  }
117  if ( it[0] == alllocal.size() ) {
118  valid = false;
119  return;
120  }
121 
122  for (size_t i=0; i<L; ++i)
123  state[i] = alllocal[it[i]];
124  } while(total_charge() != initc);
125  }
126 
127  bool valid;
128  size_t L;
129  charge initc;
130  get0_fn_t getter_fn;
131 
132  std::vector<local_state> alllocal;
133  std::vector<size_t> it;
134  std::vector<local_state> state;
135 };
136 
137 
138 template <class SymmGroup>
139 std::pair<basis_sector_iterator_<SymmGroup>, basis_sector_iterator_<SymmGroup> >
140 basis_sector_iterators(size_t L, Index<SymmGroup> const& phys, typename SymmGroup::charge initc=SymmGroup::IdentityCharge)
141 {
142  return std::make_pair(basis_sector_iterator_<SymmGroup>(L, phys, initc), basis_sector_iterator_<SymmGroup>());
143 }
144 
145 
146 #endif
bool operator==(basis_sector_iterator_< SymmGroup > const &rhs) const
std::pair< basis_sector_iterator_< SymmGroup >, basis_sector_iterator_< SymmGroup > > basis_sector_iterators(size_t L, Index< SymmGroup > const &phys, typename SymmGroup::charge initc=SymmGroup::IdentityCharge)
include one of the Index class definitions
basis_sector_iterator_(size_t L_, Index< SymmGroup > const &phys, charge initc_)
std::pair< bool, typename Matrix::value_type > equal(block_matrix< Matrix, SymmGroup > const &reference, block_matrix< Matrix, SymmGroup > const &sample)
Definition: tag_detail.h:120
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
Definition: bindings.hpp:44
std::size_t size() const
std::vector< local_state > const & operator*() const
T fuse(const A &ind, T d)
Fuse indices n[i] into one p = n[i] d^i.