Antares Simulator
Power System Simulator
remix-utils.h
1 #pragma once
2 
3 #include <algorithm>
4 #include <numeric>
5 #include <ranges>
6 #include <span>
7 #include <stdexcept>
8 #include <vector>
9 
10 namespace rng = std::ranges;
11 
12 namespace Antares::Solver::Simulation
13 {
14 inline bool operator<=(const std::vector<double>& a, const std::vector<double>& b)
15 {
16  return a.size() == b.size()
17  && rng::all_of(std::views::iota(size_t{0}, a.size()),
18  [&](size_t i) { return a[i] <= b[i]; });
19 }
20 
21 inline bool operator<=(const std::vector<double>& v, const double c)
22 {
23  return rng::all_of(v, [&c](double e) { return e <= c; });
24 }
25 
26 inline bool operator>=(const std::vector<double>& v, const double c)
27 {
28  return rng::all_of(v, [&c](double e) { return e >= c; });
29 }
30 
31 inline std::vector<double> operator+(const std::vector<double>& v, const double c)
32 {
33  std::vector<double> to_return = v;
34  rng::for_each(to_return, [&c](double& e) { e = e + c; });
35  return to_return;
36 }
37 
38 inline std::vector<double> operator-(const std::vector<double>& v, const double c)
39 {
40  std::vector<double> to_return = v;
41  rng::for_each(to_return, [&c](double& e) { e = e - c; });
42  return to_return;
43 }
44 
45 inline std::vector<double> operator+(std::vector<double> a, const std::vector<double>& b)
46 {
47  rng::transform(a, b, a.begin(), std::plus<double>());
48  return a;
49 }
50 
51 inline std::vector<double> operator-(std::vector<double> a, const std::vector<double>& b)
52 {
53  rng::transform(a, b, a.begin(), std::minus<double>());
54  return a;
55 }
56 
57 inline std::vector<double> operator*(std::span<const double> left, const double scalar)
58 {
59  std::vector<double> to_return;
60  rng::transform(left, std::back_inserter(to_return), [&](double e) { return e * scalar; });
61  return to_return;
62 }
63 
64 inline double min_on_subrange(std::vector<double>&& v, unsigned h, unsigned H)
65 {
66  if (!v.size())
67  {
68  throw std::invalid_argument("call min_on_subrange on an empty vector");
69  }
70 
71  if (H >= v.size() || h >= v.size())
72  {
73  throw std::invalid_argument("call of min_on_subrange : hour out of bound");
74  }
75 
76  if (h >= H)
77  {
78  throw std::invalid_argument("call min_on_subrange with inconsistant hours");
79  }
80 
81  std::span<double> subset(v.begin() + h, v.begin() + H);
82  return *std::ranges::min_element(subset);
83 }
84 
85 inline double sum(const std::vector<double>& v)
86 {
87  return std::accumulate(v.begin(), v.end(), 0.);
88 }
89 
90 template<typename T>
91 class CyclicIterator final
92 {
93 public:
94  CyclicIterator(std::vector<T>& v);
95  CyclicIterator& operator++(int);
96  T& operator*();
97  bool operator==(const std::vector<T>::iterator& other) const;
98 
99 private:
100  template<typename U>
101  friend CyclicIterator<U>& delete_current(CyclicIterator<U>& it);
102 
103  void back_to_begin();
104 
105  std::vector<T>& v_;
106  std::vector<T>::iterator it_;
107 };
108 
109 template<typename T>
110 CyclicIterator<T>::CyclicIterator(std::vector<T>& v):
111  v_(v),
112  it_(v.begin())
113 {
114 }
115 
116 template<typename T>
117 CyclicIterator<T>& CyclicIterator<T>::operator++(int)
118 {
119  it_++;
120  back_to_begin();
121  return *this;
122 }
123 
124 template<typename T>
125 T& CyclicIterator<T>::operator*()
126 {
127  return *it_;
128 }
129 
130 template<typename T>
131 bool CyclicIterator<T>::operator==(const typename std::vector<T>::iterator& other) const
132 {
133  return it_ == other;
134 }
135 
136 template<typename T>
137 void CyclicIterator<T>::back_to_begin()
138 {
139  if (it_ == v_.end())
140  {
141  it_ = v_.begin();
142  }
143 }
144 
145 template<typename T>
146 CyclicIterator<T>& delete_current(CyclicIterator<T>& cyclicIt)
147 {
148  cyclicIt.it_ = cyclicIt.v_.erase(cyclicIt.it_);
149  cyclicIt.back_to_begin();
150  return cyclicIt;
151 }
152 
153 }; // namespace Antares::Solver::Simulation