// license:GPL-2.0+ // copyright-holders:Couriersud /* * pmath.h * */ #ifndef PMATH_H_ #define PMATH_H_ #include "pconfig.h" #include #include #include #if (PUSE_FLOAT128) #include #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 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); } }; /*! 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; } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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); } /*! 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_ */