2#include "qip/Methods.hpp"
17template <
typename T,
typename... Args>
18std::vector<T>
merge(std::vector<T> first,
const std::vector<T> &second,
19 const Args &...rest) {
20 first.insert(first.end(), second.cbegin(), second.cend());
21 if constexpr (
sizeof...(rest) == 0) {
24 return merge(std::move(first), rest...);
33auto compare(
const std::vector<T> &first,
const std::vector<T> &second) {
35 std::is_arithmetic_v<T>,
36 "In compare(std::vector<T>, std::vector<T>), T must be arithmetic");
37 assert(first.size() == second.size());
39 auto it1 = first.cbegin();
40 auto it2 = second.cbegin();
41 auto largest_delta =
static_cast<T
>(0);
42 auto largest_at = first.cend();
43 for (; it1 != first.cend(); ++it1, ++it2) {
44 const auto delta = *it1 - *it2;
45 if (std::abs(delta) > std::abs(largest_delta)) {
46 largest_delta = delta;
50 return std::make_pair(largest_delta, largest_at);
57template <
typename T,
typename U,
typename Func>
58auto compare(
const std::vector<T> &first,
const std::vector<U> &second,
60 assert(first.size() == second.size());
62 auto it1 = first.cbegin();
63 auto it2 = second.cbegin();
64 auto largest_eps = 0.0;
65 auto largest_at = first.cend();
66 for (; it1 != first.cend(); ++it1, ++it2) {
67 const auto eps = func(*it1, *it2);
68 if (std::abs(eps) > std::abs(largest_eps)) {
73 return std::make_pair(largest_eps, largest_at);
82auto compare_eps(
const std::vector<T> &first,
const std::vector<T> &second) {
84 std::is_floating_point_v<T>,
85 "In compare_eps(std::vector<T>, std::vector<T>), T must be floating pt");
86 assert(first.size() == second.size());
88 auto it1 = first.cbegin();
89 auto it2 = second.cbegin();
90 auto largest_eps =
static_cast<T
>(0);
91 auto largest_at = first.cend();
92 for (; it1 != first.cend(); ++it1, ++it2) {
93 const auto eps = (*it1 - *it2) / (*it2);
94 if (std::abs(eps) > std::abs(largest_eps)) {
99 return std::make_pair(largest_eps, largest_at);
105template <
typename T,
typename... Args>
106void add(std::vector<T> *first,
const std::vector<T> &second,
107 const Args &...rest) {
109 if (first->size() < second.size())
110 first->resize(second.size());
112 for (std::size_t i = 0; i < second.size(); ++i) {
113 (*first)[i] += second[i];
115 if constexpr (
sizeof...(rest) != 0)
122template <
typename T,
typename... Args>
123[[nodiscard]] std::vector<T>
124add(std::vector<T> first,
const std::vector<T> &second,
const Args &...rest) {
125 add(&first, second, rest...);
140template <
typename T,
typename... Args>
141void multiply(std::vector<T> *first,
const std::vector<T> &second,
142 const Args &...rest) {
144 static_assert(std::is_arithmetic_v<T>,
145 "In multiply(std::vector<T>...) : T must be arithmetic");
148 const auto size = std::min(first->size(), second.size());
149 if (first->size() < second.size())
150 first->resize(second.size());
152 for (std::size_t i = 0; i < size; ++i) {
153 (*first)[i] *= second[i];
155 for (std::size_t i = size; i < first->size(); ++i) {
156 (*first)[i] =
static_cast<T
>(0);
158 if constexpr (
sizeof...(rest) != 0)
165template <
typename T,
typename... Args>
166[[nodiscard]] std::vector<T>
multiply(std::vector<T> first,
167 const std::vector<T> &second,
168 const Args &...rest) {
178template <
typename F,
typename T,
typename... Args>
179void compose(
const F &func, std::vector<T> *first,
const std::vector<T> &second,
180 const Args &...rest) {
183 if (first->size() < second.size())
184 first->resize(second.size());
186 for (std::size_t i = 0; i < second.size(); ++i) {
187 (*first)[i] = func((*first)[i], second[i]);
189 for (std::size_t i = second.size(); i < first->size(); ++i) {
190 (*first)[i] = func((*first)[i],
static_cast<T
>(0));
192 if constexpr (
sizeof...(rest) != 0)
199template <
typename F,
typename T,
typename... Args>
200[[nodiscard]] std::vector<T>
compose(
const F &func, std::vector<T> first,
201 const std::vector<T> &second,
202 const Args &...rest) {
203 compose(func, &first, second, rest...);
210void scale(std::vector<T> *vec, T x) {
211 static_assert(std::is_arithmetic_v<T>,
212 "In scale(std::vector<T>, T) : T must be arithmetic");
219[[nodiscard]] std::vector<T>
scale(std::vector<T> vec, T x) {
231template <
typename T =
double,
typename N = std::
size_t>
233 static_assert(std::is_arithmetic_v<T>,
234 "In uniform_range(T, T, N), T must be arithmetic");
235 static_assert(std::is_integral_v<N>,
236 "In uniform_range(T, T, N), N must be integral");
237 std::vector<T> range;
240 range.reserve(
static_cast<std::size_t
>(number));
241 range.push_back(first);
244 const auto interval =
static_cast<double>(last - first);
245 for (N i = 1; i < number - 1; ++i) {
246 const auto eps =
static_cast<double>(i) /
static_cast<double>(number - 1);
247 const auto value =
static_cast<double>(first) + (eps * interval);
248 range.push_back(
static_cast<T
>(value));
250 range.push_back(last);
260template <
typename T =
double,
typename N = std::
size_t>
262 static_assert(std::is_arithmetic_v<T>,
263 "In logarithmic_range(T, T, N), T must be arithmetic");
264 static_assert(std::is_integral_v<N>,
265 "In logarithmic_range(T, T, N), N must be integral");
267 std::vector<T> range;
270 range.reserve(
static_cast<std::size_t
>(number));
271 range.push_back(first);
274 const auto log_ratio =
275 std::log(
static_cast<double>(last) /
static_cast<double>(first));
276 for (N i = 1; i < number - 1; ++i) {
277 const auto eps =
static_cast<double>(i) /
static_cast<double>(number - 1);
278 const auto value =
static_cast<double>(first) * std::exp(log_ratio * eps);
279 range.push_back(
static_cast<T
>(value));
281 range.push_back(last);
290template <
typename T =
double,
typename N = std::
size_t>
292 static_assert(std::is_floating_point_v<T>,
293 "In loglinear_range(T, T, T, N), T must be floating point");
294 static_assert(std::is_integral_v<N>,
295 "In loglinear_range(T, T, T, N), N must be integral");
297 assert(first > 0.0 && last > 0.0 && b > 0.0);
299 std::vector<T> range;
300 range.reserve(
static_cast<std::size_t
>(number));
302 const auto du = (last - first + b * std::log(last / first)) /
303 (
static_cast<T
>(number - 1));
305 auto next_r = [b](
auto u1,
auto r_guess) {
310 const auto f_u = [b, u1](
double tr) {
return tr + b * std::log(tr) - u1; };
311 const auto dr = 0.1 * r_guess;
312 const auto delta_targ = r_guess * 1.0e-18;
313 const auto [ri, delta_r] =
qip::Newtons(f_u, r_guess, delta_targ, dr, 30);
317 auto u = first + b * std::log(first);
318 range.push_back(first);
319 for (N i = 1; i < number - 1; ++i) {
321 range.push_back(next_r(u, range.back()));
323 range.push_back(last);
330template <
typename T,
typename... Args>
331constexpr auto multiply_at(std::size_t i,
const T &first,
const Args &...rest) {
333 if constexpr (
sizeof...(rest) == 0) {
341template <
typename T,
typename... Args>
344 for (std::size_t i = 1; i < first.size(); ++i) {
350template <
typename T,
typename... Args>
351auto inner_product_sub(std::size_t p0, std::size_t pinf,
const T &first,
352 const Args &...rest) {
353 auto res =
decltype(first[0])(0);
354 for (std::size_t i = p0; i < pinf; ++i) {
361template <
typename F,
typename T>
362T apply_to(
const F &func, T list) {
363 for (
auto &l : list) {
372template <
typename T,
typename Func>
373std::vector<T>
select_if(
const std::vector<T> &in, Func condition) {
375 for (
const auto &el : in) {
384template <
typename T,
typename Func>
387 for (
const auto &el : in) {
389 inout->push_back(el);
400 std::size_t f = in.size();
403 std::swap(in[i], in[f - 1]);
416 for (
const auto &x : vec) {
419 return sum / T(vec.size());
424T
variance(std::vector<T> vec, std::size_t dof = 0) {
425 assert(dof < vec.size());
426 const auto xbar =
mean(vec);
428 for (
const auto &x : vec) {
429 const auto del = x - xbar;
432 return sum / T(vec.size() - dof);
437T
sdev(std::vector<T> vec, std::size_t dof = 0) {
438 return std::sqrt(
variance(vec, dof));
443T
sem(std::vector<T> vec, std::size_t dof = 0) {
444 return sdev(vec, dof) / std::sqrt(T(vec.size()));
454std::vector<T> &
operator+=(std::vector<T> &a,
const std::vector<T> &b) {
456 const auto smaller_size = std::min(a.size(), b.size());
457 if (a.size() < b.size())
458 a.insert(a.end(), b.begin() +
long(a.size()), b.end());
459 for (
auto i = 0ul; i < smaller_size; ++i) {
465std::vector<T> operator+(std::vector<T> a,
const std::vector<T> &b) {
470std::vector<T> &operator-=(std::vector<T> &a,
const std::vector<T> &b) {
471 const auto size = std::max(a.size(), b.size());
473 for (
auto i = 0ul; i < b.size(); ++i) {
479std::vector<T> operator-(std::vector<T> a,
const std::vector<T> &b) {
484template <
typename T,
typename U>
485std::vector<T> &operator*=(std::vector<T> &v, U x) {
487 for (
auto &v_i : v) {
493template <
typename T,
typename U>
494std::vector<T> operator*(std::vector<T> v, U x) {
497template <
typename T,
typename U>
498std::vector<T> operator*(U x, std::vector<T> v) {
503template <
typename T,
typename U>
504std::vector<T> &operator/=(std::vector<T> &v, U x) {
506 for (
auto &v_i : v) {
512template <
typename T,
typename U>
513std::vector<T> operator/(std::vector<T> v, U x) {
518template <
typename T,
typename U>
519std::vector<T> &
operator+=(std::vector<T> &v, U x) {
521 for (
auto &v_i : v) {
527template <
typename T,
typename U>
528std::vector<T> operator+(std::vector<T> v, U x) {
531template <
typename T,
typename U>
532std::vector<T> operator+(U x, std::vector<T> v) {
536template <
typename T,
typename U>
537std::vector<T> &operator-=(std::vector<T> &v, U x) {
539 for (
auto &v_i : v) {
545template <
typename T,
typename U>
546std::vector<T> operator-(std::vector<T> v, U x) {
549template <
typename T,
typename U>
550std::vector<T> operator-(U x, std::vector<T> v) {
556template <
typename T,
typename U>
557std::vector<T> operator/(U x, std::vector<T> v) {
558 for (
auto &v_i : v) {
566std::vector<T> &operator*=(std::vector<T> &a,
const std::vector<T> &b) {
567 const auto min_size = std::min(a.size(), b.size());
568 for (std::size_t i = 0; i < min_size; ++i) {
571 for (std::size_t i = min_size; i < a.size(); ++i) {
574 if (a.size() < b.size())
580std::vector<T> operator*(std::vector<T> a,
const std::vector<T> &b) {
586std::vector<T> &operator/=(std::vector<T> &a,
const std::vector<T> &b) {
587 assert(a.size() == b.size());
588 for (std::size_t i = 0; i < a.size(); ++i) {
595std::vector<T> operator/(std::vector<T> a,
const std::vector<T> &b) {
std::vector< T > & operator+=(std::vector< T > &a, const std::vector< T > &b)
Provide addition of two vectors:
Definition Vector.hpp:454
qip library: A collection of useful functions
Definition Array.hpp:9
void add(std::vector< T > *first, const std::vector< T > &second, const Args &...rest)
Adds any number of vectors, in place (modifies first vector). Must be of same type....
Definition Vector.hpp:106
std::vector< T > logarithmic_range(T first, T last, N number)
Produces a logarithmicly*(see below) distributed range of values between [first,last] with number ste...
Definition Vector.hpp:261
auto compare_eps(const std::vector< T > &first, const std::vector< T > &second)
Compares values of two arithmetic vectors of the same type and length, relative to second value....
Definition Vector.hpp:82
void compose(const F &func, std::vector< T > *first, const std::vector< T > &second, const Args &...rest)
Composes any number of vectors, in place (modifies first vector), using the provided function....
Definition Vector.hpp:179
void scale(std::vector< T > *vec, T x)
In-place scalar multiplication of std::vector - types must match.
Definition Vector.hpp:210
T sem(std::vector< T > vec, std::size_t dof=0)
Standard deviation: sqrt(variance)
Definition Vector.hpp:443
std::vector< T > select_if(const std::vector< T > &in, Func condition)
Creates a subset of a vector, whose element match condition. By copy. condition must have function si...
Definition Vector.hpp:373
T mean(std::vector< T > vec)
Mean: xbar = \sum_i x_i / N.
Definition Vector.hpp:414
std::pair< Real, Real > Newtons(Function f, Real x, Real delta_target=Real{1.0e-6}, Real dx=Real{0.01}, unsigned it_limit=250)
Solve f(x) = 0 for x using Newtons method. Returns root + error estimate/.
Definition Methods.hpp:41
std::vector< T > merge(std::vector< T > first, const std::vector< T > &second, const Args &...rest)
Merges a number of vectors: {a,b,c},{d,e},{f} -> {a,b,c,d,e,f}.
Definition Vector.hpp:18
std::vector< T > uniform_range(T first, T last, N number)
Produces a uniformly*(see below) distributed range of values between [first,last] with number steps....
Definition Vector.hpp:232
std::vector< T > reverse(std::vector< T > in)
Reverses a list.
Definition Vector.hpp:397
constexpr auto inner_product(const T &first, const Args &...rest)
Variadic inner product (v1,v2,...vn) : sum_i v1[i]*v2[i]*...vn[i].
Definition Vector.hpp:342
T sdev(std::vector< T > vec, std::size_t dof=0)
Standard deviation: sqrt(variance)
Definition Vector.hpp:437
void insert_into_if(const std::vector< T > &in, std::vector< T > *inout, Func condition)
Inserts elements from in into inout, if condition is met.
Definition Vector.hpp:385
void multiply(std::vector< T > *first, const std::vector< T > &second, const Args &...rest)
Multiplies any number of (arithmetic) vectors, in place (modifies first vector). Must be of same type...
Definition Vector.hpp:141
auto compare(const std::vector< T > &first, const std::vector< T > &second)
Directly compare two arithmetic vectors of the same type and length. Returns pair {delta,...
Definition Vector.hpp:33
T variance(std::vector< T > vec, std::size_t dof=0)
Variance: \sum_i (x_i-xbar)^2 / (N-dof)
Definition Vector.hpp:424
std::vector< T > loglinear_range(T first, T last, T b, N number)
Produces a Log-Linear distributed range of values between [first,last] with number steps....
Definition Vector.hpp:291
constexpr auto multiply_at(std::size_t i, const T &first, const Args &...rest)
first[i]*...rest[i] – used to allow inner_product
Definition Vector.hpp:331