Reaktoro  v2.11.0
A unified framework for modeling chemically reactive systems
Algorithms.hpp
1 // Reaktoro is a unified framework for modeling chemically reactive systems.
2 //
3 // Copyright © 2014-2024 Allan Leal
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library. If not, see <http://www.gnu.org/licenses/>.
17 
18 #pragma once
19 
20 // C++ includes
21 #include <algorithm>
22 #include <cassert>
23 #include <iterator>
24 #include <vector>
25 
26 // Reaktoro includes
27 #include <Reaktoro/Common/TraitsUtils.hpp>
28 
29 namespace Reaktoro {
30 
33 #define RKT_LAMBDA(x, expr) [&](const auto& x) { return expr; }
34 
36 template<typename Container, typename T>
37 auto index(const Container& c, const T& x) -> std::size_t
38 {
39  return std::find(c.begin(), c.end(), x) - c.begin();
40 }
41 
43 template<typename Container, typename Predicate>
44 auto indexfn(const Container& c, const Predicate& pred) -> std::size_t
45 {
46  return std::find_if(c.begin(), c.end(), pred) - c.begin();
47 }
48 
50 template<typename Container, typename Predicate>
51 auto filter(const Container& c, const Predicate& pred)
52 {
53  Container res;
54  std::copy_if(c.begin(), c.end(), std::back_inserter(res), pred);
55  return res;
56 }
57 
59 template<typename Container, typename T>
60 auto remove(const Container& c, const T& x)
61 {
62  return filter(c, [&](auto&& y) { return x != y; });
63 }
64 
66 template<typename Container, typename Predicate>
67 auto removefn(const Container& c, const Predicate& pred)
68 {
69  return filter(c, [&](auto&& x) { return !pred(x); });
70 }
71 
73 template<typename Container>
74 auto sort(Container& c)
75 {
76  std::sort(c.begin(), c.end());
77 }
78 
80 template<typename Container, typename Predicate>
81 auto sortfn(Container& c, const Predicate& pred)
82 {
83  std::sort(c.begin(), c.end(), pred);
84 }
85 
87 template<typename Container>
88 auto sorted(const Container& c)
89 {
90  Container res(c);
91  std::sort(res.begin(), res.end());
92  return res;
93 }
94 
96 template<typename Container, typename Predicate>
97 auto sortedfn(const Container& c, const Predicate& pred)
98 {
99  Container res(c);
100  std::sort(res.begin(), res.end(), pred);
101  return res;
102 }
103 
105 template<typename Container>
106 auto unique(const Container& c)
107 {
108  Container res(c);
109  std::sort(res.begin(), res.end());
110  res.erase(std::unique(res.begin(), res.end()), res.end());
111  return res;
112 }
113 
115 template<typename Container, typename Result, typename Function>
116 auto transform(const Container& c, Result& res, const Function& f)
117 {
118  assert(c.size() == res.size());
119  std::transform(c.begin(), c.end(), res.begin(), f);
120 }
121 
123 template<typename Container, typename Indices>
124 auto extract(const Container& a, const Indices& indices)
125 {
126  Container res;
127  res.reserve(indices.size());
128  for(auto i : indices)
129  res.push_back(a[i]);
130  return res;
131 }
132 
134 template<typename Container, typename Function>
135 auto vectorize(const Container& c, const Function& f)
136 {
137  using X = typename Container::value_type;
138  using T = std::invoke_result_t<Function, X>;
139  std::vector<T> res;
140  res.resize(c.size());
141  transform(c, res, f);
142  return res;
143 }
144 
146 template<typename Container, typename T>
147 auto contains(const Container& c, const T& x)
148 {
149  return c.size() && std::find(c.begin(), c.end(), x) != c.end();
150 }
151 
153 template<typename Container, typename Predicate>
154 auto containsfn(const Container& c, const Predicate& pred)
155 {
156  return c.size() && std::find_if(c.begin(), c.end(), pred) != c.end();
157 }
158 
160 template<typename ContainerA, typename ContainerB>
161 auto contained(const ContainerA& a, const ContainerB& b)
162 {
163  for(auto const& x : a)
164  if(!contains(b, x))
165  return false;
166  return true;
167 }
168 
170 template<typename Container>
171 auto concatenate(const Container& a, const Container& b)
172 {
173  Container res(a);
174  res.insert(res.end(), b.begin(), b.end());
175  return res;
176 }
177 
179 template<typename Container>
180 auto merge(const Container& a, const Container& b)
181 {
182  Container res(a);
183  res.insert(res.end(), b.begin(), b.end());
184  std::sort(res.begin(), res.end());
185  res.erase(std::unique(res.begin(), res.end()), res.end());
186  return res;
187 }
188 
190 template<typename Container>
191 auto intersect(const Container& a, const Container& b)
192 {
193  return filter(a, RKT_LAMBDA(x, contains(b, x)));
194 }
195 
197 template<typename Container>
198 auto difference(const Container& a, const Container& b)
199 {
200  return filter(a, RKT_LAMBDA(x, !contains(b, x)));
201 }
202 
204 template<typename ContainerA, typename ContainerB>
205 auto disjoint(const ContainerA& a, const ContainerB& b)
206 {
207  for(auto&& x : a)
208  if(contains(b, x))
209  return false;
210  return true;
211 }
212 
214 template<typename ContainerA, typename ContainerB>
215 auto identical(const ContainerA& a, const ContainerB& b)
216 {
217  return contained(a, b) && contained(b, a);
218 }
219 
221 template<typename T>
222 auto range(T first, T last, T step)
223 {
224  if(last <= first) return std::vector<T>{};
225  auto size = std::size_t((last - first - 1)/step) + 1;
226  std::vector<T> res(size);
227  for(auto i = 0; i < size; ++i)
228  res[i] = first + i*step;
229  return res;
230 }
231 
233 template<typename T>
234 auto range(T first, T last)
235 {
236  return range(first, last, static_cast<T>(1));
237 }
238 
240 template<typename T>
241 auto range(T last)
242 {
243  return range(static_cast<T>(0), last, static_cast<T>(1));
244 }
245 
247 template<typename X, typename X0, typename... XS>
248 auto oneof(const X x, const X0& x0, const XS&... xs)
249 {
250  if constexpr(sizeof...(XS) > 0)
251  return x == x0 || oneof(x, xs...);
252  return x == x0;
253 }
254 
256 template<typename Function>
257 auto sum(std::size_t ibegin, std::size_t iend, const Function& f)
258 {
259  using T = std::invoke_result_t<Function, std::size_t>;
260  T res = static_cast<T>(0);
261  for(auto i = ibegin; i < iend; ++i)
262  res += f(i);
263  return res;
264 }
265 
267 template<typename Function>
268 auto sum(std::size_t iend, const Function& f)
269 {
270  return sum(0, iend, f);
271 }
272 
274 template<typename Indices, typename Function, Requires<!isArithmetic<Indices>> = true>
275 auto sum(const Indices& inds, const Function& f)
276 {
277  using T = std::invoke_result_t<Function, std::size_t>;
278  T res = static_cast<T>(0);
279  for(auto i : inds)
280  res += f(i);
281  return res;
282 }
283 
284 } // namespace Reaktoro
The namespace containing all components of the Reaktoro library.
Definition: Algorithms.hpp:29
auto containsfn(const Container &c, const Predicate &pred)
Return true if container a contains item x for which pred(x) evaluates to true.
Definition: Algorithms.hpp:154
auto indexfn(const Container &c, const Predicate &pred) -> std::size_t
Return the index of item x in container c for which pred(x) evaluates to true or the number of items ...
Definition: Algorithms.hpp:44
auto sortfn(Container &c, const Predicate &pred)
Sort a container in-place with predicate controlling order.
Definition: Algorithms.hpp:81
auto remove(const Container &c, const T &x)
Return a container without items x.
Definition: Algorithms.hpp:60
auto vectorize(const Container &c, const Function &f)
Return a vector by applying function f on every item in container c.
Definition: Algorithms.hpp:135
auto filter(const Container &c, const Predicate &pred)
Return a container with items x for which pred(x) evaluates to true.
Definition: Algorithms.hpp:51
auto intersect(const Container &a, const Container &b)
Return the intersection of two containers.
Definition: Algorithms.hpp:191
auto sorted(const Container &c)
Return a sorted container.
Definition: Algorithms.hpp:88
auto disjoint(const ContainerA &a, const ContainerB &b)
Return true if containers a and b have distinct items.
Definition: Algorithms.hpp:205
auto removefn(const Container &c, const Predicate &pred)
Return a container without items x for which pred(x) evaluates to true.
Definition: Algorithms.hpp:67
auto identical(const ContainerA &a, const ContainerB &b)
Return true if containers a and b have identical items.
Definition: Algorithms.hpp:215
auto sum(std::size_t ibegin, std::size_t iend, const Function &f)
Return the sum f(ibegin) + ... + f(iend-1) for a given function f.
Definition: Algorithms.hpp:257
auto contained(const ContainerA &a, const ContainerB &b)
Return true if items in container a are also in container b.
Definition: Algorithms.hpp:161
auto range(T first, T last, T step)
Return a vector with given range of values and step between them.
Definition: Algorithms.hpp:222
auto index(const Container &c, const T &x) -> std::size_t
Return the index of item x in container c or the number of items if not found.
Definition: Algorithms.hpp:37
auto transform(const Container &c, Result &res, const Function &f)
Apply a function f on every item in container c and store in res.
Definition: Algorithms.hpp:116
std::vector< Index > Indices
Define a type that represents a collection of indices.
Definition: Index.hpp:29
auto concatenate(const Container &a, const Container &b)
Return a container with items from both a and b.
Definition: Algorithms.hpp:171
auto sortedfn(const Container &c, const Predicate &pred)
Return a sorted container with predicate controlling order.
Definition: Algorithms.hpp:97
auto merge(const Container &a, const Container &b)
Return a container with items from both a and b without duplicates.
Definition: Algorithms.hpp:180
auto extract(const Container &a, const Indices &indices)
Return the items in a container at given indices.
Definition: Algorithms.hpp:124
auto oneof(const X x, const X0 &x0, const XS &... xs)
Return true if x is equal to at least one of the other arguments.
Definition: Algorithms.hpp:248
auto sort(Container &c)
Sort a container in-place.
Definition: Algorithms.hpp:74
auto contains(const Container &c, const T &x)
Return true if container a contains item x.
Definition: Algorithms.hpp:147
auto difference(const Container &a, const Container &b)
Return the difference of two containers.
Definition: Algorithms.hpp:198
auto unique(const Container &c)
Return a container without duplicates.
Definition: Algorithms.hpp:106