// license:GPL-2.0+ // copyright-holders:Couriersud #ifndef PMATH_H_ #define PMATH_H_ /// /// \file pmath.h /// #include "pconfig.h" #include #include #include #if (PUSE_FLOAT128) #include #endif namespace plib { /// \brief 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 struct constants { static inline constexpr T zero() noexcept { return static_cast(0); } static inline constexpr T half() noexcept { return static_cast(0.5); } static inline constexpr T one() noexcept { return static_cast(1); } static inline constexpr T two() noexcept { return static_cast(2); } static inline constexpr T three() noexcept { return static_cast(3); } static inline constexpr T four() noexcept { return static_cast(4); } static inline constexpr T sqrt2() noexcept { return static_cast(1.414213562373095048801688724209L); } static inline constexpr T pi() noexcept { return static_cast(3.14159265358979323846264338327950L); } /// \brief Electric constant of vacuum /// static inline constexpr T eps_0() noexcept { return static_cast(8.854187817e-12); } // \brief Relative permittivity of Silicon dioxide /// static inline constexpr T eps_SiO2() noexcept { return static_cast(3.9); } /// \brief Relative permittivity of Silicon /// static inline constexpr T eps_Si() noexcept { return static_cast(11.7); } /// \brief Boltzmann constant /// static inline constexpr T k_b() noexcept { return static_cast(1.38064852e-23); } /// \brief room temperature (gives VT = 0.02585 at T=300) /// static inline constexpr T T0() noexcept { return static_cast(300); } /// \brief Elementary charge /// static inline constexpr T Q_e() noexcept { return static_cast(1.6021765314e-19); } /// \brief Intrinsic carrier concentration in 1/m^3 of Silicon /// static inline constexpr T NiSi() noexcept { return static_cast(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 static inline constexpr const T magic(V &&v) noexcept { return static_cast(v); } }; /// \brief typesafe reciprocal function /// /// \tparam T type of the argument /// \param v argument /// \return reciprocal of argument /// template static inline constexpr typename std::enable_if::value, T>::type reciprocal(T v) noexcept { return constants::one() / v; } /// \brief abs function /// /// \tparam T type of the argument /// \param v argument /// \return absolute value of argument /// template static inline constexpr typename std::enable_if::value, T>::type abs(T v) noexcept { return std::abs(v); } /// \brief sqrt function /// /// \tparam T type of the argument /// \param v argument /// \return absolute value of argument /// template static inline constexpr typename std::enable_if::value, T>::type sqrt(T v) noexcept { return std::sqrt(v); } /// \brief hypot function /// /// \tparam T type of the arguments /// \param v1 first argument /// \param v2 second argument /// \return sqrt(v1*v1+v2*v2) /// template static inline constexpr typename std::enable_if::value, T>::type hypot(T v1, T v2) noexcept { return std::hypot(v1, v2); } /// \brief exp function /// /// \tparam T type of the argument /// \param v argument /// \return exp(v) /// template static inline constexpr typename std::enable_if::value, T>::type exp(T v) noexcept { return std::exp(v); } /// \brief log function /// /// \tparam T type of the argument /// \param v argument /// \return log(v) /// template static inline constexpr typename std::enable_if::value, T>::type log(T v) noexcept { return std::log(v); } /// \brief tanh function /// /// \tparam T type of the argument /// \param v argument /// \return tanh(v) /// template static inline constexpr typename std::enable_if::value, T>::type tanh(T v) noexcept { return std::tanh(v); } /// \brief floor function /// /// \tparam T type of the argument /// \param v argument /// \return floor(v) /// template static inline constexpr typename std::enable_if::value, T>::type floor(T v) noexcept { return std::floor(v); } /// \brief log1p function /// /// \tparam T type of the argument /// \param v argument /// \return log(1 + v) /// template static inline constexpr typename std::enable_if::value, T>::type log1p(T v) noexcept { return std::log1p(v); } /// \brief sin function /// /// \tparam T type of the argument /// \param v argument /// \return sin(v) /// template static inline constexpr typename std::enable_if::value, T>::type sin(T v) noexcept { return std::sin(v); } /// \brief cos function /// /// \tparam T type of the argument /// \param v argument /// \return cos(v) /// template static inline constexpr typename std::enable_if::value, T>::type cos(T v) noexcept { return std::cos(v); } /// \brief trunc function /// /// \tparam T type of the argument /// \param v argument /// \return trunc(v) /// template static inline constexpr typename std::enable_if::value, T>::type trunc(T v) noexcept { return std::trunc(v); } /// \brief 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 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 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::one()) == true, "Not evaluated as constexpr"); } // namespace plib #endif // PMATH_H_