36 #include <boost/operators.hpp>
39 template <
class SymmGroup>
41 :
public boost::forward_iterator_helper<
42 index_product_iterator<SymmGroup>
43 , std::vector<std::pair<typename Index<SymmGroup>::charge, std::size_t> >
45 , std::vector<std::pair<typename Index<SymmGroup>::charge, std::size_t> > *
46 , std::vector<std::pair<typename Index<SymmGroup>::charge, std::size_t> > &
55 typedef std::pair<charge, elem_id>
coord_t;
58 typedef std::vector<typename index_t::const_iterator>
vec_iterator;
71 for (
int i=0; i<size; ++i) {
72 begin[i] = idx[i].begin();
73 state[i] = idx[i].begin();
74 max_i[i] = state[i]->second;
75 end[i] = idx[i].end();
82 for (
int i=0; i<size; ++i)
83 ret[i] = std::make_pair(state[i]->first, cur_i[i]);
89 for (
int i=size-1; i>=0; --i) {
91 if (cur_i[i] != max_i[i])
95 if (state[i] != end[i]) {
97 max_i[i] = state[i]->second;
109 max_i[i] = state[i]->second;
115 if (valid != rhs.valid)
120 return (size == rhs.size) &&
std::equal(state.begin(), state.end(), rhs.state.begin());
133 std::vector<elem_id> cur_i;
134 std::vector<std::size_t> max_i;
139 template <
class SymmGroup>
160 return idx_.size()-1;
167 {
return idx_.size(); }
170 std::vector<std::pair<index_id, bool> >
const & vec_right);
174 left_keys.erase(left_keys.begin() + s);
175 left_vals.erase(left_vals.begin() + s);
176 set_left.erase(set_left.begin() + s);
177 right_keys.erase(right_keys.begin() + s);
178 right_vals.erase(right_vals.begin() + s);
179 set_right.erase(set_right.begin() + s);
203 assert( left_sizes[s].count(c) > 0 );
204 return left_sizes[s].find(c)->second;
208 assert( right_sizes[s].count(c) > 0 );
209 return right_sizes[s].find(c)->second;
217 return key_to_val(key, left_keys[s], left_vals[s]);
221 return key_to_val(key, right_keys[s], right_vals[s]);
225 key_t left_k, right_k;
226 for (
int i=0; i<set_left[s].size(); ++i)
227 left_k.push_back(key[ set_left[s][i].first ]);
228 for (
int i=0; i<set_right[s].size(); ++i)
229 right_k.push_back(key[ set_right[s][i].first ]);
237 return val_to_key(ci, left_keys[s], left_vals[s]);
241 return val_to_key(ci, right_keys[s], right_vals[s]);
255 assert( key1_left.size() == set_left[set1].size() );
256 assert( key1_right.size() == set_right[set1].size() );
258 key_t key(idx_.size());
259 for (
int i=0; i<set_left[set1].size(); ++i) {
261 key[ set_left[set1][i].first ] = key1_left[i];
264 for (
int i=0; i<set_right[set1].size(); ++i)
265 key[ set_right[set1][i].first ] = key1_right[i];
273 {
return convert_coords(set1, coords1.first, coords1.second, set2); }
284 coord_t const& key_to_val(
key_t const& key, std::vector<key_t>
const& keys,
285 std::vector<coord_t>
const& vals)
const
287 assert( std::count(keys.begin(), keys.end(), key) > 0 );
288 size_t pos = std::find(keys.begin(), keys.end(), key)-keys.begin();
292 key_t const& val_to_key(
coord_t const& ci, std::vector<key_t>
const& keys,
293 std::vector<coord_t>
const& vals)
const
295 assert( std::count(vals.begin(), vals.end(), ci) > 0 );
296 size_t pos = std::find(vals.begin(), vals.end(), ci)-vals.begin();
302 std::vector<index_t> idx_;
304 std::vector<std::vector<std::pair<index_id, bool> > > set_left, set_right;
305 std::vector<std::vector<key_t> > left_keys, right_keys;
306 std::vector<std::vector<coord_t> > left_vals, right_vals;
307 std::vector<std::map<charge, size_t> > left_sizes, right_sizes;
312 template <
class SymmGroup>
315 std::vector<std::pair<index_id, bool> >
const & vec_right)
318 std::vector<index_t> b;
319 for(
int i=0; i<vec_left.size(); ++i)
320 b.push_back( idx_[vec_left[i].first] );
322 std::map<charge, size_t> block_begins;
323 std::vector<key_t> keys_;
324 std::vector<coord_t> vals_;
330 charge c = SymmGroup::IdentityCharge;
331 for (
int i=0; i<b.size(); ++i)
333 keys_.push_back(*it);
334 vals_.push_back(std::make_pair(c, block_begins[c]));
338 left_keys.push_back(keys_);
339 left_vals.push_back(vals_);
340 left_sizes.push_back(block_begins);
344 std::vector<index_t> b;
345 for(
int i=0; i<vec_right.size(); ++i)
346 b.push_back( idx_[vec_right[i].first] );
348 std::map<charge, size_t> block_begins;
349 std::vector<key_t> keys_;
350 std::vector<coord_t> vals_;
356 charge c = SymmGroup::IdentityCharge;
357 for (
int i=0; i<b.size(); ++i)
359 keys_.push_back(*it);
360 vals_.push_back(std::make_pair(c, block_begins[c]));
364 right_keys.push_back(keys_);
365 right_vals.push_back(vals_);
366 right_sizes.push_back(block_begins);
369 set_left.push_back(vec_left);
370 set_right.push_back(vec_right);
371 return left_keys.size() - 1;
std::pair< coord_t, coord_t > convert_coords(set_id set1, coord_t const &coord1_left, coord_t const &coord1_right, set_id set2) const
key_t const & get_right_key(set_id s, coord_t const &ci) const
std::pair< coord_t, coord_t > get_coords(set_id s, key_t const &key) const
Index< SymmGroup > index_t
std::vector< coord_t > value_type
std::pair< charge, elem_id > coord_t
std::pair< charge, elem_id > coord_t
index_product_iterator< SymmGroup > const_iterator
std::vector< typename index_t::const_iterator > vec_iterator
std::pair< coord_t, coord_t > convert_coords(set_id set1, std::pair< coord_t, coord_t > const &coords1, set_id set2) const
const_iterator end() const
index_product_iterator(std::vector< index_t > const &idx)
size_t right_size(set_id s, charge const &c) const
index_id insert_index(index_t const &idx)
set_id create_set(std::vector< std::pair< index_id, bool > > const &vec_left, std::vector< std::pair< index_id, bool > > const &vec_right)
coord_t const & get_right_coord(set_id s, key_t const &key) const
value_type operator*() const
size_t left_size(set_id s, charge const &c) const
const_iterator begin() const
index_t const & index(index_id i) const
bool operator==(index_product_iterator< SymmGroup > const &rhs) const
std::pair< bool, typename Matrix::value_type > equal(block_matrix< Matrix, SymmGroup > const &reference, block_matrix< Matrix, SymmGroup > const &sample)
void remove_set(set_id s)
std::vector< coord_t > key_t
key_t const & get_left_key(set_id s, coord_t const &ci) const
Index< SymmGroup > index_t
coord_t const & get_left_coord(set_id s, key_t const &key) const
T fuse(const A &ind, T d)
Fuse indices n[i] into one p = n[i] d^i.