trunk/src/emu/netlist/analog/nld_solver.c
| r30604 | r30605 | |
| 367 | 367 | //m_A[t.net_other][t.net_this] += -t.term->m_otherterm->m_go; |
| 368 | 368 | } |
| 369 | 369 | else |
| 370 | | RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().Q_Analog(); |
| 370 | RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().as_analog().Q_Analog(); |
| 371 | 371 | } |
| 372 | 372 | #else |
| 373 | 373 | for (int i = 0; i < m_rail_start; i++) |
| r30604 | r30605 | |
| 443 | 443 | const double f1 = A[j][i] * f; |
| 444 | 444 | if (f1 != 0.0) |
| 445 | 445 | { |
| 446 | | for (int k = i; k < kN; k++) |
| 447 | | A[j][k] -= A[i][k] * f1; |
| 448 | | |
| 446 | int k = i; |
| 447 | for (; k < kN - 7 ; k+=8) |
| 448 | { |
| 449 | double * RESTRICT d = &A[j][k]; |
| 450 | double * RESTRICT s = &A[i][k]; |
| 451 | d[0] -= f1 * s[0]; |
| 452 | d[1] -= f1 * s[1]; |
| 453 | d[2] -= f1 * s[2]; |
| 454 | d[3] -= f1 * s[3]; |
| 455 | d[4] -= f1 * s[4]; |
| 456 | d[5] -= f1 * s[5]; |
| 457 | d[6] -= f1 * s[6]; |
| 458 | d[7] -= f1 * s[7]; |
| 459 | } |
| 460 | for (; k < kN; k++) |
| 461 | A[j][k] -= A[i][k] * f1; |
| 449 | 462 | RHS[j] -= RHS[i] * f1; |
| 450 | 463 | } |
| 451 | 464 | } |
| r30604 | r30605 | |
| 583 | 596 | const double d = A[1][1]; |
| 584 | 597 | |
| 585 | 598 | double new_val[2]; |
| 586 | | new_val[1] = a / (a*d - b*c) * (RHS[1] - c / a * RHS[0]); |
| 599 | new_val[1] = a / (a * d - b * c) * (RHS[1] - c / a * RHS[0]); |
| 587 | 600 | new_val[0] = (RHS[0] - b * new_val[1]) / a; |
| 588 | 601 | |
| 589 | 602 | if (is_dynamic()) |
| r30604 | r30605 | |
| 625 | 638 | double gabs_t = 0.0; |
| 626 | 639 | double RHS_t = 0.0; |
| 627 | 640 | |
| 628 | | netlist_analog_net_t *net = this->m_nets[k]; |
| 629 | | const netlist_terminal_t::list_t &terms = net->m_terms; |
| 630 | | const netlist_terminal_t::list_t &rails = net->m_rails; |
| 641 | const netlist_analog_net_t &net = *this->m_nets[k]; |
| 642 | const netlist_terminal_t::list_t &terms = net.m_terms; |
| 643 | const netlist_terminal_t::list_t &rails = net.m_rails; |
| 631 | 644 | const int term_count = terms.count(); |
| 632 | 645 | const int rail_count = rails.count(); |
| 633 | 646 | |
| r30604 | r30605 | |
| 644 | 657 | gtot_t += terms[i]->m_gt; |
| 645 | 658 | gabs_t += fabs(terms[i]->m_go); |
| 646 | 659 | RHS_t += terms[i]->m_Idr; |
| 660 | terms[i]->m_otherterm_ptr = &terms[i]->m_otherterm->net().as_analog().m_new_Analog; |
| 647 | 661 | } |
| 648 | 662 | |
| 649 | 663 | gabs_t *= this->m_params.m_convergence_factor; |
| r30604 | r30605 | |
| 662 | 676 | RHS[k] = RHS_t; |
| 663 | 677 | } |
| 664 | 678 | for (int k = 0; k < this->N(); k++) |
| 679 | { |
| 665 | 680 | this->m_nets[k]->m_new_Analog = this->m_nets[k]->m_cur_Analog; |
| 681 | } |
| 666 | 682 | |
| 667 | 683 | do { |
| 668 | 684 | resched = false; |
| r30604 | r30605 | |
| 670 | 686 | |
| 671 | 687 | for (int k = 0; k < this->N(); k++) |
| 672 | 688 | { |
| 673 | | netlist_analog_net_t *net = this->m_nets[k]; |
| 674 | | const netlist_terminal_t::list_t &terms = net->m_terms; |
| 689 | netlist_analog_net_t &net = *this->m_nets[k]; |
| 690 | const netlist_terminal_t::list_t &terms = net.m_terms; |
| 675 | 691 | const int term_count = terms.count(); |
| 676 | 692 | |
| 677 | | double iIdr = RHS[k]; |
| 693 | double Idrive = RHS[k]; |
| 678 | 694 | |
| 679 | 695 | for (int i = 0; i < term_count; i++) |
| 680 | | { |
| 681 | | iIdr += terms[i]->m_go * terms[i]->m_otherterm->net().as_analog().m_new_Analog; |
| 682 | | } |
| 696 | Idrive += terms[i]->m_go * *(terms[i]->m_otherterm_ptr); |
| 683 | 697 | |
| 684 | 698 | //double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]); |
| 685 | | const double new_val = net->m_new_Analog * one_m_w[k] + iIdr * w[k]; |
| 699 | const double new_val = net.m_new_Analog * one_m_w[k] + Idrive * w[k]; |
| 686 | 700 | |
| 687 | | const double e = (new_val - net->m_new_Analog); |
| 701 | const double e = (new_val - net.m_new_Analog); |
| 688 | 702 | cerr += e * e; |
| 689 | 703 | |
| 690 | | net->m_new_Analog = new_val; |
| 704 | net.m_new_Analog = new_val; |
| 691 | 705 | } |
| 692 | 706 | if (cerr > this->m_params.m_accuracy * this->m_params.m_accuracy) |
| 693 | 707 | { |
| r30604 | r30605 | |
| 729 | 743 | |
| 730 | 744 | register_param("ACCURACY", m_accuracy, 1e-7); |
| 731 | 745 | register_param("CONVERG", m_convergence, 0.3); |
| 732 | | register_param("GS_LOOPS", m_gs_loops, 7); // Gauss-Seidel loops |
| 746 | register_param("GS_LOOPS", m_gs_loops, 5); // Gauss-Seidel loops |
| 733 | 747 | register_param("NR_LOOPS", m_nr_loops, 25); // Newton-Raphson loops |
| 734 | 748 | register_param("PARALLEL", m_parallel, 0); |
| 735 | 749 | register_param("GMIN", m_gmin, NETLIST_GMIN_DEFAULT); |