mirror of
https://github.com/holub/mame
synced 2025-07-02 00:29:37 +03:00
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.
This commit is contained in:
parent
6c075e602c
commit
c6b281685d
@ -1266,13 +1266,12 @@ void netlist_mame_cpu_device::device_start()
|
|||||||
{
|
{
|
||||||
if (n->is_logic())
|
if (n->is_logic())
|
||||||
{
|
{
|
||||||
state_add(index, n->name().c_str(), *(downcast<netlist::logic_net_t &>(*n).Q_state_ptr()));
|
state_add(index++, n->name().c_str(), *(downcast<netlist::logic_net_t &>(*n).Q_state_ptr()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state_add(index, n->name().c_str(), *(downcast<netlist::analog_net_t &>(*n).Q_Analog_state_ptr()));
|
//state_add(index++, n->name().c_str(), *(downcast<netlist::analog_net_t &>(*n).Q_Analog_state_ptr()));
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set our instruction counter
|
// set our instruction counter
|
||||||
|
@ -319,7 +319,7 @@ protected:
|
|||||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
netlist::param_num_t<double> *m_param;
|
netlist::param_num_t<nl_fptype> *m_param;
|
||||||
bool m_auto_port;
|
bool m_auto_port;
|
||||||
const char *m_param_name;
|
const char *m_param_name;
|
||||||
double m_value_for_device_timer;
|
double m_value_for_device_timer;
|
||||||
|
@ -158,12 +158,12 @@ namespace analog
|
|||||||
//printf("%s: %g %g\n", m_name.c_str(), nVd, (nl_fptype) m_Vd);
|
//printf("%s: %g %g\n", m_name.c_str(), nVd, (nl_fptype) m_Vd);
|
||||||
if (nVd > m_Vcrit)
|
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;
|
const nl_fptype a = std::abs(d) * m_VtInv;
|
||||||
m_Vd = m_Vd + (d < 0 ? -1.0 : 1.0) * std::log1p(a) * m_Vt;
|
m_Vd = m_Vd + (d < 0 ? -1.0 : 1.0) * std::log1p(a) * m_Vt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_Vd = std::max(-1e100, nVd);
|
m_Vd = std::max(-fp_constants<nl_fptype>::DIODE_MAXDIFF, nVd);
|
||||||
//m_Vd = nVd;
|
//m_Vd = nVd;
|
||||||
|
|
||||||
if (m_Vd < m_Vmin)
|
if (m_Vd < m_Vmin)
|
||||||
@ -189,7 +189,7 @@ namespace analog
|
|||||||
else /* log stepping should already be done in mosfet */
|
else /* log stepping should already be done in mosfet */
|
||||||
{
|
{
|
||||||
m_Vd = nVd;
|
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_Id = IseVDVt - m_Is;
|
||||||
m_G = IseVDVt * m_VtInv + m_gmin;
|
m_G = IseVDVt * m_VtInv + m_gmin;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ namespace analog
|
|||||||
param_fp_t m_R;
|
param_fp_t m_R;
|
||||||
param_fp_t m_V;
|
param_fp_t m_V;
|
||||||
param_str_t m_func;
|
param_str_t m_func;
|
||||||
plib::pfunction m_compiled;
|
plib::pfunction<nl_fptype> m_compiled;
|
||||||
std::vector<nl_fptype> m_funcparam;
|
std::vector<nl_fptype> m_funcparam;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -486,7 +486,7 @@ namespace analog
|
|||||||
state_var<nl_fptype> m_t;
|
state_var<nl_fptype> m_t;
|
||||||
param_fp_t m_I;
|
param_fp_t m_I;
|
||||||
param_str_t m_func;
|
param_str_t m_func;
|
||||||
plib::pfunction m_compiled;
|
plib::pfunction<nl_fptype> m_compiled;
|
||||||
std::vector<nl_fptype> m_funcparam;
|
std::vector<nl_fptype> m_funcparam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ namespace devices
|
|||||||
logic_output_t m_Q;
|
logic_output_t m_Q;
|
||||||
|
|
||||||
param_str_t m_func;
|
param_str_t m_func;
|
||||||
plib::pfunction m_compiled;
|
plib::pfunction<nl_fptype> m_compiled;
|
||||||
std::vector<nl_fptype> m_funcparam;
|
std::vector<nl_fptype> m_funcparam;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -389,7 +389,7 @@ namespace devices
|
|||||||
std::vector<unique_pool_ptr<analog_input_t>> m_I;
|
std::vector<unique_pool_ptr<analog_input_t>> m_I;
|
||||||
|
|
||||||
std::vector<nl_fptype> m_vals;
|
std::vector<nl_fptype> m_vals;
|
||||||
plib::pfunction m_compiled;
|
plib::pfunction<nl_fptype> m_compiled;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -96,7 +96,52 @@
|
|||||||
static constexpr const auto NETLIST_INTERNAL_RES = 1000000000;
|
static constexpr const auto NETLIST_INTERNAL_RES = 1000000000;
|
||||||
static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES;
|
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 = 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_ */
|
#endif /* NLCONFIG_H_ */
|
||||||
|
@ -16,23 +16,26 @@
|
|||||||
|
|
||||||
namespace plib {
|
namespace plib {
|
||||||
|
|
||||||
void pfunction::compile(const std::vector<pstring> &inputs, const pstring &expr)
|
template <typename NT>
|
||||||
{
|
void pfunction<NT>::compile(const std::vector<pstring> &inputs, const pstring &expr)
|
||||||
|
{
|
||||||
if (plib::startsWith(expr, "rpn:"))
|
if (plib::startsWith(expr, "rpn:"))
|
||||||
compile_postfix(inputs, expr.substr(4));
|
compile_postfix(inputs, expr.substr(4));
|
||||||
else
|
else
|
||||||
compile_infix(inputs, expr);
|
compile_infix(inputs, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pfunction::compile_postfix(const std::vector<pstring> &inputs, const pstring &expr)
|
template <typename NT>
|
||||||
{
|
void pfunction<NT>::compile_postfix(const std::vector<pstring> &inputs, const pstring &expr)
|
||||||
|
{
|
||||||
std::vector<pstring> cmds(plib::psplit(expr, " "));
|
std::vector<pstring> cmds(plib::psplit(expr, " "));
|
||||||
compile_postfix(inputs, cmds, expr);
|
compile_postfix(inputs, cmds, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pfunction::compile_postfix(const std::vector<pstring> &inputs,
|
template <typename NT>
|
||||||
|
void pfunction<NT>::compile_postfix(const std::vector<pstring> &inputs,
|
||||||
const std::vector<pstring> &cmds, const pstring &expr)
|
const std::vector<pstring> &cmds, const pstring &expr)
|
||||||
{
|
{
|
||||||
m_precompiled.clear();
|
m_precompiled.clear();
|
||||||
int stk = 0;
|
int stk = 0;
|
||||||
|
|
||||||
@ -85,10 +88,10 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
|
|||||||
}
|
}
|
||||||
if (stk != 1)
|
if (stk != 1)
|
||||||
throw plib::pexception(plib::pfmt("pfunction: stack count different to one on <{2}>")(expr));
|
throw plib::pexception(plib::pfmt("pfunction: stack count different to one on <{2}>")(expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_prio(const pstring &v)
|
static int get_prio(const pstring &v)
|
||||||
{
|
{
|
||||||
if (v == "(" || v == ")")
|
if (v == "(" || v == ")")
|
||||||
return 1;
|
return 1;
|
||||||
else if (plib::left(v, 1) >= "a" && plib::left(v, 1) <= "z")
|
else if (plib::left(v, 1) >= "a" && plib::left(v, 1) <= "z")
|
||||||
@ -101,19 +104,20 @@ static int get_prio(const pstring &v)
|
|||||||
return 30;
|
return 30;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pstring pop_check(std::stack<pstring> &stk, const pstring &expr)
|
static pstring pop_check(std::stack<pstring> &stk, const pstring &expr)
|
||||||
{
|
{
|
||||||
if (stk.size() == 0)
|
if (stk.size() == 0)
|
||||||
throw plib::pexception(plib::pfmt("pfunction: stack underflow during infix parsing of: <{1}>")(expr));
|
throw plib::pexception(plib::pfmt("pfunction: stack underflow during infix parsing of: <{1}>")(expr));
|
||||||
pstring res = stk.top();
|
pstring res = stk.top();
|
||||||
stk.pop();
|
stk.pop();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pfunction::compile_infix(const std::vector<pstring> &inputs, const pstring &expr)
|
template <typename NT>
|
||||||
{
|
void pfunction<NT>::compile_infix(const std::vector<pstring> &inputs, const pstring &expr)
|
||||||
|
{
|
||||||
// Shunting-yard infix parsing
|
// Shunting-yard infix parsing
|
||||||
std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
|
std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
|
||||||
std::vector<pstring> sexpr(plib::psplit(plib::replace_all(expr, " ", ""), sep));
|
std::vector<pstring> sexpr(plib::psplit(plib::replace_all(expr, " ", ""), sep));
|
||||||
@ -176,21 +180,22 @@ void pfunction::compile_infix(const std::vector<pstring> &inputs, const pstring
|
|||||||
opstk.pop();
|
opstk.pop();
|
||||||
}
|
}
|
||||||
compile_postfix(inputs, postfix, expr);
|
compile_postfix(inputs, postfix, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define ST1 stack[ptr]
|
#define ST1 stack[ptr]
|
||||||
#define ST2 stack[ptr-1]
|
#define ST2 stack[ptr-1]
|
||||||
|
|
||||||
#define OP(OP, ADJ, EXPR) \
|
#define OP(OP, ADJ, EXPR) \
|
||||||
case OP: \
|
case OP: \
|
||||||
ptr-= (ADJ); \
|
ptr-= (ADJ); \
|
||||||
stack[ptr-1] = (EXPR); \
|
stack[ptr-1] = (EXPR); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
double pfunction::evaluate(const std::vector<double> &values) noexcept
|
template <typename NT>
|
||||||
{
|
NT pfunction<NT>::evaluate(const std::vector<NT> &values) noexcept
|
||||||
std::array<double, 20> stack = { 0 };
|
{
|
||||||
|
std::array<NT, 20> stack = { 0 };
|
||||||
unsigned ptr = 0;
|
unsigned ptr = 0;
|
||||||
stack[0] = 0.0;
|
stack[0] = 0.0;
|
||||||
for (auto &rc : m_precompiled)
|
for (auto &rc : m_precompiled)
|
||||||
@ -217,6 +222,9 @@ double pfunction::evaluate(const std::vector<double> &values) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack[ptr-1];
|
return stack[ptr-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template struct pfunction<float>;
|
||||||
|
template struct pfunction<double>;
|
||||||
|
|
||||||
} // namespace plib
|
} // namespace plib
|
||||||
|
@ -21,7 +21,9 @@ namespace plib {
|
|||||||
|
|
||||||
/*! Class providing support for evaluating expressions
|
/*! Class providing support for evaluating expressions
|
||||||
*
|
*
|
||||||
|
* @tparam NT Number type, should be float or double
|
||||||
*/
|
*/
|
||||||
|
template <typename NT>
|
||||||
class pfunction
|
class pfunction
|
||||||
{
|
{
|
||||||
enum rpn_cmd
|
enum rpn_cmd
|
||||||
@ -42,7 +44,7 @@ namespace plib {
|
|||||||
{
|
{
|
||||||
rpn_inst() : m_cmd(ADD), m_param(0.0) { }
|
rpn_inst() : m_cmd(ADD), m_param(0.0) { }
|
||||||
rpn_cmd m_cmd;
|
rpn_cmd m_cmd;
|
||||||
double m_param;
|
NT m_param;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
/*! Constructor with state saving support
|
/*! Constructor with state saving support
|
||||||
@ -91,20 +93,20 @@ namespace plib {
|
|||||||
* @param values for input variables, e.g. {1.1, 2.2}
|
* @param values for input variables, e.g. {1.1, 2.2}
|
||||||
* @return value of expression
|
* @return value of expression
|
||||||
*/
|
*/
|
||||||
double evaluate(const std::vector<double> &values) noexcept;
|
NT evaluate(const std::vector<NT> &values) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void compile_postfix(const std::vector<pstring> &inputs,
|
void compile_postfix(const std::vector<pstring> &inputs,
|
||||||
const std::vector<pstring> &cmds, const pstring &expr);
|
const std::vector<pstring> &cmds, const pstring &expr);
|
||||||
|
|
||||||
double lfsr_random() noexcept
|
NT lfsr_random() noexcept
|
||||||
{
|
{
|
||||||
std::uint16_t lsb = m_lfsr & 1;
|
std::uint16_t lsb = m_lfsr & 1;
|
||||||
m_lfsr >>= 1;
|
m_lfsr >>= 1;
|
||||||
if (lsb)
|
if (lsb)
|
||||||
m_lfsr ^= 0xB400u; // taps 15, 13, 12, 10
|
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
|
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
|
std::uint16_t m_lfsr; //!< lfsr used for generating random numbers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern template struct pfunction<float>;
|
||||||
|
extern template struct pfunction<double>;
|
||||||
|
|
||||||
} // namespace plib
|
} // namespace plib
|
||||||
|
|
||||||
|
@ -311,11 +311,14 @@ struct input_t
|
|||||||
: m_value(0.0)
|
: m_value(0.0)
|
||||||
{
|
{
|
||||||
std::array<char, 400> buf; // NOLINT(cppcoreguidelines-pro-type-member-init)
|
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)
|
// 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)
|
if (e != 3)
|
||||||
throw netlist::nl_exception(plib::pfmt("error {1} scanning line {2}\n")(e)(line));
|
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_time = netlist::netlist_time::from_double(t);
|
||||||
m_param = setup.find_param(pstring(buf.data()), true);
|
m_param = setup.find_param(pstring(buf.data()), true);
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,7 @@ namespace solver
|
|||||||
//const nl_fptype DD_n = (n->Q_Analog() - t->m_last_V);
|
//const nl_fptype DD_n = (n->Q_Analog() - t->m_last_V);
|
||||||
// avoid floating point exceptions
|
// 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;
|
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);
|
//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_h_n_m_1[k] = hn;
|
||||||
m_DD_n_m_1[k] = DD_n;
|
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));
|
new_net_timestep = std::sqrt(m_params.m_dynamic_lte / std::fabs(plib::constants<nl_fptype>::cast(0.5)*DD2));
|
||||||
else
|
else
|
||||||
new_net_timestep = m_params.m_max_timestep;
|
new_net_timestep = m_params.m_max_timestep;
|
||||||
|
@ -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_gonn;
|
||||||
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gtn;
|
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_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::pmatrix2d<nl_fptype *, aligned_alloc<nl_fptype *>> m_connected_net_Vn;
|
||||||
|
|
||||||
plib::aligned_vector<terms_for_net_t> m_terms;
|
plib::aligned_vector<terms_for_net_t> m_terms;
|
||||||
@ -439,9 +439,10 @@ namespace solver
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const std::size_t iN = this->m_terms.size();
|
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++)
|
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;
|
return cerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ namespace solver
|
|||||||
|
|
||||||
mat_type mat;
|
mat_type mat;
|
||||||
|
|
||||||
plib::dynproc<void, nl_fptype * , nl_fptype * , nl_fptype * > m_proc;
|
plib::dynproc<void, FT * , FT * , FT * > m_proc;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,9 +79,9 @@ namespace solver
|
|||||||
float_type RHS_t = 0.0;
|
float_type RHS_t = 0.0;
|
||||||
|
|
||||||
const std::size_t term_count = this->m_terms[k].count();
|
const std::size_t term_count = this->m_terms[k].count();
|
||||||
const float_type * const gt = this->m_gtn[k];
|
const nl_fptype * const gt = this->m_gtn[k];
|
||||||
const float_type * const go = this->m_gonn[k];
|
const nl_fptype * const go = this->m_gonn[k];
|
||||||
const float_type * const Idr = this->m_Idrn[k];
|
const nl_fptype * const Idr = this->m_Idrn[k];
|
||||||
auto other_cur_analog = this->m_connected_net_Vn[k];
|
auto other_cur_analog = this->m_connected_net_Vn[k];
|
||||||
|
|
||||||
this->m_new_V[k] = this->m_terms[k].getV();
|
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 int * net_other = this->m_terms[k].m_connected_net_idx.data();
|
||||||
const std::size_t railstart = this->m_terms[k].railstart();
|
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;
|
float_type Idrive = 0.0;
|
||||||
for (std::size_t i = 0; i < railstart; i++)
|
for (std::size_t i = 0; i < railstart; i++)
|
||||||
|
@ -231,62 +231,62 @@ namespace devices
|
|||||||
switch (net_count)
|
switch (net_count)
|
||||||
{
|
{
|
||||||
case 1:
|
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;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
#if 0
|
#if 0
|
||||||
case 3:
|
case 3:
|
||||||
ms = create_solver<nl_fptype, 3>(3, sname, grp);
|
ms = create_solver<nl_mat_fptype, 3>(3, sname, grp);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
ms = create_solver<nl_fptype, 4>(4, sname, grp);
|
ms = create_solver<nl_mat_fptype, 4>(4, sname, grp);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
ms = create_solver<nl_fptype, 5>(5, sname, grp);
|
ms = create_solver<nl_mat_fptype, 5>(5, sname, grp);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
ms = create_solver<nl_fptype, 6>(6, sname, grp);
|
ms = create_solver<nl_mat_fptype, 6>(6, sname, grp);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
ms = create_solver<nl_fptype, 7>(7, sname, grp);
|
ms = create_solver<nl_mat_fptype, 7>(7, sname, grp);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
ms = create_solver<nl_fptype, 8>(8, sname, grp);
|
ms = create_solver<nl_mat_fptype, 8>(8, sname, grp);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
ms = create_solver<nl_fptype, 9>(9, sname, grp);
|
ms = create_solver<nl_mat_fptype, 9>(9, sname, grp);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
ms = create_solver<nl_fptype, 10>(10, sname, grp);
|
ms = create_solver<nl_mat_fptype, 10>(10, sname, grp);
|
||||||
break;
|
break;
|
||||||
#if 0
|
#if 0
|
||||||
case 11:
|
case 11:
|
||||||
ms = create_solver<nl_fptype, 11>(11, sname);
|
ms = create_solver<nl_mat_fptype, 11>(11, sname);
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
ms = create_solver<nl_fptype, 12>(12, sname);
|
ms = create_solver<nl_mat_fptype, 12>(12, sname);
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
ms = create_solver<nl_fptype, 15>(15, sname);
|
ms = create_solver<nl_mat_fptype, 15>(15, sname);
|
||||||
break;
|
break;
|
||||||
case 31:
|
case 31:
|
||||||
ms = create_solver<nl_fptype, 31>(31, sname);
|
ms = create_solver<nl_mat_fptype, 31>(31, sname);
|
||||||
break;
|
break;
|
||||||
case 35:
|
case 35:
|
||||||
ms = create_solver<nl_fptype, 35>(35, sname);
|
ms = create_solver<nl_mat_fptype, 35>(35, sname);
|
||||||
break;
|
break;
|
||||||
case 43:
|
case 43:
|
||||||
ms = create_solver<nl_fptype, 43>(43, sname);
|
ms = create_solver<nl_mat_fptype, 43>(43, sname);
|
||||||
break;
|
break;
|
||||||
case 49:
|
case 49:
|
||||||
ms = create_solver<nl_fptype, 49>(49, sname);
|
ms = create_solver<nl_mat_fptype, 49>(49, sname);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
case 87:
|
case 87:
|
||||||
ms = create_solver<nl_fptype,86>(86, sname, grp);
|
ms = create_solver<nl_mat_fptype,86>(86, sname, grp);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -294,35 +294,35 @@ namespace devices
|
|||||||
log().info(MI_NO_SPECIFIC_SOLVER(net_count));
|
log().info(MI_NO_SPECIFIC_SOLVER(net_count));
|
||||||
if (net_count <= 8)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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
|
else
|
||||||
{
|
{
|
||||||
ms = create_solver<nl_fptype, 0>(net_count, sname, grp);
|
ms = create_solver<nl_mat_fptype, 0>(net_count, sname, grp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user