summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
authorGravatarGravatar couriersud <couriersud@gmx.org>2019-10-31 21:53:50 +0100
committerGravatarGravatar couriersud <couriersud@gmx.org>2019-10-31 21:53:50 +0100
commitc6b281685d16c02b83b1b0c89acae392ecf851ff (patch)
tree2cd979f919b39e1feeffbde0b22462db59a6492a /src/lib
parent6c075e602cf83b379b8fa2c981694134b679a538 (diff)
netlist: Compile with float/double floating point. [Couriersud]
Added ability to compile using float instead of double. Specifically the the solver as well as the infrastructure now can have their own floating point type. Currently this is only an academic exercise since numerically demanding circuits like kidniki only work with double/double support. Using float here is pushing numerical stability over the limits. The long term design goal is too have the matrix type (double/float) being a parameter.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/netlist/analog/nld_generic_models.h6
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h4
-rw-r--r--src/lib/netlist/devices/nlid_system.h4
-rw-r--r--src/lib/netlist/nl_config.h47
-rw-r--r--src/lib/netlist/plib/pfunction.cpp350
-rw-r--r--src/lib/netlist/plib/pfunction.h12
-rw-r--r--src/lib/netlist/prg/nltool.cpp7
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp4
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h7
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h2
-rw-r--r--src/lib/netlist/solver/nld_ms_sor.h8
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp52
12 files changed, 282 insertions, 221 deletions
diff --git a/src/lib/netlist/analog/nld_generic_models.h b/src/lib/netlist/analog/nld_generic_models.h
index af5c6ac4450..58fecd9ea31 100644
--- a/src/lib/netlist/analog/nld_generic_models.h
+++ b/src/lib/netlist/analog/nld_generic_models.h
@@ -158,12 +158,12 @@ namespace analog
//printf("%s: %g %g\n", m_name.c_str(), nVd, (nl_fptype) m_Vd);
if (nVd > m_Vcrit)
{
- const nl_fptype d = std::min(1e100, nVd - m_Vd);
+ const nl_fptype d = std::min(fp_constants<nl_fptype>::DIODE_MAXDIFF, nVd - m_Vd);
const nl_fptype a = std::abs(d) * m_VtInv;
m_Vd = m_Vd + (d < 0 ? -1.0 : 1.0) * std::log1p(a) * m_Vt;
}
else
- m_Vd = std::max(-1e100, nVd);
+ m_Vd = std::max(-fp_constants<nl_fptype>::DIODE_MAXDIFF, nVd);
//m_Vd = nVd;
if (m_Vd < m_Vmin)
@@ -189,7 +189,7 @@ namespace analog
else /* log stepping should already be done in mosfet */
{
m_Vd = nVd;
- IseVDVt = std::exp(std::min(300.0, m_logIs + m_Vd * m_VtInv));
+ IseVDVt = std::exp(std::min(fp_constants<nl_fptype>::DIODE_MAXVOLT, m_logIs + m_Vd * m_VtInv));
m_Id = IseVDVt - m_Is;
m_G = IseVDVt * m_VtInv + m_gmin;
}
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index 4f448615380..2618c3eb20e 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -430,7 +430,7 @@ namespace analog
param_fp_t m_R;
param_fp_t m_V;
param_str_t m_func;
- plib::pfunction m_compiled;
+ plib::pfunction<nl_fptype> m_compiled;
std::vector<nl_fptype> m_funcparam;
};
@@ -486,7 +486,7 @@ namespace analog
state_var<nl_fptype> m_t;
param_fp_t m_I;
param_str_t m_func;
- plib::pfunction m_compiled;
+ plib::pfunction<nl_fptype> m_compiled;
std::vector<nl_fptype> m_funcparam;
};
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index bdccf2ab6c0..c51f5c36c56 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -149,7 +149,7 @@ namespace devices
logic_output_t m_Q;
param_str_t m_func;
- plib::pfunction m_compiled;
+ plib::pfunction<nl_fptype> m_compiled;
std::vector<nl_fptype> m_funcparam;
};
@@ -389,7 +389,7 @@ namespace devices
std::vector<unique_pool_ptr<analog_input_t>> m_I;
std::vector<nl_fptype> m_vals;
- plib::pfunction m_compiled;
+ plib::pfunction<nl_fptype> m_compiled;
};
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index 0417172203b..a73caf5cbce 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -96,7 +96,52 @@
static constexpr const auto NETLIST_INTERNAL_RES = 1000000000;
static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES;
-//#define nl_fptype float
+//============================================================
+// Floating point types used
+//
+// Don't change this. Simple analog circuits like pong
+// work with float. Kidniki just doesn't work at all
+// due to numeric issues
+//============================================================
+
using nl_fptype = double;
+//using nl_fptype = float;
+
+using nl_mat_fptype = nl_fptype;
+
+namespace netlist
+{
+ /*! Specific constants depending on floating type
+ *
+ * @tparam FT floating point type: double/float
+ */
+ template <typename FT>
+ struct fp_constants
+ { };
+
+ /*! Specific constants for double floating point type
+ */
+ template <>
+ struct fp_constants<double>
+ {
+ static constexpr const double DIODE_MAXDIFF = 1e100;
+ static constexpr const double DIODE_MAXVOLT = 300.0;
+
+ static constexpr const double TIMESTEP_MAXDIFF = 1e100;
+ static constexpr const double TIMESTEP_MINDIV = 1e-60;
+ };
+
+ /*! Specific constants for float floating point type
+ */
+ template <>
+ struct fp_constants<float>
+ {
+ static constexpr const float DIODE_MAXDIFF = 1e5;
+ static constexpr const float DIODE_MAXVOLT = 30.0;
+
+ static constexpr const float TIMESTEP_MAXDIFF = 1e30;
+ static constexpr const float TIMESTEP_MINDIV = 1e-8;
+ };
+} // namespace netlist
#endif /* NLCONFIG_H_ */
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index e4ea2d57163..44254706636 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -16,207 +16,215 @@
namespace plib {
-void pfunction::compile(const std::vector<pstring> &inputs, const pstring &expr)
-{
- if (plib::startsWith(expr, "rpn:"))
- compile_postfix(inputs, expr.substr(4));
- else
- compile_infix(inputs, expr);
-}
-
-void pfunction::compile_postfix(const std::vector<pstring> &inputs, const pstring &expr)
-{
- std::vector<pstring> cmds(plib::psplit(expr, " "));
- compile_postfix(inputs, cmds, expr);
-}
-
-void pfunction::compile_postfix(const std::vector<pstring> &inputs,
- const std::vector<pstring> &cmds, const pstring &expr)
-{
- m_precompiled.clear();
- int stk = 0;
-
- for (const pstring &cmd : cmds)
+ template <typename NT>
+ void pfunction<NT>::compile(const std::vector<pstring> &inputs, const pstring &expr)
{
- rpn_inst rc;
- if (cmd == "+")
- { rc.m_cmd = ADD; stk -= 1; }
- else if (cmd == "-")
- { rc.m_cmd = SUB; stk -= 1; }
- else if (cmd == "*")
- { rc.m_cmd = MULT; stk -= 1; }
- else if (cmd == "/")
- { rc.m_cmd = DIV; stk -= 1; }
- else if (cmd == "pow")
- { rc.m_cmd = POW; stk -= 1; }
- else if (cmd == "sin")
- { rc.m_cmd = SIN; stk -= 0; }
- else if (cmd == "cos")
- { rc.m_cmd = COS; stk -= 0; }
- else if (cmd == "trunc")
- { rc.m_cmd = TRUNC; stk -= 0; }
- else if (cmd == "rand")
- { rc.m_cmd = RAND; stk += 1; }
+ if (plib::startsWith(expr, "rpn:"))
+ compile_postfix(inputs, expr.substr(4));
else
+ compile_infix(inputs, expr);
+ }
+
+ template <typename NT>
+ void pfunction<NT>::compile_postfix(const std::vector<pstring> &inputs, const pstring &expr)
+ {
+ std::vector<pstring> cmds(plib::psplit(expr, " "));
+ compile_postfix(inputs, cmds, expr);
+ }
+
+ template <typename NT>
+ void pfunction<NT>::compile_postfix(const std::vector<pstring> &inputs,
+ const std::vector<pstring> &cmds, const pstring &expr)
+ {
+ m_precompiled.clear();
+ int stk = 0;
+
+ for (const pstring &cmd : cmds)
{
- for (std::size_t i = 0; i < inputs.size(); i++)
+ rpn_inst rc;
+ if (cmd == "+")
+ { rc.m_cmd = ADD; stk -= 1; }
+ else if (cmd == "-")
+ { rc.m_cmd = SUB; stk -= 1; }
+ else if (cmd == "*")
+ { rc.m_cmd = MULT; stk -= 1; }
+ else if (cmd == "/")
+ { rc.m_cmd = DIV; stk -= 1; }
+ else if (cmd == "pow")
+ { rc.m_cmd = POW; stk -= 1; }
+ else if (cmd == "sin")
+ { rc.m_cmd = SIN; stk -= 0; }
+ else if (cmd == "cos")
+ { rc.m_cmd = COS; stk -= 0; }
+ else if (cmd == "trunc")
+ { rc.m_cmd = TRUNC; stk -= 0; }
+ else if (cmd == "rand")
+ { rc.m_cmd = RAND; stk += 1; }
+ else
{
- if (inputs[i] == cmd)
+ for (std::size_t i = 0; i < inputs.size(); i++)
+ {
+ if (inputs[i] == cmd)
+ {
+ rc.m_cmd = PUSH_INPUT;
+ rc.m_param = static_cast<double>(i);
+ stk += 1;
+ break;
+ }
+ }
+ if (rc.m_cmd != PUSH_INPUT)
{
- rc.m_cmd = PUSH_INPUT;
- rc.m_param = static_cast<double>(i);
+ rc.m_cmd = PUSH_CONST;
+ bool err(false);
+ rc.m_param = plib::pstonum_ne<decltype(rc.m_param)>(cmd, err);
+ if (err)
+ throw plib::pexception(plib::pfmt("pfunction: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr));
stk += 1;
- break;
}
}
- if (rc.m_cmd != PUSH_INPUT)
- {
- rc.m_cmd = PUSH_CONST;
- bool err(false);
- rc.m_param = plib::pstonum_ne<decltype(rc.m_param)>(cmd, err);
- if (err)
- throw plib::pexception(plib::pfmt("pfunction: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr));
- stk += 1;
- }
+ if (stk < 1)
+ throw plib::pexception(plib::pfmt("pfunction: stack underflow on token <{1}> in <{2}>")(cmd)(expr));
+ m_precompiled.push_back(rc);
}
- if (stk < 1)
- throw plib::pexception(plib::pfmt("pfunction: stack underflow on token <{1}> in <{2}>")(cmd)(expr));
- m_precompiled.push_back(rc);
+ if (stk != 1)
+ throw plib::pexception(plib::pfmt("pfunction: stack count different to one on <{2}>")(expr));
}
- if (stk != 1)
- throw plib::pexception(plib::pfmt("pfunction: stack count different to one on <{2}>")(expr));
-}
-
-static int get_prio(const pstring &v)
-{
- if (v == "(" || v == ")")
- return 1;
- else if (plib::left(v, 1) >= "a" && plib::left(v, 1) <= "z")
- return 0;
- else if (v == "*" || v == "/")
- return 20;
- else if (v == "+" || v == "-")
- return 10;
- else if (v == "^")
- return 30;
- else
- return -1;
-}
-
-static pstring pop_check(std::stack<pstring> &stk, const pstring &expr)
-{
- if (stk.size() == 0)
- throw plib::pexception(plib::pfmt("pfunction: stack underflow during infix parsing of: <{1}>")(expr));
- pstring res = stk.top();
- stk.pop();
- return res;
-}
-
-void pfunction::compile_infix(const std::vector<pstring> &inputs, const pstring &expr)
-{
- // Shunting-yard infix parsing
- std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
- std::vector<pstring> sexpr(plib::psplit(plib::replace_all(expr, " ", ""), sep));
- std::stack<pstring> opstk;
- std::vector<pstring> postfix;
-
- for (std::size_t i = 0; i < sexpr.size(); i++)
+
+ static int get_prio(const pstring &v)
{
- pstring &s = sexpr[i];
- if (s=="(")
- opstk.push(s);
- else if (s==")")
- {
- pstring x = pop_check(opstk, expr);
- while (x != "(")
- {
- postfix.push_back(x);
- x = pop_check(opstk, expr);
- }
- if (opstk.size() > 0 && get_prio(opstk.top()) == 0)
- postfix.push_back(pop_check(opstk, expr));
- }
- else if (s==",")
+ if (v == "(" || v == ")")
+ return 1;
+ else if (plib::left(v, 1) >= "a" && plib::left(v, 1) <= "z")
+ return 0;
+ else if (v == "*" || v == "/")
+ return 20;
+ else if (v == "+" || v == "-")
+ return 10;
+ else if (v == "^")
+ return 30;
+ else
+ return -1;
+ }
+
+ static pstring pop_check(std::stack<pstring> &stk, const pstring &expr)
+ {
+ if (stk.size() == 0)
+ throw plib::pexception(plib::pfmt("pfunction: stack underflow during infix parsing of: <{1}>")(expr));
+ pstring res = stk.top();
+ stk.pop();
+ return res;
+ }
+
+ template <typename NT>
+ void pfunction<NT>::compile_infix(const std::vector<pstring> &inputs, const pstring &expr)
+ {
+ // Shunting-yard infix parsing
+ std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
+ std::vector<pstring> sexpr(plib::psplit(plib::replace_all(expr, " ", ""), sep));
+ std::stack<pstring> opstk;
+ std::vector<pstring> postfix;
+
+ for (std::size_t i = 0; i < sexpr.size(); i++)
{
- pstring x = pop_check(opstk, expr);
- while (x != "(")
+ pstring &s = sexpr[i];
+ if (s=="(")
+ opstk.push(s);
+ else if (s==")")
{
- postfix.push_back(x);
- x = pop_check(opstk, expr);
+ pstring x = pop_check(opstk, expr);
+ while (x != "(")
+ {
+ postfix.push_back(x);
+ x = pop_check(opstk, expr);
+ }
+ if (opstk.size() > 0 && get_prio(opstk.top()) == 0)
+ postfix.push_back(pop_check(opstk, expr));
}
- opstk.push(x);
- }
- else {
- int p = get_prio(s);
- if (p>0)
+ else if (s==",")
{
- if (opstk.size() == 0)
- opstk.push(s);
- else
+ pstring x = pop_check(opstk, expr);
+ while (x != "(")
{
- if (get_prio(opstk.top()) >= get_prio(s))
- postfix.push_back(pop_check(opstk, expr));
- opstk.push(s);
+ postfix.push_back(x);
+ x = pop_check(opstk, expr);
}
+ opstk.push(x);
}
- else if (p == 0) // Function or variable
- {
- if (sexpr[i+1] == "(")
- opstk.push(s);
+ else {
+ int p = get_prio(s);
+ if (p>0)
+ {
+ if (opstk.size() == 0)
+ opstk.push(s);
+ else
+ {
+ if (get_prio(opstk.top()) >= get_prio(s))
+ postfix.push_back(pop_check(opstk, expr));
+ opstk.push(s);
+ }
+ }
+ else if (p == 0) // Function or variable
+ {
+ if (sexpr[i+1] == "(")
+ opstk.push(s);
+ else
+ postfix.push_back(s);
+ }
else
postfix.push_back(s);
}
- else
- postfix.push_back(s);
}
+ while (opstk.size() > 0)
+ {
+ postfix.push_back(opstk.top());
+ opstk.pop();
+ }
+ compile_postfix(inputs, postfix, expr);
}
- while (opstk.size() > 0)
- {
- postfix.push_back(opstk.top());
- opstk.pop();
- }
- compile_postfix(inputs, postfix, expr);
-}
-#define ST1 stack[ptr]
-#define ST2 stack[ptr-1]
+ #define ST1 stack[ptr]
+ #define ST2 stack[ptr-1]
-#define OP(OP, ADJ, EXPR) \
-case OP: \
- ptr-= (ADJ); \
- stack[ptr-1] = (EXPR); \
- break;
+ #define OP(OP, ADJ, EXPR) \
+ case OP: \
+ ptr-= (ADJ); \
+ stack[ptr-1] = (EXPR); \
+ break;
-double pfunction::evaluate(const std::vector<double> &values) noexcept
-{
- std::array<double, 20> stack = { 0 };
- unsigned ptr = 0;
- stack[0] = 0.0;
- for (auto &rc : m_precompiled)
+ template <typename NT>
+ NT pfunction<NT>::evaluate(const std::vector<NT> &values) noexcept
{
- switch (rc.m_cmd)
+ std::array<NT, 20> stack = { 0 };
+ unsigned ptr = 0;
+ stack[0] = 0.0;
+ for (auto &rc : m_precompiled)
{
- OP(ADD, 1, ST2 + ST1)
- OP(MULT, 1, ST2 * ST1)
- OP(SUB, 1, ST2 - ST1)
- OP(DIV, 1, ST2 / ST1)
- OP(POW, 1, std::pow(ST2, ST1))
- OP(SIN, 0, std::sin(ST2))
- OP(COS, 0, std::cos(ST2))
- OP(TRUNC, 0, std::trunc(ST2))
- case RAND:
- stack[ptr++] = lfsr_random();
- break;
- case PUSH_INPUT:
- stack[ptr++] = values[static_cast<unsigned>(rc.m_param)];
- break;
- case PUSH_CONST:
- stack[ptr++] = rc.m_param;
- break;
+ switch (rc.m_cmd)
+ {
+ OP(ADD, 1, ST2 + ST1)
+ OP(MULT, 1, ST2 * ST1)
+ OP(SUB, 1, ST2 - ST1)
+ OP(DIV, 1, ST2 / ST1)
+ OP(POW, 1, std::pow(ST2, ST1))
+ OP(SIN, 0, std::sin(ST2))
+ OP(COS, 0, std::cos(ST2))
+ OP(TRUNC, 0, std::trunc(ST2))
+ case RAND:
+ stack[ptr++] = lfsr_random();
+ break;
+ case PUSH_INPUT:
+ stack[ptr++] = values[static_cast<unsigned>(rc.m_param)];
+ break;
+ case PUSH_CONST:
+ stack[ptr++] = rc.m_param;
+ break;
+ }
}
+ return stack[ptr-1];
}
- return stack[ptr-1];
-}
+
+ template struct pfunction<float>;
+ template struct pfunction<double>;
} // namespace plib
diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h
index 8c6d71f33e4..31ff9475fae 100644
--- a/src/lib/netlist/plib/pfunction.h
+++ b/src/lib/netlist/plib/pfunction.h
@@ -21,7 +21,9 @@ namespace plib {
/*! Class providing support for evaluating expressions
*
+ * @tparam NT Number type, should be float or double
*/
+ template <typename NT>
class pfunction
{
enum rpn_cmd
@@ -42,7 +44,7 @@ namespace plib {
{
rpn_inst() : m_cmd(ADD), m_param(0.0) { }
rpn_cmd m_cmd;
- double m_param;
+ NT m_param;
};
public:
/*! Constructor with state saving support
@@ -91,20 +93,20 @@ namespace plib {
* @param values for input variables, e.g. {1.1, 2.2}
* @return value of expression
*/
- double evaluate(const std::vector<double> &values) noexcept;
+ NT evaluate(const std::vector<NT> &values) noexcept;
private:
void compile_postfix(const std::vector<pstring> &inputs,
const std::vector<pstring> &cmds, const pstring &expr);
- double lfsr_random() noexcept
+ NT lfsr_random() noexcept
{
std::uint16_t lsb = m_lfsr & 1;
m_lfsr >>= 1;
if (lsb)
m_lfsr ^= 0xB400u; // taps 15, 13, 12, 10
- return static_cast<double>(m_lfsr) / static_cast<double>(0xffffu);
+ return static_cast<NT>(m_lfsr) / static_cast<NT>(0xffffu);
}
std::vector<rpn_inst> m_precompiled; //!< precompiled expression
@@ -112,6 +114,8 @@ namespace plib {
std::uint16_t m_lfsr; //!< lfsr used for generating random numbers
};
+ extern template struct pfunction<float>;
+ extern template struct pfunction<double>;
} // namespace plib
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 5f25ac20219..20a37d24ff1 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -311,11 +311,14 @@ struct input_t
: m_value(0.0)
{
std::array<char, 400> buf; // NOLINT(cppcoreguidelines-pro-type-member-init)
- nl_fptype t(0);
+ double t(0);
+ double val(0);
+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
- int e = std::sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf.data(), &m_value);
+ int e = std::sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf.data(), &val);
if (e != 3)
throw netlist::nl_exception(plib::pfmt("error {1} scanning line {2}\n")(e)(line));
+ m_value = static_cast<nl_fptype>(val);
m_time = netlist::netlist_time::from_double(t);
m_param = setup.find_param(pstring(buf.data()), true);
}
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index 97a496822d9..1dc26a6ea21 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -565,7 +565,7 @@ namespace solver
//const nl_fptype DD_n = (n->Q_Analog() - t->m_last_V);
// avoid floating point exceptions
- const nl_fptype DD_n = std::max(-1e100, std::min(1e100,(t.getV() - m_last_V[k])));
+ const nl_fptype DD_n = std::max(-fp_constants<nl_fptype>::TIMESTEP_MAXDIFF, std::min(fp_constants<nl_fptype>::TIMESTEP_MAXDIFF,(t.getV() - m_last_V[k])));
const nl_fptype hn = cur_ts;
//printf("%g %g %g %g\n", DD_n, hn, t.m_DD_n_m_1, t.m_h_n_m_1);
@@ -574,7 +574,7 @@ namespace solver
m_h_n_m_1[k] = hn;
m_DD_n_m_1[k] = DD_n;
- if (std::fabs(DD2) > plib::constants<nl_fptype>::cast(1e-60)) // avoid div-by-zero
+ if (std::fabs(DD2) > fp_constants<nl_fptype>::TIMESTEP_MINDIV) // avoid div-by-zero
new_net_timestep = std::sqrt(m_params.m_dynamic_lte / std::fabs(plib::constants<nl_fptype>::cast(0.5)*DD2));
else
new_net_timestep = m_params.m_max_timestep;
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index 4252e7ed751..fdfaff7a399 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -383,7 +383,7 @@ namespace solver
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gonn;
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gtn;
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_Idrn;
- plib::pmatrix2d<nl_fptype *, aligned_alloc<nl_fptype *>> m_mat_ptr;
+ plib::pmatrix2d<nl_mat_fptype *, aligned_alloc<nl_mat_fptype *>> m_mat_ptr;
plib::pmatrix2d<nl_fptype *, aligned_alloc<nl_fptype *>> m_connected_net_Vn;
plib::aligned_vector<terms_for_net_t> m_terms;
@@ -439,9 +439,10 @@ namespace solver
*/
const std::size_t iN = this->m_terms.size();
- typename std::decay<decltype(V[0])>::type cerr = 0;
+ using vtype = typename std::decay<decltype(V[0])>::type;
+ vtype cerr = 0;
for (std::size_t i = 0; i < iN; i++)
- cerr = std::max(cerr, std::abs(V[i] - this->m_terms[i].getV()));
+ cerr = std::max(cerr, std::abs(V[i] - static_cast<vtype>(this->m_terms[i].getV())));
return cerr;
}
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index bfc92ba97f9..6c942f3b1d6 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -131,7 +131,7 @@ namespace solver
mat_type mat;
- plib::dynproc<void, nl_fptype * , nl_fptype * , nl_fptype * > m_proc;
+ plib::dynproc<void, FT * , FT * , FT * > m_proc;
};
diff --git a/src/lib/netlist/solver/nld_ms_sor.h b/src/lib/netlist/solver/nld_ms_sor.h
index cfc0e1e8fd5..8bf4bf48721 100644
--- a/src/lib/netlist/solver/nld_ms_sor.h
+++ b/src/lib/netlist/solver/nld_ms_sor.h
@@ -79,9 +79,9 @@ namespace solver
float_type RHS_t = 0.0;
const std::size_t term_count = this->m_terms[k].count();
- const float_type * const gt = this->m_gtn[k];
- const float_type * const go = this->m_gonn[k];
- const float_type * const Idr = this->m_Idrn[k];
+ const nl_fptype * const gt = this->m_gtn[k];
+ const nl_fptype * const go = this->m_gonn[k];
+ const nl_fptype * const Idr = this->m_Idrn[k];
auto other_cur_analog = this->m_connected_net_Vn[k];
this->m_new_V[k] = this->m_terms[k].getV();
@@ -130,7 +130,7 @@ namespace solver
{
const int * net_other = this->m_terms[k].m_connected_net_idx.data();
const std::size_t railstart = this->m_terms[k].railstart();
- const float_type * go = this->m_gonn[k];
+ const nl_fptype * go = this->m_gonn[k];
float_type Idrive = 0.0;
for (std::size_t i = 0; i < railstart; i++)
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index db2c831a79e..506bff88dab 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -231,62 +231,62 @@ namespace devices
switch (net_count)
{
case 1:
- ms = plib::make_unique<solver::matrix_solver_direct1_t<nl_fptype>>(state(), sname, grp, &m_params);
+ ms = plib::make_unique<solver::matrix_solver_direct1_t<nl_mat_fptype>>(state(), sname, grp, &m_params);
break;
case 2:
- ms = plib::make_unique<solver::matrix_solver_direct2_t<nl_fptype>>(state(), sname, grp, &m_params);
+ ms = plib::make_unique<solver::matrix_solver_direct2_t<nl_mat_fptype>>(state(), sname, grp, &m_params);
break;
#if 0
case 3:
- ms = create_solver<nl_fptype, 3>(3, sname, grp);
+ ms = create_solver<nl_mat_fptype, 3>(3, sname, grp);
break;
case 4:
- ms = create_solver<nl_fptype, 4>(4, sname, grp);
+ ms = create_solver<nl_mat_fptype, 4>(4, sname, grp);
break;
case 5:
- ms = create_solver<nl_fptype, 5>(5, sname, grp);
+ ms = create_solver<nl_mat_fptype, 5>(5, sname, grp);
break;
case 6:
- ms = create_solver<nl_fptype, 6>(6, sname, grp);
+ ms = create_solver<nl_mat_fptype, 6>(6, sname, grp);
break;
case 7:
- ms = create_solver<nl_fptype, 7>(7, sname, grp);
+ ms = create_solver<nl_mat_fptype, 7>(7, sname, grp);
break;
case 8:
- ms = create_solver<nl_fptype, 8>(8, sname, grp);
+ ms = create_solver<nl_mat_fptype, 8>(8, sname, grp);
break;
case 9:
- ms = create_solver<nl_fptype, 9>(9, sname, grp);
+ ms = create_solver<nl_mat_fptype, 9>(9, sname, grp);
break;
case 10:
- ms = create_solver<nl_fptype, 10>(10, sname, grp);
+ ms = create_solver<nl_mat_fptype, 10>(10, sname, grp);
break;
#if 0
case 11:
- ms = create_solver<nl_fptype, 11>(11, sname);
+ ms = create_solver<nl_mat_fptype, 11>(11, sname);
break;
case 12:
- ms = create_solver<nl_fptype, 12>(12, sname);
+ ms = create_solver<nl_mat_fptype, 12>(12, sname);
break;
case 15:
- ms = create_solver<nl_fptype, 15>(15, sname);
+ ms = create_solver<nl_mat_fptype, 15>(15, sname);
break;
case 31:
- ms = create_solver<nl_fptype, 31>(31, sname);
+ ms = create_solver<nl_mat_fptype, 31>(31, sname);
break;
case 35:
- ms = create_solver<nl_fptype, 35>(35, sname);
+ ms = create_solver<nl_mat_fptype, 35>(35, sname);
break;
case 43:
- ms = create_solver<nl_fptype, 43>(43, sname);
+ ms = create_solver<nl_mat_fptype, 43>(43, sname);
break;
case 49:
- ms = create_solver<nl_fptype, 49>(49, sname);
+ ms = create_solver<nl_mat_fptype, 49>(49, sname);
break;
#endif
#if 1
case 87:
- ms = create_solver<nl_fptype,86>(86, sname, grp);
+ ms = create_solver<nl_mat_fptype,86>(86, sname, grp);
break;
#endif
#endif
@@ -294,35 +294,35 @@ namespace devices
log().info(MI_NO_SPECIFIC_SOLVER(net_count));
if (net_count <= 8)
{
- ms = create_solver<nl_fptype, -8>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, -8>(net_count, sname, grp);
}
else if (net_count <= 16)
{
- ms = create_solver<nl_fptype, -16>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, -16>(net_count, sname, grp);
}
else if (net_count <= 32)
{
- ms = create_solver<nl_fptype, -32>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, -32>(net_count, sname, grp);
}
else if (net_count <= 64)
{
- ms = create_solver<nl_fptype, -64>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, -64>(net_count, sname, grp);
}
else if (net_count <= 128)
{
- ms = create_solver<nl_fptype, -128>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, -128>(net_count, sname, grp);
}
else if (net_count <= 256)
{
- ms = create_solver<nl_fptype, -256>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, -256>(net_count, sname, grp);
}
else if (net_count <= 512)
{
- ms = create_solver<nl_fptype, -512>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, -512>(net_count, sname, grp);
}
else
{
- ms = create_solver<nl_fptype, 0>(net_count, sname, grp);
+ ms = create_solver<nl_mat_fptype, 0>(net_count, sname, grp);
}
break;
}