diff options
Diffstat (limited to 'src/lib/netlist/plib/pmath.h')
-rw-r--r-- | src/lib/netlist/plib/pmath.h | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/src/lib/netlist/plib/pmath.h b/src/lib/netlist/plib/pmath.h new file mode 100644 index 00000000000..acacd0a5ab1 --- /dev/null +++ b/src/lib/netlist/plib/pmath.h @@ -0,0 +1,337 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * pmath.h + * + */ + +#ifndef PMATH_H_ +#define PMATH_H_ + +#include "pconfig.h" + +#include <algorithm> +#include <type_traits> +#include <cmath> + +#if (PUSE_FLOAT128) +#include <quadmath.h> +#endif + +namespace plib +{ + + /*! Holds constants used repeatedly. + * + * @tparam T floating point type + * + * Using the structure members we can avoid magic numbers in the code. + * In addition, this is a typesafe approach. + */ + template <typename T> + struct constants + { + static inline constexpr T zero() noexcept { return static_cast<T>(0); } + static inline constexpr T half() noexcept { return static_cast<T>(0.5); } + static inline constexpr T one() noexcept { return static_cast<T>(1); } + static inline constexpr T two() noexcept { return static_cast<T>(2); } + static inline constexpr T three() noexcept { return static_cast<T>(3); } + static inline constexpr T four() noexcept { return static_cast<T>(4); } + static inline constexpr T sqrt2() noexcept { return static_cast<T>(1.414213562373095048801688724209L); } + static inline constexpr T pi() noexcept { return static_cast<T>(3.14159265358979323846264338327950L); } + + /*! + * \brief Electric constant of vacuum + */ + static inline constexpr T eps_0() noexcept { return static_cast<T>(8.854187817e-12); } + /*! + * \brief Relative permittivity of Silicon dioxide + */ + static inline constexpr T eps_SiO2() noexcept { return static_cast<T>(3.9); } + /*! + * \brief Relative permittivity of Silicon + */ + static inline constexpr T eps_Si() noexcept { return static_cast<T>(11.7); } + /*! + * \brief Boltzmann constant + */ + static inline constexpr T k_b() noexcept { return static_cast<T>(1.38064852e-23); } + /*! + * \brief room temperature (gives VT = 0.02585 at T=300) + */ + static inline constexpr T T0() noexcept { return static_cast<T>(300); } + /*! + * \brief Elementary charge + */ + static inline constexpr T Q_e() noexcept { return static_cast<T>(1.6021765314e-19); } + /*! + * \brief Intrinsic carrier concentration in 1/m^3 of Silicon + */ + static inline constexpr T NiSi() noexcept { return static_cast<T>(1.45e16); } + /*! + * \brief clearly identify magic numbers in code + * + * Magic numbers should be avoided. The magic member at least clearly + * identifies them and makes it easier to convert them to named constants + * later. + */ + template <typename V> + static inline constexpr const T magic(V &&v) noexcept { return static_cast<T>(v); } + }; + + /*! typesafe reciprocal function + * + * @tparam T type of the argument + * @param v argument + * @return reciprocal of argument + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + reciprocal(T v) noexcept + { + return constants<T>::one() / v; + } + + /*! abs function + * + * @tparam T type of the argument + * @param v argument + * @return absolute value of argument + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + abs(T v) noexcept + { + return std::abs(v); + } + + /*! sqrt function + * + * @tparam T type of the argument + * @param v argument + * @return absolute value of argument + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + sqrt(T v) noexcept + { + return std::sqrt(v); + } + + /*! hypot function + * + * @tparam T type of the arguments + * @param v1 first argument + * @param v2 second argument + * @return sqrt(v1*v1+v2*v2) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + hypot(T v1, T v2) noexcept + { + return std::hypot(v1, v2); + } + + /*! exp function + * + * @tparam T type of the argument + * @param v argument + * @return exp(v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + exp(T v) noexcept + { + return std::exp(v); + } + + /*! log function + * + * @tparam T type of the argument + * @param v argument + * @return log(v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + log(T v) noexcept + { + return std::log(v); + } + + /*! tanh function + * + * @tparam T type of the argument + * @param v argument + * @return tanh(v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + tanh(T v) noexcept + { + return std::tanh(v); + } + + /*! floor function + * + * @tparam T type of the argument + * @param v argument + * @return floor(v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + floor(T v) noexcept + { + return std::floor(v); + } + + /*! log1p function + * + * @tparam T type of the argument + * @param v argument + * @return log(1 + v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + log1p(T v) noexcept + { + return std::log1p(v); + } + + /*! sin function + * + * @tparam T type of the argument + * @param v argument + * @return sin(v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + sin(T v) noexcept + { + return std::sin(v); + } + + /*! cos function + * + * @tparam T type of the argument + * @param v argument + * @return cos(v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + cos(T v) noexcept + { + return std::cos(v); + } + + /*! trunc function + * + * @tparam T type of the argument + * @param v argument + * @return trunc(v) + */ + template <typename T> + static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type + trunc(T v) noexcept + { + return std::trunc(v); + } + + /*! pow function + * + * @tparam T1 type of the first argument + * @tparam T2 type of the second argument + * @param v argument + * @param p power + * @return v^p + * + * FIXME: limited implementation + */ + template <typename T1, typename T2> + static inline T1 + pow(T1 v, T2 p) noexcept + { + return std::pow(v, p); + } + +#if (PUSE_FLOAT128) + static inline constexpr __float128 reciprocal(__float128 v) noexcept + { + return constants<__float128>::one() / v; + } + + static inline __float128 abs(__float128 v) noexcept + { + return fabsq(v); + } + + static inline __float128 sqrt(__float128 v) noexcept + { + return sqrtq(v); + } + + static inline __float128 hypot(__float128 v1, __float128 v2) noexcept + { + return hypotq(v1, v2); + } + + static inline __float128 exp(__float128 v) noexcept + { + return expq(v); + } + + static inline __float128 log(__float128 v) noexcept + { + return logq(v); + } + + static inline __float128 tanh(__float128 v) noexcept + { + return tanhq(v); + } + + static inline __float128 floor(__float128 v) noexcept + { + return floorq(v); + } + + static inline __float128 log1p(__float128 v) noexcept + { + return log1pq(v); + } + + static inline __float128 sin(__float128 v) noexcept + { + return sinq(v); + } + + static inline __float128 cos(__float128 v) noexcept + { + return cosq(v); + } + + static inline __float128 trunc(__float128 v) noexcept + { + return truncq(v); + } + + template <typename T> + static inline __float128 pow(__float128 v, T p) noexcept + { + return powq(v, static_cast<__float128>(p)); + } + + static inline __float128 pow(__float128 v, int p) noexcept + { + if (p==2) + return v*v; + else + return powq(v, static_cast<__float128>(p)); + } + +#endif + + static_assert(noexcept(constants<double>::one()) == true, "Not evaluated as constexpr"); + +} // namespace plib + +#endif /* PMATH_H_ */ |