Loading...
Searching...
No Matches
commonUtils.hpp
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BITPIT_COMMON_UTILS_HPP__
26#define __BITPIT_COMMON_UTILS_HPP__
27
30#include <array>
31#include <algorithm>
32#include <cfloat>
33#include <cmath>
34#include <functional>
35#include <limits>
36#include <iomanip>
37#include <iostream>
38#include <sstream>
39#include <string>
40#include <vector>
41#include <map>
42
43// Stringification macro
44#define BITPIT_STR2(X) #X
45#define BITPIT_STR(X) BITPIT_STR2(X)
46
47// Macros to allow using oveload in preprocessing macro
48#define BITPIT_CAT(A, B) A ## B
49
50#define BITPIT_COUNT_ARGS_MAX6(_1, _2, _3, _4, _5, _6 /* ad nauseam */, COUNT, ...) COUNT
51#define BITPIT_EXPAND_ARGS_FOR_COUNT(x) x
52#define BITPIT_ARGS_SIZE(...) BITPIT_EXPAND_ARGS_FOR_COUNT(BITPIT_COUNT_ARGS_MAX6(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0))
53
54#define BITPIT_SELECT_OVERLOAD(NAME, NUM) BITPIT_CAT(NAME ## _, NUM)
55#define BITPIT_OVERLOAD_CALL(NAME, ...) BITPIT_SELECT_OVERLOAD(NAME, BITPIT_ARGS_SIZE(__VA_ARGS__))(__VA_ARGS__)
56
76#define BITPIT_CREATE_WORKSPACE(workspace, item_type, size, stack_size) \
77item_type *workspace; \
78std::array<item_type, stack_size> workspace##_stack; \
79std::unique_ptr<std::vector<item_type>> workspace##_heap; \
80if (size <= stack_size) { \
81 workspace = workspace##_stack.data(); \
82} else { \
83 workspace##_heap = std::unique_ptr<std::vector<item_type>>(new std::vector<item_type>(size)); \
84 workspace = workspace##_heap->data(); \
85}
86
87namespace bitpit {
88
89namespace utils {
90
91template <typename T, typename Comparator = std::less<T> >
92bool addToOrderedVector(const T &value, std::vector<T> &list, Comparator comparator = Comparator());
93
94template <typename T, typename Comparator = std::less<T> >
95typename std::vector<T>::const_iterator findInOrderedVector(const T &value, const std::vector<T> &list, Comparator comparator = Comparator());
96
97template<typename T>
98void reorderVector(std::vector<size_t>& order, std::vector<T>& v, std::size_t size);
99
100template<typename OrderContainer, typename DataContainer>
101void reorderContainer(OrderContainer &order, DataContainer &v, std::size_t size);
102
103template<typename Container, typename Index>
104void swapValue(Container &v, Index i, Index j);
105
106template<>
107void swapValue(std::vector<bool> &v, std::size_t i, std::size_t j);
108
109template <class T>
110void eraseValue(std::vector<T> &, const T&);
111
112template <class T>
113std::vector<T> intersectionVector(const std::vector<T>&, const std::vector<T>&);
114
115#ifndef __BITPIT_COMMON_UTILS_SRC__
116extern template bool addToOrderedVector<>(const long&, std::vector<long>&, std::less<long>);
117extern template bool addToOrderedVector<>(const unsigned long&, std::vector<unsigned long>&, std::less<unsigned long>);
118
119extern template std::vector<long>::const_iterator findInOrderedVector<>(const long&, const std::vector<long>&, std::less<long>);
120extern template std::vector<unsigned long>::const_iterator findInOrderedVector<>(const unsigned long&, const std::vector<unsigned long>&, std::less<unsigned long>);
121#endif
122
123void extractWithoutReplacement( // Extract integers without replacement
124 int , // (input) number of integers to be extracted
125 int , // (input) upper bound of extraction interval
126 std::vector<int> & // (input/output) list of extracted value
127);
128
129std::size_t countDigits(int n);
130
131unsigned long factorial(unsigned long n);
132
138{
139
140public:
141 virtual ~DoubleFloatingComparison() = default;
142
143protected:
144 constexpr static const double DEFAULT_ABS_TOL = 10 * std::numeric_limits<double>::epsilon();
145 constexpr static const double DEFAULT_REL_TOL = 10 * std::numeric_limits<double>::epsilon();
146
147 DoubleFloatingComparison() = default;
148
149};
150
161{
174 bool operator()(double x, double y, double relativeTolerance = DEFAULT_REL_TOL, double absoluteTolerance = DEFAULT_ABS_TOL) const
175 {
176 // Check if the numbers are really close (needed when comparing
177 // numbers near zero).
178 double absoluteDifference = std::abs(x - y);
179 if (absoluteDifference <= absoluteTolerance) {
180 return true;
181 }
182
183 // Compare using a relative difference
184 //
185 // The check that is performed is:
186 //
187 // abs(x - y) <= abs(x) * epsilon OR abs(x - y) <= abs(y) * epsilon
188 //
189 // The multiplication in the right side of inequalities may cause an
190 // unwanted underflow condition. To prevent this, the difference is
191 // scaled rather than epsilon.
192 double relativeDifference = absoluteDifference / std::max(std::abs(x), std::abs(y));
193
194 return (relativeDifference <= relativeTolerance);
195 }
196
197};
198
203{
224 bool operator()(double x, double y, double relativeTolerance = DEFAULT_REL_TOL, double absoluteTolerance = DEFAULT_ABS_TOL) const
225 {
226 if (x > y) {
227 return false;
228 }
229
230 if (DoubleFloatingEqual()(x, y, relativeTolerance, absoluteTolerance)) {
231 return false;
232 }
233
234 return true;
235 }
236
237};
238
244{
265 bool operator()(double x, double y, double relativeTolerance = DEFAULT_REL_TOL, double absoluteTolerance = DEFAULT_ABS_TOL) const
266 {
267 if (x < y) {
268 return true;
269 }
270
271 if (DoubleFloatingEqual()(x, y, relativeTolerance, absoluteTolerance)) {
272 return true;
273 }
274
275 return false;
276 }
277
278};
279
284{
305 bool operator()(double x, double y, double relativeTolerance = DEFAULT_REL_TOL, double absoluteTolerance = DEFAULT_ABS_TOL) const
306 {
307 if (x < y) {
308 return false;
309 }
310
311 if (DoubleFloatingEqual()(x, y, relativeTolerance, absoluteTolerance)) {
312 return false;
313 }
314
315 return true;
316 }
317
318};
319
325{
347 bool operator()(double x, double y, double relativeTolerance = DEFAULT_REL_TOL, double absoluteTolerance = DEFAULT_ABS_TOL) const
348 {
349 if (x > y) {
350 return true;
351 }
352
353 if (DoubleFloatingEqual()(x, y, relativeTolerance, absoluteTolerance)) {
354 return true;
355 }
356
357 return false;
358 }
359
360};
361
362}
363
364}
365
366// Template implementation
367#include "commonUtils.tpp"
368
369#endif
void swapValue(std::vector< bool > &v, std::size_t i, std::size_t j)
std::vector< T > intersectionVector(const std::vector< T > &, const std::vector< T > &)
unsigned long factorial(unsigned long n)
void reorderContainer(OrderContainer &order, DataContainer &v, std::size_t size)
void extractWithoutReplacement(int n, int m, std::vector< int > &list)
void reorderVector(std::vector< size_t > &order, std::vector< T > &v, std::size_t size)
std::size_t countDigits(int n)
void eraseValue(std::vector< T > &, const T &)
bool operator()(double x, double y, double relativeTolerance=DEFAULT_REL_TOL, double absoluteTolerance=DEFAULT_ABS_TOL) const
bool operator()(double x, double y, double relativeTolerance=DEFAULT_REL_TOL, double absoluteTolerance=DEFAULT_ABS_TOL) const
bool operator()(double x, double y, double relativeTolerance=DEFAULT_REL_TOL, double absoluteTolerance=DEFAULT_ABS_TOL) const
bool operator()(double x, double y, double relativeTolerance=DEFAULT_REL_TOL, double absoluteTolerance=DEFAULT_ABS_TOL) const
bool operator()(double x, double y, double relativeTolerance=DEFAULT_REL_TOL, double absoluteTolerance=DEFAULT_ABS_TOL) const
--- layout: doxygen_footer ---