LearnTA  0.0.1
fractional_order.hh
1 
6 #pragma once
7 
8 #include <deque>
9 #include <unordered_set>
10 
11 #include <boost/functional/hash.hpp>
12 #include <boost/log/trivial.hpp>
13 #include <boost/log/core.hpp>
14 #include <boost/log/expressions.hpp>
15 
16 #include "common_types.hh"
17 
18 namespace learnta {
25  private:
26  std::deque<std::deque<ClockVariables>> order;
27  // The number of the variables
28  std::size_t size;
29  public:
30  FractionalOrder() {
31  order.push_front({0});
32  size = 1;
33  }
34 
35  FractionalOrder(const FractionalOrder &order) = default;
36  FractionalOrder(FractionalOrder &&order) = default;
37  FractionalOrder& operator=(const FractionalOrder& order) = default;
38  FractionalOrder& operator=(FractionalOrder&& order) = default;
42  explicit FractionalOrder(const std::vector<double> &fractionalParts) {
43  std::vector<std::pair<double, ClockVariables>> fractionalPartsWithIndices;
44  fractionalPartsWithIndices.resize(fractionalParts.size());
45  for (std::size_t i = 0; i < fractionalParts.size(); ++i) {
46  fractionalPartsWithIndices.at(i) = std::make_pair(fractionalParts.at(i), i);
47  }
48  std::sort(fractionalPartsWithIndices.begin(), fractionalPartsWithIndices.end());
49  double currentFractionalPart = 0;
50  order.emplace_back();
51  for (const auto&[fractionalPart, index]: fractionalPartsWithIndices) {
52  if (currentFractionalPart == fractionalPart) {
53  order.back().push_back(index);
54  } else {
55  order.emplace_back(std::deque<ClockVariables>{index});
56  currentFractionalPart = fractionalPart;
57  }
58  }
59 
60  size = fractionalParts.size();
61  }
62 
66  [[nodiscard]] const std::deque<ClockVariables>& successorVariables() const {
67  if (order.front().empty()) {
68  return order.back();
69  } else {
70  return order.front();
71  }
72  }
73 
77  [[nodiscard]] FractionalOrder successor() const {
78  FractionalOrder result = *this;
79  if (order.front().empty()) {
80  // If there is no variables equal to 0.
81  std::swap(result.order.front(), result.order.back());
82  result.order.pop_back();
83  } else {
84  // If there are some variables equal to 0.
85  result.order.emplace_front();
86  }
87 
88  return result;
89  }
90 
94  void successorAssign() {
95  if (order.front().empty()) {
96  // If there is no variables equal to 0.
97  std::swap(order.front(), order.back());
98  order.pop_back();
99  } else {
100  // If there are some variables equal to 0.
101  order.emplace_front();
102  }
103  }
104 
108  [[nodiscard]] std::deque<ClockVariables> predecessorVariables() const {
109  if (order.empty()) {
110  BOOST_LOG_TRIVIAL(error) << "Something wrong happened in the predecessorVariables. order is empty";
111  }
112  if (order.front().empty()) {
113  if (order.size() <= 1) {
114  BOOST_LOG_TRIVIAL(error) << "Something wrong happened in the predecessorVariables. No variable exists";
115  }
116  return *(std::next(order.begin()));
117  } else {
118  return order.front();
119  }
120  }
121 
125  [[nodiscard]] FractionalOrder predecessor() const {
126  FractionalOrder result = *this;
127  if (order.front().empty()) {
128  // If there is no variables equal to 0.
129  result.order.pop_front();
130  } else {
131  // If there are some variables equal to 0.
132  result.order.emplace_back();
133  std::swap(result.order.front(), result.order.back());
134  }
135 
136  return result;
137  }
138 
142  [[nodiscard]] FractionalOrder extendN() const {
143  FractionalOrder result = *this;
144  result.order.front().push_back(result.size++);
145  return result;
146  }
147 
153  [[nodiscard]] FractionalOrder removeN() const {
154  FractionalOrder result = *this;
155  assert(static_cast<std::size_t>(result.order.front().back() + 1) == this->size);
156  assert(result.size > 0);
157  result.order.front().pop_back();
158  result.size--;
159  return result;
160  }
161 
165  [[nodiscard]] FractionalOrder extendZero() const {
166  FractionalOrder result = *this;
167 
168  for (auto &variables: result.order) {
169  std::transform(variables.begin(), variables.end(), variables.begin(), [](auto variable) {
170  return variable + 1;
171  });
172  }
173  result.order.front().push_front(0);
174  result.size++;
175  return result;
176  }
177 
179  [[nodiscard]] size_t getSize() const {
180  return size;
181  }
182 
183  bool operator==(const FractionalOrder &another) const {
184  return this->size == another.size && this->order == another.order;
185  }
186 
187  std::ostream &print(std::ostream &os) const {
188  auto it = order.begin();
189  if (it->empty()) {
190  os << "0 < ";
191  it++;
192  } else {
193  os << "0 <= ";
194  }
195  for (; it != order.end(); it++) {
196  os << "{";
197  for (const auto var: *it) {
198  os << "x" << int(var) << ", ";
199  }
200  os << "}";
201  }
202 
203  return os;
204  }
205 
206  [[nodiscard]] std::size_t hash_value() const {
207  return boost::hash_value(std::make_pair(this->order, this->size));
208  }
209  };
210 
211  static inline std::ostream &operator<<(std::ostream &os, const learnta::FractionalOrder &order) {
212  return order.print(os);
213  }
214 
215  inline std::size_t hash_value(learnta::FractionalOrder const &order) {
216  return order.hash_value();
217  }
218 }
Order on the fractional part of the variables.
Definition: fractional_order.hh:24
FractionalOrder extendN() const
Add another variable such that .
Definition: fractional_order.hh:142
FractionalOrder extendZero() const
Rename each variable to and add such that .
Definition: fractional_order.hh:165
FractionalOrder(const std::vector< double > &fractionalParts)
Construct a fractional order from a concrete vector of fractional parts.
Definition: fractional_order.hh:42
FractionalOrder predecessor() const
Make it to be the predecessor.
Definition: fractional_order.hh:125
void successorAssign()
Make it to be the successor.
Definition: fractional_order.hh:94
size_t getSize() const
Returns the number of the variables.
Definition: fractional_order.hh:179
const std::deque< ClockVariables > & successorVariables() const
Return the variable to elapse.
Definition: fractional_order.hh:66
FractionalOrder removeN() const
Remove .
Definition: fractional_order.hh:153
std::deque< ClockVariables > predecessorVariables() const
Return the variable to backward-elapse.
Definition: fractional_order.hh:108
FractionalOrder successor() const
Make it to be the successor.
Definition: fractional_order.hh:77
Definition: experiment_runner.hh:23