Previous 199869 Revisions Next

r30665 Sunday 25th May, 2014 at 21:45:51 UTC by Couriersud
Further simplification and clean up around the linear system solvers.
[src/emu/netlist]nl_base.c nl_base.h plists.h
[src/emu/netlist/analog]nld_solver.c nld_solver.h

trunk/src/emu/netlist/nl_base.c
r30664r30665
771771, m_go(NETLIST_GMIN_DEFAULT)
772772, m_gt(NETLIST_GMIN_DEFAULT)
773773, m_otherterm(NULL)
774, m_otherterm_ptr(NULL)
774, m_new_analog_ptr(NULL)
775775{
776776}
777777
trunk/src/emu/netlist/nl_base.h
r30664r30665
429429   NETLIST_PREVENT_COPYING(netlist_terminal_t)
430430public:
431431
432    typedef plinearlist_t<netlist_terminal_t *> list_t;
432    typedef plinearlist_t<netlist_terminal_t * RESTRICT> list_t;
433433
434434   ATTR_COLD netlist_terminal_t();
435435
r30664r30665
462462
463463   // used by gauss-seidel-solver
464464
465   double * RESTRICT m_otherterm_ptr;
465   double * RESTRICT m_new_analog_ptr;
466466
467467protected:
468468   ATTR_COLD virtual void save_register();
r30664r30665
732732
733733    //FIXME: needed by current solver code
734734    netlist_matrix_solver_t *m_solver;
735    netlist_terminal_t::list_t m_terms;
736    netlist_terminal_t::list_t m_rails;
735//    netlist_terminal_t::list_t m_terms;
736//    netlist_terminal_t::list_t m_rails;
737737};
738738
739739// ----------------------------------------------------------------------------------------
trunk/src/emu/netlist/analog/nld_solver.h
r30664r30665
4646   ATTR_COLD netlist_matrix_solver_t();
4747   ATTR_COLD virtual ~netlist_matrix_solver_t();
4848
49   ATTR_COLD virtual void vsetup(netlist_analog_net_t::list_t &nets, NETLIB_NAME(solver) &owner);
49    ATTR_COLD virtual void vsetup(netlist_analog_net_t::list_t &nets,
50            NETLIB_NAME(solver) &owner) = 0;
5051
5152   ATTR_HOT double solve();
5253
r30664r30665
6465
6566   netlist_solver_parameters_t m_params;
6667
67   ATTR_COLD void log_stats();
68   ATTR_COLD virtual void log_stats() {};
6869
6970protected:
7071
71    netlist_analog_net_t::list_t m_nets;
72   class net_entry
73   {
74       NETLIST_PREVENT_COPYING(net_entry)
7275
76   public:
77       net_entry(netlist_analog_net_t *net) : m_net(net) {}
78        net_entry() : m_net(NULL) {}
7379
80       netlist_analog_net_t * RESTRICT m_net;
81       netlist_terminal_t::list_t m_terms;
82       netlist_terminal_t::list_t m_rails;
83   };
84
85    ATTR_COLD virtual void setup(netlist_analog_net_t::list_t &nets,
86            NETLIB_NAME(solver) &owner, net_entry *list);
87
7488   NETLIB_NAME(solver) *m_owner;
7589
7690    // return true if a reschedule is needed ...
7791    ATTR_HOT virtual int vsolve_non_dynamic() = 0;
7892
7993    int m_calculations;
80    int m_gs_fail;
81    int m_gs_total;
8294
8395private:
8496
r30664r30665
110122
111123   netlist_matrix_solver_direct_t()
112124    : netlist_matrix_solver_t()
113    , m_term_num(0)
125    , m_dim(0)
114126    , m_rail_start(0)
115127    {}
116128
r30664r30665
119131   ATTR_COLD virtual void vsetup(netlist_analog_net_t::list_t &nets, NETLIB_NAME(solver) &owner);
120132   ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); }
121133
122   ATTR_HOT inline const int N() const { if (m_N == 0) return m_nets.count(); else return m_N; }
134   ATTR_HOT inline const int N() const { if (m_N == 0) return m_dim; else return m_N; }
123135
124136protected:
125137    ATTR_HOT virtual int vsolve_non_dynamic();
126    ATTR_HOT int solve_non_dynamic(double (* RESTRICT A)[_storage_N], double (* RESTRICT RHS));
127   ATTR_HOT inline void build_LE(double (* RESTRICT A)[_storage_N], double (* RESTRICT RHS));
128   ATTR_HOT inline void gauss_LE(double (* RESTRICT A)[_storage_N],
129         double (* RESTRICT RHS),
130         double (* RESTRICT x));
138    ATTR_HOT int solve_non_dynamic();
139   ATTR_HOT inline void build_LE();
140   ATTR_HOT inline void gauss_LE(double (* RESTRICT x));
131141   ATTR_HOT inline double delta(
132         const double (* RESTRICT RHS),
133142         const double (* RESTRICT V));
134   ATTR_HOT inline void store(const double (* RESTRICT RHS), const double (* RESTRICT V));
143   ATTR_HOT inline void store(const double (* RESTRICT V), bool store_RHS);
135144
136   double m_last_RHS[_storage_N]; // right hand side - contains currents
145    net_entry m_nets[_storage_N];
137146
147    double m_A[_storage_N][_storage_N];
148    double m_RHS[_storage_N];
149    double m_last_RHS[_storage_N]; // right hand side - contains currents
150
138151private:
139
140152   ATTR_COLD int get_net_idx(netlist_net_t *net);
141153
142154   struct terms_t{
143      int net_this;
144      int net_other;
145      netlist_terminal_t *term;
155
156       terms_t(netlist_terminal_t *term, int net_this, int net_other)
157       : m_term(term), m_net_this(net_this), m_net_other(net_other)
158       {}
159        terms_t()
160        : m_term(NULL), m_net_this(-1), m_net_other(-1)
161        {}
162
163        netlist_terminal_t *m_term;
164      int m_net_this;
165      int m_net_other;
146166   };
147   int m_term_num;
167
168   int m_dim;
148169   int m_rail_start;
149   terms_t m_terms[_storage_N * _storage_N];
170   plinearlist_t<terms_t> m_terms;
150171};
151172
152173template <int m_N, int _storage_N>
r30664r30665
154175{
155176public:
156177
157   netlist_matrix_solver_gauss_seidel_t() : netlist_matrix_solver_direct_t<m_N, _storage_N>() {}
178   netlist_matrix_solver_gauss_seidel_t()
179      : netlist_matrix_solver_direct_t<m_N, _storage_N>()
180      , m_gs_fail(0)
181      , m_gs_total(0)
182      {}
158183
159184   virtual ~netlist_matrix_solver_gauss_seidel_t() {}
160185
186    ATTR_COLD virtual void log_stats();
187
161188protected:
162189   ATTR_HOT int vsolve_non_dynamic();
163190
191private:
192    int m_gs_fail;
193    int m_gs_total;
194
164195};
165196
166197class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1>
trunk/src/emu/netlist/analog/nld_solver.c
r30664r30665
2525ATTR_COLD netlist_matrix_solver_t::netlist_matrix_solver_t()
2626: m_owner(NULL)
2727, m_calculations(0)
28, m_gs_fail(0)
29, m_gs_total(0)
3028{
3129}
3230
r30664r30665
3634        delete m_inps[i];
3735}
3836
39ATTR_COLD void netlist_matrix_solver_t::vsetup(netlist_analog_net_t::list_t &nets, NETLIB_NAME(solver) &aowner)
37ATTR_COLD void netlist_matrix_solver_t::setup(netlist_analog_net_t::list_t &nets, NETLIB_NAME(solver) &aowner, net_entry *list)
4038{
4139   m_owner = &aowner;
4240
4341   NL_VERBOSE_OUT(("New solver setup\n"));
4442
45   for (netlist_analog_net_t * const * pn = nets.first(); pn != NULL; pn = nets.next(pn))
43   for (int k = 0; k < nets.count(); k++)
44       list[k].m_net = nets[k];
45
46   for (int k = 0; k < nets.count(); k++)
4647   {
4748      NL_VERBOSE_OUT(("setting up net\n"));
4849
49      m_nets.add(*pn);
50      netlist_analog_net_t *net = list[k].m_net;
5051
51      (*pn)->m_solver = this;
52      net->m_solver = this;
5253
53        for (int i = 0; i < (*pn)->m_core_terms.count(); i++)
54        for (int i = 0; i < net->m_core_terms.count(); i++)
5455      {
55          netlist_core_terminal_t *p = (*pn)->m_core_terms[i];
56         NL_VERBOSE_OUT(("%s %s %d\n", p->name().cstr(), (*pn)->name().cstr(), (int) (*pn)->isRailNet()));
56          netlist_core_terminal_t *p = net->m_core_terms[i];
57         NL_VERBOSE_OUT(("%s %s %d\n", p->name().cstr(), net->name().cstr(), (int) net->isRailNet()));
5758         switch (p->type())
5859         {
5960            case netlist_terminal_t::TERMINAL:
r30664r30665
7778               {
7879                  netlist_terminal_t *pterm = dynamic_cast<netlist_terminal_t *>(p);
7980                  // for gauss seidel
80                     pterm->m_otherterm_ptr = &pterm->m_otherterm->net().as_analog().m_new_Analog;
81                     pterm->m_new_analog_ptr = &pterm->m_otherterm->net().as_analog().m_new_Analog;
8182
8283                  if (pterm->m_otherterm->net().isRailNet())
83                     (*pn)->m_rails.add(pterm);
84                     list[k].m_rails.add(pterm);
8485                  else
85                     (*pn)->m_terms.add(pterm);
86                      list[k].m_terms.add(pterm);
8687               }
8788               NL_VERBOSE_OUT(("Added terminal\n"));
8889               break;
r30664r30665
114115               break;
115116         }
116117      }
117      NL_VERBOSE_OUT(("added net with %d populated connections (%d railnets)\n", (*pn)->m_terms.count(), (*pn)->m_rails.count()));
118      NL_VERBOSE_OUT(("added net with %d populated connections (%d railnets)\n", net->m_terms.count(), (*pn)->m_rails.count()));
118119   }
119120}
120121
r30664r30665
268269   return next_time_step;
269270}
270271
271void netlist_matrix_solver_t::log_stats()
272template <int m_N, int _storage_N>
273void netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::log_stats()
272274{
273275#if 0
274276    printf("==============================================\n");
275    printf("Solver %s\n", name().cstr());
276    printf("       ==> %d nets\n", m_nets.count()); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr());
277    printf("       has %s elements\n", is_dynamic() ? "dynamic" : "no dynamic");
278    printf("       has %s elements\n", is_timestep() ? "timestep" : "no timestep");
277    printf("Solver %s\n", this->name().cstr());
278    printf("       ==> %d nets\n", this->N()); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr());
279    printf("       has %s elements\n", this->is_dynamic() ? "dynamic" : "no dynamic");
280    printf("       has %s elements\n", this->is_timestep() ? "timestep" : "no timestep");
279281    printf("       %10d invocations (%6d Hz)  %10d gs fails (%6.2f%%) %4.1f average\n",
280            m_calculations,
281            m_calculations * 10 / (int) (netlist().time().as_double() * 10.0),
282            m_gs_fail,
283            100.0 * (double) m_gs_fail / (double) m_calculations,
284            (double) m_gs_total / (double) m_calculations);
282            this->m_calculations,
283            this->m_calculations * 10 / (int) (this->netlist().time().as_double() * 10.0),
284            this->m_gs_fail,
285            100.0 * (double) this->m_gs_fail / (double) this->m_calculations,
286            (double) this->m_gs_total / (double) this->m_calculations);
285287#endif
286288}
287289
r30664r30665
294296ATTR_COLD int netlist_matrix_solver_direct_t<m_N, _storage_N>::get_net_idx(netlist_net_t *net)
295297{
296298   for (int k = 0; k < N(); k++)
297      if (m_nets[k] == net)
299      if (m_nets[k].m_net == net)
298300         return k;
299301   return -1;
300302}
r30664r30665
302304template <int m_N, int _storage_N>
303305ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::vsetup(netlist_analog_net_t::list_t &nets, NETLIB_NAME(solver) &owner)
304306{
305   netlist_matrix_solver_t::vsetup(nets, owner);
307    m_dim = nets.count();
308   netlist_matrix_solver_t::setup(nets, owner, m_nets);
306309
307   m_term_num = 0;
310   m_terms.clear();
308311   m_rail_start = 0;
309312   for (int k = 0; k < N(); k++)
310313   {
311      netlist_analog_net_t *net = m_nets[k];
312      const netlist_terminal_t::list_t &terms = net->m_terms;
314      const netlist_terminal_t::list_t &terms = m_nets[k].m_terms;
313315      for (int i = 0; i < terms.count(); i++)
314316      {
315         m_terms[m_term_num].net_this = k;
316317         int ot = get_net_idx(&terms[i]->m_otherterm->net());
317         m_terms[m_term_num].net_other = ot;
318         m_terms[m_term_num].term = terms[i];
319318         if (ot>=0)
320319         {
321            m_term_num++;
320             m_terms.add(terms_t(terms[i], k, ot));
322321            SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go));
323322         }
324323      }
325324   }
326   m_rail_start = m_term_num;
325   m_rail_start = m_terms.count();
327326   for (int k = 0; k < N(); k++)
328327   {
329      netlist_analog_net_t *net = m_nets[k];
330      const netlist_terminal_t::list_t &terms = net->m_terms;
331      const netlist_terminal_t::list_t &rails = net->m_rails;
328      const netlist_terminal_t::list_t &terms = m_nets[k].m_terms;
329      const netlist_terminal_t::list_t &rails = m_nets[k].m_rails;
332330      for (int i = 0; i < terms.count(); i++)
333331      {
334         m_terms[m_term_num].net_this = k;
335         int ot = get_net_idx(&terms[i]->m_otherterm->net());
336         m_terms[m_term_num].net_other = ot;
337         m_terms[m_term_num].term = terms[i];
332            int ot = get_net_idx(&terms[i]->m_otherterm->net());
338333         if (ot<0)
339334         {
340            m_term_num++;
341            SOLVER_VERBOSE_OUT(("found term with missing othernet %s\n", terms[i]->name().cstr()));
335                m_terms.add(terms_t(terms[i], k, ot));
336            netlist().warning("found term with missing othernet %s\n", terms[i]->name().cstr());
342337         }
343338      }
344339      for (int i = 0; i < rails.count(); i++)
345340      {
346         m_terms[m_term_num].net_this = k;
347         m_terms[m_term_num].net_other = -1; //get_net_idx(&rails[i]->m_otherterm->net());
348         m_terms[m_term_num].term = rails[i];
349         m_term_num++;
341            m_terms.add(terms_t(rails[i], k, -1));
350342         SOLVER_VERBOSE_OUT(("Net %d Rail %s %f %f\n", k, rails[i]->name().cstr(), rails[i]->m_gt, rails[i]->m_go));
351343      }
352344   }
353345}
354346
355347template <int m_N, int _storage_N>
356ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::build_LE(
357      double (* RESTRICT A)[_storage_N],
358      double (* RESTRICT RHS))
348ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::build_LE()
359349{
350    for (int k=0; k < _storage_N; k++)
351        for (int i=0; i < _storage_N; i++)
352            m_A[k][i] = 0.0;
353
354    for (int k=0; k < _storage_N; k++)
355        m_RHS[k] = 0.0;
360356#if 0
357
361358   for (int i = 0; i < m_term_num; i++)
362359   {
363360      terms_t &t = m_terms[i];
364      RHS[t.net_this] += t.term->m_Idr;
365      A[t.net_this][t.net_this] += t.term->m_gt;
366      if (t.net_other >= 0)
361      m_RHS[t.m_net_this] += t.m_term->m_Idr;
362      m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt;
363      if (t.m_net_other >= 0)
367364      {
368365         //m_A[t.net_other][t.net_other] += t.term->m_otherterm->m_gt;
369         A[t.net_this][t.net_other] += -t.term->m_go;
366         m_A[t.m_net_this][t.m_net_other] += -t.m_term->m_go;
370367         //m_A[t.net_other][t.net_this] += -t.term->m_otherterm->m_go;
371368      }
372369      else
373         RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().as_analog().Q_Analog();
370         m_RHS[t.m_net_this] += t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog();
374371   }
375372#else
376373   for (int i = 0; i < m_rail_start; i++)
r30664r30665
378375      const terms_t &t = m_terms[i];
379376      //printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go);
380377
381      RHS[t.net_this] += t.term->m_Idr;
382      A[t.net_this][t.net_this] += t.term->m_gt;
383      A[t.net_this][t.net_other] += -t.term->m_go;
378      m_RHS[t.m_net_this] += t.m_term->m_Idr;
379      m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt;
380      m_A[t.m_net_this][t.m_net_other] += -t.m_term->m_go;
384381   }
385   for (int i = m_rail_start; i < m_term_num; i++)
382   for (int i = m_rail_start; i < m_terms.count(); i++)
386383   {
387384      const terms_t &t = m_terms[i];
388385
389      RHS[t.net_this] += t.term->m_Idr;
390      A[t.net_this][t.net_this] += t.term->m_gt;
391      RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().as_analog().Q_Analog();
386      m_RHS[t.m_net_this] += t.m_term->m_Idr;
387      m_A[t.m_net_this][t.m_net_this] += t.m_term->m_gt;
388      m_RHS[t.m_net_this] += t.m_term->m_go * t.m_term->m_otherterm->net().as_analog().Q_Analog();
392389   }
393390#endif
394391}
395392
396393template <int m_N, int _storage_N>
397394ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::gauss_LE(
398      double (* RESTRICT A)[_storage_N],
399      double (* RESTRICT RHS),
400395      double (* RESTRICT x))
401396{
402397#if 0
403398   for (int i = 0; i < N(); i++)
404399   {
405400      for (int k = 0; k < N(); k++)
406         printf("%f ", A[i][k]);
407      printf("| %f = %f \n", x[i], RHS[i]);
401         printf("%f ", m_A[i][k]);
402      printf("| %f = %f \n", x[i], m_RHS[i]);
408403   }
409404   printf("\n");
410405#endif
r30664r30665
419414           int maxrow = i;
420415           for (int j = i + 1; j < kN; j++)
421416           {
422               if (fabs(A[j][i]) > fabs(A[maxrow][i]))
417               if (fabs(m_A[j][i]) > fabs(m_A[maxrow][i]))
423418                   maxrow = j;
424419           }
425420
r30664r30665
427422           {
428423               /* Swap the maxrow and ith row */
429424               for (int k = i; k < kN; k++) {
430                   std::swap(A[i][k], A[maxrow][k]);
425                   std::swap(m_A[i][k], m_A[maxrow][k]);
431426               }
432               std::swap(RHS[i], RHS[maxrow]);
427               std::swap(m_RHS[i], m_RHS[maxrow]);
433428           }
434429       }
435430
436431       /* Singular matrix? */
437      double f = A[i][i];
432      double f = m_A[i][i];
438433      //if (fabs(f) < 1e-20) printf("Singular!");
439434      f = 1.0 / f;
440435
r30664r30665
443438      for (int j = i + 1; j < kN; j++)
444439      {
445440            //__builtin_prefetch(&A[j+1][i], 1);
446            const double f1 = A[j][i] * f;
441            const double f1 = m_A[j][i] * f;
447442         if (f1 != 0.0)
448443         {
449444                for (int k = i; k < kN; k++)
450                    A[j][k] -= A[i][k] * f1;
451               RHS[j] -= RHS[i] * f1;
445                    m_A[j][k] -= m_A[i][k] * f1;
446               m_RHS[j] -= m_RHS[i] * f1;
452447         }
453448      }
454449   }
r30664r30665
458453        //__builtin_prefetch(&A[j-1][j], 0);
459454      double tmp = 0;
460455        for (int k = j + 1; k < kN; k++)
461            tmp += A[j][k] * x[k];
462      x[j] = (RHS[j] - tmp) / A[j][j];
456            tmp += m_A[j][k] * x[k];
457      x[j] = (m_RHS[j] - tmp) / m_A[j][j];
463458   }
464459#if 0
465460   printf("Solution:\n");
466461   for (int i = 0; i < N(); i++)
467462   {
468463      for (int k = 0; k < N(); k++)
469         printf("%f ", A[i][k]);
470      printf("| %f = %f \n", x[i], RHS[i]);
464         printf("%f ", m_A[i][k]);
465      printf("| %f = %f \n", x[i], m_RHS[i]);
471466   }
472467   printf("\n");
473468#endif
r30664r30665
476471
477472template <int m_N, int _storage_N>
478473ATTR_HOT double netlist_matrix_solver_direct_t<m_N, _storage_N>::delta(
479      const double (* RESTRICT RHS),
480474      const double (* RESTRICT V))
481475{
482476   double cerr = 0;
483477   double cerr2 = 0;
484478   for (int i = 0; i < this->N(); i++)
485479   {
486      double e = (V[i] - this->m_nets[i]->m_cur_Analog);
487      double e2 = (RHS[i] - this->m_last_RHS[i]);
480      double e = (V[i] - this->m_nets[i].m_net->m_cur_Analog);
481      double e2 = (m_RHS[i] - this->m_last_RHS[i]);
488482      cerr += e * e;
489483      cerr2 += e2 * e2;
490484   }
r30664r30665
493487
494488template <int m_N, int _storage_N>
495489ATTR_HOT void netlist_matrix_solver_direct_t<m_N, _storage_N>::store(
496      const double (* RESTRICT RHS),
497      const double (* RESTRICT V))
490      const double (* RESTRICT V), bool store_RHS)
498491{
499492   for (int i = 0; i < this->N(); i++)
500493   {
501      this->m_nets[i]->m_cur_Analog = this->m_nets[i]->m_new_Analog = V[i];
494      this->m_nets[i].m_net->m_cur_Analog = this->m_nets[i].m_net->m_new_Analog = V[i];
502495   }
503   if (RHS != NULL)
496   if (store_RHS)
504497   {
505498      for (int i = 0; i < this->N(); i++)
506499      {
507         this->m_last_RHS[i] = RHS[i];
500         this->m_last_RHS[i] = m_RHS[i];
508501      }
509502   }
510503}
511504
512505template <int m_N, int _storage_N>
513ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(double (* RESTRICT A)[_storage_N], double (* RESTRICT RHS))
506ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic()
514507{
515508    double new_v[_storage_N] = { 0.0 };
516509
517    this->gauss_LE(A, RHS, new_v);
510    this->gauss_LE(new_v);
518511
519512    if (this->is_dynamic())
520513    {
521        double err = delta(RHS, new_v);
514        double err = delta(new_v);
522515
523        store(RHS, new_v);
516        store(new_v, true);
524517
525518        if (err > this->m_params.m_accuracy * this->m_params.m_accuracy)
526519        {
r30664r30665
528521        }
529522        return 1;
530523    }
531    store(NULL, new_v);  // ==> No need to store RHS
524    store(new_v, false);  // ==> No need to store RHS
532525    return 1;
533526}
534527
535528template <int m_N, int _storage_N>
536529ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic()
537530{
538   double A[_storage_N][_storage_N] = { { 0.0 } };
539   double RHS[_storage_N] = { 0.0 };
531   this->build_LE();
540532
541   this->build_LE(A, RHS);
542
543   return this->solve_non_dynamic(A, RHS);
533   return this->solve_non_dynamic();
544534}
545535
546536
r30664r30665
551541ATTR_HOT int netlist_matrix_solver_direct1_t::vsolve_non_dynamic()
552542{
553543
554    netlist_analog_net_t *net = m_nets[0];
555   double m_A[1][1] = { {0.0} };
556   double m_RHS[1] = { 0.0 };
557   build_LE(m_A, m_RHS);
544    netlist_analog_net_t *net = m_nets[0].m_net;
545   this->build_LE();
558546   //NL_VERBOSE_OUT(("%f %f\n", new_val, m_RHS[0] / m_A[0][0]);
559547
560548   double new_val =  m_RHS[0] / m_A[0][0];
r30664r30665
581569
582570ATTR_HOT int netlist_matrix_solver_direct2_t::vsolve_non_dynamic()
583571{
584   double A[2][2] = { { 0.0 } };
585   double RHS[2] = { 0.0 };
586572
587   build_LE(A, RHS);
573   build_LE();
588574
589   const double a = A[0][0];
590   const double b = A[0][1];
591   const double c = A[1][0];
592   const double d = A[1][1];
575   const double a = m_A[0][0];
576   const double b = m_A[0][1];
577   const double c = m_A[1][0];
578   const double d = m_A[1][1];
593579
594580   double new_val[2];
595   new_val[1] = a / (a * d - b * c) * (RHS[1] - c / a * RHS[0]);
596   new_val[0] = (RHS[0] - b * new_val[1]) / a;
581   new_val[1] = a / (a * d - b * c) * (m_RHS[1] - c / a * m_RHS[0]);
582   new_val[0] = (m_RHS[0] - b * new_val[1]) / a;
597583
598584   if (is_dynamic())
599585   {
600      double err = delta(RHS, new_val);
601      store(RHS, new_val);
586      double err = delta(new_val);
587      store(new_val, true);
602588      if (err > m_params.m_accuracy * m_params.m_accuracy)
603589         return 2;
604590      else
605591         return 1;
606592   }
607   store(NULL, new_val);
593   store(new_val, false);
608594   return 1;
609595}
610596
r30664r30665
621607     */
622608
623609#if 0
624    double A[_storage_N][_storage_N] = { { 0.0 } };
625    double RHS[_storage_N] = { 0.0 };
626610    double new_v[_storage_N] = { 0.0 };
627611    const int iN = this->N();
628612
r30664r30665
630614
631615    int  resched_cnt = 0;
632616
633    this->build_LE(A, RHS);
617    this->build_LE();
634618
635619    for (int k = 0; k < iN; k++)
636620    {
637        new_v[k] = this->m_nets[k]->m_cur_Analog;
621        new_v[k] = this->m_nets[k].m_net->m_cur_Analog;
638622    }
639623    do {
640624        resched = false;
r30664r30665
647631
648632            // loop auto-vectorized
649633            for (int i = 0; i < iN; i++)
650                Idrive -= A[pk][i] * new_v[i];
634                Idrive -= this->m_A[pk][i] * new_v[i];
651635
652            const double new_val = (RHS[pk] + Idrive + A[pk][pk] * new_v[pk]) / A[pk][pk];
636            const double new_val = (this->m_RHS[pk] + Idrive + this->m_A[pk][pk] * new_v[pk]) / this->m_A[pk][pk];
653637
654638            const double e = (new_val - new_v[k]);
655639            cerr += e * e;
r30664r30665
668652    {
669653        //this->netlist().warning("Falling back to direct solver .. Consider increasing RESCHED_LOOPS");
670654        this->m_gs_fail++;
671        int tmp = netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(A, RHS);
655        int tmp = netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic();
672656        this->m_calculations++;
673657        return tmp;
674658    }
675659    else {
676660        this->m_calculations++;
677661
678        this->store(NULL, new_v);
662        this->store(new_v, false);
679663
680664        return resched_cnt;
681665    }
r30664r30665
697681
698682    for (int k = 0; k < iN; k++)
699683    {
700        this->m_nets[k]->m_new_Analog = this->m_nets[k]->m_cur_Analog;
684        this->m_nets[k].m_net->m_new_Analog = this->m_nets[k].m_net->m_cur_Analog;
701685    }
702686
703687   for (int k = 0; k < iN; k++)
r30664r30665
706690      double gabs_t = 0.0;
707691      double RHS_t = 0.0;
708692
709      const netlist_analog_net_t &net = *this->m_nets[k];
710      const netlist_terminal_t::list_t &terms = net.m_terms;
711      const netlist_terminal_t::list_t &rails = net.m_rails;
693      //const netlist_analog_net_t &net = *this->m_nets[k];
694      const netlist_terminal_t::list_t &terms = this->m_nets[k].m_terms;
695      const netlist_terminal_t::list_t &rails = this->m_nets[k].m_rails;
712696      const int term_count = terms.count();
713697      const int rail_count = rails.count();
714698
r30664r30665
717701         gtot_t += rails[i]->m_gt;
718702         gabs_t += fabs(rails[i]->m_go);
719703         RHS_t += rails[i]->m_Idr;
720         //RHS_t += rails[i]->m_go * rails[i]->m_otherterm->net().as_analog().Q_Analog();
721            RHS_t += rails[i]->m_go * *rails[i]->m_otherterm_ptr;
704         RHS_t += rails[i]->m_go * rails[i]->m_otherterm->net().as_analog().Q_Analog();
722705      }
723706
724707      for (int i = 0; i < term_count; i++)
r30664r30665
731714      gabs_t *= 1.0;
732715      if (gabs_t > gtot_t)
733716      {
734          //this->netlist().warning("Falling back to direct solver .. Consider increasing RESCHED_LOOPS");
735717         w[k] = 1.0 / (gtot_t + gabs_t);
736718            one_m_w[k] = 1.0 - 1.0 * gtot_t / (gtot_t + gabs_t);
737719      }
738720      else
739721      {
740         w[k] = 1.0/ gtot_t;
741         one_m_w[k] = 1.0 - 1.0;
722           const double ws = 1.0;
723         w[k] = ws / gtot_t;
724         one_m_w[k] = 1.0 - ws;
742725      }
743726
744727      RHS[k] = RHS_t;
r30664r30665
750733
751734      for (int k = 0; k < iN; k++)
752735      {
753         netlist_analog_net_t &net = *this->m_nets[k];
754         const netlist_terminal_t::list_t &terms = net.m_terms;
736         netlist_analog_net_t & RESTRICT net = *this->m_nets[k].m_net;
737         const netlist_terminal_t::list_t &terms = this->m_nets[k].m_terms;
755738         const int term_count = terms.count();
756739         double Idrive = 0;
757740
758         for (int i = 0; i < term_count; i++)
759                Idrive += terms[i]->m_go * *(terms[i]->m_otherterm_ptr);
741            for (int i = 0; i < term_count; i++)
742                Idrive += terms[i]->m_go * *(terms[i]->m_new_analog_ptr);
760743
761         //double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]);
744            //double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]);
762745         const double new_val = net.m_new_Analog * one_m_w[k] + (Idrive + RHS[k]) * w[k];
763746
764747         const double e = (new_val - net.m_new_Analog);
r30664r30665
786769       this->m_calculations++;
787770
788771       for (int k = 0; k < this->N(); k++)
789           this->m_nets[k]->m_cur_Analog = this->m_nets[k]->m_new_Analog;
772           this->m_nets[k].m_net->m_cur_Analog = this->m_nets[k].m_net->m_new_Analog;
790773
791774       return resched_cnt;
792775   }
trunk/src/emu/netlist/plists.h
r30664r30665
6161   {
6262       if (m_list != NULL)
6363           delete[] m_list;
64       m_list = NULL;
6465   }
6566
6667   ATTR_HOT inline void add(const _ListClass &elem)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team