From 60379b658a0c44fbb6398d122da9464005ea5917 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sun, 3 Nov 2019 23:19:52 +0100 Subject: netlist: code maintenance. (nw) - Separate code out into pmath.h and pstonum.h. - Fix VC build error - optimize pfmtlog.h a bit --- scripts/src/netlist.lua | 4 +- src/lib/netlist/analog/nld_bjt.cpp | 3 - src/lib/netlist/analog/nld_generic_models.h | 2 - src/lib/netlist/analog/nld_mosfet.cpp | 2 - src/lib/netlist/analog/nld_opamps.cpp | 2 - src/lib/netlist/analog/nlid_fourterm.cpp | 2 - src/lib/netlist/analog/nlid_twoterm.cpp | 2 - src/lib/netlist/analog/nlid_twoterm.h | 2 - src/lib/netlist/devices/nld_74123.cpp | 2 - src/lib/netlist/devices/nld_schmitt.cpp | 3 - src/lib/netlist/nl_base.cpp | 2 - src/lib/netlist/nl_base.h | 1 + src/lib/netlist/nl_config.h | 4 +- src/lib/netlist/nl_dice_compat.h | 6 +- src/lib/netlist/nl_setup.cpp | 2 - src/lib/netlist/plib/gmres.h | 6 +- src/lib/netlist/plib/mat_cr.h | 4 +- src/lib/netlist/plib/parray.h | 2 +- src/lib/netlist/plib/pfmtlog.cpp | 1 + src/lib/netlist/plib/pfmtlog.h | 53 +++- src/lib/netlist/plib/pfunction.cpp | 3 +- src/lib/netlist/plib/pfunction.h | 1 + src/lib/netlist/plib/pmath.h | 337 ++++++++++++++++++++ src/lib/netlist/plib/pmatrix2d.h | 2 - src/lib/netlist/plib/poptions.h | 1 + src/lib/netlist/plib/ppreprocessor.cpp | 1 + src/lib/netlist/plib/pstonum.h | 148 +++++++++ src/lib/netlist/plib/ptime.h | 4 +- src/lib/netlist/plib/ptokenizer.cpp | 1 + src/lib/netlist/plib/ptypes.h | 1 - src/lib/netlist/plib/putil.h | 442 +-------------------------- src/lib/netlist/plib/vector_ops.h | 3 +- src/lib/netlist/solver/nld_matrix_solver.cpp | 2 - src/lib/netlist/solver/nld_matrix_solver.h | 2 - src/lib/netlist/solver/nld_ms_direct.h | 1 - src/lib/netlist/solver/nld_ms_direct_lu.h | 6 +- src/lib/netlist/solver/nld_ms_gmres.h | 2 - src/lib/netlist/solver/nld_ms_sor_mat.h | 6 +- src/lib/netlist/solver/nld_solver.cpp | 1 - src/lib/netlist/tools/nl_convert.cpp | 7 +- 40 files changed, 560 insertions(+), 516 deletions(-) create mode 100644 src/lib/netlist/plib/pmath.h create mode 100644 src/lib/netlist/plib/pstonum.h diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua index 2ae8c3e869f..a0ecc416f5a 100644 --- a/scripts/src/netlist.lua +++ b/scripts/src/netlist.lua @@ -62,6 +62,7 @@ project "netlist" MAME_DIR .. "src/lib/netlist/plib/pdynlib.h", MAME_DIR .. "src/lib/netlist/plib/pmain.cpp", MAME_DIR .. "src/lib/netlist/plib/pmain.h", + MAME_DIR .. "src/lib/netlist/plib/pmath.h", MAME_DIR .. "src/lib/netlist/plib/pmempool.h", MAME_DIR .. "src/lib/netlist/plib/pomp.h", MAME_DIR .. "src/lib/netlist/plib/poptions.cpp", @@ -69,7 +70,8 @@ project "netlist" MAME_DIR .. "src/lib/netlist/plib/ppmf.h", MAME_DIR .. "src/lib/netlist/plib/ppreprocessor.cpp", MAME_DIR .. "src/lib/netlist/plib/ppreprocessor.h", - MAME_DIR .. "src/lib/netlist/plib/pstate.h", + MAME_DIR .. "src/lib/netlist/plib/pstate.h", + MAME_DIR .. "src/lib/netlist/plib/pstonum.h", MAME_DIR .. "src/lib/netlist/plib/pstring.cpp", MAME_DIR .. "src/lib/netlist/plib/pstring.h", MAME_DIR .. "src/lib/netlist/plib/pstrutil.h", diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp index 6a314c919f7..635225769fb 100644 --- a/src/lib/netlist/analog/nld_bjt.cpp +++ b/src/lib/netlist/analog/nld_bjt.cpp @@ -9,9 +9,6 @@ #include "netlist/nl_setup.h" #include "nlid_twoterm.h" - -#include - namespace netlist { namespace analog diff --git a/src/lib/netlist/analog/nld_generic_models.h b/src/lib/netlist/analog/nld_generic_models.h index 5eac70b6ed4..f094e6412a2 100644 --- a/src/lib/netlist/analog/nld_generic_models.h +++ b/src/lib/netlist/analog/nld_generic_models.h @@ -11,8 +11,6 @@ #include "netlist/nl_base.h" #include "netlist/nl_setup.h" -#include - namespace netlist { namespace analog diff --git a/src/lib/netlist/analog/nld_mosfet.cpp b/src/lib/netlist/analog/nld_mosfet.cpp index 5780c598ac5..9a3084094b8 100644 --- a/src/lib/netlist/analog/nld_mosfet.cpp +++ b/src/lib/netlist/analog/nld_mosfet.cpp @@ -22,8 +22,6 @@ #include "netlist/nl_setup.h" #include "nlid_twoterm.h" -#include - #define BODY_CONNECTED_TO_SOURCE (1) namespace netlist diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index 692fea19931..7ba550cc639 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -11,8 +11,6 @@ #include "nlid_fourterm.h" #include "nlid_twoterm.h" -#include - namespace netlist { namespace analog diff --git a/src/lib/netlist/analog/nlid_fourterm.cpp b/src/lib/netlist/analog/nlid_fourterm.cpp index 73fc2d53c8d..6cc4083d6b3 100644 --- a/src/lib/netlist/analog/nlid_fourterm.cpp +++ b/src/lib/netlist/analog/nlid_fourterm.cpp @@ -9,8 +9,6 @@ #include "netlist/nl_factory.h" #include "nlid_fourterm.h" -#include - namespace netlist { namespace analog diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp index 073e657d369..82c4099c15c 100644 --- a/src/lib/netlist/analog/nlid_twoterm.cpp +++ b/src/lib/netlist/analog/nlid_twoterm.cpp @@ -10,8 +10,6 @@ #include "netlist/nl_factory.h" #include "nlid_twoterm.h" -#include - namespace netlist { namespace analog diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h index d9c1b8e8050..45bf6d9dbf8 100644 --- a/src/lib/netlist/analog/nlid_twoterm.h +++ b/src/lib/netlist/analog/nlid_twoterm.h @@ -39,8 +39,6 @@ #include "nld_generic_models.h" #include "plib/pfunction.h" -#include - // ----------------------------------------------------------------------------- // Implementation // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp index a80e8c5fd0d..77c78b9293d 100644 --- a/src/lib/netlist/devices/nld_74123.cpp +++ b/src/lib/netlist/devices/nld_74123.cpp @@ -8,8 +8,6 @@ #include "nlid_system.h" #include "netlist/analog/nlid_twoterm.h" -#include - namespace netlist { namespace devices diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp index 29dbf8cf6b0..963c6a22d49 100644 --- a/src/lib/netlist/devices/nld_schmitt.cpp +++ b/src/lib/netlist/devices/nld_schmitt.cpp @@ -12,9 +12,6 @@ #include "netlist/nl_errstr.h" #include "netlist/solver/nld_solver.h" -#include - - namespace netlist { namespace devices diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 7206efca2f3..0ccfc788d9f 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -19,8 +19,6 @@ #include "nl_errstr.h" -#include -//#include #include namespace netlist diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 907c3f76829..586000b7b0e 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -22,6 +22,7 @@ #include "plib/pstate.h" #include "plib/pstream.h" #include "plib/ptime.h" +#include "plib/pstonum.h" #include "nl_errstr.h" #include "nltypes.h" diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 1add7136dcc..bbd32490c30 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -166,8 +166,8 @@ namespace netlist template <> struct fp_constants { - static inline constexpr float DIODE_MAXDIFF() noexcept { return 1e20; } - static inline constexpr float DIODE_MAXVOLT() noexcept { return 90.0; } + static inline constexpr float DIODE_MAXDIFF() noexcept { return 1e20f; } + static inline constexpr float DIODE_MAXVOLT() noexcept { return 90.0f; } static inline constexpr float TIMESTEP_MAXDIFF() noexcept { return 1e30f; } static inline constexpr float TIMESTEP_MINDIV() noexcept { return 1e-8f; } diff --git a/src/lib/netlist/nl_dice_compat.h b/src/lib/netlist/nl_dice_compat.h index 7683f9dd451..89d7b392b3f 100644 --- a/src/lib/netlist/nl_dice_compat.h +++ b/src/lib/netlist/nl_dice_compat.h @@ -28,8 +28,6 @@ sed -e 's/#define \(.*\)"\(.*\)"[ \t]*,[ \t]*\(.*\)/NET_ALIAS(\1,\2.\3)/' src/ma #include "devices/net_lib.h" #include "analog/nld_twoterm.h" -#include - #endif @@ -204,7 +202,7 @@ inline int CAPACITOR_tc_hl(const double c, const double r) * Vt = (VH-VL)*exp(-t/RC) * ln(Vt/(VH-VL))*RC = -t */ - static const double TIME_CONSTANT = -std::log(0.8 / (4.0-0.1)); + static const double TIME_CONSTANT = -plib::log(0.8 / (4.0-0.1)); int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9); return ret; } @@ -215,7 +213,7 @@ inline int CAPACITOR_tc_lh(const double c, const double r) * Vt = (VH-VL)*(1-exp(-t/RC)) * -t=ln(1-Vt/(VH-VL))*RC */ - static const double TIME_CONSTANT = -std::log(1.0 - 2.0 / (4.0-0.1)); + static const double TIME_CONSTANT = -plib::log(1.0 - 2.0 / (4.0-0.1)); int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9); return ret; } diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index efc503069e9..37eb34c5f97 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -17,8 +17,6 @@ #include "plib/putil.h" #include "solver/nld_solver.h" -#include - namespace netlist { // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h index 686e1444d36..992b8bab2a5 100644 --- a/src/lib/netlist/plib/gmres.h +++ b/src/lib/netlist/plib/gmres.h @@ -14,8 +14,6 @@ #include "vector_ops.h" #include -#include - namespace plib { @@ -150,12 +148,12 @@ namespace plib // works halfway, i.e. Mame perforamnce 50% // 151% for (std::size_t j = m_mat.row_idx[i]; j< m_mat.row_idx[i+1]; j++) - v += std::abs(m_mat.A[j]); + v += plib::abs(m_mat.A[j]); m_diag[i] = reciprocal(v); #else // 124% for (std::size_t j = m_mat.row_idx[i]; j< m_mat.row_idx[i+1]; j++) - v = std::max(v, std::abs(m_mat.A[j])); + v = std::max(v, plib::abs(m_mat.A[j])); m_diag[i] = reciprocal(v); #endif //m_diag[i] = reciprocal(m_mat.A[m_mat.diag[i]]); diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h index 132cab5d96f..96f3379c21b 100644 --- a/src/lib/netlist/plib/mat_cr.h +++ b/src/lib/netlist/plib/mat_cr.h @@ -17,10 +17,10 @@ #include "pstate.h" #include "ptypes.h" #include "putil.h" +#include "pmath.h" #include #include -#include #include #include @@ -120,7 +120,7 @@ namespace plib row_idx[k] = nz; for (std::size_t j=0; j < size(); j++) - if (f[k][j] <= max_fill && std::abs(static_cast(k)-static_cast(j)) <= static_cast(band_width)) + if (f[k][j] <= max_fill && plib::abs(static_cast(k)-static_cast(j)) <= static_cast(band_width)) { col_idx[nz] = static_cast(j); if (j == k) diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h index 6570c8e592f..18367d161c0 100644 --- a/src/lib/netlist/plib/parray.h +++ b/src/lib/netlist/plib/parray.h @@ -42,7 +42,7 @@ namespace plib { * Passing SIZE > 0 has the same functionality as a std::array. * SIZE = 0 is pure dynamic allocation, the actual array size is passed to the * constructor. - * SIZE < 0 reserves std::abs(SIZE) elements statically in place allocated. The + * SIZE < 0 reserves abs(SIZE) elements statically in place allocated. The * actual size is passed in by the constructor. * This array is purely intended for HPC application where depending on the * architecture a preference dynamic/static has to be made. diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp index 2158d10cb2d..f832599ab23 100644 --- a/src/lib/netlist/plib/pfmtlog.cpp +++ b/src/lib/netlist/plib/pfmtlog.cpp @@ -8,6 +8,7 @@ #include "pfmtlog.h" #include "palloc.h" #include "pstrutil.h" +#include "pstonum.h" #include #include diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index df0463cbb61..489e16aea8e 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -31,6 +31,10 @@ struct ptype_traits_base static constexpr const T cast(const T &x) { return x; } static constexpr const bool is_signed = std::numeric_limits::is_signed; static char32_t fmt_spec() { return 'u'; } + static inline void streamify(std::ostream &s, const T &v) + { + s << v; + } }; #if (PUSE_FLOAT128) @@ -41,17 +45,13 @@ struct ptype_traits_base<__float128> static constexpr const long double cast(const __float128 &x) { return static_cast(x); } static constexpr const bool is_signed = true; static char32_t fmt_spec() { return 'f'; } + static inline void streamify(std::ostream &s, const __float128 &v) + { + s << static_cast(v); + } }; #endif -template <> -struct ptype_traits_base -{ - static unsigned int cast(const bool &x) { return static_cast(x); } - static const bool is_signed = std::numeric_limits::is_signed; - static char32_t fmt_spec() { return 'u'; } -}; - template struct ptype_traits; @@ -160,12 +160,25 @@ struct ptype_traits : ptype_traits_base }; template<> -struct ptype_traits : ptype_traits_base +struct ptype_traits : ptype_traits_base { - static const char *cast(const std::string &x) { return x.c_str(); } + static const char *cast(const char *x) { return x; } static char32_t fmt_spec() { return 's'; } }; +template<> +struct ptype_traits : ptype_traits_base +{ + static char32_t fmt_spec() { return 's'; } +}; + +template<> +struct ptype_traits : ptype_traits_base +{ + static const void *cast(const void *x) { return x; } + static char32_t fmt_spec() { return 'p'; } +}; + class pfmt { public: @@ -193,7 +206,7 @@ public: e(const T &x) {return format_element('e', x); } #if PUSE_FLOAT128 - // FIXME: not what we want + // FIXME: should use quadmath_snprintf pfmt & e(const __float128 &x) {return format_element('e', static_cast(x)); } #endif @@ -207,13 +220,13 @@ public: template pfmt &operator ()(const T &x) { - return format_element(ptype_traits::fmt_spec(), ptype_traits::cast(x)); + return format_element(x); } template pfmt &operator ()(const T *x) { - return format_element(ptype_traits::fmt_spec(), ptype_traits::cast(x)); + return format_element(x); } pfmt &operator ()() @@ -262,8 +275,16 @@ protected: rtype setfmt(std::stringstream &strm, char32_t cfmt_spec); template - pfmt &format_element(const char32_t cfmt_spec, T &&val) + pfmt &format_element(T &&v) { + return format_element(ptype_traits::type>::fmt_spec(), std::forward(v)); + } + + template + pfmt &format_element(const char32_t cfmt_spec, T &&v) + { + //auto val = ptype_traits::type>::cast(std::forward(v)); + rtype ret; m_arg++; @@ -274,7 +295,9 @@ protected: ret = setfmt(strm, cfmt_spec); if (ret.ret>=0) { - strm << std::forward(val); + //strm << val; + ptype_traits::type>::streamify(strm, std::forward(v)); + const pstring ps(strm.str()); pstring pad(""); auto aw(static_cast(std::abs(ret.width))); diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp index db6e491e988..5c3df2ed05d 100644 --- a/src/lib/netlist/plib/pfunction.cpp +++ b/src/lib/netlist/plib/pfunction.cpp @@ -10,8 +10,9 @@ #include "pfmtlog.h" #include "pstrutil.h" #include "putil.h" +#include "pmath.h" +#include "pstonum.h" -#include #include namespace plib { diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h index b2a42a54e14..e41efac4ac9 100644 --- a/src/lib/netlist/plib/pfunction.h +++ b/src/lib/netlist/plib/pfunction.h @@ -11,6 +11,7 @@ #include "pstate.h" #include "pstring.h" #include "putil.h" +#include "pmath.h" #include 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 +#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_ */ diff --git a/src/lib/netlist/plib/pmatrix2d.h b/src/lib/netlist/plib/pmatrix2d.h index 7d6072fc358..435ef4d44b7 100644 --- a/src/lib/netlist/plib/pmatrix2d.h +++ b/src/lib/netlist/plib/pmatrix2d.h @@ -13,8 +13,6 @@ #include "palloc.h" #include -#include -//#include #include #include diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 63f10a0e875..b8d65e7832a 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -11,6 +11,7 @@ #include "plists.h" #include "pstring.h" #include "putil.h" +#include "pstonum.h" namespace plib { /*************************************************************************** diff --git a/src/lib/netlist/plib/ppreprocessor.cpp b/src/lib/netlist/plib/ppreprocessor.cpp index e29be1757ed..78146e7a18b 100644 --- a/src/lib/netlist/plib/ppreprocessor.cpp +++ b/src/lib/netlist/plib/ppreprocessor.cpp @@ -8,6 +8,7 @@ #include "ppreprocessor.h" #include "palloc.h" #include "putil.h" +#include "pstonum.h" namespace plib { diff --git a/src/lib/netlist/plib/pstonum.h b/src/lib/netlist/plib/pstonum.h new file mode 100644 index 00000000000..c73a348db9b --- /dev/null +++ b/src/lib/netlist/plib/pstonum.h @@ -0,0 +1,148 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * pstonuml.h + * + */ + +#ifndef PSTONUM_H_ +#define PSTONUM_H_ + +#include "pconfig.h" +#include "pexception.h" +#include "pstring.h" +#include "pmath.h" // for pstonum + +#include +#include +#include +#include +#include + +namespace plib +{ + // ---------------------------------------------------------------------------------------- + // number conversions + // ---------------------------------------------------------------------------------------- + + template + T pstonum_locale(const std::locale &loc, const S &arg, std::size_t *idx) + { + std::stringstream ss; + ss.imbue(loc); + ss << arg; + auto len(ss.tellp()); + T x(constants::zero()); + if (ss >> x) + { + auto pos(ss.tellg()); + if (pos == static_cast(-1)) + pos = len; + *idx = static_cast(pos); + } + else + *idx = constants::zero(); + //printf("%s, %f, %lu %ld\n", arg, (double)x, *idx, (long int) ss.tellg()); + return x; + } + + template + struct pstonum_helper; + + template + struct pstonum_helper::value && std::is_signed::value>::type> + { + template + long long operator()(std::locale loc, const S &arg, std::size_t *idx) + { + //return std::stoll(arg, idx); + return pstonum_locale(loc, arg, idx); + } + }; + + template + struct pstonum_helper::value && !std::is_signed::value>::type> + { + template + unsigned long long operator()(std::locale loc, const S &arg, std::size_t *idx) + { + //return std::stoll(arg, idx); + return pstonum_locale(loc, arg, idx); + } + }; + + template + struct pstonum_helper::value>::type> + { + template + long double operator()(std::locale loc, const S &arg, std::size_t *idx) + { + return pstonum_locale(loc, arg, idx); + } + }; + +#if PUSE_FLOAT128 + template<> + struct pstonum_helper<__float128> + { + // FIXME: use strtoflt128 from quadmath.h + template + __float128 operator()(std::locale loc, const S &arg, std::size_t *idx) + { + return static_cast<__float128>(pstonum_locale(loc, arg, idx)); + } + }; +#endif + + template + T pstonum(const S &arg, const std::locale &loc = std::locale::classic()) + { + decltype(arg.c_str()) cstr = arg.c_str(); + std::size_t idx(0); + auto ret = pstonum_helper()(loc, cstr, &idx); + using ret_type = decltype(ret); + if (ret >= static_cast(std::numeric_limits::lowest()) + && ret <= static_cast(std::numeric_limits::max())) + //&& (ret == T(0) || plib::abs(ret) >= std::numeric_limits::min() )) + { + if (cstr[idx] != 0) + throw pexception(pstring("Continuation after numeric value ends: ") + pstring(cstr)); + } + else + { + throw pexception(pstring("Out of range: ") + pstring(cstr)); + } + return static_cast(ret); + } + + template + R pstonum_ne(const T &str, bool &err, std::locale loc = std::locale::classic()) noexcept + { + try + { + err = false; + return pstonum(str, loc); + } + catch (...) + { + err = true; + return R(0); + } + } + + template + R pstonum_ne_def(const T &str, R def, std::locale loc = std::locale::classic()) noexcept + { + try + { + return pstonum(str, loc); + } + catch (...) + { + return def; + } + } + +} // namespace plib + +#endif /* PUTIL_H_ */ diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h index 9f253a269bd..77e1deb8307 100644 --- a/src/lib/netlist/plib/ptime.h +++ b/src/lib/netlist/plib/ptime.h @@ -9,9 +9,7 @@ #include "pconfig.h" #include "ptypes.h" - -#include // std::floor -//#include +#include "pmath.h" // std::floor // ---------------------------------------------------------------------------------------- // netlist_time diff --git a/src/lib/netlist/plib/ptokenizer.cpp b/src/lib/netlist/plib/ptokenizer.cpp index fbda60de458..bd5b7f09af3 100644 --- a/src/lib/netlist/plib/ptokenizer.cpp +++ b/src/lib/netlist/plib/ptokenizer.cpp @@ -8,6 +8,7 @@ #include "ptokenizer.h" #include "palloc.h" #include "putil.h" +#include "pstonum.h" namespace plib { diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index adaa6a2b2fd..afc25bc0d0a 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -92,7 +92,6 @@ namespace plib return !(v & (v-1)); } - //============================================================ // abs, lcd, gcm //============================================================ diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index 7cd54f2f43f..6a79dadae90 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -13,16 +13,13 @@ #include "pstring.h" #include -#include -#include -#include -#include +//#include +//#include +//#include +//#include #include -#include -#if (PUSE_FLOAT128) -#include -#endif +// FIXME: pstonum should get an own header #define PSTRINGIFY_HELP(y) # y #define PSTRINGIFY(x) PSTRINGIFY_HELP(x) @@ -221,312 +218,6 @@ namespace plib } } // namespace container - /* May be further specialized .... This is the generic version */ - 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 v1 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"); - - template struct indexed_compare { @@ -547,128 +238,6 @@ namespace plib const std::string &token, const std::size_t maxsplit); - // ---------------------------------------------------------------------------------------- - // number conversions - // ---------------------------------------------------------------------------------------- - - template - T pstonum_locale(const std::locale &loc, const S &arg, std::size_t *idx) - { - std::stringstream ss; - ss.imbue(loc); - ss << arg; - auto len(ss.tellp()); - T x(constants::zero()); - if (ss >> x) - { - auto pos(ss.tellg()); - if (pos == static_cast(-1)) - pos = len; - *idx = static_cast(pos); - } - else - *idx = constants::zero(); - //printf("%s, %f, %lu %ld\n", arg, (double)x, *idx, (long int) ss.tellg()); - return x; - } - - template - struct pstonum_helper; - - template - struct pstonum_helper::value && std::is_signed::value>::type> - { - template - long long operator()(std::locale loc, const S &arg, std::size_t *idx) - { - //return std::stoll(arg, idx); - return pstonum_locale(loc, arg, idx); - } - }; - - template - struct pstonum_helper::value && !std::is_signed::value>::type> - { - template - unsigned long long operator()(std::locale loc, const S &arg, std::size_t *idx) - { - //return std::stoll(arg, idx); - return pstonum_locale(loc, arg, idx); - } - }; - - template - struct pstonum_helper::value>::type> - { - template - long double operator()(std::locale loc, const S &arg, std::size_t *idx) - { - return pstonum_locale(loc, arg, idx); - } - }; - -#if PUSE_FLOAT128 - template<> - struct pstonum_helper<__float128> - { - // FIXME: use strtoflt128 from quadmath.h - template - __float128 operator()(std::locale loc, const S &arg, std::size_t *idx) - { - return static_cast<__float128>(pstonum_locale(loc, arg, idx)); - } - }; -#endif - - template - T pstonum(const S &arg, const std::locale &loc = std::locale::classic()) - { - decltype(arg.c_str()) cstr = arg.c_str(); - std::size_t idx(0); - auto ret = pstonum_helper()(loc, cstr, &idx); - using ret_type = decltype(ret); - if (ret >= static_cast(std::numeric_limits::lowest()) - && ret <= static_cast(std::numeric_limits::max())) - //&& (ret == T(0) || std::abs(ret) >= std::numeric_limits::min() )) - { - if (cstr[idx] != 0) - throw pexception(pstring("Continuation after numeric value ends: ") + pstring(cstr)); - } - else - { - throw pexception(pstring("Out of range: ") + pstring(cstr)); - } - return static_cast(ret); - } - - template - R pstonum_ne(const T &str, bool &err, std::locale loc = std::locale::classic()) noexcept - { - try - { - err = false; - return pstonum(str, loc); - } - catch (...) - { - err = true; - return R(0); - } - } - - template - R pstonum_ne_def(const T &str, R def, std::locale loc = std::locale::classic()) noexcept - { - try - { - return pstonum(str, loc); - } - catch (...) - { - return def; - } - } - //============================================================ // penum - strongly typed enumeration //============================================================ @@ -704,5 +273,4 @@ namespace plib } \ }; - #endif /* PUTIL_H_ */ diff --git a/src/lib/netlist/plib/vector_ops.h b/src/lib/netlist/plib/vector_ops.h index 51c592968f5..bb94b0793f3 100644 --- a/src/lib/netlist/plib/vector_ops.h +++ b/src/lib/netlist/plib/vector_ops.h @@ -14,7 +14,6 @@ #include #include -#include #include #if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) @@ -137,7 +136,7 @@ namespace plib { T ret = 0.0; for ( std::size_t i = 0; i < n; i++ ) - ret = std::max(ret, std::abs(v[i])); + ret = std::max(ret, plib::abs(v[i])); return ret; } diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index a9ae7ec82a1..6082ebb3194 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -8,8 +8,6 @@ #include "nld_matrix_solver.h" #include "plib/putil.h" -#include // <<= needed by windows build - namespace netlist { namespace solver diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index ffa58979289..fba615e5af8 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -16,8 +16,6 @@ #include "plib/putil.h" #include "plib/vector_ops.h" -#include - namespace netlist { namespace solver diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index 031cae34a27..ecaf311b76e 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -14,7 +14,6 @@ #include "plib/vector_ops.h" #include -#include namespace netlist { diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h index e7cedc1dd29..1e1f7f1f158 100644 --- a/src/lib/netlist/solver/nld_ms_direct_lu.h +++ b/src/lib/netlist/solver/nld_ms_direct_lu.h @@ -186,8 +186,8 @@ nl_double matrix_solver_direct_t::compute_next_timestep() n->m_h_n_m_1 = hn; n->m_DD_n_m_1 = DD_n; - if (std::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero - new_net_timestep = std::sqrt(m_params.m_dynamic_lte / std::abs(NL_FCONST(0.5)*DD2)); + if (plib::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero + new_net_timestep = std::sqrt(m_params.m_dynamic_lte / plib::abs(NL_FCONST(0.5)*DD2)); else new_net_timestep = m_params.m_max_timestep; @@ -549,7 +549,7 @@ nl_double matrix_solver_direct_t::delta( const unsigned iN = this->N(); nl_double cerr = 0; for (unsigned i = 0; i < iN; i++) - cerr = std::fmax(cerr, std::abs(V[i] - this->m_nets[i]->m_cur_Analog)); + cerr = std::fmax(cerr, plib::abs(V[i] - this->m_nets[i]->m_cur_Analog)); return cerr; } diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index abee33bb18a..acd90c7fdaf 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -16,8 +16,6 @@ #include "plib/vector_ops.h" #include -#include - namespace netlist { diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h index a5ded1a38ba..ddc340053df 100644 --- a/src/lib/netlist/solver/nld_ms_sor_mat.h +++ b/src/lib/netlist/solver/nld_ms_sor_mat.h @@ -134,16 +134,16 @@ namespace solver for (int k = 0; k < iN; k++) { #if 0 - float_type akk = std::abs(this->m_A[k][k]); + float_type akk = plib::abs(this->m_A[k][k]); if ( akk > lambdaN) lambdaN = akk; if (akk < lambda1) lambda1 = akk; #else - float_type akk = std::abs(this->m_A[k][k]); + float_type akk = plib::abs(this->m_A[k][k]); float_type s = 0.0; for (int i=0; im_A[k][i]); + s = s + plib::abs(this->m_A[k][i]); akk = s / akk - 1.0; if ( akk > lambdaN) lambdaN = akk; diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index ecbf48ab0c2..16f2f68cb5a 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -46,7 +46,6 @@ #include "plib/pomp.h" #include -#include namespace netlist { diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index b29bf79d693..53e2c539198 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -6,11 +6,12 @@ */ #include "plib/palloc.h" -#include "nl_convert.h" #include "plib/putil.h" +#include "plib/pstonum.h" + +#include "nl_convert.h" #include -#include #include /* FIXME: temporarily defined here - should be in a file */ @@ -206,7 +207,7 @@ const pstring nl_convert_base_t::get_nl_val(const double val) { for (auto &e : m_units) { - if (e.m_mult <= std::abs(val)) + if (e.m_mult <= plib::abs(val)) return plib::pfmt(e.m_func)(val / e.m_mult); } return plib::pfmt("{1}")(val); -- cgit v1.2.3