1#ifndef HYPERISO_UTILS_H
2#define HYPERISO_UTILS_H
11#include <unordered_set>
12#include <unordered_map>
43const std::numeric_limits<double>
nld = *
new std::numeric_limits<double>;
55bool ends_with(
const std::string& str,
const std::string& suffix);
71std::vector<std::string>
split(
const std::string& s,
char delimiter);
107template<
typename T,
typename U>
108inline std::unordered_set<T>
get_keys(
const std::map<T, U>& map) {
109 std::unordered_set<T> keys;
110 for (
const std::pair<const T, U>& item : map) {
111 keys.emplace(item.first);
124template<
typename T,
typename U>
125inline std::unordered_set<T>
get_keys(
const std::unordered_map<T, U>& map) {
126 std::unordered_set<T> keys;
127 for (
const std::pair<const T, U>& item : map) {
128 keys.emplace(item.first);
144template<
typename T,
typename U>
145inline bool haveSameKeys(
const std::map<T, U>& map1,
const std::map<T, U>& map2) {
176void print_value(std::ostream& os,
const std::shared_ptr<T> &ptr) {
200template <
typename Map>
202 std::is_same_v<
typename Map::value_type,
203 std::pair<const typename Map::key_type, typename Map::mapped_type>>,
207 for (
const auto& [key, value] : m) {
213 os.seekp(-2, std::ios_base::end);
240template <
typename T, std::size_t cache_size,
typename Func,
typename... Args>
241void fill_cache(Func&&
f,
double a,
double b, std::array<T, cache_size>& cache, Args&&... args) {
242 double x_0 = (b - a) *
nld.epsilon() + a;
243 cache[0] =
f(x_0, std::forward<Args>(args)...);
244 for (std::size_t i = 1; i < cache_size - 1; ++i) {
245 double s =
static_cast<double>(i) /
static_cast<double>(cache_size - 1);
246 double x = (b - a) * s + a;
247 cache[i] =
f(x, std::forward<Args>(args)...);
249 double x_1 = (b - a) * (1. -
nld.epsilon()) + a;
250 cache[cache_size - 1] =
f(x_1, std::forward<Args>(args)...);
275template <
typename T,
typename U, std::
size_t cache_size>
276T lerp(U x,
const std::array<T, cache_size>& lookup,
double a=0.0,
double b=1.0)
279 x = std::clamp(
static_cast<double>(x), a, b);
280 double u = (x - a) / (b - a);
281 double scaled = u * (cache_size - 1);
282 std::size_t i =
static_cast<std::size_t
>(std::floor(scaled));
284 if (i >= cache_size - 1) {
285 return lookup[cache_size - 1];
288 double t = scaled -
static_cast<double>(i);
289 return T((1.0 - t)) * lookup[i] +
T(t) * lookup[i + 1];
void fill_cache(Func &&f, double a, double b, std::array< T, cache_size > &cache, Args &&... args)
Fills a lookup cache for a function on a finite interval [a, b].
bool ends_with(const std::string &str, const std::string &suffix)
Tests whether a string ends with a given suffix.
std::enable_if_t< std::is_same_v< typename Map::value_type, std::pair< const typename Map::key_type, typename Map::mapped_type > >, std::ostream & > operator<<(std::ostream &os, const Map &m)
Generic stream output operator for map-like containers.
const std::numeric_limits< double > nld
Numeric limits for double-precision floating point.
std::vector< std::string > split(const std::string &s, char delimiter)
Splits a string into parts using a single-character delimiter.
std::string doubleToString(double value, int precision)
Converts a double to a fixed-format string with a given precision.
void print_value(std::ostream &os, const T &value)
Generic helper to print a value to an output stream.
std::complex< double > complex_t
Convenience alias for std::complex<double>.
bool haveSameKeys(const std::map< T, U > &map1, const std::map< T, U > &map2)
Checks whether two std::map instances have the same set of keys.
std::unordered_set< T > get_keys(const std::map< T, U > &map)
Extracts the key set from a std::map into an unordered_set.
std::string to_lowercase(const std::string &str)
Returns a lowercase copy of the input string.
T lerp(U x, const std::array< T, cache_size > &lookup, double a=0.0, double b=1.0)
Linearly interpolates a cached function on [a, b].
double T(double x)
Wilson coefficient T(x).
double f(double x)
Wilson special function f depending on x.