2 * Copyright (C) 2010 Felix Salfelder
3 * Author: felix@salfelder.org
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "m_divdiff.h"
26 # include <gsl/gsl_fit.h>
32 ''=working; accessed by get.
34 1=old time step. accepted value only
38 /*----------------------------------------------------------------------------*/
39 uint_t
ADP_NODE::order() const{
40 return( min(_order
, CKT_BASE::_sim
->get_tt_order() ) );
41 } // order used for extrapolation.
42 /*----------------------------------------------------------------------------*/
43 //ADP_NODE::ADP_NODE( const ADP_NODE& p ) :
48 // std::cout << "copy?? (should not happen)\n";
53 /*----------------------------------------------------------------------------*/
54 ADP_NODE::ADP_NODE( const std::string n
, const CARD_LIST
* c
):
55 NODE_BASE(n
, unsigned(-1), c
),
66 trace1("ADP_NODE::ADP_NODE ", n
);
71 _positive
= true; //hack
77 ADP_NODE_LIST::adp_node_list
.push_back( this );
79 trace2("ADP_NODE::init", long_label(), _user_number
);
81 // tt_value3=NAN; //FIXME
82 tt_expect
=NAN
; //FIXME
83 tr_value3
=NAN
; //FIXME
85 // _n[n_ic].new_model_node("." + long_label() + ".ic", this);
90 /*----------------------------------------------------------------------------*/
91 //ADP_NODE::ADP_NODE( const COMPONENT* c, const std::string n ) :
98 // trace0("ADP_NODE::ADP_NODE ");
104 /*----------------------------------------------------------------------------*/
105 // ADP_NODE_UDC::ADP_NODE_UDC( const COMPONENT* c ) : ADP_NODE(c, "udc") { }
106 /*----------------------------------------------------------------------------*/
107 // ADP_NODE_RCD::ADP_NODE_RCD( const COMPONENT* c ) : ADP_NODE(c, "rcd"), udc(.2) {}
108 /*----------------------------------------------------------------------------*/
110 void ADP_NODE::init(const COMPONENT
* c
, const std::string name_in
)
113 set_label( c
->long_label() + "." + name_in
);
120 _positive
= true; //hack
130 // _number=_sim->newnode_adp();
131 ADP_NODE_LIST::adp_node_list
.push_back( this );
133 trace2("ADP_NODE::init", long_label(), _user_number
);
135 // tt_value3=NAN; //FIXME
136 tt_expect
=NAN
; //FIXME
137 tr_value3
=NAN
; //FIXME
139 // _n[n_ic].new_model_node("." + long_label() + ".ic", this);
141 /*----------------------------------------------------------------------------*/
142 ADP_NODE::~ADP_NODE(){
144 /*----------------------------------------------------------------------------*/
145 void ADP_NODE::set_tr( hp_float_t x
){
146 if(x
>tr()) _region
= 2;
147 if(x
<tr()) _region
=-2;
148 if(x
==tr()) _region
= 0;
151 /*----------------------------------------------------------------------------*/
152 void ADP_NODE::set_tt( hp_float_t x
)
154 assert(is_number(x
));
155 if( x
<0 && _positive
){
156 error( bDANGER
, "%s, expecting postive tt value, got %E\n", long_label().c_str(), x
);
158 assert(x
>=-1e-19 || !_positive
);
159 assert(m_() != INVALID_NODE
);
160 assert(m_() < _sim
->_adp_nodes
);
162 // _sim->_tt1[m_()] = x;
164 /*----------------------------------------------------------------------------*/
165 double ADP_NODE::State() const
167 // _sim->_tt is state @ begin of frame.
168 // how to avoid trhack?
169 assert(m_() < _sim
->_adp_nodes
);
171 return _sim
->_tt
[m_()] + trhack
;
173 /*----------------------------------------------------------------------------*/
174 hp_float_t
ADP_NODE::get_aft_1() const { return tt1() + _delta
[1] ; }
175 /*----------------------------------------------------------------------------*/
176 double ADP_NODE::tr_duration()const{ return CKT_BASE::_sim
->last_time(); }
177 /*----------------------------------------------------------------------------*/
178 // called right after tr
179 TIME_PAIR
ADP_NODE_RCD::tt_review( ) {
180 unreachable(); // no longer used
181 return TIME_PAIR(0,NEVER
);
183 /*----------------------------------------------------------------------------*/
184 TIME_PAIR
ADP_NODE::tt_preview( ) {
189 /*----------------------------------------------------------------------------*/
190 void ADP_NODE::tr_add( double x
) const {
191 assert(is_number(tr()));
194 /*----------------------------------------------------------------------------*/
196 void ADP_NODE::reset() {
197 trace2( "ADP_NODE::reset()", CKT_BASE::_sim
->_Time0
, tr_value
);
198 std::cout
<< "rst " << label() << "\n";
200 tr_value
= 0; // tt1() = 0; tt() =0;
202 /*----------------------------------------------------------------------------*/
203 double* ADP_NODE::derivatives(double* c
)
206 double Time
[order()+1];
208 case 4: incomplete();
225 ::derivatives(c
, order()+1, Time
);
228 /*----------------------------------------------------------------------------*/
229 void ADP_NODE::tt_accept()
232 // sets t{t,r}_value0 to the accepted values.
233 // should compute new wanted_dT.
235 trace4(("ADP_NODE::tt_accept() " + long_label()).c_str(),
236 tr_value
, tt_value
, CKT_BASE::_sim
->tt_iteration_number(), CKT_BASE::_sim
->get_tt_order());
237 assert( is_number(tr_value
) );
238 assert( CKT_BASE::_sim
->last_time() >0 );
240 uint_t order
= CKT_BASE::_sim
->get_tt_order();
243 // set_order(min(_order+1, order)); hmmm
247 switch (order
) { untested();
250 return tt_accept_first();
253 tr_dd12
= ( tr() - tr1() ) / dT0();
257 tr_dd123
= (tr_dd12
- tr_dd23
)/( dT1() + dT0() );
266 if (_integrator
&& order
){
267 trace0("ADP_NODE::tt_accept reintegration");
268 // tr_value = _delta[0];
270 // tt_value = (this->*_integrator)(_delta[0]);
271 assert( !_positive
|| tt_value
> E_min
);
274 error(bDANGER
, "ADP_NODE::tt_accept overshoot? %f\n", label().c_str(), tt_value
);
281 assert(tt_value
<=1 );
283 // std::cout << "acc after int " << label() << tr_value << "\n";
285 assert( tt_value
== tt_value
);
289 //tt_value += 13; // (printed) output value
290 if (tt_value
<0 && _positive
){
293 // _delta[0] -= tt();
296 trace2(("ADP_NODE::tt_accept" + short_label()).c_str(), tt_value
, tr_value
);
297 trace1(("ADP_NODE::tt_accept done " + short_label()).c_str(), tt());
298 assert(tt() >=0 || !_positive
);
300 if (( dT0() / tr_duration() ) < 1.000000001){
301 trace1(("ADP_NODE::tt_accept" + short_label()).c_str(), dT0() / tr_duration() );
302 trace6(("ADP_NODE::tt_accept" + short_label()).c_str(), tt() ,
303 tt1(), tr(), tt() - tt1() - tr1(), tr1(),
304 ( tt() - tt1() - tr1()) / (tr1() + 1e-10) );
308 /*----------------------------------------------------------------------------*/
309 void ADP_NODE::tt_last( ) {
311 // tt() = tt() + tr(); //FIXME. add tt_keep_values.
312 // if( tt() < 0 && _positive ){ //FIXME. add tt_keep_values.
314 // tt() = 0; //FIXME. add tt_keep_values.
318 /*----------------------------------------------------------------------------*/
320 void ADP_NODE::tt_accept_first( )
324 tt_value
= tt() + tr_value
;
325 assert(tt() >=0 || !_positive
);
328 trace3(("ADP_NODE::tt_accept_first" + short_label()).c_str(),
329 tr_value
,CKT_BASE::_sim
->tt_iteration_number(), tt_value
);
330 assert( tr_value
== tr_value
);
332 assert( CKT_BASE::_sim
->get_tt_order() == 0 );
333 assert( CKT_BASE::_sim
->tt_iteration_number() == 0 );
336 // assert(0 == CKT_BASE::_sim->_dT0);
343 assert(tt_value
== tt_value
);
344 if (_positive
&& tt_value
< 0 ){
346 // assert(tt() >= 0);
348 trace4(("ADP_NODE::tt_accept_first" + short_label()).c_str(),
349 tr_value
,CKT_BASE::_sim
->tt_iteration_number(), tt_value
, tt_value
);
352 /*----------------------------------------------------------------------------*/
353 // stress_last, tt_review, tt_accept, outdata, tt_advance, apply
354 /*----------------------------------------------------------------------------*/
355 void ADP_NODE::tt_advance()
358 _order
= min(_new_order
, CKT_BASE::_sim
->get_tt_order());
360 _order
=CKT_BASE::_sim
->get_tt_order();
365 /*----------------------------------------------------------------------------*/
366 void ADP_NODE::tt_regress()
370 /*----------------------------------------------------------------------------*/
371 hp_float_t
ADP_NODE::get_total() const{
374 /*----------------------------------------------------------------------------*/
375 void ADP_NODE::tr_stress_last( ) { unreachable(); }
376 /*----------------------------------------------------------------------------*/
378 void ADP_NODE::tr_stress_last( double val
) {
380 tr_value
= val
- get();
381 trace3(("ADP_NODE::tr_stress_last" + label()).c_str(), val
, get(), CKT_BASE::_sim
->tt_iteration_number());
382 _delta
[0] = tr_value
; // good idea? no.
384 trace4(("ADP_NODE::tr_stress_last(double) " + short_label()).c_str(),
385 tr_value
,CKT_BASE::_sim
->tt_iteration_number(), val
, get());
387 // std::cout << "ADP_NODE::tr_stress_last " << label() << tr_value << "\n";
392 /*----------------------------------------------------------------------------*/
393 void ADP_NODE::tr_expect_2_avg(){
396 _delta_expect
= (_delta
[2]+_delta
[1])/2.0;
397 tt_expect
= tt_integrate_2_linear(_delta_expect
);
399 /*----------------------------------------------------------------------------*/
400 double ADP_NODE::tt_integrate_2_linear(double tr_
){
401 incomplete(); // regression?
402 hp_float_t delta
= (_delta
[1] + tr_
)/2 * ( dT0() / tr_duration() -1 );
403 double ret
= get_aft_1() + delta
; // RET
407 trace6(( "ADP_NODE::tt_integrate_2_linear "+short_label()).c_str(), get_tr(),
408 get1(), ret
, delta
, tr_
, tr_duration() );
411 if (ret
< -1e-10 && _positive
){
412 unsigned order
= CKT_BASE::_sim
->get_tt_order();
413 error(bDANGER
, "* ADP_NODE::tt_integrate_2_linear neg step %i, Time0=%f (%f,%f,%f), %s, tt_value = %g, ( %g, %g; %g) %i tt: %f, expecting %f\n", \
414 CKT_BASE::_sim
->tt_iteration_number(),
415 CKT_BASE::_sim
->_Time0
, dT0(), Time_delta(), dT1(),
416 short_label().c_str(), tt_value
,
417 _delta
[2], _delta
[1], tr_
,
423 if (ret
< 0 && _positive
) ret
=0;
424 _integrator
= &ADP_NODE::tt_integrate_2_linear
;
427 /*---------------------------------*/
428 void ADP_NODE::tr_expect_2_linear(){
430 trace4(( "ADP_NODE::tt_expect_2_linear " + short_label()).c_str(),
431 tr_value
, tr(), tr1(), tr2() );
432 trace3(( "ADP_NODE::tt_expect_2_linear " + short_label()).c_str(), Time_delta(), get1(), dT1() );
433 // _delta_expect = fabs( (_delta[1]) + ( (_delta[1]) - (_delta[2])) * (hp_float_t) ((Time_delta() )/dT1()));
435 // expected tr for time0
436 _delta_expect
= ( tr1() + ( (tr1()) - (tr2())) * (hp_float_t
) ((Time_delta() )/dT1()));
439 if(_delta_expect
!= _delta_expect
) assert(false);
440 if(tr1() != tr1()) assert(false);
442 // tt_expect = tt_integrate_2_linear(_delta_expect);
444 if (tt_expect
< -1e-10 && _positive
){
445 unsigned order
= CKT_BASE::_sim
->get_tt_order();
446 error(bDANGER
, "* ADP_NODE::tt_expect_2_linear neg step %i, Time0=%f (%f,%f,%f), %s, tt_value = %g, ( %g, %g; %g) %i tt: %f, expecting %f\n", \
447 CKT_BASE::_sim
->tt_iteration_number(),
448 CKT_BASE::_sim
->_Time0
, dT0(), Time_delta(), dT1(),
449 short_label().c_str(), tt_value
,
450 tr2(), tr1(), _delta_expect
,
456 if (tt_expect
< 0 && _positive
) tt_expect
=0;
458 _corrector
= NULL
; // &ADP_NODE::tr_correct_1_exp; // HACK. ouch. move to ADP_EXP
461 // _integrator = &ADP_NODE::tt_integrate_2_linear;
463 /*---------------------------------*/
464 // 3 points denoising expect
465 void ADP_NODE::tr_expect_3_linear(){
467 trace4(( "ADP_NODE::tt_expect3_linear " + short_label()).c_str(), tr_value
, _delta
[0], _delta
[1], _delta
[2] );
468 trace3(( "ADP_NODE::tt_expect3_linear " + short_label()).c_str(), Time_delta(), get1(), dT1() );
469 // tr_expect = fabs( (_delta[1]) + ( (_delta[1]) - (_delta[2])) * (hp_float_t) ((Time_delta() )/dT1()));
472 hp_float_t t1
= dT2();
473 hp_float_t t2
= dT1()+dT2();
474 hp_float_t t3
= dT0()+dT1()+dT2();
476 // expected tr for time0
478 const double x
[3]={0, t1
, t2
};
479 const double y
[3]={tr_value3
, _delta
[2], _delta
[1]};
482 double cov00
, cov01
, cov11
, sumsq
;
483 #ifdef HAVE_GSL_FIT_H
484 gsl_fit_linear( x
, 1, y
, 1, 3, &c0
, &c1
, &cov00
, &cov01
, &cov11
, &sumsq
);
486 USE(x
); USE(y
); USE(cov00
); USE(cov01
); USE(cov11
); USE(sumsq
);
487 incomplete(); untested();
490 _delta_expect
= c0
+ c1
* t3
;
492 if(_delta_expect
!= _delta_expect
) _delta_expect
=0;
493 if(_delta
[1] != _delta
[1]) assert(false);
495 hp_float_t diff
= (_delta
[1] + _delta_expect
)/2 * Time_delta() / tr_duration();
496 tt_expect
= get1() + diff
;
497 assert (tt_expect
== tt_expect
);
499 trace6(( "ADP_NODE::tt_expect3_linear "+short_label()).c_str(), get_tr(),
500 get1(), tt_expect
, diff
, _delta_expect
, tr_duration() );
504 unsigned order
= CKT_BASE::_sim
->get_tt_order();
505 error(bDANGER
, "* ADP_NODE::tt_expect3_linear neg error step %i, Time0=%f \
506 * (%f,%f,%f), %s, tt_value = %g, ( %g, %g, %g)-> %g -- %i tt: %f, \
508 CKT_BASE::_sim
->tt_iteration_number(),
509 CKT_BASE::_sim
->_Time0
, dT0(), dT1(), dT2(),
510 short_label().c_str(),
511 tt_value
, tr_value3
, _delta
[2], _delta
[1], _delta_expect
,
518 /*---------------------------------*/
519 /*---------------------------------*/
521 void ADP_NODE::tr_expect_2_square(){
523 _delta_expect
= square( sqrt(_delta
[1]) + ( sqrt(_delta
[1]) - sqrt(_delta
[2])) * (hp_float_t
) ((Time_delta() )/dT1()));
525 /*---------------------------------*/
526 double foo(double x
){
529 return (1-x
/2 + 11/24*x
*x
-7/16*x
*x
*x
)*exp(1);
530 return pow((1+x
),(1/x
));
533 /*----------------------------------------------------------------------*/
534 double my_log(double x
){
535 if(x
>0) return log(x
);
539 double ADP_NODE::tt_integrate_2_linear2(double tr_
) {
540 trace2("ADP_NODE::tt_integrate_2_exp", _delta
[1], tr_
);
541 trace2("ADP_NODE::tt_integrate_2_exp", _delta
[1], _sign
);
542 hp_float_t h
= tr_duration();
545 double del1
= _delta
[1];
547 double x
= (del0
- del1
) / 2;
548 double delta
= (_delta
[1] + tr_
)/2 * dT0()/h
+ x
;
550 if (delta
!= delta
|| delta
==-inf
|| delta
==inf
){
551 delta
= (tr_
+ _delta
[1])/2 * (dT0()-h
) / h
;
552 incomplete(); // call another thing.
555 assert(delta
!= -inf
);
556 assert(delta
!= inf
);
558 double ret
= get_aft_1() + _sign
* delta
; // RET
560 trace5(( "ADP_NODE::tt_integrate_2_exp "+short_label()).c_str(),
561 _delta
[2], _delta
[1], tr_
, tt_expect
, delta
);
564 _integrator
= &ADP_NODE::tt_integrate_2_linear2
;
567 /*----------------------------------------------------------------------*/
568 void ADP_NODE::tr_expect_3_exp(){
572 if ( ( _delta
[2] > 0 && _delta
[1] > 0 && _delta
[1] < _delta
[2] && tr_value3
< _delta
[2] )
573 || ( _delta
[2] < 0 && _delta
[1] < 0 && _delta
[1] > _delta
[2] && tr_value3
> _delta
[2] ) ){
575 return tr_expect_2_exp();
578 if (_delta
[1] < 0 && _delta
[2] < 0 && tr_value3
<0){
580 } else if ( ! (_delta
[1] > 0 && _delta
[2] > 0 && tr_value3
>0) ){
581 return tr_expect_3_linear();
584 if ( tr_value3
> _delta
[2] && _delta
[2] > _delta
[1] ){
588 double ln3
= log(_sign
* tr_value3
/tr_duration());
589 double ln2
= log(_sign
* _delta
[2]/tr_duration());
590 double ln1
= log(_sign
* _delta
[1]/tr_duration());
592 hp_float_t tdh
=tr_duration()/2;
595 hp_float_t t2
= t3
+dT2();
596 hp_float_t t1
= t2
+dT1();
598 hp_float_t x
= dT2()+dT1()+dT0()+tdh
;
601 // exponent= ax^2 + bx + c
605 ln0
+= (ln2
-ln3
) * ( x
- t3
) / (t2
-t3
);
606 ln0
+= (ln1
- ln3
- ( ln2
- ln3
) * (t1
-t3
)/ (t2
-t3
) ) * (x
-t3
) * ( x
-t2
) / (t1
-t3
) / (t1
-t3
);
609 // int_0^x exp( ln1 + t/dT0*(ln0-ln1) ) @ x=dT0
610 _delta_expect
= _sign
*exp(ln0
) * tr_duration();
611 _corrector
= &ADP_NODE::tr_correct_3_exp
;
612 tt_expect
= tt_integrate_2_exp(_delta_expect
); // 3 doesnt make sense yet?
614 /*----------------------------------------------------------------------*/
615 double ADP_NODE::tr_correct_3_exp()
617 trace0(("ADP_NODE::tr_correct_3_exp correction " + label()).c_str());
618 return (tr_value
+_delta_expect
)/2;
620 /*----------------------------------------------------------------------*/
621 double ADP_NODE::tr_correct_generic()
624 trace0(("ADP_NODE::tr_correct_generic correction " + label()).c_str());
625 return (tr_value
+_delta_expect
)/2;
627 /*----------------------------------------------------------------------*/
628 double ADP_NODE::tt_integrate_3_exp(double tr_
)
631 // hp_float_t sign=1;
632 double h
=tr_duration();
634 if ( ( _delta
[2] > 0 && _delta
[1] > 0 && _delta
[1] < _delta
[2] && tr_value3
< _delta
[2] )
635 || ( _delta
[2] < 0 && _delta
[1] < 0 && _delta
[1] > _delta
[2] && tr_value3
> _delta
[2] ) ){
638 //return tr_expect_2_exp();
641 if (_delta
[1] < 0 && _delta
[2] < 0 && tr_value3
<0){
643 } else if ( ! (_delta
[1] > 0 && _delta
[2] > 0 && tr_value3
>0) ){
646 // return tr_expect_3_linear();
649 if ( tr_value3
> _delta
[2] && _delta
[2] > _delta
[1] ){
652 double ln1
= log(_sign
*_delta
[1]/tr_duration());
653 double ln0
= log(_sign
*tr_
/tr_duration());
655 hp_float_t delta
= _sign
* (exp( ln1
+ (ln0
-ln1
) ) - (_sign
*_delta
[1]/tr_duration()) )/(ln0
-ln1
)* dT0();
657 if (delta
!= delta
|| delta
==inf
|| delta
==-inf
){
659 // fixme: cll anothert integrator.
660 hp_float_t delta_trapez
= (_delta
[1] + tr_
)/2 * ( dT0()-h
) / tr_duration() ;
661 trace2("ADP_NODE::tt_expect3_exp fallback to delta_trapez", delta_trapez
, delta
);
664 _integrator
= &ADP_NODE::tt_integrate_1_const
;
665 return( get1() + delta_trapez
);
668 tt_value
= get1() + delta
* _sign
;
669 assert(tt_value
== tt_value
);
670 assert(tt_value
>=0 || !_positive
);
672 _integrator
= &ADP_NODE::tt_integrate_3_exp
;
675 /*----------------------------------------------------------------------*/
676 void ADP_NODE::tr_expect_3_exp_fit(){
680 if ( ( _delta
[2] > 0 && _delta
[1] > 0 && _delta
[1] < _delta
[2] && tr_value3
< _delta
[2] )
681 || ( _delta
[2] < 0 && _delta
[1] < 0 && _delta
[1] > _delta
[2] && tr_value3
> _delta
[2] ) ){
683 return tr_expect_2_exp();
686 if (_delta
[1] < 0 && _delta
[2] < 0 && tr_value3
<0){
688 } else if ( ! (_delta
[1] > 0 && _delta
[2] > 0 && tr_value3
>0) ){
689 return tr_expect_3_linear();
692 if ( tr_value3
> _delta
[2] && _delta
[2] > _delta
[1] ){
695 hp_float_t f0
= sign
*tr_value3
;
696 hp_float_t f1
= sign
*_delta
[2];
697 hp_float_t f2
= sign
*_delta
[1];
699 hp_float_t t1
= dT2();
700 hp_float_t t2
= dT1()+dT2();
701 hp_float_t t3
= dT0()+dT1()+dT2();
703 hp_float_t a
= ( (log(f0
) + log(f1
) + log(f2
)) * ( t1
*t1
+ t2
*t2
) - (t1
+ t2
) * ( t1
*log(f1
) + t2
*log(f2
) ) ) /
704 (3 * ( t1
*t1
+ t2
*t2
) - (t1
+t2
)*(t1
+t2
) );
705 hp_float_t alpha
= ( 3*( t1
*log(f1
) + t2
*log(f2
)) - (t1
+ t2
) * ( log(f0
)+log(f1
) +log(f2
) ) ) /
706 (3 * ( t1
*t1
+ t2
*t2
) - (t1
+t2
)*(t1
+t2
) );
709 if (alpha
!= alpha
) {
711 return tr_expect_2_linear();
717 _delta_expect
= sign
*c
* exp(alpha
*t3
);
719 trace6(( "ADP_NODE::tt_expect3_exp() "+short_label()).c_str(), Time0(), tr_value3
, _delta
[2], _delta
[1], get1(), _delta_expect
);
720 assert( _delta_expect
== _delta_expect
);
722 hp_float_t E
= - c
/alpha
;
723 hp_float_t delta
= E
* ( - exp( t3
*alpha
) + exp(t2
*alpha
) )/ CKT_BASE::_sim
->last_time() ;
724 hp_float_t delta_trapez
= (_delta
[1] + _delta_expect
)/2 * Time_delta() / CKT_BASE::_sim
->last_time();
726 trace4("ADP_NODE::tt_expect3_exp", delta
, delta_trapez
, tt1(), get() );
727 tt_expect
= get1() + sign
* delta
;
729 if ( tt_expect
!= tt_expect
){
730 std::cerr
<< "tt_expect is broken:\n"
733 << "alpha=" << alpha
<< "\n"
734 << "( 0.0, " << f0
<<" )\n"
735 << "( " << t1
<< ", " << f1
<<" )\n"
736 << "( " << t2
<< ", " << f2
<<" )\n"
737 << "( " << t3
<< ", ? )\n";
739 return tr_expect_2_linear();
742 if (tt_expect
< -1e-8 && _positive
){
743 error(bDANGER
, "* ADP_NODE::tt_expect3_exp neg error step %i, Time0=%f, %s,"
744 " tt_value = %g, ( %g, %g, %g; %g) tte: %g \n", \
745 CKT_BASE::_sim
->tt_iteration_number(),
746 dT0(), short_label().c_str(), tt_value
,
747 tr_value3
, _delta
[2], _delta
[1], _delta_expect
,
754 if ( f0
<0 && f1
<0 && f2
<0)
755 assert (_delta_expect
<= 0);
758 /*---------------------------------*/
759 void ADP_NODE::tr_expect_3_quadratic(){
762 trace3(( "ADP_NODE::tr_expect_3_quadratic() "+short_label()).c_str(), tr_value3
, _delta
[2], _delta
[1] );
763 // uses 1 2 3 to set expect.
764 assert( tr_dd12
== ( _delta
[1] - _delta
[2] ) / dT1());
765 hp_float_t sum
= dT0() + dT1() + dT2();
766 hp_float_t tr_expect_kaputt
;
768 // doch nicht kaputt.
769 tr_expect_kaputt
= ( \
770 sum
* ( _delta
[1] + tr_dd12
* dT0() ) \
771 - dT0() * (( - dT1()* tr_dd12
+ _delta
[1] ) + (dT0()+dT1()) * ( tr_dd12
+ tr_dd123
* ( -dT2()-dT1() ) ) ) \
773 USE(tr_expect_kaputt
);
776 _delta_expect
= -(((_delta
[2] - tr_value3
)/dT2() - (_delta
[1] - _delta
[2])/dT1())*(dT0() + dT1())/(dT1() + dT2()) -
777 (_delta
[2] - tr_value3
)/dT2())*(dT0() + dT1() + dT2()) + tr_value3
;
779 hp_float_t diff
= (_delta
[1] + _delta_expect
)/2 * Time_delta() / CKT_BASE::_sim
->last_time();
780 tt_expect
= get() + diff
;
781 assert (tt_expect
== tt_expect
);
783 /*--------------------------------------------------------------------------*/
784 // evaluate tt at Time0 using parabola through tt1, tr1 and tr0
785 double ADP_NODE::tt_integrate_2_poly(double offset
) const
788 trace5("integrate_2_poly", tr1(), tr2(), dT1(), dT0(), tt1());
789 double a
= .5*(tr1() - tr2()) / dT1();
791 double T
= dT0() - offset
;
792 // hack. _dTmin is (fixed) period width.
793 // tt1() is at end of period(!)
803 /*--------------------------------------------------------------------------*/
804 double ADP_NODE::tt_integrate_3_poly() const
808 trace3("integrate_3_poly", tr1(), tr2(), tr3());
809 trace4("integrate_3_poly", tt1(), dT0(), dT1(), dT2());
810 double tr_dd12
= ( tr1() - tr2() ) / dT1();
811 double tr_dd23
= ( tr2() - tr3() ) / dT2();
812 double tr_dd123
= (tr_dd12
- tr_dd23
)/( dT1() + dT2() );
813 double sum
= dT0() + dT1() + dT2();
816 integral
= tt1() + ( \
817 sum
* ( tr1() + tr_dd12
* dT0() ) \
818 - dT0() * (( - dT1()* tr_dd12
+ tr1() ) + (dT0()+dT1()) * ( tr_dd12
+ tr_dd123
* ( -dT2()-dT1() ) ) ) \
822 assert(is_number(integral
));
825 /*--------------------------------------------------------------------------*/
826 double ADP_NODE::debug(){
829 /*---------------------------------*/
830 void ADP_NODE::tr_expect_2_something(){
832 _delta_expect
= _delta
[1] + (_delta
[1] - _delta
[2]) * dT0()/dT1();
833 tt_expect
= get1() + ( Time_delta() ) / CKT_BASE::_sim
->last_time();
834 trace2(( "ADP_NODE::tt_expect2_something "+short_label()).c_str(), get1(), tt_expect
);
836 /*---------------------------------*/
837 void ADP_NODE::tr_expect_1_const(){
839 trace2(( "ADP_NODE::tt_expect_1_const() "+short_label()).c_str(),
841 trace3(( "ADP_NODE::tt_expect_1_const() "+short_label()).c_str(),
842 Time_delta(), CKT_BASE::_sim
->_time0
, CKT_BASE::_sim
->last_time() );
845 // _corrector = &ADP_NODE::tr_correct_1_const;
846 // tr() = tt_integrate_1_const(_delta_expect);
849 assert (!_positive
|| tt_expect
>=0);
851 /*---------------------------------*/
852 double ADP_NODE::tt_integrate_1_exp( double tr_
){
853 // FIXME implement quadratic model
854 return( tt_integrate_1_const(tr_
) );
856 /*---------------------------------*/
857 double ADP_NODE::tt_integrate_1_const( double tr_
){
860 double delta
= ( tr1() + tr_
)/2 * (dT0() / tr_duration() - 1) ;
861 // double ret = tt1() + delta + tr_; // RET
863 long double ret
= get_aft_1() + delta
; // RET
865 trace5(("ADP_NODE::tt_integrate_1_const" + label()).c_str(), tt1(),
866 delta
, tr_
, ret
, dT0() / tr_duration());
867 trace1(("ADP_NODE::tt_integrate_1_const" + label()).c_str(),tr_noise
);
868 // trace1("ADP_NODE::tt_integrate_1_const", tt());
870 if (ret
< 0 && _positive
){
871 error(bDANGER
, "* ADP_NODE::tt_integrate_1_const neg error step %i,"
872 " Time0=%f (%f), %s, tt_value = %g, ( %g, %g) \n",
873 CKT_BASE::_sim
->tt_iteration_number(),
874 CKT_BASE::_sim
->_Time0
, dT0(),
875 short_label().c_str(), tt_expect
,
876 _delta
[0], _delta
[1]);
881 if (_delta
[1] < 0 && tr_
< 0 ){
885 _integrator
= &ADP_NODE::tt_integrate_1_const
;
886 assert (!_positive
|| ret
>=0);
887 return( (double) ret
);
889 /*---------------------------------*/
890 double ADP_NODE::tr_correct_1_const(){
891 trace0(("ADP_NODE::tr_correct_1_const correction " + label()).c_str());
892 return (_delta_expect
+ tr_value
)/2;
894 /*---------------------------------*/
895 double ADP_NODE::tt_integrate_( double ){
896 // take order and tr_value
897 // integrate things. write to tt_value.
900 /*---------------------------------*/
901 /*----------------------------------------------------------------------------*/
903 void ADP_NODE::tt_commit_first( )
905 trace2(("ADP_NODE::tt_commit_first() " + short_label()).c_str(), tt(), tr());
910 tt_first_time
= CKT_BASE::_sim
->_Time0
;
911 assert(_delta_expect
!= HUGE_VAL
);
913 /*---------------------------------*/
914 void ADP_NODE::tt_commit( )
917 // called before CARD_LIST apply...
918 // extrapolates tr values for guessed dT0
925 trace3(( "ADP_NODE::tt_commit "+short_label()).c_str(), tt_value
, tr(),
926 CKT_BASE::_sim
->tt_iteration_number() );
927 trace6(("ADP_NODE::tt_commit " + short_label()).c_str(),
929 CKT_BASE::_sim
->get_tt_order(),
930 CKT_BASE::_sim
->_Time0
,
934 // sets _delta_expect and tt_expect
935 if(!is_number( tr1()) && CKT_BASE::_sim
->tt_iteration_number()>=2 )
937 error(bDANGER
,"ADP_NODE::tt_commit history broken %s, %i, step %i\n", long_label().c_str(), m_(), _sim
->tt_iteration_number());
938 assert( is_number( tr1()) || CKT_BASE::_sim
->tt_iteration_number()<2 );
943 // this is before sweep....
944 assert( CKT_BASE::_sim
->last_time() >0 );
945 assert( tt_value
== tt_value
);
946 assert( tt_value
>=0 || !_positive
);
947 // tr_value will be printed as "tr"
949 if (tt_expect
< -1e-8 ){
951 error(bDANGER
, "* ADP_NODE::tt_commit neg error step %i, order %i, tt_expect=%e\n", \
952 CKT_BASE::_sim
->tt_iteration_number(), _order
,tt_expect
);
955 /*---------------------------------*/
956 // tr relative to Time1
957 hp_float_t
ADP_NODE::tr_rel( double dT
) const{
958 long double now_rel
= dT
;
961 case 0: // transient sim
962 if(_sim
->analysis_is_tran() ){
970 trace1("ADP_NODE::tr 2", now_rel
/ dT1());
971 return tr1() + ( tr1() - tr2()) * double ((now_rel
)/(long double) dT1());
973 return -(((tr2() - tr3())/dT2() - (tr1() - tr2())/dT1())*(hp_float_t(now_rel
) + dT1())/(dT1() + dT2()) -
974 (tr2() - tr3())/dT2())*(hp_float_t(now_rel
) + dT1() + dT2()) + tr3();
980 /*---------------------------------*/
981 // evaluate parabola through (y1-dy1-dy2, x3), (y1-dy1,x2) , (y1,x1) at y
982 static double interpoly2(double x3
, double x2
, double x1
, double dy2
, double dy1
, double y1
, double y
)
987 return -(((x2
- x3
)/dy2
- (x1
- x2
)/dy1
)*((rel
) + dy1
)/(dy1
+ dy2
) -
988 (x2
- x3
)/dy2
)*(rel
+ dy1
+ dy2
) + x3
;
992 // 0 during 1st timeframe
993 // 1 during 2nd timeframe.
994 double ADP_NODE::tr(double Time
, const double* guess
)const
996 long double Time1
= Time0() - dT0();
997 long double now_rel
= Time
- Time1
; // dT0, in case Time=Time0;
1001 case 0: untested(); unreachable();
1002 assert( _sim
->analysis_is_tran() );
1005 return tr1() + ( *guess
- tr1()) * double((now_rel
)/(long double) dT0());
1006 case 2: incomplete();
1007 // return interpoly3
1016 assert( _sim
->analysis_is_tran() );
1019 assert(is_number(tr1()));
1022 trace1("ADP_NODE::tr 2", now_rel
/ dT1());
1023 return tr1() + ( tr1() - tr2()) * double((now_rel
)/(long double) dT1());
1025 return -(((tr2() - tr3())/dT2() - (tr1() - tr2())/dT1())*(double(now_rel
) + dT1())/(dT1() + dT2()) -
1026 (tr2() - tr3())/dT2())*double((now_rel
) + dT1() + dT2()) + tr3();
1027 return interpoly2(tr3(), tr2(), tr1(), dT2(), dT1(), (double) Time1
, (double)Time
);
1028 default: unreachable();
1032 /*---------------------------------*/
1033 void ADP_NODE::tr_expect_()
1037 _order
= min(_order
+1,CKT_BASE::_sim
->get_tt_order());
1039 trace2("ADP_NODE::tr_expect_", _order
, CKT_BASE::_sim
->tt_iteration_number());
1040 trace4("ADP_NODE::tr_expect_ ", _sim
->_Time0
, tr(_sim
->_Time0
), tr1(), tr2() );
1041 assert(_order
<= CKT_BASE::_sim
->tt_iteration_number());
1042 assert ( isnan(tr()) || order()==0 );
1046 trace0("ADP_NODE::tr_expect_, not doing anything");
1049 trace3(("ADP_NODE::tr_expect_ extradebug" + long_label()).c_str(), tr2(), tr1(), tr(Time0()) );
1050 if ( fabs(tr2()-tr_rel(-dT1())) > 1e-6 && !(is_almost(tr2(), tr(Time2())))){
1051 error( bDANGER
, "ADP_NODE::tr_expect_ tt_iteration_number %i\n", tt_iteration_number());
1052 error( bDANGER
, "ADP_NODE::tr_expect_ mismatch, T0: %.20E, T1 %.20E, Time2 %.20E\n", Time0(), Time1(), Time2());
1053 error( bDANGER
, "ADP_NODE::tr_expect_ mismatch dT1() %E dT0() %E\n", dT1(), dT0() );
1054 error( bDANGER
, "ADP_NODE::tr_expect_ mismatch, tr1: %E, tr2: %E d %E \n", tr1(), tr2(), tr1()-tr2() );
1055 error( bDANGER
, "ADP_NODE::tr_expect_ mismatch, tr2():tr(Time2()=%E))= %E : %E\n", Time2(), tr2(), tr(Time2()) );
1056 error( bDANGER
, "ADP_NODE::tr_expect_ delta, tr2()-tr(Time2()))= %E\n", tr2()- tr(Time2()) );
1057 error( bDANGER
, "ADP_NODE::tr_expect_ mismatch in %s\n", long_label().c_str() );
1059 throw(Exception(" mismatch " + long_label()));
1063 if (! is_almost(tr1(), tr(Time1()))) {
1064 error( bDANGER
, "ADP_NODE::tr_sanity check failed %1.19g %1.19g \n",tr1(),tr(Time1()));
1067 // assert(is_almost(tr1(), tr(Time1())));
1068 //tr()=tr(_sim->_Time0);
1073 // FIXME assert( tr_dd12 == ( _delta[1] - _delta[2] ) / dT1());
1074 tr_dd12
= ( tr1() - tr2() ) / dT1();
1075 tr()=tr(_sim
->_Time0
);
1081 trace6( "ADP_NODE::tr_expect_ done ", tr1(), _delta_expect
, _order
,
1082 tt(), tt1(), _user_number
);
1083 assert(tt1() >=0 || !_positive
);
1085 // assert(is_number(_tt[0]));
1087 // return _delta_expect;
1088 // tt_value << " " << get1() << " order " << _order << " val1 " <<
1090 // "ttex " << tt_expect << "\n";
1092 /*-----------------------------------------*/
1093 int ADP_NODE::region() const{
1096 /*-----------------------------------------*/
1097 void ADP_NODE::tr_expect_1_exp(){
1101 if(_delta
[1] < 0) _sign
=-1;
1102 trace3(( "ADP_NODE::tt_expect_1_exp() "+short_label()).c_str(),
1103 tr_value
, _delta
[0], _delta
[1] );
1104 trace3(( "ADP_NODE::tt_expect_1_exp() "+short_label()).c_str(),
1105 Time_delta(), CKT_BASE::_sim
->_time0
, CKT_BASE::_sim
->last_time() );
1107 _delta_expect
= _delta
[1];
1108 assert (_delta_expect
< 0.1);
1110 _corrector
= &ADP_NODE::tr_correct_1_exp
;
1111 tt_expect
= tt_integrate_1_const(_delta_expect
);
1113 _integrator
= &ADP_NODE::tt_integrate_1_exp
;
1115 /*---------------------------------*/
1116 void ADP_NODE::tr_expect_2_exp(){
1117 trace2("ADP_NODE::tr_expect_2_exp()", _delta
[1], _delta
[2]);
1118 double h
= tr_duration();
1120 assert( order() == 2 );
1121 assert( is_number(_delta
[1]) );
1122 assert( is_number(_delta
[2]) );
1124 if (_delta
[1] <= 0 && _delta
[2] < 0 ){
1128 // need total ordering.
1129 if ( !( ( _delta
[2] <= _delta
[1] && _delta
[1] <= 0)
1130 || ( _delta
[2] >= _delta
[1] && _delta
[1] >= 0))){
1132 trace2(("ADP_NODE::tr_expect_2_exp no total ord linear... " +
1133 short_label()).c_str(), _delta
[2], _delta
[1]);
1136 // tr_expect_2_linear();
1139 _corrector
= &ADP_NODE::tr_correct_1_exp
;
1142 if ( fabs(_delta
[1] - _delta
[2]) < tr_noise
){
1143 trace3(("ADP_NODE::tr_expect_2_exp just noise " +
1144 short_label()).c_str(), _delta
[2], _delta
[1], tr_noise
);
1148 // _corrector = &ADP_NODE::tr_correct_1_exp;
1151 //hp_float_t t2 = tr_duration()/2;
1152 //hp_float_t t1 = t2+dT1();
1153 //dashier geht nicht. kleine schritte zu schlecht.
1154 double d1
= _delta
[1];
1155 double d2
= _delta
[2];
1159 // double alpha = - log ( d2/d1 ) / dT1();
1161 //d1=_der_aft[1]; // dashier muesste man noch ausrechnen.
1164 // expect using deltas as derivatives.
1169 // alpha = - log ( d2/d1 ) / dT1();
1170 double q
= ( d1
/d2
) ;
1172 if ( _sign
*d1
<= _sign
*d2
&& q
!= q
) q
=1;
1174 //expect using deltas.
1178 // _delta_expect = pow(d1,((dT0() + dT1())/dT1())) / pow(d2,(dT0()/dT1()))*h;
1180 _delta_expect
= pow(q
, (dT0()/dT1()))*d1
*h
;
1182 trace6("ADP_NODE::tr_expect_2_exp", _delta_expect
- _delta
[1], _der_aft
[2], _der_aft
[1],
1183 _delta
[1], _delta
[2], dT0());
1184 trace6("ADP_NODE::tr_expect_2_exp", _delta_expect
, _der_aft
[2], _der_aft
[1],
1185 _delta
[1] - _delta
[2], _delta_expect
, _sign
);
1186 //trace6("ADP_NODE::tr_expect_2_exp", _delta[1], _delta[2], _delta_expect, p, r, q);
1188 assert(_delta_expect
== _delta_expect
);
1189 assert(_delta_expect
< 1e6
);
1190 _corrector
= &ADP_NODE::tr_correct_1_exp
;
1191 assert (_sign
*_delta
[1] >= 0 );
1193 assert( 1e-15 >= _sign
*(_delta_expect
- _delta
[1]) );
1195 tt_expect
= tt_integrate_2_exp(_delta_expect
);
1197 /*---------------------------------*/
1198 double ADP_NODE::tr_correct_1_exp(){
1201 trace0(("ADP_NODE::tr_correct_1_exp correction " + label()).c_str());
1203 double new_delta
; // return value. new value for tr_value.
1204 double h
= tr_duration();
1206 //assert(tt1() == tt1());
1208 long double a
= _delta
[1];
1209 //long double c = tr_value;
1210 long double b
= tt_expect
;
1211 long double d
= tt1();
1212 long double dT
= dT0();
1214 trace4(("ADP_NODE::tr_correct_1_exp, _der_aft? " + label()).c_str(),
1215 _delta
[1], tt_expect
, tr_value
, tt1() );
1217 //model value as (does it make sense?)
1218 /// t \mapsto K* ( 1- exp (tau*t) )+ d
1219 // long double K = (b-d)/(c/a-1);
1220 // long double tau = log((c-a)/(b-d) + 1) / h;
1222 //_delta_expect = K *(- exp(tau* (dT0()+h) ) + exp ((tau*dT0())) );
1224 // a*(a - b - c + d)^(dT0/h)/(-b + d)^(dT0/h)
1227 long double d_b
= d
-b
;
1228 long double a_c
= _delta
[1] - tr_value
;
1231 if ( fabs ( a_c
) < tr_noise
) {
1232 trace2("ADP_NODE::tr_correct_1_exp ", a_c
, tr_noise
);
1233 _integrator
=&ADP_NODE::tt_integrate_1_const
;
1234 return(tr_value
+ _delta
[1])/2;
1237 if ( fabs ( d_b
) < 1e-20 ) {
1238 trace6("ADP_NODE::tr_correct_1_exp ", _delta
[1], tr_value
, tt1(),
1239 tt_expect
, 1e-13, fabs ( d_b
/ (fabs(d
)+fabs(b
))));
1240 _integrator
=&ADP_NODE::tt_integrate_1_const
;
1241 return(tr_value
+ _delta
[1])/2;
1243 if ( ( fabs ( d_b
) / (fabs(d
)+fabs(b
) ) < 1e-13 ) ) {
1244 trace6("ADP_NODE::tr_correct_1_exp ", _delta
[1], tr_value
, tt1(),
1245 tt_expect
, 1e-13, fabs ( d_b
/ (fabs(d
)+fabs(b
))));
1246 _integrator
=&ADP_NODE::tt_integrate_1_const
;
1247 return(tr_value
+ _delta
[1])/2;
1249 long double B
= (1 + (a_c
)/(d_b
));
1250 long double gain
= ( dT
/h
);
1251 assert(is_number(gain
));
1257 long double P
= pow(B
,gain
);
1259 if ( !is_number((double)P
) ) {
1260 trace0("ADP_NODE::tr_correct_1_exp P is not number. probably just noise");
1261 return(tr_value
+ _delta
[1])/2;
1264 // new_delta = (double)( a*pow((a - c + d-b)/(d-b),(dT/h)) );
1265 new_delta
= (double)( a
*P
);
1267 trace6(("ADP_NODE::tr_correct_1_exp, " + label()).c_str(), \
1268 a
, tr_value
, P
, dT0(), B
, gain
);
1269 trace6(("ADP_NODE::tr_correct_1_exp, " + label()).c_str(), tt_expect
,
1270 tt1(), tt_value
, _delta
[1], tr_value
, new_delta
);
1271 trace4( "ADP_NODE::tr_correct_1_exp " , CKT_BASE::_sim
->tt_iteration_number(), d_b
, a_c
,
1272 CKT_BASE::_sim
->_dT0
/CKT_BASE::_sim
->_dTmin
);
1274 assert(is_number(B
));
1275 assert(is_number(P
));
1276 assert(is_number(new_delta
));
1277 assert(new_delta
* _delta
[1] >= 0);
1278 assert(new_delta
<1);
1280 if( (_delta
[1] >= new_delta
&& new_delta
>= 0)
1281 || (_delta
[1] <= new_delta
&& new_delta
<= 0)){
1283 _integrator
=&ADP_NODE::tt_integrate_1_const
;
1288 /*----------------------------------------------------------------------*/
1289 double ADP_NODE::tt_integrate_2_exp(double tr_
) {
1290 trace4("ADP_NODE::tt_integrate_2_exp", _delta
[1], tr_
, _sign
, tr_value
);
1291 trace4("ADP_NODE::tt_integrate_2_exp", tr_duration(), dT0(), tt1() +
1293 hp_float_t h
= tr_duration();
1295 assert (_sign
* tr_
>= 0 );
1296 assert (_sign
* _delta
[1] >= 0 );
1297 trace4( "ADP_NODE::tt_integrate_2_exp ", _delta
[1], tr_
, _delta
[1]- tr_
, _sign
);
1299 if (_sign
*_delta
[1] < _sign
*tr_
) {
1303 long double ln1
= log(_sign
*_delta
[1]/h
);
1304 long double ln0
= log(_sign
*tr_
/h
);
1306 //int_{h}^{dT0} exp( ln1 + v/dT0 * (ln0 - ln1) ) dv
1307 long double delta
= dT0()/(ln0
-ln1
) * ( _sign
*tr_
/h
- exp( ln1
+ (h
/dT0())
1308 *(ln0
-ln1
) ) ) * _sign
;
1311 //int_{h/2}^{dT0-h/2} exp( ln1 + v/dT0 * (ln0 - ln1) ) dv
1312 delta
= dT0()/(ln0
-ln1
) * ( exp( ln1
+ (1-h
/2/dT0()) * (ln0
-ln1
) )
1313 - exp( ln1
+ ( h
/2/dT0()) * (ln0
-ln1
) ) ) * _sign
;
1315 if (delta
!= delta
|| delta
==-inf
|| delta
==inf
){
1316 return ( tt_integrate_1_const( tr_
) );
1317 trace0( "FIXME" ); // call another thiongh.
1320 assert(delta
!= -inf
);
1321 assert(delta
!= inf
);
1323 long double ret
= get1() + _delta
[1] + delta
; // RET
1325 if ( h
== dT0() && fabs(delta
)> 1e-14 ){
1326 trace2("ADP_NODE::tt_integrate_1_exp 0", _delta
[1], delta
);
1327 assert(false); // throw something?
1330 trace6(( "ADP_NODE::tt_integrate_1_exp "+short_label()).c_str(),
1331 _delta
[2], _delta
[1], tr_
, tt_expect
, delta
, ret
);
1335 assert (_sign
*tr_
>= 0 );
1336 _integrator
= &ADP_NODE::tt_integrate_1_exp
;
1338 if( _positive
&& ret
< 0){
1342 assert(tt_expect
>=0 || !_positive
);
1343 assert(ret
>=0 || !_positive
);
1344 assert(ret
<2); // RCD?
1348 /*----------------------------------------------------------------------*/
1349 // ADP_CARD::ADP_CARD() {unreachable();}
1350 /*----------------------------------------------------------------------*/
1351 ADP_CARD::ADP_CARD(const ADP_CARD
& p
) : COMPONENT(p
) {unreachable();}
1352 /*----------------------------------------------------------------------*/
1354 TIME_PAIR
ADP_NODE_UDC::tt_review( ) {
1355 return ADP_NODE::tt_review();
1357 /*----------------------------------------------------------------------*/
1358 TIME_PAIR
ADP_NODE::tt_review( ) {
1359 hp_float_t myreltol
= OPT::adpreltol
;
1360 hp_float_t myabstol
= OPT::adpabstol
;
1361 double h
= tr_duration();
1363 //fixme: where corrector?
1365 // assert(order()>0);
1366 // trace1(("ADP_NODE::tt_review: correction " + label()).c_str(), _delta_expect);
1367 // delta_model = (this->*_corrector)(); // value predicted by model.
1370 // trace1(("ADP_NODE::tt_review: no corrector " + label()).c_str(), delta_model );
1373 trace3("ADP_NODE::tt_review", CKT_BASE::_sim
->tt_iteration_number(), myabstol
, myreltol
);
1374 assert(delta_model
== delta_model
);
1375 if( myreltol
== 0 ) {_wdT
=0; return TIME_PAIR(0,0); }
1376 if( myabstol
== 0 ) {_wdT
=0; return TIME_PAIR(0,0); }
1378 if ( ( tr_value
* delta_model
) < 0 ) {
1379 trace2(("ADP_NODE::tt_review: oops, sign has changed "+ label()).c_str(), tr_value
,delta_model
);
1381 // FIXME: implement abs err!
1382 double tr_high
= tr_value
+ tr_noise
;
1383 double tr_low
= tr_value
- tr_noise
;
1385 if ( delta_model
> tr_high
) {
1386 _abs_tr_err
= tr_high
- delta_model
;
1387 } else if (delta_model
< tr_low
){
1388 _abs_tr_err
= delta_model
- tr_low
;
1390 _abs_tr_err
= fabs(delta_model
- tr_value
);
1393 trace2("ADP_NODE::tt_review", long_label(), tr_noise
);
1395 if (tr_noise
<0 || !is_number(tr_noise
)){
1396 error(bDANGER
, "ADP_NODE::tt_review noise error: %s\n", long_label().c_str());
1397 assert (tr_noise
>=0);
1400 _abs_tr_err
= fabs (tr_value
- delta_model
);
1401 _abs_tr_err
= max ( fabs (tr_value
- delta_model
) - tr_noise
,0.0 );
1402 // _abs_tr_err = fabs (tr_value - delta_model) / tr_noise ;
1404 if (_abs_tr_err
< 1e-40 ) {
1408 _rel_tr_err
= _abs_tr_err
; // / max( fabs(tr_value) , fabs(delta_model));
1410 // use noise for predictor only?
1411 // _rel_tr_err = fabs( tr_value-delta_model )/ fabs(tr_noise ) ;
1413 _rel_tt_err
= fabs (tt_value
- tt_expect
) / (fabs(tt_value
) + fabs(tt_expect
));
1415 tr_value
= delta_model
;
1417 trace3(("ADP_NODE::tt_review" + label() + "got tol").c_str(), myreltol
, _abs_tr_err
, _rel_tr_err
);
1418 if( _abs_tr_err
== 0 ) {
1419 trace1(("ADP_NODE::tt_review" + label() + "noabs").c_str(), TIME_PAIR(0, NEVER
)._event
);
1420 _wdT
= inf
; return TIME_PAIR(0, NEVER
);
1422 if( myreltol
== inf
&& myabstol
== inf
) { _wdT
= inf
; return TIME_PAIR();}
1423 if( myreltol
== 0 && myabstol
== 0 ) {_wdT
=0; return TIME_PAIR(0,0);}
1427 _wdT
= dT0() * sqrt( myreltol
/ _rel_tr_err
) + h
;
1428 _wdT
= dT0() * log( 1+ myreltol
/ _rel_tr_err
) + h
;
1431 if (_rel_tr_err
>= 1 ){
1432 error( bDANGER
, "stepdebug %i dev: %s reltr %f>1 model %E, tr_ %E fill %E\n",
1433 CKT_BASE::_sim
->tt_iteration_number(),
1434 label().c_str(), _rel_tr_err
, delta_model
, tr_value
, tt_value
);
1437 error( bDANGER
, "stepdebug dev: _wdT %s wdT: %g %g %f rel_tr %f abserr: %g, corr %i ord %i\n",
1438 label().c_str(), _wdT
, dT0(), myreltol
, _rel_tr_err
, _abs_tr_err
, (bool)_corrector
, order() );
1441 trace4("ADP_NODE::tt_review adaptive _wdT", myreltol
, inf
, h
, _rel_tr_err
);
1442 if( _wdT
< 0 || _wdT
!= _wdT
) {
1443 error(bDANGER
, " dev: _wdT %s %f %f %f\n", label().c_str(), _wdT
, dT0(), _rel_tr_err
);
1446 if( _rel_tr_err
!= _rel_tr_err
) _wdT
= NEVER
;
1447 if( !(_rel_tr_err
== _rel_tr_err
) ) _wdT
= NEVER
;
1449 trace3( ("ADP_NODE::tt_review " + label()).c_str(), CKT_BASE::_sim
->_Time0
, _wdT
, myreltol
);
1453 assert(tr_value
== tr_value
);
1454 assert(_delta_expect
== _delta_expect
);
1455 tt_value
+= tr_value
; // only printed if OPT::printrejected
1457 return( TIME_PAIR(0, _wdT
));
1460 void ADP_NODE_RCD::tr_expect_1(){ return tr_expect_1_exp();}
1461 void ADP_NODE_RCD::tr_expect_2(){ return tr_expect_2_exp();}
1462 void ADP_NODE_RCD::tr_expect_3(){ return tr_expect_3_exp();}
1464 void ADP_NODE_UDC::tr_expect_1(){ return tr_expect_1_const();}
1465 void ADP_NODE_UDC::tr_expect_2(){ return tr_expect_2_linear();}
1466 void ADP_NODE_UDC::tr_expect_3(){ return tr_expect_3_quadratic();}
1467 /*----------------------------------------------------------------------------*/
1468 // vim:ts=8:sw=2:et: