netlist: code maintenance. (nw)

- Separate code out into pmath.h and pstonum.h.
- Fix VC build error
- optimize pfmtlog.h a bit
This commit is contained in:
couriersud 2019-11-03 23:19:52 +01:00
parent 3892c598f5
commit 60379b658a
40 changed files with 560 additions and 516 deletions

View File

@ -62,6 +62,7 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/plib/pdynlib.h", MAME_DIR .. "src/lib/netlist/plib/pdynlib.h",
MAME_DIR .. "src/lib/netlist/plib/pmain.cpp", MAME_DIR .. "src/lib/netlist/plib/pmain.cpp",
MAME_DIR .. "src/lib/netlist/plib/pmain.h", 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/pmempool.h",
MAME_DIR .. "src/lib/netlist/plib/pomp.h", MAME_DIR .. "src/lib/netlist/plib/pomp.h",
MAME_DIR .. "src/lib/netlist/plib/poptions.cpp", 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/ppmf.h",
MAME_DIR .. "src/lib/netlist/plib/ppreprocessor.cpp", MAME_DIR .. "src/lib/netlist/plib/ppreprocessor.cpp",
MAME_DIR .. "src/lib/netlist/plib/ppreprocessor.h", 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.cpp",
MAME_DIR .. "src/lib/netlist/plib/pstring.h", MAME_DIR .. "src/lib/netlist/plib/pstring.h",
MAME_DIR .. "src/lib/netlist/plib/pstrutil.h", MAME_DIR .. "src/lib/netlist/plib/pstrutil.h",

View File

@ -9,9 +9,6 @@
#include "netlist/nl_setup.h" #include "netlist/nl_setup.h"
#include "nlid_twoterm.h" #include "nlid_twoterm.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace analog namespace analog

View File

@ -11,8 +11,6 @@
#include "netlist/nl_base.h" #include "netlist/nl_base.h"
#include "netlist/nl_setup.h" #include "netlist/nl_setup.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace analog namespace analog

View File

@ -22,8 +22,6 @@
#include "netlist/nl_setup.h" #include "netlist/nl_setup.h"
#include "nlid_twoterm.h" #include "nlid_twoterm.h"
#include <cmath>
#define BODY_CONNECTED_TO_SOURCE (1) #define BODY_CONNECTED_TO_SOURCE (1)
namespace netlist namespace netlist

View File

@ -11,8 +11,6 @@
#include "nlid_fourterm.h" #include "nlid_fourterm.h"
#include "nlid_twoterm.h" #include "nlid_twoterm.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace analog namespace analog

View File

@ -9,8 +9,6 @@
#include "netlist/nl_factory.h" #include "netlist/nl_factory.h"
#include "nlid_fourterm.h" #include "nlid_fourterm.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace analog namespace analog

View File

@ -10,8 +10,6 @@
#include "netlist/nl_factory.h" #include "netlist/nl_factory.h"
#include "nlid_twoterm.h" #include "nlid_twoterm.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace analog namespace analog

View File

@ -39,8 +39,6 @@
#include "nld_generic_models.h" #include "nld_generic_models.h"
#include "plib/pfunction.h" #include "plib/pfunction.h"
#include <cmath>
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation // Implementation
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -8,8 +8,6 @@
#include "nlid_system.h" #include "nlid_system.h"
#include "netlist/analog/nlid_twoterm.h" #include "netlist/analog/nlid_twoterm.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace devices namespace devices

View File

@ -12,9 +12,6 @@
#include "netlist/nl_errstr.h" #include "netlist/nl_errstr.h"
#include "netlist/solver/nld_solver.h" #include "netlist/solver/nld_solver.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace devices namespace devices

View File

@ -19,8 +19,6 @@
#include "nl_errstr.h" #include "nl_errstr.h"
#include <cmath>
//#include <cstring>
#include <limits> #include <limits>
namespace netlist namespace netlist

View File

@ -22,6 +22,7 @@
#include "plib/pstate.h" #include "plib/pstate.h"
#include "plib/pstream.h" #include "plib/pstream.h"
#include "plib/ptime.h" #include "plib/ptime.h"
#include "plib/pstonum.h"
#include "nl_errstr.h" #include "nl_errstr.h"
#include "nltypes.h" #include "nltypes.h"

View File

@ -166,8 +166,8 @@ namespace netlist
template <> template <>
struct fp_constants<float> struct fp_constants<float>
{ {
static inline constexpr float DIODE_MAXDIFF() noexcept { return 1e20; } static inline constexpr float DIODE_MAXDIFF() noexcept { return 1e20f; }
static inline constexpr float DIODE_MAXVOLT() noexcept { return 90.0; } static inline constexpr float DIODE_MAXVOLT() noexcept { return 90.0f; }
static inline constexpr float TIMESTEP_MAXDIFF() noexcept { return 1e30f; } static inline constexpr float TIMESTEP_MAXDIFF() noexcept { return 1e30f; }
static inline constexpr float TIMESTEP_MINDIV() noexcept { return 1e-8f; } static inline constexpr float TIMESTEP_MINDIV() noexcept { return 1e-8f; }

View File

@ -28,8 +28,6 @@ sed -e 's/#define \(.*\)"\(.*\)"[ \t]*,[ \t]*\(.*\)/NET_ALIAS(\1,\2.\3)/' src/ma
#include "devices/net_lib.h" #include "devices/net_lib.h"
#include "analog/nld_twoterm.h" #include "analog/nld_twoterm.h"
#include <cmath>
#endif #endif
@ -204,7 +202,7 @@ inline int CAPACITOR_tc_hl(const double c, const double r)
* Vt = (VH-VL)*exp(-t/RC) * Vt = (VH-VL)*exp(-t/RC)
* ln(Vt/(VH-VL))*RC = -t * 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); int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9);
return ret; return ret;
} }
@ -215,7 +213,7 @@ inline int CAPACITOR_tc_lh(const double c, const double r)
* Vt = (VH-VL)*(1-exp(-t/RC)) * Vt = (VH-VL)*(1-exp(-t/RC))
* -t=ln(1-Vt/(VH-VL))*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); int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9);
return ret; return ret;
} }

View File

@ -17,8 +17,6 @@
#include "plib/putil.h" #include "plib/putil.h"
#include "solver/nld_solver.h" #include "solver/nld_solver.h"
#include <cmath>
namespace netlist namespace netlist
{ {
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------

View File

@ -14,8 +14,6 @@
#include "vector_ops.h" #include "vector_ops.h"
#include <algorithm> #include <algorithm>
#include <cmath>
namespace plib namespace plib
{ {
@ -150,12 +148,12 @@ namespace plib
// works halfway, i.e. Mame perforamnce 50% // works halfway, i.e. Mame perforamnce 50%
// 151% // 151%
for (std::size_t j = m_mat.row_idx[i]; j< m_mat.row_idx[i+1]; j++) 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); m_diag[i] = reciprocal(v);
#else #else
// 124% // 124%
for (std::size_t j = m_mat.row_idx[i]; j< m_mat.row_idx[i+1]; j++) 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); m_diag[i] = reciprocal(v);
#endif #endif
//m_diag[i] = reciprocal(m_mat.A[m_mat.diag[i]]); //m_diag[i] = reciprocal(m_mat.A[m_mat.diag[i]]);

View File

@ -17,10 +17,10 @@
#include "pstate.h" #include "pstate.h"
#include "ptypes.h" #include "ptypes.h"
#include "putil.h" #include "putil.h"
#include "pmath.h"
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cmath>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@ -120,7 +120,7 @@ namespace plib
row_idx[k] = nz; row_idx[k] = nz;
for (std::size_t j=0; j < size(); j++) for (std::size_t j=0; j < size(); j++)
if (f[k][j] <= max_fill && std::abs(static_cast<int>(k)-static_cast<int>(j)) <= static_cast<int>(band_width)) if (f[k][j] <= max_fill && plib::abs(static_cast<int>(k)-static_cast<int>(j)) <= static_cast<int>(band_width))
{ {
col_idx[nz] = static_cast<C>(j); col_idx[nz] = static_cast<C>(j);
if (j == k) if (j == k)

View File

@ -42,7 +42,7 @@ namespace plib {
* Passing SIZE > 0 has the same functionality as a std::array. * 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 * SIZE = 0 is pure dynamic allocation, the actual array size is passed to the
* constructor. * 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. * actual size is passed in by the constructor.
* This array is purely intended for HPC application where depending on the * This array is purely intended for HPC application where depending on the
* architecture a preference dynamic/static has to be made. * architecture a preference dynamic/static has to be made.

View File

@ -8,6 +8,7 @@
#include "pfmtlog.h" #include "pfmtlog.h"
#include "palloc.h" #include "palloc.h"
#include "pstrutil.h" #include "pstrutil.h"
#include "pstonum.h"
#include <algorithm> #include <algorithm>
#include <array> #include <array>

View File

@ -31,6 +31,10 @@ struct ptype_traits_base
static constexpr const T cast(const T &x) { return x; } static constexpr const T cast(const T &x) { return x; }
static constexpr const bool is_signed = std::numeric_limits<T>::is_signed; static constexpr const bool is_signed = std::numeric_limits<T>::is_signed;
static char32_t fmt_spec() { return 'u'; } static char32_t fmt_spec() { return 'u'; }
static inline void streamify(std::ostream &s, const T &v)
{
s << v;
}
}; };
#if (PUSE_FLOAT128) #if (PUSE_FLOAT128)
@ -41,17 +45,13 @@ struct ptype_traits_base<__float128>
static constexpr const long double cast(const __float128 &x) { return static_cast<long double>(x); } static constexpr const long double cast(const __float128 &x) { return static_cast<long double>(x); }
static constexpr const bool is_signed = true; static constexpr const bool is_signed = true;
static char32_t fmt_spec() { return 'f'; } static char32_t fmt_spec() { return 'f'; }
static inline void streamify(std::ostream &s, const __float128 &v)
{
s << static_cast<long double>(v);
}
}; };
#endif #endif
template <>
struct ptype_traits_base<bool>
{
static unsigned int cast(const bool &x) { return static_cast<unsigned int>(x); }
static const bool is_signed = std::numeric_limits<bool>::is_signed;
static char32_t fmt_spec() { return 'u'; }
};
template <typename T> template <typename T>
struct ptype_traits; struct ptype_traits;
@ -160,12 +160,25 @@ struct ptype_traits<char *> : ptype_traits_base<char *>
}; };
template<> template<>
struct ptype_traits<std::string> : ptype_traits_base<char *> struct ptype_traits<const char *> : ptype_traits_base<const char *>
{ {
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'; } static char32_t fmt_spec() { return 's'; }
}; };
template<>
struct ptype_traits<std::string> : ptype_traits_base<std::string>
{
static char32_t fmt_spec() { return 's'; }
};
template<>
struct ptype_traits<const void *> : ptype_traits_base<const void *>
{
static const void *cast(const void *x) { return x; }
static char32_t fmt_spec() { return 'p'; }
};
class pfmt class pfmt
{ {
public: public:
@ -193,7 +206,7 @@ public:
e(const T &x) {return format_element('e', x); } e(const T &x) {return format_element('e', x); }
#if PUSE_FLOAT128 #if PUSE_FLOAT128
// FIXME: not what we want // FIXME: should use quadmath_snprintf
pfmt & e(const __float128 &x) {return format_element('e', static_cast<long double>(x)); } pfmt & e(const __float128 &x) {return format_element('e', static_cast<long double>(x)); }
#endif #endif
@ -207,13 +220,13 @@ public:
template<typename T> template<typename T>
pfmt &operator ()(const T &x) pfmt &operator ()(const T &x)
{ {
return format_element(ptype_traits<T>::fmt_spec(), ptype_traits<T>::cast(x)); return format_element(x);
} }
template<typename T> template<typename T>
pfmt &operator ()(const T *x) pfmt &operator ()(const T *x)
{ {
return format_element(ptype_traits<T *>::fmt_spec(), ptype_traits<T *>::cast(x)); return format_element(x);
} }
pfmt &operator ()() pfmt &operator ()()
@ -262,8 +275,16 @@ protected:
rtype setfmt(std::stringstream &strm, char32_t cfmt_spec); rtype setfmt(std::stringstream &strm, char32_t cfmt_spec);
template <typename T> template <typename T>
pfmt &format_element(const char32_t cfmt_spec, T &&val) pfmt &format_element(T &&v)
{ {
return format_element(ptype_traits<typename std::decay<T>::type>::fmt_spec(), std::forward<T>(v));
}
template <typename T>
pfmt &format_element(const char32_t cfmt_spec, T &&v)
{
//auto val = ptype_traits<typename std::decay<T>::type>::cast(std::forward<T>(v));
rtype ret; rtype ret;
m_arg++; m_arg++;
@ -274,7 +295,9 @@ protected:
ret = setfmt(strm, cfmt_spec); ret = setfmt(strm, cfmt_spec);
if (ret.ret>=0) if (ret.ret>=0)
{ {
strm << std::forward<T>(val); //strm << val;
ptype_traits<typename std::decay<T>::type>::streamify(strm, std::forward<T>(v));
const pstring ps(strm.str()); const pstring ps(strm.str());
pstring pad(""); pstring pad("");
auto aw(static_cast<std::size_t>(std::abs(ret.width))); auto aw(static_cast<std::size_t>(std::abs(ret.width)));

View File

@ -10,8 +10,9 @@
#include "pfmtlog.h" #include "pfmtlog.h"
#include "pstrutil.h" #include "pstrutil.h"
#include "putil.h" #include "putil.h"
#include "pmath.h"
#include "pstonum.h"
#include <cmath>
#include <stack> #include <stack>
namespace plib { namespace plib {

View File

@ -11,6 +11,7 @@
#include "pstate.h" #include "pstate.h"
#include "pstring.h" #include "pstring.h"
#include "putil.h" #include "putil.h"
#include "pmath.h"
#include <vector> #include <vector>

View File

@ -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_ */

View File

@ -13,8 +13,6 @@
#include "palloc.h" #include "palloc.h"
#include <algorithm> #include <algorithm>
#include <cmath>
//#include <cstdlib>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>

View File

@ -11,6 +11,7 @@
#include "plists.h" #include "plists.h"
#include "pstring.h" #include "pstring.h"
#include "putil.h" #include "putil.h"
#include "pstonum.h"
namespace plib { namespace plib {
/*************************************************************************** /***************************************************************************

View File

@ -8,6 +8,7 @@
#include "ppreprocessor.h" #include "ppreprocessor.h"
#include "palloc.h" #include "palloc.h"
#include "putil.h" #include "putil.h"
#include "pstonum.h"
namespace plib { namespace plib {

View File

@ -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 <algorithm>
#include <initializer_list>
#include <iostream>
#include <locale>
#include <sstream>
namespace plib
{
// ----------------------------------------------------------------------------------------
// number conversions
// ----------------------------------------------------------------------------------------
template <typename T, typename S>
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<T>::zero());
if (ss >> x)
{
auto pos(ss.tellg());
if (pos == static_cast<decltype(pos)>(-1))
pos = len;
*idx = static_cast<std::size_t>(pos);
}
else
*idx = constants<std::size_t>::zero();
//printf("%s, %f, %lu %ld\n", arg, (double)x, *idx, (long int) ss.tellg());
return x;
}
template <typename T, typename E = void>
struct pstonum_helper;
template<typename T>
struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value>::type>
{
template <typename S>
long long operator()(std::locale loc, const S &arg, std::size_t *idx)
{
//return std::stoll(arg, idx);
return pstonum_locale<long long>(loc, arg, idx);
}
};
template<typename T>
struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value && !std::is_signed<T>::value>::type>
{
template <typename S>
unsigned long long operator()(std::locale loc, const S &arg, std::size_t *idx)
{
//return std::stoll(arg, idx);
return pstonum_locale<unsigned long long>(loc, arg, idx);
}
};
template<typename T>
struct pstonum_helper<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
{
template <typename S>
long double operator()(std::locale loc, const S &arg, std::size_t *idx)
{
return pstonum_locale<long double>(loc, arg, idx);
}
};
#if PUSE_FLOAT128
template<>
struct pstonum_helper<__float128>
{
// FIXME: use strtoflt128 from quadmath.h
template <typename S>
__float128 operator()(std::locale loc, const S &arg, std::size_t *idx)
{
return static_cast<__float128>(pstonum_locale<long double>(loc, arg, idx));
}
};
#endif
template<typename T, typename S>
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<T>()(loc, cstr, &idx);
using ret_type = decltype(ret);
if (ret >= static_cast<ret_type>(std::numeric_limits<T>::lowest())
&& ret <= static_cast<ret_type>(std::numeric_limits<T>::max()))
//&& (ret == T(0) || plib::abs(ret) >= std::numeric_limits<T>::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<T>(ret);
}
template<typename R, typename T>
R pstonum_ne(const T &str, bool &err, std::locale loc = std::locale::classic()) noexcept
{
try
{
err = false;
return pstonum<R>(str, loc);
}
catch (...)
{
err = true;
return R(0);
}
}
template<typename R, typename T>
R pstonum_ne_def(const T &str, R def, std::locale loc = std::locale::classic()) noexcept
{
try
{
return pstonum<R>(str, loc);
}
catch (...)
{
return def;
}
}
} // namespace plib
#endif /* PUTIL_H_ */

View File

@ -9,9 +9,7 @@
#include "pconfig.h" #include "pconfig.h"
#include "ptypes.h" #include "ptypes.h"
#include "pmath.h" // std::floor
#include <cmath> // std::floor
//#include <cstdint>
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// netlist_time // netlist_time

View File

@ -8,6 +8,7 @@
#include "ptokenizer.h" #include "ptokenizer.h"
#include "palloc.h" #include "palloc.h"
#include "putil.h" #include "putil.h"
#include "pstonum.h"
namespace plib { namespace plib {

View File

@ -92,7 +92,6 @@ namespace plib
return !(v & (v-1)); return !(v & (v-1));
} }
//============================================================ //============================================================
// abs, lcd, gcm // abs, lcd, gcm
//============================================================ //============================================================

View File

@ -13,16 +13,13 @@
#include "pstring.h" #include "pstring.h"
#include <algorithm> #include <algorithm>
#include <initializer_list> //#include <initializer_list>
#include <iostream> //#include <iostream>
#include <locale> //#include <locale>
#include <sstream> //#include <sstream>
#include <vector> #include <vector>
#include <cmath>
#if (PUSE_FLOAT128) // FIXME: pstonum should get an own header
#include <quadmath.h>
#endif
#define PSTRINGIFY_HELP(y) # y #define PSTRINGIFY_HELP(y) # y
#define PSTRINGIFY(x) PSTRINGIFY_HELP(x) #define PSTRINGIFY(x) PSTRINGIFY_HELP(x)
@ -221,312 +218,6 @@ namespace plib
} }
} // namespace container } // namespace container
/* May be further specialized .... This is the generic version */
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 v1 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");
template <class C> template <class C>
struct indexed_compare struct indexed_compare
{ {
@ -547,128 +238,6 @@ namespace plib
const std::string &token, const std::string &token,
const std::size_t maxsplit); const std::size_t maxsplit);
// ----------------------------------------------------------------------------------------
// number conversions
// ----------------------------------------------------------------------------------------
template <typename T, typename S>
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<T>::zero());
if (ss >> x)
{
auto pos(ss.tellg());
if (pos == static_cast<decltype(pos)>(-1))
pos = len;
*idx = static_cast<std::size_t>(pos);
}
else
*idx = constants<std::size_t>::zero();
//printf("%s, %f, %lu %ld\n", arg, (double)x, *idx, (long int) ss.tellg());
return x;
}
template <typename T, typename E = void>
struct pstonum_helper;
template<typename T>
struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value>::type>
{
template <typename S>
long long operator()(std::locale loc, const S &arg, std::size_t *idx)
{
//return std::stoll(arg, idx);
return pstonum_locale<long long>(loc, arg, idx);
}
};
template<typename T>
struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value && !std::is_signed<T>::value>::type>
{
template <typename S>
unsigned long long operator()(std::locale loc, const S &arg, std::size_t *idx)
{
//return std::stoll(arg, idx);
return pstonum_locale<unsigned long long>(loc, arg, idx);
}
};
template<typename T>
struct pstonum_helper<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
{
template <typename S>
long double operator()(std::locale loc, const S &arg, std::size_t *idx)
{
return pstonum_locale<long double>(loc, arg, idx);
}
};
#if PUSE_FLOAT128
template<>
struct pstonum_helper<__float128>
{
// FIXME: use strtoflt128 from quadmath.h
template <typename S>
__float128 operator()(std::locale loc, const S &arg, std::size_t *idx)
{
return static_cast<__float128>(pstonum_locale<long double>(loc, arg, idx));
}
};
#endif
template<typename T, typename S>
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<T>()(loc, cstr, &idx);
using ret_type = decltype(ret);
if (ret >= static_cast<ret_type>(std::numeric_limits<T>::lowest())
&& ret <= static_cast<ret_type>(std::numeric_limits<T>::max()))
//&& (ret == T(0) || std::abs(ret) >= std::numeric_limits<T>::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<T>(ret);
}
template<typename R, typename T>
R pstonum_ne(const T &str, bool &err, std::locale loc = std::locale::classic()) noexcept
{
try
{
err = false;
return pstonum<R>(str, loc);
}
catch (...)
{
err = true;
return R(0);
}
}
template<typename R, typename T>
R pstonum_ne_def(const T &str, R def, std::locale loc = std::locale::classic()) noexcept
{
try
{
return pstonum<R>(str, loc);
}
catch (...)
{
return def;
}
}
//============================================================ //============================================================
// penum - strongly typed enumeration // penum - strongly typed enumeration
//============================================================ //============================================================
@ -704,5 +273,4 @@ namespace plib
} \ } \
}; };
#endif /* PUTIL_H_ */ #endif /* PUTIL_H_ */

View File

@ -14,7 +14,6 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cmath>
#include <type_traits> #include <type_traits>
#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) #if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
@ -137,7 +136,7 @@ namespace plib
{ {
T ret = 0.0; T ret = 0.0;
for ( std::size_t i = 0; i < n; i++ ) 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; return ret;
} }

View File

@ -8,8 +8,6 @@
#include "nld_matrix_solver.h" #include "nld_matrix_solver.h"
#include "plib/putil.h" #include "plib/putil.h"
#include <cmath> // <<= needed by windows build
namespace netlist namespace netlist
{ {
namespace solver namespace solver

View File

@ -16,8 +16,6 @@
#include "plib/putil.h" #include "plib/putil.h"
#include "plib/vector_ops.h" #include "plib/vector_ops.h"
#include <cmath>
namespace netlist namespace netlist
{ {
namespace solver namespace solver

View File

@ -14,7 +14,6 @@
#include "plib/vector_ops.h" #include "plib/vector_ops.h"
#include <algorithm> #include <algorithm>
#include <cmath>
namespace netlist namespace netlist
{ {

View File

@ -186,8 +186,8 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::compute_next_timestep()
n->m_h_n_m_1 = hn; n->m_h_n_m_1 = hn;
n->m_DD_n_m_1 = DD_n; n->m_DD_n_m_1 = DD_n;
if (std::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero if (plib::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)); new_net_timestep = std::sqrt(m_params.m_dynamic_lte / plib::abs(NL_FCONST(0.5)*DD2));
else else
new_net_timestep = m_params.m_max_timestep; new_net_timestep = m_params.m_max_timestep;
@ -549,7 +549,7 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::delta(
const unsigned iN = this->N(); const unsigned iN = this->N();
nl_double cerr = 0; nl_double cerr = 0;
for (unsigned i = 0; i < iN; i++) 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; return cerr;
} }

View File

@ -16,8 +16,6 @@
#include "plib/vector_ops.h" #include "plib/vector_ops.h"
#include <algorithm> #include <algorithm>
#include <cmath>
namespace netlist namespace netlist
{ {

View File

@ -134,16 +134,16 @@ namespace solver
for (int k = 0; k < iN; k++) for (int k = 0; k < iN; k++)
{ {
#if 0 #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) if ( akk > lambdaN)
lambdaN = akk; lambdaN = akk;
if (akk < lambda1) if (akk < lambda1)
lambda1 = akk; lambda1 = akk;
#else #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; float_type s = 0.0;
for (int i=0; i<iN; i++) for (int i=0; i<iN; i++)
s = s + std::abs(this->m_A[k][i]); s = s + plib::abs(this->m_A[k][i]);
akk = s / akk - 1.0; akk = s / akk - 1.0;
if ( akk > lambdaN) if ( akk > lambdaN)
lambdaN = akk; lambdaN = akk;

View File

@ -46,7 +46,6 @@
#include "plib/pomp.h" #include "plib/pomp.h"
#include <algorithm> #include <algorithm>
#include <cmath>
namespace netlist namespace netlist
{ {

View File

@ -6,11 +6,12 @@
*/ */
#include "plib/palloc.h" #include "plib/palloc.h"
#include "nl_convert.h"
#include "plib/putil.h" #include "plib/putil.h"
#include "plib/pstonum.h"
#include "nl_convert.h"
#include <algorithm> #include <algorithm>
#include <cmath>
#include <unordered_map> #include <unordered_map>
/* FIXME: temporarily defined here - should be in a file */ /* 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) 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(e.m_func)(val / e.m_mult);
} }
return plib::pfmt("{1}")(val); return plib::pfmt("{1}")(val);