mirror of
https://github.com/holub/mame
synced 2025-06-01 02:21:48 +03:00
Introduced a nl_math static class to have all math related
functions in one place. This is a portability exercise, e.g. log1p is not supported on all platforms. (nw)
This commit is contained in:
parent
e923df8137
commit
423def0ccc
@ -25,9 +25,9 @@ public:
|
||||
m_VT = 0.0258 * n;
|
||||
m_VT_inv = 1.0 / m_VT;
|
||||
}
|
||||
nl_double I(const nl_double V) const { return m_Is * exp(V * m_VT_inv) - m_Is; }
|
||||
nl_double g(const nl_double V) const { return m_Is * m_VT_inv * exp(V * m_VT_inv); }
|
||||
nl_double V(const nl_double I) const { return log(1.0 + I / m_Is) * m_VT; }
|
||||
nl_double I(const nl_double V) const { return m_Is * nl_math::exp(V * m_VT_inv) - m_Is; }
|
||||
nl_double g(const nl_double V) const { return m_Is * m_VT_inv * nl_math::exp(V * m_VT_inv); }
|
||||
nl_double V(const nl_double I) const { return nl_math::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x)
|
||||
nl_double gI(const nl_double I) const { return m_VT_inv * (I + m_Is); }
|
||||
|
||||
private:
|
||||
|
@ -106,8 +106,8 @@ ATTR_HOT nl_double netlist_matrix_solver_direct_t<m_N, _storage_N>::compute_next
|
||||
|
||||
n->m_h_n_m_1 = hn;
|
||||
n->m_DD_n_m_1 = DD_n;
|
||||
if (fabs(DD2) > 1e-50) // avoid div-by-zero
|
||||
new_net_timestep = sqrt(m_params.m_lte / fabs(0.5*DD2));
|
||||
if (nl_math::abs(DD2) > 1e-50) // avoid div-by-zero
|
||||
new_net_timestep = nl_math::sqrt(m_params.m_lte / nl_math::abs(0.5*DD2));
|
||||
else
|
||||
new_net_timestep = m_params.m_max_timestep;
|
||||
|
||||
@ -290,7 +290,7 @@ ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
|
||||
int maxrow = i;
|
||||
for (int j = i + 1; j < kN; j++)
|
||||
{
|
||||
if (fabs(m_A[j][i]) > fabs(m_A[maxrow][i]))
|
||||
if (nl_math::abs(m_A[j][i]) > nl_math::abs(m_A[maxrow][i]))
|
||||
maxrow = j;
|
||||
}
|
||||
|
||||
@ -359,8 +359,8 @@ ATTR_HOT nl_double netlist_matrix_solver_direct_t<m_N, _storage_N>::delta(
|
||||
nl_double cerr2 = 0;
|
||||
for (int i = 0; i < this->N(); i++)
|
||||
{
|
||||
const nl_double e = fabs(V[i] - this->m_nets[i]->m_cur_Analog);
|
||||
const nl_double e2 = fabs(m_RHS[i] - this->m_last_RHS[i]);
|
||||
const nl_double e = nl_math::abs(V[i] - this->m_nets[i]->m_cur_Analog);
|
||||
const nl_double e2 = nl_math::abs(m_RHS[i] - this->m_last_RHS[i]);
|
||||
cerr = (e > cerr ? e : cerr);
|
||||
cerr2 = (e2 > cerr2 ? e2 : cerr2);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ ATTR_HOT inline int netlist_matrix_solver_direct1_t::vsolve_non_dynamic()
|
||||
nl_double new_val = m_RHS[0] / m_A[0][0];
|
||||
|
||||
nl_double e = (new_val - net->m_cur_Analog);
|
||||
nl_double cerr = fabs(e);
|
||||
nl_double cerr = nl_math::abs(e);
|
||||
|
||||
net->m_cur_Analog = new_val;
|
||||
|
||||
|
@ -104,7 +104,7 @@ ATTR_HOT nl_double netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve()
|
||||
this->m_Vdelta[k] = nv;
|
||||
}
|
||||
if (sqo > 1e-90)
|
||||
m_lp_fact = std::min(sqrt(sq/sqo), 2.0);
|
||||
m_lp_fact = std::min(nl_math::sqrt(sq/sqo), 2.0);
|
||||
else
|
||||
m_lp_fact = 0.0;
|
||||
}
|
||||
@ -143,7 +143,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
for (int i = 0; i < iN; i++)
|
||||
{
|
||||
frob += this->m_A[k][i] * this->m_A[k][i];
|
||||
s = s + fabs(this->m_A[k][i]);
|
||||
s = s + nl_math::abs(this->m_A[k][i]);
|
||||
}
|
||||
|
||||
if (s<rmin)
|
||||
@ -152,9 +152,9 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
rmax = s;
|
||||
}
|
||||
#if 0
|
||||
nl_double frobA = sqrt(frob /(iN));
|
||||
nl_double frobA = nl_math::sqrt(frob /(iN));
|
||||
if (1 &&frobA < 1.0)
|
||||
//ws = 2.0 / (1.0 + sqrt(1.0-frobA));
|
||||
//ws = 2.0 / (1.0 + nl_math::sqrt(1.0-frobA));
|
||||
ws = 2.0 / (2.0 - frobA);
|
||||
else
|
||||
ws = 1.0;
|
||||
@ -169,7 +169,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
// suitable parameter.
|
||||
nl_double rm = (rmax + rmin) * 0.5;
|
||||
if (rm < 1.0)
|
||||
ws = 2.0 / (1.0 + sqrt(1.0-rm));
|
||||
ws = 2.0 / (1.0 + nl_math::sqrt(1.0-rm));
|
||||
else
|
||||
ws = 1.0;
|
||||
if (ws > 1.02 && rmax > 1.001)
|
||||
@ -200,13 +200,13 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
{
|
||||
//if (i < k) frobL += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] /this-> m_A[k][k];
|
||||
//if (i > k) frobU += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] / this->m_A[k][k];
|
||||
//norm_t += fabs(this->m_A[k][i]);
|
||||
//norm_t += nl_math::abs(this->m_A[k][i]);
|
||||
}
|
||||
|
||||
//if (norm_t > norm) norm = norm_t;
|
||||
const nl_double new_val = (1.0-ws) * new_v[k] + ws * (this->m_RHS[k] - Idrive + this->m_A[k][k] * new_v[k]) / this->m_A[k][k];
|
||||
|
||||
const nl_double e = fabs(new_val - new_v[k]);
|
||||
const nl_double e = nl_math::abs(new_val - new_v[k]);
|
||||
cerr = (e > cerr ? e : cerr);
|
||||
new_v[k] = new_val;
|
||||
}
|
||||
@ -216,10 +216,10 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
resched = true;
|
||||
}
|
||||
resched_cnt++;
|
||||
//ATTR_UNUSED nl_double frobUL = sqrt((frobU + frobL) / (double) (iN) / (double) (iN));
|
||||
//ATTR_UNUSED nl_double frobUL = nl_math::sqrt((frobU + frobL) / (double) (iN) / (double) (iN));
|
||||
} while (resched && (resched_cnt < this->m_params.m_gs_loops));
|
||||
//printf("Frobenius %f %f %f %f %f\n", sqrt(frobU), sqrt(frobL), frobUL, frobA, norm);
|
||||
//printf("Omega Estimate1 %f %f\n", 2.0 / (1.0 + sqrt(1-frobUL)), 2.0 / (1.0 + sqrt(1-frobA)) ); // printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
|
||||
//printf("Frobenius %f %f %f %f %f\n", nl_math::sqrt(frobU), nl_math::sqrt(frobL), frobUL, frobA, norm);
|
||||
//printf("Omega Estimate1 %f %f\n", 2.0 / (1.0 + nl_math::sqrt(1-frobUL)), 2.0 / (1.0 + nl_math::sqrt(1-frobA)) ); // printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
|
||||
//printf("Omega Estimate2 %f %f\n", 2.0 / (2.0 - frobUL), 2.0 / (2.0 - frobA) ); // printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
|
||||
|
||||
|
||||
@ -250,7 +250,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
*
|
||||
* and estimate using
|
||||
*
|
||||
* omega = 2.0 / (1.0 + sqrt(1-rho))
|
||||
* omega = 2.0 / (1.0 + nl_math::sqrt(1-rho))
|
||||
*/
|
||||
|
||||
const nl_double ws = this->m_params.m_sor; //1.045; //2.0 / (1.0 + /*sin*/(3.14159 * 5.5 / (double) (m_nets.count()+1)));
|
||||
@ -284,7 +284,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
}
|
||||
if (USE_GABS)
|
||||
for (int i = 0; i < term_count; i++)
|
||||
gabs_t = gabs_t + fabs(go[i]);
|
||||
gabs_t = gabs_t + nl_math::abs(go[i]);
|
||||
|
||||
for (int i = this->m_terms[k]->m_railstart; i < term_count; i++)
|
||||
RHS_t = RHS_t + go[i] * *other_cur_analog[i];
|
||||
@ -292,7 +292,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
|
||||
RHS[k] = RHS_t;
|
||||
|
||||
//if (fabs(gabs_t - fabs(gtot_t)) > 1e-20)
|
||||
//if (nl_math::abs(gabs_t - nl_math::abs(gtot_t)) > 1e-20)
|
||||
// printf("%d %e abs: %f tot: %f\n",k, gabs_t / gtot_t -1.0, gabs_t, gtot_t);
|
||||
|
||||
gabs_t *= 0.95; // avoid rounding issues
|
||||
@ -329,9 +329,9 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
Idrive = Idrive + go[i] * old_V[net_other[i]];
|
||||
|
||||
//const nl_double new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k];
|
||||
//resched = resched || (std::abs(new_val - new_V[k]) > accuracy);
|
||||
//resched = resched || (nl_math::abs(new_val - new_V[k]) > accuracy);
|
||||
const nl_double new_val = old_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k];
|
||||
resched = resched || (std::abs(new_val - old_V[k]) > accuracy);
|
||||
resched = resched || (nl_math::abs(new_val - old_V[k]) > accuracy);
|
||||
new_V[k] = new_val;
|
||||
}
|
||||
for (int k = 0; k < iN; k++)
|
||||
|
@ -94,7 +94,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
*
|
||||
* and estimate using
|
||||
*
|
||||
* omega = 2.0 / (1.0 + sqrt(1-rho))
|
||||
* omega = 2.0 / (1.0 + nl_math::sqrt(1-rho))
|
||||
*/
|
||||
|
||||
const nl_double ws = this->m_params.m_sor; //1.045; //2.0 / (1.0 + /*sin*/(3.14159 * 5.5 / (double) (m_nets.count()+1)));
|
||||
@ -128,7 +128,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
|
||||
if (USE_GABS)
|
||||
for (int i = 0; i < term_count; i++)
|
||||
gabs_t = gabs_t + fabs(go[i]);
|
||||
gabs_t = gabs_t + nl_math::abs(go[i]);
|
||||
|
||||
for (int i = this->m_terms[k]->m_railstart; i < term_count; i++)
|
||||
RHS_t = RHS_t + go[i] * *other_cur_analog[i];
|
||||
@ -174,7 +174,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
|
||||
const nl_double new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k];
|
||||
|
||||
resched = resched || (std::abs(new_val - new_V[k]) > accuracy);
|
||||
resched = resched || (nl_math::abs(new_val - new_V[k]) > accuracy);
|
||||
new_V[k] = new_val;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ ATTR_HOT nl_double netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve()
|
||||
this->m_Vdelta[k] = nv;
|
||||
}
|
||||
if (sqo > 1e-90)
|
||||
m_lp_fact = std::min(sqrt(sq/sqo), 2.0);
|
||||
m_lp_fact = std::min(nl_math::sqrt(sq/sqo), (nl_double) 2.0);
|
||||
else
|
||||
m_lp_fact = 0.0;
|
||||
}
|
||||
@ -154,16 +154,16 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
|
||||
for (int k = 0; k < iN; k++)
|
||||
{
|
||||
#if 0
|
||||
nl_double akk = fabs(this->m_A[k][k]);
|
||||
nl_double akk = nl_math::abs(this->m_A[k][k]);
|
||||
if ( akk > lambdaN)
|
||||
lambdaN = akk;
|
||||
if (akk < lambda1)
|
||||
lambda1 = akk;
|
||||
#else
|
||||
nl_double akk = fabs(this->m_A[k][k]);
|
||||
nl_double akk = nl_math::abs(this->m_A[k][k]);
|
||||
nl_double s = 0.0;
|
||||
for (int i=0; i<iN; i++)
|
||||
s = s + fabs(this->m_A[k][i]);
|
||||
s = s + nl_math::abs(this->m_A[k][i]);
|
||||
akk = s / akk - 1.0;
|
||||
//if ( akk > lambdaN)
|
||||
// lambdaN = akk;
|
||||
@ -194,7 +194,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
|
||||
for (int i = 0; i < iN; i++)
|
||||
{
|
||||
frob += this->m_A[k][i] * this->m_A[k][i];
|
||||
s = s + fabs(this->m_A[k][i]);
|
||||
s = s + nl_math::abs(this->m_A[k][i]);
|
||||
}
|
||||
|
||||
if (s<rmin)
|
||||
@ -203,9 +203,9 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
|
||||
rmax = s;
|
||||
}
|
||||
#if 0
|
||||
nl_double frobA = sqrt(frob /(iN));
|
||||
nl_double frobA = nl_math::sqrt(frob /(iN));
|
||||
if (1 &&frobA < 1.0)
|
||||
//ws = 2.0 / (1.0 + sqrt(1.0-frobA));
|
||||
//ws = 2.0 / (1.0 + nl_math::sqrt(1.0-frobA));
|
||||
ws = 2.0 / (2.0 - frobA);
|
||||
else
|
||||
ws = 1.0;
|
||||
@ -220,7 +220,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
|
||||
// suitable parameter.
|
||||
nl_double rm = (rmax + rmin) * 0.5;
|
||||
if (rm < 1.0)
|
||||
ws = 2.0 / (1.0 + sqrt(1.0-rm));
|
||||
ws = 2.0 / (1.0 + nl_math::sqrt(1.0-rm));
|
||||
else
|
||||
ws = 1.0;
|
||||
if (ws > 1.02 && rmax > 1.001)
|
||||
@ -252,19 +252,19 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
|
||||
{
|
||||
if (i < k) frobL += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] /this-> m_A[k][k];
|
||||
if (i > k) frobU += this->m_A[k][i] * this->m_A[k][i] / this->m_A[k][k] / this->m_A[k][k];
|
||||
norm_t += fabs(this->m_A[k][i]);
|
||||
norm_t += nl_math::abs(this->m_A[k][i]);
|
||||
}
|
||||
#endif
|
||||
//if (norm_t > norm) norm = norm_t;
|
||||
#if 0
|
||||
const nl_double new_val = (1.0-ws) * new_v[k] + ws * (this->m_RHS[k] - Idrive + this->m_A[k][k] * new_v[k]) / this->m_A[k][k];
|
||||
|
||||
const nl_double e = fabs(new_val - new_v[k]);
|
||||
const nl_double e = nl_math::abs(new_val - new_v[k]);
|
||||
cerr = (e > cerr ? e : cerr);
|
||||
new_v[k] = new_val;
|
||||
#else
|
||||
const nl_double delta = m_omega * (this->m_RHS[k] - Idrive) / this->m_A[k][k];
|
||||
const nl_double adelta = std::abs(delta);
|
||||
const nl_double adelta = nl_math::abs(delta);
|
||||
cerr = (adelta > cerr ? adelta : cerr);
|
||||
new_v[k] += delta;
|
||||
#endif
|
||||
@ -275,10 +275,10 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
|
||||
resched = true;
|
||||
}
|
||||
resched_cnt++;
|
||||
//ATTR_UNUSED nl_double frobUL = sqrt((frobU + frobL) / (double) (iN) / (double) (iN));
|
||||
//ATTR_UNUSED nl_double frobUL = nl_math::sqrt((frobU + frobL) / (double) (iN) / (double) (iN));
|
||||
} while (resched && (resched_cnt < this->m_params.m_gs_loops));
|
||||
//printf("Frobenius %f %f %f %f %f\n", sqrt(frobU), sqrt(frobL), frobUL, frobA, norm);
|
||||
//printf("Omega Estimate1 %f %f\n", 2.0 / (1.0 + sqrt(1-frobUL)), 2.0 / (1.0 + sqrt(1-frobA)) ); // printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
|
||||
//printf("Frobenius %f %f %f %f %f\n", nl_math::sqrt(frobU), nl_math::sqrt(frobL), frobUL, frobA, norm);
|
||||
//printf("Omega Estimate1 %f %f\n", 2.0 / (1.0 + nl_math::sqrt(1-frobUL)), 2.0 / (1.0 + nl_math::sqrt(1-frobA)) ); // printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
|
||||
//printf("Omega Estimate2 %f %f\n", 2.0 / (2.0 - frobUL), 2.0 / (2.0 - frobA) ); // printf("Frobenius %f\n", sqrt(frob / (double) (iN * iN) ));
|
||||
|
||||
|
||||
|
@ -20,13 +20,14 @@ ATTR_COLD netlist_generic_diode::netlist_generic_diode()
|
||||
|
||||
ATTR_COLD void netlist_generic_diode::set_param(const nl_double Is, const nl_double n, nl_double gmin)
|
||||
{
|
||||
static const int csqrt2 = nl_math::sqrt(2.0);
|
||||
m_Is = Is;
|
||||
m_n = n;
|
||||
m_gmin = gmin;
|
||||
|
||||
m_Vt = 0.0258 * m_n;
|
||||
|
||||
m_Vcrit = m_Vt * log(m_Vt / m_Is / sqrt(2.0));
|
||||
m_Vcrit = m_Vt * nl_math::log(m_Vt / m_Is / csqrt2);
|
||||
m_VtInv = 1.0 / m_Vt;
|
||||
}
|
||||
|
||||
@ -162,7 +163,7 @@ NETLIB_UPDATE_PARAM(POT)
|
||||
{
|
||||
nl_double v = m_Dial.Value();
|
||||
if (m_DialIsLog.Value())
|
||||
v = (exp(v) - 1.0) / (exp(1.0) - 1.0);
|
||||
v = (nl_math::exp(v) - 1.0) / (nl_math::exp(1.0) - 1.0);
|
||||
|
||||
// FIXME: Only attached nets should be brought up to current time
|
||||
//netlist().solver()->update_to_current_time(); // bring up current time
|
||||
@ -208,7 +209,7 @@ NETLIB_UPDATE_PARAM(POT2)
|
||||
nl_double v = m_Dial.Value();
|
||||
|
||||
if (m_DialIsLog.Value())
|
||||
v = (exp(v) - 1.0) / (exp(1.0) - 1.0);
|
||||
v = (nl_math::exp(v) - 1.0) / (nl_math::exp(1.0) - 1.0);
|
||||
if (m_Reverse.Value())
|
||||
v = 1.0 - v;
|
||||
|
||||
|
@ -226,20 +226,17 @@ public:
|
||||
{
|
||||
m_Vd = nVd;
|
||||
|
||||
const nl_double eVDVt = exp(m_Vd * m_VtInv);
|
||||
const nl_double eVDVt = nl_math::exp(m_Vd * m_VtInv);
|
||||
m_Id = m_Is * (eVDVt - 1.0);
|
||||
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
m_Vd = m_Vd + log((nVd - m_Vd) * m_VtInv + 1.0) * m_Vt;
|
||||
#else
|
||||
nl_double a = (nVd - m_Vd) * m_VtInv;
|
||||
if (a<1e-12 - 1.0) a = 1e-12 - 1.0;
|
||||
m_Vd = m_Vd + log1p(a) * m_Vt;
|
||||
#endif
|
||||
const nl_double eVDVt = exp(m_Vd * m_VtInv);
|
||||
|
||||
const nl_double eVDVt = nl_math::exp(m_Vd * m_VtInv);
|
||||
m_Id = m_Is * (eVDVt - 1.0);
|
||||
|
||||
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
|
||||
@ -277,35 +274,6 @@ private:
|
||||
// nld_D
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// this one has an accuracy of better than 5%. That's enough for our purpose
|
||||
// add c3 and it'll be better than 1%
|
||||
|
||||
#if 0
|
||||
inline nl_double fastexp_h(const nl_double x)
|
||||
{
|
||||
static const nl_double ln2r = 1.442695040888963387;
|
||||
static const nl_double ln2 = 0.693147180559945286;
|
||||
//static const nl_double c3 = 0.166666666666666667;
|
||||
|
||||
const nl_double y = x * ln2r;
|
||||
const unsigned int t = y;
|
||||
const nl_double z = (x - ln2 * (double) t);
|
||||
const nl_double zz = z * z;
|
||||
//const nl_double zzz = zz * z;
|
||||
|
||||
return (double)(1 << t)*(1.0 + z + 0.5 * zz); // + c3*zzz;
|
||||
}
|
||||
|
||||
inline nl_double fastexp(const nl_double x)
|
||||
{
|
||||
if (x<0)
|
||||
return 1.0 / fastexp_h(-x);
|
||||
else
|
||||
return fastexp_h(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
class NETLIB_NAME(D) : public NETLIB_NAME(twoterm)
|
||||
{
|
||||
public:
|
||||
|
@ -1305,7 +1305,6 @@ ATTR_HOT inline void netlist_logic_input_t::activate_lh()
|
||||
|
||||
ATTR_HOT inline void netlist_net_t::push_to_queue(const netlist_time &delay)
|
||||
{
|
||||
//if (UNEXPECTED(m_num_cons == 0 || is_queued()))
|
||||
if (!is_queued() && (num_cons() > 0))
|
||||
{
|
||||
m_time = netlist().time() + delay;
|
||||
@ -1319,7 +1318,6 @@ ATTR_HOT inline void netlist_net_t::push_to_queue(const netlist_time &delay)
|
||||
|
||||
ATTR_HOT inline void netlist_net_t::reschedule_in_queue(const netlist_time &delay)
|
||||
{
|
||||
//if (UNEXPECTED(m_num_cons == 0 || is_queued()))
|
||||
if (is_queued())
|
||||
netlist().remove_from_queue(*this);
|
||||
|
||||
@ -1334,6 +1332,7 @@ ATTR_HOT inline void netlist_net_t::reschedule_in_queue(const netlist_time &dela
|
||||
|
||||
ATTR_HOT inline const netlist_sig_t netlist_logic_input_t::Q() const
|
||||
{
|
||||
nl_assert(family() == LOGIC);
|
||||
return net().as_logic().Q();
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ inline int CAPACITOR_tc_hl(const double c, const double r)
|
||||
* Vt = (VH-VL)*exp(-t/RC)
|
||||
* ln(Vt/(VH-VL))*RC = -t
|
||||
*/
|
||||
static const double TIME_CONSTANT = -log(2.0 / (3.7-0.3));
|
||||
static const double TIME_CONSTANT = -nl_math::log(2.0 / (3.7-0.3));
|
||||
int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9);
|
||||
return ret;
|
||||
}
|
||||
@ -172,7 +172,7 @@ inline int CAPACITOR_tc_lh(const double c, const double r)
|
||||
* Vt = (VH-VL)*(1-exp(-t/RC))
|
||||
* -t=ln(1-Vt/(VH-VL))*RC
|
||||
*/
|
||||
static const double TIME_CONSTANT = -log(1.0 - 0.8 / (3.7-0.3));
|
||||
static const double TIME_CONSTANT = -nl_math::log(1.0 - 0.8 / (3.7-0.3));
|
||||
int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9);
|
||||
return ret;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "pstring.h"
|
||||
#include "plists.h"
|
||||
#include <cmath>
|
||||
|
||||
class nl_util
|
||||
{
|
||||
@ -40,4 +41,58 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class nl_math
|
||||
{
|
||||
// this is purely static
|
||||
private:
|
||||
nl_math() {};
|
||||
|
||||
public:
|
||||
ATTR_HOT inline static float exp(const float x) { return std::exp(x); }
|
||||
ATTR_HOT inline static double abs(const double x) { return std::abs(x); }
|
||||
ATTR_HOT inline static float abs(const float x) { return std::abs(x); }
|
||||
ATTR_HOT inline static double log(const double x) { return std::log(x); }
|
||||
ATTR_HOT inline static float log(const float x) { return std::log(x); }
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
ATTR_HOT inline static double log1p(const double x) { return nl_math::log(1.0 + x); }
|
||||
ATTR_HOT inline static float log1p(const float x) { return nl_math::log(1.0 + x); }
|
||||
#else
|
||||
ATTR_HOT inline static double log1p(const double x) { return log1p(x); }
|
||||
ATTR_HOT inline static float log1p(const float x) { return log1pf(x); }
|
||||
#endif
|
||||
ATTR_HOT inline static double sqrt(const double x) { return std::sqrt(x); }
|
||||
ATTR_HOT inline static float sqrt(const float x) { return std::sqrt(x); }
|
||||
|
||||
// this one has an accuracy of better than 5%. That's enough for our purpose
|
||||
// add c3 and it'll be better than 1%
|
||||
|
||||
#if 0
|
||||
inline static double fastexp_h(const double x)
|
||||
{
|
||||
static const double ln2r = 1.442695040888963387;
|
||||
static const double ln2 = 0.693147180559945286;
|
||||
static const double c3 = 0.166666666666666667;
|
||||
|
||||
const double y = x * ln2r;
|
||||
const unsigned int t = y;
|
||||
const double z = (x - ln2 * (double) t);
|
||||
const double zz = z * z;
|
||||
const double zzz = zz * z;
|
||||
|
||||
return (double)(1 << t)*(1.0 + z + 0.5 * zz + c3 * zzz);
|
||||
}
|
||||
|
||||
ATTR_HOT inline static double exp(const double x)
|
||||
{
|
||||
if (x<0)
|
||||
return 1.0 / fastexp_h(-x);
|
||||
else
|
||||
return fastexp_h(x);
|
||||
}
|
||||
#else
|
||||
ATTR_HOT inline static double exp(const double x) { return std::exp(x); }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* NL_UTIL_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user