SIRIUS 7.5.0
Electronic structure library and applications
math_tools.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2023 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file math_tools.hpp
21 *
22 * \brief Math helper functions.
23 */
24
25#ifndef __MATH_TOOLS_HPP__
26#define __MATH_TOOLS_HPP__
27
28namespace sirius {
29
30inline auto confined_polynomial(double r, double R, int p1, int p2, int dm)
31{
32 double t = 1.0 - std::pow(r / R, 2);
33 switch (dm) {
34 case 0: {
35 return (std::pow(r, p1) * std::pow(t, p2));
36 }
37 case 2: {
38 return (-4 * p1 * p2 * std::pow(r, p1) * std::pow(t, p2 - 1) / std::pow(R, 2) +
39 p1 * (p1 - 1) * std::pow(r, p1 - 2) * std::pow(t, p2) +
40 std::pow(r, p1) * (4 * (p2 - 1) * p2 * std::pow(r, 2) * std::pow(t, p2 - 2) / std::pow(R, 4) -
41 2 * p2 * std::pow(t, p2 - 1) / std::pow(R, 2)));
42 }
43 default: {
44 RTE_THROW("wrong derivative order");
45 return 0.0;
46 }
47 }
48}
49
50/// Sign of the variable.
51template <typename T>
52inline int sign(T val)
53{
54 return (T(0) < val) - (val < T(0));
55}
56
57/// Checks if number is integer with a given tolerance.
58template <typename T>
59inline bool is_int(T val__, T eps__)
60{
61 if (std::abs(std::round(val__) - val__) > eps__) {
62 return false;
63 } else {
64 return true;
65 }
66}
67
68/// Compute a factorial.
69template <typename T>
70inline T factorial(int n)
71{
72 RTE_ASSERT(n >= 0);
73
74 T result{1};
75 for (int i = 1; i <= n; i++) {
76 result *= i;
77 }
78 return result;
79}
80
81inline auto round(double a__, int n__)
82{
83 double a0 = std::floor(a__);
84 double b = std::round((a__ - a0) * std::pow(10, n__)) / std::pow(10, n__);
85 return a0 + b;
86}
87
88inline auto round(std::complex<double> a__, int n__)
89{
90 return std::complex<double>(round(a__.real(), n__), round(a__.imag(), n__));
91}
92
93/// Simple hash function.
94/** Example: std::printf("hash: %16llX\n", hash()); */
95inline auto hash(void const* buff, size_t size, uint64_t h = 5381)
96{
97 unsigned char const* p = static_cast<unsigned char const*>(buff);
98 for (size_t i = 0; i < size; i++) {
99 h = ((h << 5) + h) + p[i];
100 }
101 return h;
102}
103
104/// Simple random number generator.
105inline uint32_t random_uint32(bool reset = false)
106{
107 static uint32_t a = 123456;
108 if (reset) {
109 a = 123456;
110 }
111 a = (a ^ 61) ^ (a >> 16);
112 a = a + (a << 3);
113 a = a ^ (a >> 4);
114 a = a * 0x27d4eb2d;
115 a = a ^ (a >> 15);
116 return a;
117}
118
119template <typename T>
120inline T random();
121
122template <>
123inline int random<int>()
124{
125 return static_cast<int>(random_uint32());
126}
127
128template <>
129inline double random<double>()
130{
131 return static_cast<double>(random_uint32()) / std::numeric_limits<uint32_t>::max();
132}
133
134template <>
135inline std::complex<double> random<std::complex<double>>()
136{
137 return std::complex<double>(random<double>(), random<double>());
138}
139
140template <>
141inline float random<float>()
142{
143 return static_cast<float>(random<double>());
144}
145
146template <>
147inline std::complex<float> random<std::complex<float>>()
148{
149 return std::complex<float>(random<float>(), random<float>());
150}
151
152template <typename T>
153auto abs_diff(T a, T b)
154{
155 return std::abs(a - b);
156}
157
158template <typename T>
159auto rel_diff(T a, T b)
160{
161 return std::abs(a - b) / (std::abs(a) + std::abs(b) + 1e-13);
162}
163
164/// Return complex conjugate of a number. For a real value this is the number itself.
165inline auto conj(double x__)
166{
167 /* std::conj() will return complex for a double value input; this is not what we want */
168 return x__;
169}
170
171/// Return complex conjugate of a number.
172inline auto conj(std::complex<double> x__)
173{
174 return std::conj(x__);
175}
176
177template <typename T>
178inline T zero_if_not_complex(T x__)
179{
180 return x__;
181};
182
183template <typename T>
184inline T zero_if_not_complex(std::complex<T> x__)
185{
186 return 0;
187};
188
189}
190
191#endif
192
void reset()
Reset device.
Definition: acc.hpp:240
Namespace of the SIRIUS library.
Definition: sirius.f90:5
bool is_int(T val__, T eps__)
Checks if number is integer with a given tolerance.
Definition: math_tools.hpp:59
T factorial(int n)
Compute a factorial.
Definition: math_tools.hpp:70
auto hash(void const *buff, size_t size, uint64_t h=5381)
Simple hash function.
Definition: math_tools.hpp:95
uint32_t random_uint32(bool reset=false)
Simple random number generator.
Definition: math_tools.hpp:105
auto conj(std::complex< double > x__)
Return complex conjugate of a number.
Definition: math_tools.hpp:172
int sign(T val)
Sign of the variable.
Definition: math_tools.hpp:52
auto conj(double x__)
Return complex conjugate of a number. For a real value this is the number itself.
Definition: math_tools.hpp:165