ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Maths.hpp
1 #pragma once
2 #include "Vector.hpp"
3 #include <cmath>
4 #include <type_traits>
5 
6 namespace qip {
7 
10 struct less_abs {
11  template <class T>
12  constexpr bool operator()(const T &lhs, const T &rhs) const {
13  static_assert(std::is_arithmetic_v<T>,
14  "In less_abs<T>(), T must be arithmetic");
15  return std::abs(lhs) < std::abs(rhs);
16  }
17 };
18 
19 //==============================================================================
21 template <typename T, typename... Args>
22 T max(T first, Args... rest) {
23  if constexpr (sizeof...(rest) == 0) {
24  return first;
25  } else {
26  const auto max_rest = max(rest...);
27  if (first >= max_rest)
28  return first;
29  return max_rest;
30  }
31 }
33 template <typename T, typename... Args>
34 T min(T first, Args... rest) {
35  if constexpr (sizeof...(rest) == 0) {
36  return first;
37  } else {
38  const auto min_rest = min(rest...);
39  if (first <= min_rest)
40  return first;
41  return min_rest;
42  }
43 }
44 
47 template <typename T, typename... Args>
48 T max_abs(T first, Args... rest) {
49  static_assert(std::is_arithmetic_v<T>,
50  "In max_abs<T>(), T must be arithmetic");
51  if constexpr (sizeof...(rest) == 0) {
52  return first;
53  } else {
54  const auto max_rest = max_abs(rest...);
55  if (std::abs(first) >= std::abs(max_rest))
56  return first;
57  return max_rest;
58  }
59 }
62 template <typename T, typename... Args>
63 T min_abs(T first, Args... rest) {
64  static_assert(std::is_arithmetic_v<T>,
65  "In min_abs<T>(), T must be arithmetic");
66  if constexpr (sizeof...(rest) == 0) {
67  return first;
68  } else {
69  const auto min_rest = min_abs(rest...);
70  if (std::abs(first) <= std::abs(min_rest))
71  return first;
72  return min_rest;
73  }
74 }
75 
77 template <typename T, typename... Args>
78 T max_difference(T first, Args... rest) {
79  static_assert(std::is_arithmetic_v<T>,
80  "In max_difference<T>(), T must be arithmetic");
81  return max(first, rest...) - min(first, rest...);
82 }
83 
84 //==============================================================================
87 template <int n, typename T>
88 constexpr auto pow(T x) {
89  using namespace qip::overloads;
90  // Returns double for inverse powers, T otherwise
91  if constexpr (n < 0) {
92  return double(1.0) / pow<-n>(x);
93  } else if constexpr (n == 0) {
94  (void)x; // 'x' unused in this branch
95  return static_cast<T>(1);
96  } else if constexpr (n == 1) {
97  return x;
98  } else {
99  return x * pow<n - 1>(x);
100  }
101 }
102 
104 template <typename T>
105 constexpr T pow(T x, int n) {
106  static_assert(std::is_floating_point_v<T>,
107  "In pow(T x, int n), T must be foating point");
108  if (n < 0) {
109  return static_cast<T>(1) / pow<T>(x, -n);
110  }
111  // T result = static_cast<T>(1);
112  T result{1};
113  for (int i = 0; i < n; ++i) {
114  result *= x;
115  }
116  return result;
117 }
118 
119 //==============================================================================
121 template <typename T>
122 constexpr int sign(T value) {
123  static_assert(std::is_arithmetic_v<T>,
124  "In sign(T value), T must be arithmetic");
125  return (T(0) < value) - (value < T(0));
126 }
127 
130 template <typename T>
131 constexpr T clip(T value, T max_abs) {
132  static_assert(std::is_arithmetic_v<T>,
133  "In clip(T value, T max_abs), T must be arithmetic");
134  if (value > max_abs)
135  return max_abs;
136  if (value < -max_abs)
137  return -max_abs;
138  return value;
139 }
140 
142 template <typename T>
143 constexpr T chop(T value, T min_abs) {
144  static_assert(std::is_arithmetic_v<T>,
145  "In clip(T value, T max_abs), T must be arithmetic");
146  if (std::abs(value) < min_abs)
147  return static_cast<T>(0);
148  return value;
149 }
150 
151 } // namespace qip
namespace qip::overloads provides operator overloads for std::vector
Definition: Vector.hpp:450
qip library: A collection of useful functions
Definition: Array.hpp:8
T max_difference(T first, Args... rest)
Returns max{args..} - min{args...}, for any number of args (variadic)
Definition: Maths.hpp:78
T max(T first, Args... rest)
Returns maximum of any number of parameters (variadic function)
Definition: Maths.hpp:22
constexpr int sign(T value)
Returns sign of value. Note: sign(0)==0.
Definition: Maths.hpp:122
T max_abs(T first, Args... rest)
Returns value with maximum absolute value of any number of parameters (variadic function)
Definition: Maths.hpp:48
T min(T first, Args... rest)
Returns minimum of any number of parameters (variadic function)
Definition: Maths.hpp:34
constexpr T chop(T value, T min_abs)
Sets values |v|<min to zero; if |v|>=min, returns v.
Definition: Maths.hpp:143
T min_abs(T first, Args... rest)
Returns value with minimum absolute value of any number of parameters (variadic function)
Definition: Maths.hpp:63
constexpr auto pow(T x)
x^n for integer n (n compile-time template parameter), x any arithmetic type (T). Returns double for ...
Definition: Maths.hpp:88
constexpr T clip(T value, T max_abs)
Clips value to between -max <= value <= max clip(x,max) : |x| > max, ret max; if |x|<-max,...
Definition: Maths.hpp:131
Function object for performing comparisons of absolute values (uses std::abs). Works similarly to std...
Definition: Maths.hpp:10