summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/lib/netlist/build/makefile2
-rw-r--r--src/lib/netlist/devices/nld_4066.cpp17
-rw-r--r--src/lib/netlist/nl_base.h2
-rw-r--r--src/lib/netlist/nl_config.h38
-rw-r--r--src/lib/netlist/nl_setup.h10
-rw-r--r--src/lib/netlist/plib/pconfig.h4
-rw-r--r--src/lib/netlist/plib/pfmtlog.h22
-rw-r--r--src/lib/netlist/plib/pfunction.cpp6
-rw-r--r--src/lib/netlist/plib/pfunction.h3
-rw-r--r--src/lib/netlist/plib/pmath.h50
-rw-r--r--src/lib/netlist/plib/pstate.h4
-rw-r--r--src/lib/netlist/plib/pstonum.h15
-rw-r--r--src/lib/netlist/plib/ptime.h22
-rw-r--r--src/lib/netlist/plib/ptypes.h34
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp7
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h23
-rw-r--r--src/lib/netlist/solver/nld_ms_direct.h38
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h3
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp7
19 files changed, 175 insertions, 132 deletions
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index 62bd8df58e5..89b790c176b 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -239,7 +239,7 @@ native:
$(MAKE) CEXTRAFLAGS="-march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra "
gcc9:
- $(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -msse4.2 -Wall -pedantic -Wpedantic -Wsign-compare -Wextra" EXTRALIBS="-lquadmath"
+ $(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -fext-numeric-literals -msse4.2 -Wall -pedantic -Wpedantic -Wsign-compare -Wextra" EXTRALIBS="-lquadmath"
clang:
$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Werror -Wno-padded -Wno-weak-vtables -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp
index 6e67fe15d5f..43c5961d43b 100644
--- a/src/lib/netlist/devices/nld_4066.cpp
+++ b/src/lib/netlist/devices/nld_4066.cpp
@@ -117,18 +117,19 @@ namespace netlist
nl_fptype sup = (m_supply.VCC().Q_Analog() - m_supply.GND().Q_Analog());
nl_fptype in = m_DUM1.m_P.net().Q_Analog() - m_supply.GND().Q_Analog();
nl_fptype rON = m_base_r() * nlconst::magic(5.0) / sup;
- nl_fptype R = std::exp(-(in / sup - 0.55) * 25.0) + rON;
+ nl_fptype R = std::exp(-(in / sup - nlconst::magic(0.55)) * nlconst::magic(25.0)) + rON;
nl_fptype G = plib::reciprocal(R);
// dI/dVin = (VR1-VR2)*(1.0/sup*b) * exp((Vin/sup-a) * b)
- const auto dfdz = 25.0/(R*sup) * m_R.deltaV();
+ const auto dfdz = nlconst::magic(25.0)/(R*sup) * m_R.deltaV();
const auto Ieq = dfdz * in;
- m_R.set_mat( G, -G, 0.0,
- -G, G, 0.0);
+ const auto zero(nlconst::zero());
+ m_R.set_mat( G, -G, zero,
+ -G, G, zero);
//VIN VR1
- m_DUM1.set_mat( 0.0, 0.0, 0.0, // IIN
- dfdz, 0.0, Ieq); // IR1
- m_DUM2.set_mat( 0.0, 0.0, 0.0, // IIN
- -dfdz, 0.0, -Ieq); // IR2
+ m_DUM1.set_mat( zero, zero, zero, // IIN
+ dfdz, zero, Ieq); // IR1
+ m_DUM2.set_mat( zero, zero, zero, // IIN
+ -dfdz, zero, -Ieq); // IR2
}
NETLIB_IS_DYNAMIC(true)
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index a0f687c1b5d..ba18104b2e4 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -1789,7 +1789,7 @@ namespace netlist
plib::pfunction<nl_fptype> func;
func.compile_infix(p, {});
auto valx = func.evaluate();
- if (std::is_integral<T>::value)
+ if (plib::is_integral<T>::value)
if (plib::abs(valx - plib::trunc(valx)) > nlconst::magic(1e-6))
throw nl_exception(MF_INVALID_NUMBER_CONVERSION_1_2(device.name() + "." + name, p));
m_param = static_cast<T>(valx);
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index e08065dd47e..a60c316b206 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -55,10 +55,12 @@
/// \brief Compile in academic solvers
///
-/// Set to 0 to disable compiling in the following solvers:
+/// Set to 0 to disable compiling the following solvers:
///
/// Sherman-Morrison, Woodbury, SOR and GMRES
///
+/// In addition, compilation of FLOAT, LONGDOUBLE and FLOATQ128 matrix
+/// solvers will be disabled.
/// GMRES may be added to productive solvers in the future
/// again. Compiling in all solvers may increase compile
/// time significantly.
@@ -113,18 +115,20 @@
/// \brief Support float type for matrix calculations.
///
-/// Defaults to off to provide faster build times
+/// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
#ifndef NL_USE_FLOAT_MATRIX
-#define NL_USE_FLOAT_MATRIX (0)
+#define NL_USE_FLOAT_MATRIX (NL_USE_ACADEMIC_SOLVERS)
+//#define NL_USE_FLOAT_MATRIX 1
#endif
/// \brief Support long double type for matrix calculations.
///
-/// Defaults to off to provide faster build times
+/// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
#ifndef NL_USE_LONG_DOUBLE_MATRIX
-#define NL_USE_LONG_DOUBLE_MATRIX (0)
+#define NL_USE_LONG_DOUBLE_MATRIX (NL_USE_ACADEMIC_SOLVERS)
+//#define NL_USE_LONG_DOUBLE_MATRIX 1
#endif
//============================================================
@@ -187,6 +191,8 @@ static constexpr const int NETLIST_CLOCK = 1'000'000'000;
///
using nl_fptype = double;
+//using nl_fptype = long double;
+//using nl_fptype = float;
namespace netlist
{
@@ -244,27 +250,27 @@ namespace netlist
};
#if (NL_USE_FLOAT128)
- /// \brief Specific constants for __float128 floating point type
+ /// \brief Specific constants for FLOAT128 floating point type
///
template <>
- struct fp_constants<__float128>
+ struct fp_constants<FLOAT128>
{
#if 0
// MAME compile doesn't support Q
- static inline constexpr __float128 DIODE_MAXDIFF() noexcept { return 1e100Q; }
- static inline constexpr __float128 DIODE_MAXVOLT() noexcept { return 300.0Q; }
+ static inline constexpr FLOAT128 DIODE_MAXDIFF() noexcept { return 1e100Q; }
+ static inline constexpr FLOAT128 DIODE_MAXVOLT() noexcept { return 300.0Q; }
- static inline constexpr __float128 TIMESTEP_MAXDIFF() noexcept { return 1e100Q; }
- static inline constexpr __float128 TIMESTEP_MINDIV() noexcept { return 1e-60Q; }
+ static inline constexpr FLOAT128 TIMESTEP_MAXDIFF() noexcept { return 1e100Q; }
+ static inline constexpr FLOAT128 TIMESTEP_MINDIV() noexcept { return 1e-60Q; }
- static inline constexpr const char * name() noexcept { return "__float128"; }
+ static inline constexpr const char * name() noexcept { return "FLOAT128"; }
static inline constexpr const char * suffix() noexcept { return "Q"; }
#else
- static inline constexpr __float128 DIODE_MAXDIFF() noexcept { return static_cast<__float128>(1e100L); }
- static inline constexpr __float128 DIODE_MAXVOLT() noexcept { return static_cast<__float128>(300.0L); }
+ static inline constexpr FLOAT128 DIODE_MAXDIFF() noexcept { return static_cast<FLOAT128>(1e100L); }
+ static inline constexpr FLOAT128 DIODE_MAXVOLT() noexcept { return static_cast<FLOAT128>(300.0L); }
- static inline constexpr __float128 TIMESTEP_MAXDIFF() noexcept { return static_cast<__float128>(1e100L); }
- static inline constexpr __float128 TIMESTEP_MINDIV() noexcept { return static_cast<__float128>(1e-60L); }
+ static inline constexpr FLOAT128 TIMESTEP_MAXDIFF() noexcept { return static_cast<FLOAT128>(1e100L); }
+ static inline constexpr FLOAT128 TIMESTEP_MINDIV() noexcept { return static_cast<FLOAT128>(1e-60L); }
static inline constexpr const char * name() noexcept { return "__float128"; }
static inline constexpr const char * suffix() noexcept { return "Q"; }
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 2f6ba2bfcd1..9b1a24c4d7c 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -254,25 +254,19 @@ namespace netlist
void register_link(const pstring &sin, const pstring &sout);
void register_link_arr(const pstring &terms);
+
void register_param(const pstring &param, const pstring &value);
// FIXME: quick hack
void register_param_x(const pstring &param, nl_fptype value);
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value || std::is_integral<T>::value>::type
+ typename std::enable_if<plib::is_floating_point<T>::value || plib::is_integral<T>::value>::type
register_param_val(const pstring &param, T value)
{
register_param_x(param, static_cast<nl_fptype>(value));
}
-#if PUSE_FLOAT128
- void register_param(const pstring &param, __float128 value)
- {
- register_param_x(param, static_cast<nl_fptype>(value));
- }
-#endif
-
void register_lib_entry(const pstring &name, const pstring &sourcefile);
void register_frontier(const pstring &attach, const pstring &r_IN, const pstring &r_OUT);
diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h
index ae739cfb976..a40120cc7f5 100644
--- a/src/lib/netlist/plib/pconfig.h
+++ b/src/lib/netlist/plib/pconfig.h
@@ -134,6 +134,10 @@ typedef __uint128_t UINT128;
typedef __int128_t INT128;
#endif
+#if (PUSE_FLOAT128)
+typedef __float128 FLOAT128;
+#endif
+
//============================================================
// Check for OpenMP
//============================================================
diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h
index f73e83c2ca2..8b7b2974ce4 100644
--- a/src/lib/netlist/plib/pfmtlog.h
+++ b/src/lib/netlist/plib/pfmtlog.h
@@ -47,12 +47,12 @@ namespace plib {
#if (PUSE_FLOAT128)
template <>
- struct ptype_traits_base<__float128>
+ struct ptype_traits_base<FLOAT128>
{
// FIXME: need native support at some time
static constexpr const bool is_signed = true;
static char32_t fmt_spec() { return 'f'; }
- static inline void streamify(std::ostream &s, const __float128 &v)
+ static inline void streamify(std::ostream &s, const FLOAT128 &v)
{
s << static_cast<long double>(v);
}
@@ -153,7 +153,7 @@ namespace plib {
#if (PUSE_FLOAT128)
template<>
- struct ptype_traits<__float128> : ptype_traits_base<__float128>
+ struct ptype_traits<FLOAT128> : ptype_traits_base<FLOAT128>
{
static char32_t fmt_spec() { return 'f'; }
};
@@ -202,20 +202,20 @@ namespace plib {
operator pstring() const { return m_str; }
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type
+ typename std::enable_if<plib::is_floating_point<T>::value, pfmt &>::type
f(const T &x) {return format_element('f', x); }
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type
+ typename std::enable_if<plib::is_floating_point<T>::value, pfmt &>::type
e(const T &x) {return format_element('e', x); }
-
+#if 0
#if PUSE_FLOAT128
// 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
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type
+ typename std::enable_if<plib::is_floating_point<T>::value, pfmt &>::type
g(const T &x) {return format_element('g', x); }
pfmt &operator ()(const void *x) {return format_element('p', x); }
@@ -245,14 +245,14 @@ namespace plib {
}
template<typename T>
- typename std::enable_if<std::is_integral<T>::value, pfmt &>::type
+ typename std::enable_if<plib::is_integral<T>::value, pfmt &>::type
x(const T &x)
{
return format_element('x', x);
}
template<typename T>
- typename std::enable_if<std::is_integral<T>::value, pfmt &>::type
+ typename std::enable_if<plib::is_integral<T>::value, pfmt &>::type
o(const T &x)
{
return format_element('o', x);
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 21f61643fea..b5b4dd779c5 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -236,7 +236,7 @@ namespace plib {
}
template <typename NT>
- static inline typename std::enable_if<std::is_floating_point<NT>::value, NT>::type
+ static inline typename std::enable_if<plib::is_floating_point<NT>::value, NT>::type
lfsr_random(std::uint16_t &lfsr) noexcept
{
std::uint16_t lsb = lfsr & 1;
@@ -247,7 +247,7 @@ namespace plib {
}
template <typename NT>
- static inline typename std::enable_if<std::is_integral<NT>::value, NT>::type
+ static inline typename std::enable_if<plib::is_integral<NT>::value, NT>::type
lfsr_random(std::uint16_t &lfsr) noexcept
{
std::uint16_t lsb = lfsr & 1;
@@ -304,7 +304,7 @@ namespace plib {
template class pfunction<double>;
template class pfunction<long double>;
#if (PUSE_FLOAT128)
- template class pfunction<__float128>;
+ template class pfunction<FLOAT128>;
#endif
} // namespace plib
diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h
index e09a90ea87e..364d7c8745c 100644
--- a/src/lib/netlist/plib/pfunction.h
+++ b/src/lib/netlist/plib/pfunction.h
@@ -120,8 +120,9 @@ namespace plib {
extern template class pfunction<double>;
extern template class pfunction<long double>;
#if (PUSE_FLOAT128)
- extern template class pfunction<__float128>;
+ extern template class pfunction<FLOAT128>;
#endif
+
} // namespace plib
#endif // PEXCEPTION_H_
diff --git a/src/lib/netlist/plib/pmath.h b/src/lib/netlist/plib/pmath.h
index e995c3a6c27..819d51159a4 100644
--- a/src/lib/netlist/plib/pmath.h
+++ b/src/lib/netlist/plib/pmath.h
@@ -247,85 +247,85 @@ namespace plib
/// FIXME: limited implementation
///
template <typename T1, typename T2>
- static inline T1
- pow(T1 v, T2 p) noexcept
+ static inline
+ auto pow(T1 v, T2 p) noexcept -> decltype(std::pow(v, p))
{
return std::pow(v, p);
}
#if (PUSE_FLOAT128)
- static inline constexpr __float128 reciprocal(__float128 v) noexcept
+ static inline constexpr FLOAT128 reciprocal(FLOAT128 v) noexcept
{
- return constants<__float128>::one() / v;
+ return constants<FLOAT128>::one() / v;
}
- static inline __float128 abs(__float128 v) noexcept
+ static inline FLOAT128 abs(FLOAT128 v) noexcept
{
return fabsq(v);
}
- static inline __float128 sqrt(__float128 v) noexcept
+ static inline FLOAT128 sqrt(FLOAT128 v) noexcept
{
return sqrtq(v);
}
- static inline __float128 hypot(__float128 v1, __float128 v2) noexcept
+ static inline FLOAT128 hypot(FLOAT128 v1, FLOAT128 v2) noexcept
{
return hypotq(v1, v2);
}
- static inline __float128 exp(__float128 v) noexcept
+ static inline FLOAT128 exp(FLOAT128 v) noexcept
{
return expq(v);
}
- static inline __float128 log(__float128 v) noexcept
+ static inline FLOAT128 log(FLOAT128 v) noexcept
{
return logq(v);
}
- static inline __float128 tanh(__float128 v) noexcept
+ static inline FLOAT128 tanh(FLOAT128 v) noexcept
{
return tanhq(v);
}
- static inline __float128 floor(__float128 v) noexcept
+ static inline FLOAT128 floor(FLOAT128 v) noexcept
{
return floorq(v);
}
- static inline __float128 log1p(__float128 v) noexcept
+ static inline FLOAT128 log1p(FLOAT128 v) noexcept
{
return log1pq(v);
}
- static inline __float128 sin(__float128 v) noexcept
+ static inline FLOAT128 sin(FLOAT128 v) noexcept
{
return sinq(v);
}
- static inline __float128 cos(__float128 v) noexcept
+ static inline FLOAT128 cos(FLOAT128 v) noexcept
{
return cosq(v);
}
- static inline __float128 trunc(__float128 v) noexcept
+ static inline FLOAT128 trunc(FLOAT128 v) noexcept
{
return truncq(v);
}
template <typename T>
- static inline __float128 pow(__float128 v, T p) noexcept
+ static inline FLOAT128 pow(FLOAT128 v, T p) noexcept
{
- return powq(v, static_cast<__float128>(p));
+ return powq(v, static_cast<FLOAT128>(p));
}
- static inline __float128 pow(__float128 v, int p) noexcept
+ static inline FLOAT128 pow(FLOAT128 v, int p) noexcept
{
if (p==2)
return v*v;
else
- return powq(v, static_cast<__float128>(p));
+ return powq(v, static_cast<FLOAT128>(p));
}
#endif
@@ -351,7 +351,7 @@ namespace plib
///
template<typename T>
constexpr
- typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, T>::type
+ typename std::enable_if<plib::is_integral<T>::value && plib::is_signed<T>::value, T>::type
abs(T v) noexcept
{
return v < 0 ? -v : v;
@@ -365,7 +365,7 @@ namespace plib
///
template<typename T>
constexpr
- typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, T>::type
+ typename std::enable_if<plib::is_integral<T>::value && plib::is_unsigned<T>::value, T>::type
abs(T v) noexcept
{
return v;
@@ -386,8 +386,8 @@ namespace plib
constexpr typename std::common_type<M, N>::type
gcd(M m, N n) noexcept
{
- static_assert(std::is_integral<M>::value, "gcd: M must be an integer");
- static_assert(std::is_integral<N>::value, "gcd: N must be an integer");
+ static_assert(plib::is_integral<M>::value, "gcd: M must be an integer");
+ static_assert(plib::is_integral<N>::value, "gcd: N must be an integer");
return m == 0 ? plib::abs(n)
: n == 0 ? plib::abs(m)
@@ -409,8 +409,8 @@ namespace plib
constexpr typename std::common_type<M, N>::type
lcm(M m, N n) noexcept
{
- static_assert(std::is_integral<M>::value, "lcm: M must be an integer");
- static_assert(std::is_integral<N>::value, "lcm: N must be an integer");
+ static_assert(plib::is_integral<M>::value, "lcm: M must be an integer");
+ static_assert(plib::is_integral<N>::value, "lcm: N must be an integer");
return (m != 0 && n != 0) ? (plib::abs(m) / gcd(m, n)) * plib::abs(n) : 0;
}
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h
index 4a7875e1767..151e50a4aae 100644
--- a/src/lib/netlist/plib/pstate.h
+++ b/src/lib/netlist/plib/pstate.h
@@ -51,7 +51,7 @@ public:
{
return datatype_t(sizeof(T),
plib::is_integral<T>::value || std::is_enum<T>::value,
- std::is_floating_point<T>::value);
+ plib::is_floating_point<T>::value);
}
class callback_t
@@ -97,7 +97,7 @@ public:
state_manager_t() = default;
- template<typename C> //, typename std::enable_if<std::is_integral<C>::value || std::is_floating_point<C>::value>::type>
+ template<typename C>
void save_item(const void *owner, C &state, const pstring &stname)
{
save_state_ptr( owner, stname, dtype<C>(), 1, &state);
diff --git a/src/lib/netlist/plib/pstonum.h b/src/lib/netlist/plib/pstonum.h
index 737dca9f471..131f642c26f 100644
--- a/src/lib/netlist/plib/pstonum.h
+++ b/src/lib/netlist/plib/pstonum.h
@@ -50,7 +50,7 @@ namespace plib
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>
+ struct pstonum_helper<T, typename std::enable_if<plib::is_integral<T>::value && plib::is_signed<T>::value>::type>
{
template <typename S>
long long operator()(std::locale loc, const S &arg, std::size_t *idx)
@@ -61,7 +61,7 @@ namespace plib
};
template<typename T>
- struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value && !std::is_signed<T>::value>::type>
+ struct pstonum_helper<T, typename std::enable_if<plib::is_integral<T>::value && !plib::is_signed<T>::value>::type>
{
template <typename S>
unsigned long long operator()(std::locale loc, const S &arg, std::size_t *idx)
@@ -83,13 +83,13 @@ namespace plib
#if PUSE_FLOAT128
template<>
- struct pstonum_helper<__float128>
+ 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)
+ FLOAT128 operator()(std::locale loc, const S &arg, std::size_t *idx)
{
- return static_cast<__float128>(pstonum_locale<long double>(loc, arg, idx));
+ return static_cast<FLOAT128>(pstonum_locale<long double>(loc, arg, idx));
}
};
#endif
@@ -101,9 +101,8 @@ namespace plib
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 (ret >= static_cast<ret_type>(plib::numeric_limits<T>::lowest())
+ && ret <= static_cast<ret_type>(plib::numeric_limits<T>::max()))
{
if (cstr[idx] != 0)
throw pexception(pstring("Continuation after numeric value ends: ") + pstring(cstr));
diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h
index 7168477f49f..836f832bda8 100644
--- a/src/lib/netlist/plib/ptime.h
+++ b/src/lib/netlist/plib/ptime.h
@@ -57,14 +57,14 @@ namespace plib
C14CONSTEXPR ptime &operator=(ptime &&rhs) noexcept = default;
constexpr explicit ptime(const double t) = delete;
- //: m_time((internal_type) ( t * (double) resolution)) { }
constexpr explicit ptime(const internal_type nom, const internal_type den) noexcept
: m_time(nom * (RES / den)) { }
- // FIXME: check for overflow
template <typename O>
constexpr explicit ptime(const ptime<O, RES> &rhs) noexcept
- : m_time(rhs.m_time) { }
+ : m_time(static_cast<TYPE>(rhs.m_time))
+ {
+ }
template <typename O>
C14CONSTEXPR ptime &operator+=(const ptime<O, RES> &rhs) noexcept
@@ -149,21 +149,13 @@ namespace plib
constexpr internal_type as_raw() const noexcept { return m_time; }
- template <typename FT, typename = std::enable_if<std::is_floating_point<FT>::value, FT>>
+ template <typename FT, typename = std::enable_if<plib::is_floating_point<FT>::value, FT>>
constexpr FT
as_fp() const noexcept
{
return static_cast<FT>(m_time) * inv_res<FT>();
}
-#if PUSE_FLOAT128
- constexpr __float128
- as_fp() const noexcept
- {
- return static_cast<__float128>(m_time) * inv_res<__float128>();
- }
-#endif
-
constexpr double as_double() const noexcept { return as_fp<double>(); }
constexpr double as_float() const noexcept { return as_fp<float>(); }
constexpr double as_long_double() const noexcept { return as_fp<long double>(); }
@@ -183,11 +175,7 @@ namespace plib
static constexpr ptime from_raw(internal_type raw) noexcept { return ptime(raw); }
template <typename FT>
- static constexpr typename std::enable_if<std::is_floating_point<FT>::value
-#if PUSE_FLOAT128
- || std::is_same<FT, __float128>::value
-#endif
- , ptime>::type
+ static constexpr typename std::enable_if<plib::is_floating_point<FT>::value, ptime>::type
from_fp(FT t) noexcept { return ptime(static_cast<internal_type>(plib::floor(t * static_cast<FT>(RES) + static_cast<FT>(0.5))), RES); }
static constexpr ptime from_double(double t) noexcept
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index d011d228154..7231dcd2c0a 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -14,6 +14,10 @@
#include <string>
#include <type_traits>
+#if (PUSE_FLOAT128)
+#include <quadmath.h>
+#endif
+
// noexcept on move operator -> issue with macosx clang
#define COPYASSIGNMOVE(name, def) \
name(const name &) = def; \
@@ -28,24 +32,50 @@
namespace plib
{
template<typename T> struct is_integral : public std::is_integral<T> { };
+ template<typename T> struct is_signed : public std::is_signed<T> { };
+ template<typename T> struct is_unsigned : public std::is_unsigned<T> { };
template<typename T> struct numeric_limits : public std::numeric_limits<T> { };
// 128 bit support at least on GCC is not fully supported
#if PHAS_INT128
template<> struct is_integral<UINT128> { static constexpr bool value = true; };
template<> struct is_integral<INT128> { static constexpr bool value = true; };
+
+ template<> struct is_signed<UINT128> { static constexpr bool value = false; };
+ template<> struct is_signed<INT128> { static constexpr bool value = true; };
+
+ template<> struct is_unsigned<UINT128> { static constexpr bool value = true; };
+ template<> struct is_unsigned<INT128> { static constexpr bool value = false; };
+
template<> struct numeric_limits<UINT128>
{
static constexpr UINT128 max() noexcept
{
- return ~((UINT128)0);
+ return ~(static_cast<UINT128>(0));
}
};
template<> struct numeric_limits<INT128>
{
static constexpr INT128 max() noexcept
{
- return (~((UINT128)0)) >> 1;
+ return (~static_cast<UINT128>(0)) >> 1;
+ }
+ };
+#endif
+
+ template<typename T> struct is_floating_point : public std::is_floating_point<T> { };
+
+#if PUSE_FLOAT128
+ template<> struct is_floating_point<FLOAT128> { static constexpr bool value = true; };
+ template<> struct numeric_limits<FLOAT128>
+ {
+ static constexpr FLOAT128 max() noexcept
+ {
+ return FLT128_MAX;
+ }
+ static constexpr FLOAT128 lowest() noexcept
+ {
+ return -FLT128_MAX;
}
};
#endif
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index e4b543a9a96..beab7c3508e 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -471,8 +471,13 @@ namespace solver
if (this_resched && !m_Q_sync.net().is_queued())
{
log().warning(MW_NEWTON_LOOPS_EXCEEDED_ON_NET_1(this->name()));
- // FIXME: may collide with compute_next_timestep
+ // FIXME: test and enable - this is working better, though not optimal yet
+#if 0
+ // Don't store, the result can not be used
+ return netlist_time::from_fp(m_params.m_nr_recalc_delay());
+#else
m_Q_sync.net().toggle_and_push_to_queue(netlist_time::from_fp(m_params.m_nr_recalc_delay()));
+#endif
}
}
else
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index 0db1cd6e7b9..225aa02162a 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -51,7 +51,7 @@ namespace solver
FLOAT
, DOUBLE
, LONGDOUBLE
- , FLOAT128
+ , FLOATQ128
)
using static_compile_container = std::vector<std::pair<pstring, pstring>>;
@@ -143,10 +143,10 @@ namespace solver
terminal_t **terms() noexcept { return m_terms.data(); }
- template <typename FT, typename = std::enable_if<std::is_floating_point<FT>::value, void>>
+ template <typename FT, typename = std::enable_if<plib::is_floating_point<FT>::value, void>>
FT getV() const noexcept { return static_cast<FT>(m_net->Q_Analog()); }
- template <typename FT, typename = std::enable_if<std::is_floating_point<FT>::value, void>>
+ template <typename FT, typename = std::enable_if<plib::is_floating_point<FT>::value, void>>
void setV(FT v) noexcept { m_net->set_Q_Analog(static_cast<nl_fptype>(v)); }
bool isNet(const analog_net_t * net) const noexcept { return net == m_net; }
@@ -299,7 +299,7 @@ namespace solver
, m_mat_ptr(size, this->max_railstart() + 1)
, m_last_V(size, nlconst::zero())
, m_DD_n_m_1(size, nlconst::zero())
- , m_h_n_m_1(size, nlconst::zero())
+ , m_h_n_m_1(size, nlconst::magic(1e-6)) // we need a non zero value here
{
//
// save states
@@ -318,9 +318,9 @@ namespace solver
static constexpr const std::size_t m_pitch_ABS = (((SIZEABS + 0) + 7) / 8) * 8;
PALIGNAS_VECTOROPT()
- plib::parray<FT, SIZE> m_new_V;
+ plib::parray<float_type, SIZE> m_new_V;
PALIGNAS_VECTOROPT()
- plib::parray<FT, SIZE> m_RHS;
+ plib::parray<float_type, SIZE> m_RHS;
PALIGNAS_VECTOROPT()
plib::pmatrix2d<float_type *> m_mat_ptr;
@@ -416,11 +416,11 @@ namespace solver
// and thus belong into a different calculation. This applies to all solvers.
const std::size_t iN = size();
- const auto reltol(static_cast<FT>(m_params.m_reltol));
- const auto vntol(static_cast<FT>(m_params.m_vntol));
+ const auto reltol(static_cast<float_type>(m_params.m_reltol));
+ const auto vntol(static_cast<float_type>(m_params.m_vntol));
for (std::size_t i = 0; i < iN; i++)
{
- const auto vold(this->m_terms[i].template getV<FT>());
+ const auto vold(this->m_terms[i].template getV<float_type>());
const auto vnew(m_new_V[i]);
const auto tol(vntol + reltol * std::max(plib::abs(vnew),plib::abs(vold)));
if (plib::abs(vnew - vold) > tol)
@@ -511,6 +511,7 @@ namespace solver
auto &net = m_terms[k];
auto **tcr_r = &(m_mat_ptr[k][0]);
+ using source_type = typename decltype(m_gtn)::value_type;
const std::size_t term_count = net.count();
const std::size_t railstart = net.railstart();
const auto &go = m_gonn[k];
@@ -520,7 +521,7 @@ namespace solver
// FIXME: gonn, gtn and Idr - which float types should they have?
- auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<FT>::zero());
+ auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<source_type>::zero());
// update diagonal element ...
*tcr_r[railstart] = static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t;
@@ -528,7 +529,7 @@ namespace solver
for (std::size_t i = 0; i < railstart; i++)
*tcr_r[i] += static_cast<FT>(go[i]);
- auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<FT>::zero()));
+ auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<source_type>::zero()));
for (std::size_t i = railstart; i < term_count; i++)
RHS_t += (- go[i]) * *cnV[i];
diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h
index 69584ee6026..d9c78aefd53 100644
--- a/src/lib/netlist/solver/nld_ms_direct.h
+++ b/src/lib/netlist/solver/nld_ms_direct.h
@@ -67,15 +67,17 @@ namespace solver
for (std::size_t i = 0; i < kN; i++)
{
// FIXME: Singular matrix?
- const FT f = plib::reciprocal(m_A[i][i]);
+ const auto &Ai = m_A[i];
+ const FT f = plib::reciprocal(Ai[i]);
const auto &nzrd = this->m_terms[i].m_nzrd;
const auto &nzbd = this->m_terms[i].m_nzbd;
for (auto &j : nzbd)
{
- const FT f1 = -f * m_A[j][i];
+ auto &Aj = m_A[j];
+ const FT f1 = -f * Aj[i];
for (auto &k : nzrd)
- m_A[j][k] += m_A[i][k] * f1;
+ Aj[k] += Ai[k] * f1;
this->m_RHS[j] += this->m_RHS[i] * f1;
}
}
@@ -95,24 +97,30 @@ namespace solver
if (maxrow != i)
{
+#if 0
// Swap the maxrow and ith row
for (std::size_t k = 0; k < kN; k++) {
std::swap(m_A[i][k], m_A[maxrow][k]);
}
+#else
+ std::swap(m_A[i], m_A[maxrow]);
+#endif
std::swap(this->m_RHS[i], this->m_RHS[maxrow]);
}
// FIXME: Singular matrix?
- const FT f = plib::reciprocal(m_A[i][i]);
+ const auto &Ai = m_A[i];
+ const FT f = plib::reciprocal(Ai[i]);
// Eliminate column i from row j
for (std::size_t j = i + 1; j < kN; j++)
{
+ auto &Aj = m_A[j];
const FT f1 = - m_A[j][i] * f;
if (f1 != plib::constants<FT>::zero())
{
- const FT * pi = &(m_A[i][i+1]);
- FT * pj = &(m_A[j][i+1]);
+ const FT * pi = &(Ai[i+1]);
+ FT * pj = &(Aj[i+1]);
plib::vec_add_mult_scalar_p(kN-i-1,pj,pi,f1);
//for (unsigned k = i+1; k < kN; k++)
// pj[k] = pj[k] + pi[k] * f1;
@@ -137,22 +145,26 @@ namespace solver
{
for (std::size_t j = kN; j-- > 0; )
{
- FT tmp = 0;
+ FT tmp(0);
+ const auto & Aj(m_A[j]);
+
for (std::size_t k = j+1; k < kN; k++)
- tmp += m_A[j][k] * x[k];
- x[j] = (this->m_RHS[j] - tmp) / m_A[j][j];
+ tmp += Aj[k] * x[k];
+ x[j] = (this->m_RHS[j] - tmp) / Aj[j];
}
}
else
{
for (std::size_t j = kN; j-- > 0; )
{
- FT tmp = 0;
+ FT tmp(0);
const auto &nzrd = this->m_terms[j].m_nzrd;
- const auto e = nzrd.size(); // - 1; // exclude RHS element
+ const auto & Aj(m_A[j]);
+ const auto e = nzrd.size();
+
for ( std::size_t k = 0; k < e; k++)
- tmp += m_A[j][nzrd[k]] * x[nzrd[k]];
- x[j] = (this->m_RHS[j] - tmp) / m_A[j][j];
+ tmp += Aj[nzrd[k]] * x[nzrd[k]];
+ x[j] = (this->m_RHS[j] - tmp) / Aj[j];
}
}
}
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index da45c0e2880..3f23ef64b26 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -123,8 +123,7 @@ namespace solver
pstring static_compile_name();
mat_type mat;
-
- plib::dynproc<void, FT *, FT *, FT *, FT *, FT ** > m_proc;
+ plib::dynproc<void, FT *, nl_fptype *, nl_fptype *, nl_fptype *, nl_fptype ** > m_proc;
};
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index 775a3ff87eb..35a5afd961d 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -329,6 +329,7 @@ namespace devices
#if (NL_USE_FLOAT_MATRIX)
ms = create_solvers<float>(sname, grp);
#else
+ log().info("FPTYPE {1} not supported. Using DOUBLE", m_params.m_fp_type().name());
ms = create_solvers<double>(sname, grp);
#endif
break;
@@ -339,13 +340,15 @@ namespace devices
#if (NL_USE_LONG_DOUBLE_MATRIX)
ms = create_solvers<long double>(sname, grp);
#else
+ log().info("FPTYPE {1} not supported. Using DOUBLE", m_params.m_fp_type().name());
ms = create_solvers<double>(sname, grp);
#endif
break;
- case solver::matrix_fp_type_e::FLOAT128:
+ case solver::matrix_fp_type_e::FLOATQ128:
#if (NL_USE_FLOAT128)
- ms = create_solvers<__float128>(sname, grp);
+ ms = create_solvers<FLOAT128>(sname, grp);
#else
+ log().info("FPTYPE {1} not supported. Using DOUBLE", m_params.m_fp_type().name());
ms = create_solvers<double>(sname, grp);
#endif
break;