ALPSCore reference
galois.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
7 
8 namespace alps { namespace alea { namespace internal {
9 
11  : size_(size)
12 {
13  if (size_ % 2 != 0)
14  throw std::runtime_error("Number of batches must be even to allow "
15  "for rebatching");
16  reset();
17 }
18 
20 {
21  if (merge_mode) {
22  level_ = 1;
23  factor_ = 2;
24  skip_ = 1;
25  } else {
26  level_ = 0;
27  factor_ = 1;
28  skip_ = 0;
29  }
30  cycle_ = 0;
31  level_pos_ = 0;
32  current_ = 0;
33 }
34 
36 {
37  galois_hopper save = *this;
38  ++(*this);
39  return save;
40 }
41 
43 {
44  if (level_ == 0)
45  advance_fill();
46  else
47  advance_galois();
48  return *this;
49 }
50 
51 void galois_hopper::advance_fill()
52 {
53  assert(level_ == 0);
54  ++current_;
55  ++level_pos_;
56 
57  // we have filled all the elements, switch to Galois mode
58  if (current_ == size_) {
59  reset(true);
60  ++cycle_;
61  }
62 }
63 
64 void galois_hopper::advance_galois()
65 {
66  assert(level_ != 0);
67  ++level_pos_;
68  if (level_pos_ == size_/2) {
69  ++level_;
70  level_pos_ = 0;
71  factor_ *= 2;
72  skip_ *= 2;
73  }
74  current_ = (current_ + 2 * skip_) % (size_ + 1);
75  assert(current_ != size_);
76 
77  // We have completed the cycle. Make sure skip does not overflow
78  if (current_ == 0 && merge_into() == 1) {
79  assert(level_pos_ == 0);
80  ++cycle_;
81  }
82 }
83 
84 }}}
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
Definition: size.hpp:20
void reset(bool merge_mode=false)
Definition: galois.cpp:19
galois_hopper & operator++()
Definition: galois.cpp:42
std::enable_if< is_alea_result< T >::value, void >::type save(Archive &ar, const T &r, const unsigned int)