flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
numerics2.hpp
Go to the documentation of this file.
1// ====================================================================
2// This file is part of FlexibleSUSY.
3//
4// FlexibleSUSY is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// FlexibleSUSY is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with FlexibleSUSY. If not, see
16// <http://www.gnu.org/licenses/>.
17// ====================================================================
18
19#ifndef NUMERICS_HPP
20#define NUMERICS_HPP
21
22#include <array>
23#include <cmath>
24#include <complex>
25#include <limits>
26#include <cstddef>
27#include <cstdlib>
28#include <type_traits>
29
30namespace flexiblesusy {
31
32namespace detail {
33
34template <class T> struct is_complex : public std::false_type {};
35template <class T> struct is_complex<const T > : public is_complex<T>{};
36template <class T> struct is_complex<volatile const T > : public is_complex<T>{};
37template <class T> struct is_complex<volatile T > : public is_complex<T>{};
38template <class T> struct is_complex<std::complex<T> > : public std::true_type{};
39
40} // namespace detail
41
42
44template <typename T>
45std::enable_if_t<std::is_unsigned<T>::value, bool>
47{
48 return a <= prec;
49}
50
51
53template <typename T>
54std::enable_if_t<!std::is_unsigned<T>::value &&
55 !detail::is_complex<T>::value, bool>
57{
58 return std::abs(a) <= prec;
59}
60
61
63template <typename T>
64std::enable_if_t<detail::is_complex<T>::value, bool>
66 typename T::value_type prec
68{
69 return is_zero(a.real(), prec) && is_zero(a.imag(), prec);
70}
71
72
74template <typename T>
75bool is_equal(T a, T b, T prec = std::numeric_limits<T>::epsilon()) noexcept
76{
77 return is_zero(a - b, prec);
78}
79
80
82template <typename T>
83bool is_equal(std::complex<T> a, std::complex<T> b,
84 T prec = std::numeric_limits<T>::epsilon()) noexcept
85{
86 return is_equal(a.real(), b.real(), prec) &&
87 is_equal(a.imag(), b.imag(), prec);
88}
89
90
92template <typename T>
93std::enable_if_t<!std::is_unsigned<T>::value, bool>
95{
96 const T max = std::max(std::abs(a), std::abs(b));
97 return is_zero(a - b, max*prec);
98}
99
100
103template <typename T>
104std::enable_if_t<!std::is_unsigned<T>::value, bool>
105is_equal_rel(T a, T b, T prec = std::numeric_limits<T>::epsilon()) noexcept
106{
108 return true;
109 }
110
111 const T min = std::min(std::abs(a), std::abs(b));
112
114 return is_equal(a, b, prec);
115 }
116
117 const T max = std::max(std::abs(a), std::abs(b));
118
119 return is_equal(a, b, prec*max);
120}
121
122
125template <typename T>
126std::enable_if_t<std::is_unsigned<T>::value, bool>
127is_equal_rel(T a, T b, T prec = std::numeric_limits<T>::epsilon()) noexcept
128{
129 using ST = typename std::make_signed<T>::type;
130 const auto sa = static_cast<ST>(a);
131 const auto sb = static_cast<ST>(b);
132 const auto sprec = static_cast<ST>(prec);
133
134 return is_equal_rel(sa, sb, sprec);
135}
136
137
139bool is_finite(const double*, long) noexcept;
140
141
143template <typename T, std::size_t N>
144bool is_finite(const T (&v)[N]) noexcept
145{
146 return is_finite(&v[0], N);
147}
148
149
151template <typename T, std::size_t N>
152bool is_finite(const std::array<T, N>& v) noexcept
153{
154 return is_finite(&v[0], N);
155}
156
157
159template <class T>
160std::complex<T> fast_log(const std::complex<T>& z) noexcept
161{
162 const T rz = std::real(z);
163 const T iz = std::imag(z);
164
165 return std::complex<T>(0.5*std::log(rz*rz + iz*iz), std::atan2(iz, rz));
166}
167
168} // namespace flexiblesusy
169
170#endif
const Real epsilon
Definition: mathdefs.hpp:18
bool is_equal(T a, T b, T prec=std::numeric_limits< T >::epsilon()) noexcept
compares two numbers for (absolute) equality
Definition: numerics2.hpp:75
std::enable_if_t< std::is_unsigned< T >::value, bool > is_zero(T a, T prec=std::numeric_limits< T >::epsilon()) noexcept
compares a number for being close to zero
Definition: numerics2.hpp:46
bool is_finite(const gsl_vector *x)
Returns true if GSL vector contains only finite elements, false otherwise.
Definition: gsl_utils.cpp:32
std::complex< T > fast_log(const std::complex< T > &z) noexcept
fast implementation of complex logarithm
Definition: numerics2.hpp:160
Complex< T > log(const Complex< T > &z) noexcept
Definition: complex.hpp:54
bool is_equal_rel(const Eigen::PlainObjectBase< Derived > &a, const Eigen::PlainObjectBase< Derived > &b, double eps)
Definition: eigen_utils.hpp:89
std::enable_if_t<!std::is_unsigned< T >::value, bool > is_equal_fraction(T a, T b, T prec=std::numeric_limits< T >::epsilon()) noexcept
compares two numbers for relative equality
Definition: numerics2.hpp:94