Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   Related Pages  

func.h

Go to the documentation of this file.
00001 
00026 #ifndef __func_h
00027 #define __func_h
00028 
00029 #include <math.h>
00030 #include <string>
00031 #include <iostream>
00032 #include <sstream>
00033 #include <mak/infinity.h>
00034 #include "punnets_base.h"
00035 
00036 #define USE_DYNAMIC
00037 
00038 namespace punnets_common {
00039 
00048 
00049 class message_base
00050 {
00051 public:
00052     message_base() { }
00053     virtual ~message_base() { }
00054 
00058     virtual const char *getMessageId() const = 0;
00059 };  
00060 
00068 
00069 class func_base
00070 {
00071 protected:
00075     virtual void valueChange() { }
00076     
00077 public:
00078     func_base() { }
00079     virtual ~func_base() { }
00080 
00082     virtual bool shouldDelete(ntime_t /*current*/) { return false; }
00085     virtual bool processMessage(ntime_t, const message_base &) { return false; }
00086 
00088     virtual void setLambda(real /*new_lambda*/) { }
00090     virtual void setZeroPoint(real /*new_zeropoint*/) { }
00091 
00093     virtual real getMaxGradient( ntime_t t ) const = 0;
00096     virtual ntime_t getNextIncontinuity( ntime_t /*from*/ ) const { return mak::Infinity; };
00097 
00099     virtual real getValue( ntime_t t ) const = 0;
00101     virtual real get1stDeriv( ntime_t t ) const = 0;
00103     virtual real get2ndDeriv( ntime_t t ) const = 0;
00104 
00106     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const = 0;
00108     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const = 0;
00110     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const = 0;
00111 
00113     virtual func_base * clone() = 0;
00115     virtual std::string getDescription() = 0;
00116 };  
00117 
00124 
00125 class func_deriveq_base : public func_base
00126 {
00127 protected:
00128     real lambda;
00129     ntime_t zerop;
00130 
00134     virtual void zeropChange() { }
00135     
00136 public:
00137     func_deriveq_base() : func_base(), lambda(1.0), zerop(-10000000.0) { }
00138     virtual ~func_deriveq_base() { }
00139 
00141     virtual void setLambda(real new_lambda) { assert( new_lambda > 0.0 ); lambda = new_lambda; valueChange(); }
00143     virtual void setZeroPoint(real new_zeropoint) { zerop = new_zeropoint; zeropChange(); }
00144 
00146     class message_set_lambda : public message_base
00147     {
00148         real lambda;
00149 public: 
00150         message_set_lambda(real newlambda) : message_base() { lambda = newlambda; }
00151         static const char * const messageId;
00152         virtual const char *getMessageId() const { return messageId; }
00153         real getLambda() const { return lambda; }
00154     };
00156     class message_set_zero_point : public message_base
00157     {
00158         real zerop;
00159 public: 
00160         message_set_zero_point(real newzerop) : message_base() { zerop = newzerop; }
00161         static const char * const messageId;
00162         virtual const char *getMessageId() const { return messageId; }
00163         real getZeroPoint() const { return zerop; }
00164     };
00165 
00167     virtual bool processMessage(ntime_t t, const message_base &m) { 
00168 #ifdef USE_DYNAMIC
00169         if( const message_set_lambda *mm = dynamic_cast<const message_set_lambda *>(&m) ) {
00170             setLambda( mm->getLambda() );
00171             return true;
00172         }
00173 #else
00174         if( m.getMessageId() == message_set_lambda::messageId ) {
00175             setLambda( dynamic_cast<const message_set_lambda &>(m).getLambda() );
00176             return true;
00177         }
00178 #endif
00179 #ifdef USE_DYNAMIC
00180         if( const message_set_zero_point *mm = dynamic_cast<const message_set_zero_point *>(&m) ) {
00181             setZeroPoint( mm->getZeroPoint() );
00182             return true;
00183         }
00184 #else
00185         if( m.getMessageId() == message_set_zero_point::messageId ) {
00186             setZeroPoint( dynamic_cast<const message_set_zero_point &>(m).getZeroPoint() );
00187             return true;
00188         }
00189 #endif
00190         return func_base::processMessage(t,m); 
00191     }
00192 };  
00194 
00195 
00200 
00201 class func_const : public func_base
00202 {
00203     real c;
00204 public:
00206     func_const(real ic) : func_base(), c(ic) { }            
00207 
00208     virtual real getMaxGradient( ntime_t /*t*/ ) const { return 0; };
00209 
00210     virtual real getValue( ntime_t /*t*/ ) const 
00211                 { return c; }
00212 
00213     virtual real get1stDeriv( ntime_t /*t*/ ) const
00214                 { return 0; }
00215     virtual real get2ndDeriv( ntime_t /*t*/ ) const
00216                 { return 0; }
00217 
00218     virtual void getValueDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const 
00219                 { upslope = downslope = 0; ceil = floor = c;  }
00220 
00221     virtual void get1stDerivDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const 
00222                 { upslope = downslope = 0; ceil = floor = 0;  }
00223 
00224     virtual void get2ndDerivDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const 
00225                 { upslope = downslope = 0; ceil = floor = 0;  }
00226 
00227     virtual func_const * clone() { return new func_const(*this); }
00228     virtual std::string getDescription() { std::ostringstream oss; oss << "func_const c=" << c; return oss.str(); }
00229 };
00230 
00231 
00237 
00238 class func_const_int : public func_deriveq_base
00239 {
00240     real c;
00241 
00242     real limit;
00243 
00245     virtual void valueChange() { limit = c / lambda; }
00246 public:
00248     func_const_int(real ic) : func_deriveq_base(), c(ic) { valueChange(); }         
00249 
00250     virtual real getMaxGradient( ntime_t /*t*/ ) const { return limit < 0 ? 0 : c; };
00251 
00252     virtual real getValue( ntime_t t ) const 
00253                 { return limit * (1 - exp(- lambda * (t - zerop))); }
00254 
00255     virtual real get1stDeriv( ntime_t t ) const
00256                 { return limit * lambda * exp(- lambda * (t - zerop)); }
00257     virtual real get2ndDeriv( ntime_t t ) const
00258                 { return - limit * lambda * lambda * exp(- lambda * (t - zerop)); }
00259     virtual real get3rdDeriv( ntime_t t ) const
00260                 { return limit * lambda * lambda * lambda * exp(- lambda * (t - zerop)); }
00261 
00262     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00263     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00264     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00265 
00266     virtual func_const_int * clone() { return new func_const_int(*this); }
00267     virtual std::string getDescription() { std::ostringstream oss; oss << "func_const_int c=" << c << ", lambda=" << lambda << ", zerop=" << zerop; return oss.str(); }
00268 };
00270 
00271 
00276 
00277 class func_step : public func_base
00278 {
00279     real r;
00280     ntime_t t0;
00281 public:
00282     func_step(real ir, ntime_t it0) : func_base(), r(ir), t0(it0) { }           
00283 
00284     virtual real getMaxGradient( ntime_t /*t*/ ) const { return 0; };
00285 
00286     virtual real getValue( ntime_t t ) const 
00287                 { return (t0 < t ? r : 0.0); }
00288 
00289     virtual real get1stDeriv( ntime_t /*t*/ ) const
00290                 { return 0; }
00291     virtual real get2ndDeriv( ntime_t /*t*/ ) const
00292                 { return 0; }
00293 
00294     virtual ntime_t getNextIncontinuity( ntime_t from ) const { return from < t0 ? t0 : mak::Infinity; };
00295 
00296     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00297                 { upslope = downslope = 0; ceil = floor = (t >= t0 ? r : 0);  }
00298 
00299     virtual void get1stDerivDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const 
00300                 { upslope = downslope = 0; ceil = floor = 0;  }
00301 
00302     virtual void get2ndDerivDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const 
00303                 { upslope = downslope = 0; ceil = floor = 0;  }
00304 
00305     virtual func_step * clone() { return new func_step(*this); }
00306     virtual std::string getDescription() { std::ostringstream oss; oss << "func_step r=" << r << ", t0=" << t0; return oss.str(); }
00307 };
00309 
00315 
00316 class func_delta_int : public func_deriveq_base
00317 {
00318     real r;
00319     ntime_t t0;
00320 
00321     virtual void valueChange() { }
00322 
00323 public:
00325     func_delta_int(real ir, ntime_t it0) : func_deriveq_base(), r(ir), t0(it0) { valueChange(); }           
00326 
00327     virtual real getMaxGradient( ntime_t /*t*/ ) const { return r<0 ? - lambda * r : 0 ; };
00328 
00329     void setParam(real ir, ntime_t it0) { r = ir; t0 = it0; }
00330 
00331     virtual real getValue( ntime_t t ) const 
00334                 { 
00335 //                  std::cout << "zerop=" << zerop << ", t0=" << t0 << ",t=" << t << std::endl;
00336                     return (zerop < t0 && t0 <= t) ? r * exp( - lambda * (t - t0) ) : 0.0; }
00337 
00338     virtual real get1stDeriv( ntime_t t ) const
00339                 { return (zerop < t0 && t0 <= t) ? - lambda * r * exp( - lambda * (t - t0) ) : 0.0; }
00340     virtual real get2ndDeriv( ntime_t t ) const
00341                 { return (zerop < t0 && t0 <= t) ? lambda * lambda * r * exp( - lambda * (t - t0) ) : 0.0; }
00342     virtual real get3rdDeriv( ntime_t t ) const
00343                 { return (zerop < t0 && t0 <= t) ? - lambda * lambda * lambda * r * exp( - lambda * (t - t0) ) : 0.0; }
00344 
00345     virtual ntime_t getNextIncontinuity( ntime_t from ) const { return from < t0 ? t0 : mak::Infinity; };
00346 
00347     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00348     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00349     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00350 
00351     virtual std::string getDescription() { std::ostringstream oss; oss << "func_delta_int r=" << r << ", t0=" << t0 << ", lambda=" << lambda << ", zerop=" << zerop; return oss.str(); }
00352 
00354     class message_add_pulse : public message_base
00355     {
00356         real pulselev;
00357 public: 
00358         message_add_pulse(real ipl) : message_base() { pulselev = ipl; }
00359         static const char * const messageId;
00360         virtual const char *getMessageId() const { return messageId; }
00361         real getPulseLevel() const { return pulselev; }
00362     };
00363 
00364     virtual bool processMessage(ntime_t t, const message_base &m) { 
00365 #ifdef USE_DYNAMIC
00366         if( const message_add_pulse *mm = dynamic_cast<const message_add_pulse *>(&m) ) {
00367             setParam( getValue(t) + mm->getPulseLevel(), t );
00368             return true;
00369         }
00370 #else
00371         if( m.getMessageId() == message_add_pulse::messageId ) {
00372             setParam( getValue(t) + dynamic_cast<const message_add_pulse &>(m).getPulseLevel(), t );
00373             return true;
00374         }
00375 #endif
00376         return func_deriveq_base::processMessage(t, m); 
00377     }
00378 
00379     virtual func_delta_int * clone() { return new func_delta_int(*this); }
00380 };
00381 
00386 
00387 class func_response : public func_deriveq_base
00388 {
00389     real r, rinit;
00390 
00391     virtual void valueChange() { }
00392 
00393 public:
00394     func_response(real ir) : func_deriveq_base(), r(ir), rinit(ir) { valueChange(); }           
00395 
00396     virtual real getMaxGradient( ntime_t /*t*/ ) const { return r<0 ? - lambda * r : 0 ; };
00397 
00398     virtual real getValue( ntime_t t ) const 
00399                 { 
00400                     return r * exp( - lambda * (t - zerop) ) ; }
00401 
00402     virtual real get1stDeriv( ntime_t t ) const
00403                 { return - lambda * r * exp( - lambda * (t - zerop) ); }
00404     virtual real get2ndDeriv( ntime_t t ) const
00405                 { return lambda * lambda * r * exp( - lambda * (t - zerop) ); }
00406     virtual real get3rdDeriv( ntime_t t ) const
00407                 { return - lambda * lambda * lambda * r * exp( - lambda * (t - zerop) ); }
00408 
00409     virtual ntime_t getNextIncontinuity( ntime_t /*from*/ ) const { return mak::Infinity; };
00410 
00411     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00412     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00413     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00414 
00415     virtual std::string getDescription() { std::ostringstream oss; oss << "func_response r=" << r << ", lambda=" << lambda << ", zerop=" << zerop; return oss.str(); }
00416 
00417     virtual func_response * clone() { return new func_response(*this); }
00418 
00419     virtual void setZeroPoint(real new_zeropoint) { 
00420             r = rinit + r * exp( - lambda * (new_zeropoint - zerop) );
00421                 zerop = new_zeropoint; zeropChange(); }
00422 };
00423 
00424 
00425 
00430 
00431 class func_sine : public func_base
00432 {
00433     real r;
00434     real omega;
00435     real theta;
00436 
00437     static const real alpha = 1.311;
00438     static const real beta  = 0.375867;
00439 
00440     void valueChange() { }
00441 
00442 public:
00444     func_sine(real ir, real iomega, real itheta) : func_base(), r(ir), omega(iomega), theta(itheta) { valueChange(); }          
00445 
00446     virtual real getMaxGradient( ntime_t /*t*/ ) const { return omega * r; };
00447 
00448     virtual real getValue( ntime_t t ) const
00449                 { return r * sin(omega * t + theta); }
00450 
00451     virtual real get1stDeriv( ntime_t t ) const
00452                 { return omega * r * cos(omega * t + theta); }
00453 
00454     virtual real get2ndDeriv( ntime_t t ) const
00455                 { return - omega * omega * r * sin(omega * t + theta); }
00456 
00457     virtual real get3rdDeriv( ntime_t t ) const
00458                 { return - omega * omega * omega * r * cos(omega * t + theta); }
00459 
00460     virtual ntime_t getNextIncontinuity( ntime_t /*from*/ ) const { return mak::Infinity; };
00461 
00462     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00463     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00464     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00465 
00466     virtual func_sine * clone() { return new func_sine(*this); }
00467     virtual std::string getDescription() { std::ostringstream oss; oss << "func_sine r=" << r << ", omega=" << omega << ", theta=" << theta; return oss.str(); }
00468 };
00469 
00470 
00476 
00477 class func_sineshot : public func_base
00478 {
00479     real r;
00480     real omega;
00481     real t0;
00482 
00483     real r_div_2;       
00484     real omega_2;       
00485     real duration;      
00486 
00487     static const real alpha = 1.311;
00488     static const real beta  = 0.375867;
00489 
00490     void valueChange() { duration = M_PI / omega; omega_2 = 2 * omega; r_div_2 = r * 0.5; }
00491 
00492 public:
00494     func_sineshot(real ir, real iomega, real it0) : func_base(), r(ir), omega(iomega), t0(it0) { valueChange(); }           
00495 
00496     virtual real getMaxGradient( ntime_t /*t*/ ) const { return fabs(r_div_2) * omega_2; };
00497 
00498     virtual bool shouldDelete(ntime_t current) { return (current >= t0 + duration); }
00499 
00500     virtual real getValue( ntime_t t ) const
00501                 { return (t0 <= t && t <= t0 + duration ? r_div_2 * (1-cos(omega_2 * (t-t0) )) : 0.0); }
00502 
00503     virtual real get1stDeriv( ntime_t t ) const
00504                 { return (t0 <= t && t <= t0 + duration ? r_div_2 * omega_2 * sin(omega_2 * (t-t0) ) : 0.0); }
00505 
00506     virtual real get2ndDeriv( ntime_t t ) const
00507                 { return (t0 <= t && t <= t0 + duration ? r_div_2 * omega_2 * omega_2 * cos(omega_2 * (t-t0) ) : 0.0); }
00508 
00509     virtual ntime_t getNextIncontinuity( ntime_t from ) const { return from < t0 ? t0 : mak::Infinity; };
00512 
00513     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00514     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00515     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00516     virtual func_sineshot * clone() { return new func_sineshot(*this); }
00517     virtual std::string getDescription() { std::ostringstream oss; oss << "func_sineshot r=" << r << ", omega=" << omega << ", t0=" << t0; return oss.str(); }
00518 
00520     class message_set_t0 : public message_base
00521     {
00522 public: 
00523         message_set_t0() : message_base() { }
00524         static const char * const messageId;
00525         virtual const char *getMessageId() const { return messageId; }
00526     };
00527 
00528     virtual bool processMessage(ntime_t t, const message_base &m) { 
00529 #ifdef USE_DYNAMIC
00530         if( dynamic_cast<const message_set_t0 *>(&m) != NULL ) 
00531 #else
00532         if( m.getMessageId() == message_set_t0::messageId ) 
00533 #endif
00534         {
00535             t0 = t;
00536             return true;
00537         }
00538         return func_base::processMessage(t, m); 
00539     }
00540 };
00541 
00542 
00547 
00548 class func_sine_int : public func_deriveq_base
00549 {
00550     real r;
00551     real omega;
00552     real theta;
00553 
00554     real r_inv_lsq_osq; 
00555     real zerop_value;
00556 
00557     void valueChange() { r_inv_lsq_osq = r / (lambda * lambda + omega * omega); }
00558     void zeropChange() { zerop_value = lambda * sin( theta + omega * zerop ) - omega * cos( theta + omega * zerop ); }
00559 
00560 public:
00562     func_sine_int(real ir, real iomega, real itheta) : func_deriveq_base(), r(ir), omega(iomega), theta(itheta) { valueChange(); }          
00563 
00564     virtual real getMaxGradient( ntime_t /*t*/ ) const { return r_inv_lsq_osq * (omega * (lambda + 1) - lambda * lambda * zerop_value); };
00565 
00566     virtual real getValue(ntime_t t) const
00567                 { return r_inv_lsq_osq * (
00568                             lambda * sin( theta + omega * t ) - omega * cos( theta + omega * t )
00569                             + exp( lambda * (zerop - t) ) * zerop_value );
00570                 }
00571     virtual real get1stDeriv(ntime_t t) const
00572                 { return r_inv_lsq_osq * (
00573                             omega * (lambda * cos( theta + omega * t ) + omega * sin( theta + omega * t ))
00574                                 - lambda * exp( lambda * (zerop - t) ) * zerop_value );
00575                 }
00576     virtual real get2ndDeriv(ntime_t t) const
00577                 { return r_inv_lsq_osq * (
00578                             omega * omega * (- lambda * sin( theta + omega * t ) + omega * cos( theta + omega * t ))
00579                                 + lambda * lambda * exp( lambda * (zerop - t) ) * zerop_value );
00580                 }
00581     virtual real get3rdDeriv(ntime_t t) const
00582                 { return r_inv_lsq_osq * (
00583                             omega * omega * omega * (- lambda * cos( theta + omega * t ) - omega * sin( theta + omega * t ))
00584                                 - lambda * lambda * lambda * exp( lambda * (zerop - t) ) * zerop_value );
00585                 }
00586 
00587     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00588                 { upslope = fabs(omega); downslope = -upslope; ceil = r; floor = -r;
00589                   if( getValue(t) > 0 ) {   upslope = get1stDeriv(t); if(   upslope < 0 ) upslope *= -1; }
00590                                    else { downslope = get1stDeriv(t); if( downslope > 0 ) downslope *= -1; } }
00591 
00592     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00593                 { upslope = omega * omega; downslope = -upslope; ceil = fabs(omega) * r; floor = -ceil;
00594                   if( get1stDeriv(t) > 0 ) {   upslope = get2ndDeriv(t); if(   upslope < 0 ) upslope *= -1; }
00595                                       else { downslope = get2ndDeriv(t); if( downslope > 0 ) downslope *= -1; } }
00596 
00597     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00598                 { upslope = fabs( omega * omega * omega); downslope = -upslope; ceil = omega * omega * r; floor = -ceil;
00599                   if( get2ndDeriv(t) > 0 ) {   upslope = get3rdDeriv(t); if(   upslope < 0 ) upslope *= -1; }
00600                                       else { downslope = get3rdDeriv(t); if( downslope > 0 ) downslope *= -1; } }
00601 
00602     virtual func_sine_int * clone() { return new func_sine_int(*this); }
00603     virtual std::string getDescription() { std::ostringstream oss; oss << "func_sine_int r=" << r << ", omega=" << omega << ", theta=" << theta << ", lambda=" << lambda << ", zerop=" << zerop; return oss.str(); }
00604 };
00605 
00611 
00612 class func_sineshot_int : public func_deriveq_base
00613 {
00614     real r;
00615     real omega;
00616 
00617     real r_div_2;       
00618     real omega_2;       
00619     real duration;      
00620 
00621     static const real alpha = 1.311;
00622     static const real beta  = 0.375867;
00623 
00624     void valueChange() { duration = M_PI / omega; omega_2 = 2 * omega; r_div_2 = r * 0.5; }
00625     void zeropChange() {  }
00626 
00627 public:
00629     func_sineshot_int(real ir, real iomega) : func_deriveq_base(), r(ir), omega(iomega) { valueChange(); }          
00630 
00631     virtual real getMaxGradient( ntime_t /*t*/ ) const { return fabs(r_div_2) * omega_2; };
00632 
00633     virtual real getValue( ntime_t t ) const
00634                 { return (zerop <= t && t <= zerop + duration ? r_div_2 * (1-cos(omega_2 * (t-zerop) )) : 0.0); }
00635 
00636     virtual real get1stDeriv( ntime_t t ) const
00637                 { return (zerop <= t && t <= zerop + duration ? r_div_2 * omega_2 * sin(omega_2 * (t-zerop) ) : 0.0); }
00638 
00639     virtual real get2ndDeriv( ntime_t t ) const
00640                 { return (zerop <= t && t <= zerop + duration ? r_div_2 * omega_2 * omega_2 * cos(omega_2 * (t-zerop) ) : 0.0); }
00641 
00642     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00643     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00644     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const;
00645 
00646     virtual func_sineshot_int * clone() { return new func_sineshot_int(*this); }
00647     virtual std::string getDescription() { std::ostringstream oss; oss << "func_sineshot_int r=" << r << ", omega=" << omega; return oss.str(); }
00648 };
00649 
00654 
00655 class func_exp : public func_base
00656 {
00657     real r;
00658     real psi;
00659     real t0;
00660 
00661 public:
00663     func_exp(real ir, real ipsi, real it0) : func_base(), r(ir), psi(ipsi), t0(it0) { if( psi < 0.0 ) throw "func_exp"; }   
00664 
00665     virtual real getMaxGradient( ntime_t t ) const { return r>0 ? 0 : get1stDeriv(t); }
00666 
00667     virtual real getValue( ntime_t t ) const
00668                 { return r * exp( -psi * (t - t0) ); }
00669 
00670     virtual real get1stDeriv( ntime_t t ) const
00671                 { return -psi * r * exp( -psi * (t - t0) ); }
00672 
00673     virtual real get2ndDeriv( ntime_t t ) const
00674                 { return psi * psi * r * exp( -psi * (t - t0) ); }
00675 
00676     virtual real get3rdDeriv( ntime_t t ) const
00677                 { return - psi * psi * psi * r * exp( -psi * (t - t0) ); }
00678 
00679     virtual ntime_t getNextIncontinuity( ntime_t /*from*/ ) const { return mak::Infinity; };
00680 
00681     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00682                 { if( r >= 0 ) {   upslope = 0; ceil =  mak::Infinity; downslope = func_exp::get1stDeriv(t); floor = 0.0; } 
00683                   else         { downslope = 0; floor= -mak::Infinity;   upslope = func_exp::get1stDeriv(t); ceil  = 0.0; } }
00684 
00685     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00686                 { if( r <= 0 ) {   upslope = 0; ceil =  mak::Infinity; downslope = func_exp::get2ndDeriv(t); floor = 0.0; } 
00687                   else         { downslope = 0; floor= -mak::Infinity;   upslope = func_exp::get2ndDeriv(t); ceil  = 0.0; } }
00688 
00689     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00690                 { if( r >= 0 ) {   upslope = 0; ceil =  mak::Infinity; downslope = func_exp::get3rdDeriv(t); floor = 0.0; } 
00691                   else         { downslope = 0; floor= -mak::Infinity;   upslope = func_exp::get3rdDeriv(t); ceil  = 0.0; } }
00692 
00693     virtual func_exp * clone() { return new func_exp(*this); }
00694     virtual std::string getDescription() { std::ostringstream oss; oss << "func_exp r=" << r << ", psi=" << psi << ", t0=" << t0; return oss.str(); }
00695 };
00696 
00697 
00698 
00704 
00705 class func_exp_int : public func_deriveq_base
00706 {
00707     real r;
00708     real psi;
00709     real t0;
00710     real r_per_lambda_minus_psi;
00711 
00712     void valueChange() { if( psi < 0.0 || lambda < 0.0 ) abort(); r_per_lambda_minus_psi = r / ( lambda - psi ); }
00713 
00714 public:
00716     func_exp_int(real ir, real ipsi, real it0) : func_deriveq_base(), r(ir), psi(ipsi), t0(it0) { valueChange(); }
00717 
00718     virtual real getMaxGradient( ntime_t /*t*/ ) const { throw "not supported"; }
00719 
00720     virtual real getValue(ntime_t t) const
00721                 { return r_per_lambda_minus_psi * ( 
00722                                 exp( - psi * (t - t0) )
00723                                 - exp( lambda * (zerop - t) - psi * (zerop - t0) ) );
00724                 }
00725 
00726     virtual real get1stDeriv(ntime_t t) const
00727                 { return r_per_lambda_minus_psi * ( 
00728                                 - psi * exp( - psi * (t - t0) )
00729                                 + lambda * exp( lambda * (zerop - t) - psi * (zerop - t0) ) );
00730                 }
00731 
00732     virtual real get2ndDeriv(ntime_t t) const
00733                 { return r_per_lambda_minus_psi * ( 
00734                                 psi*psi * exp( - psi * (t - t0) )
00735                                 - lambda*lambda * exp( lambda * (zerop - t) - psi * (zerop - t0) ) );
00736                 }
00737 
00738     virtual real get3rdDeriv(ntime_t t) const
00739                 { return r_per_lambda_minus_psi * ( 
00740                                 -psi*psi*psi * exp( - psi * (t - t0) )
00741                                 +lambda*lambda*lambda * exp( lambda * (zerop - t) - psi * (zerop - t0) ) );
00742                 }
00743 
00744     virtual ntime_t getNextIncontinuity( ntime_t /*from*/ ) const { return mak::Infinity; };
00745 
00746     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00747                 { 
00748                     real value = getValue(t);
00749                     real deriv = get1stDeriv(t);
00750                     if( r >= 0 )
00751                     {
00752                         if( deriv > 0 )
00753                         {
00754                             real log_lambda_per_psi = log(lambda / psi) / (lambda - psi);
00755                             upslope = deriv; 
00756                             ceil = r_per_lambda_minus_psi * exp( - psi * (zerop - t0) ) * ( exp( -psi * log_lambda_per_psi ) - exp( - lambda * log_lambda_per_psi) );
00757                             downslope = - value / log_lambda_per_psi; /* can be more efficient */
00758                             floor = 0;
00759                         }
00760                         else {
00761                             upslope = 0; ceil = mak::Infinity;
00762                             downslope = -1; throw "Not supported";
00763                             floor = 0;
00764                         }
00765                     }
00766                     else /* r < 0 */ {
00767                         if( deriv < 0 )
00768                         {
00769                             real log_lambda_per_psi = log(lambda / psi) / (lambda - psi);
00770                             downslope = deriv; 
00771                             floor = r_per_lambda_minus_psi * exp( - psi * (zerop - t0) ) * ( exp( -psi * log_lambda_per_psi ) - exp( - lambda * log_lambda_per_psi) );
00772                             upslope = - value / log_lambda_per_psi; /* can be more efficient */
00773                             ceil = 0;
00774                         }
00775                         else {
00776                             downslope = 0; floor = -mak::Infinity;
00777                             upslope = 1; throw "Not supported";
00778                             ceil = 0;
00779                         }
00780                     }
00781                 }
00782 
00783 //  virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00784     virtual void get1stDerivDomain( ntime_t , real &, real &, real &, real & ) const 
00785                 { throw "not supported"; }
00786 
00787 //  virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const 
00788     virtual void get2ndDerivDomain( ntime_t , real &, real &, real &, real & ) const 
00789                 { throw "not supported"; }
00790 
00791     virtual func_exp_int * clone() { return new func_exp_int(*this); }
00792     virtual std::string getDescription() { std::ostringstream oss; oss << "func_exp_int r=" << r << ",t0=" << t0; return oss.str(); }
00793 };
00794 
00800 
00801 class func_exp_diff : public func_base
00802 {
00803     real psi1, psi2;
00804     real phi, scale, invscale;
00805     real t0orig;
00806     real r0, t0;
00807     real r1, t1;
00808     real r2, t2;
00809     real it0, ir1, ir2;
00810     real r1orig, r2orig;
00811     real maxval;
00812     real xi;
00813 
00814     void valueChange();
00815 
00816 public:
00818     func_exp_diff(real ir1, real ipsi1, real ir2, real ipsi2, real it0);
00819 
00820     virtual real getMaxGradient( ntime_t t ) const { return r0<0 ? r0 * xi : (t >= t1 ? 0 : get1stDeriv(t)); }
00821 
00822     virtual real getValue( ntime_t t ) const
00823                 { return r0 * (exp( -psi1 * (t - t0) ) - exp( -psi2 * (t - t0) ) ); }
00824 
00825     virtual real get1stDeriv( ntime_t t ) const
00826                 { return r1 * (exp( -psi1 * (t - t1) ) - exp( -psi2 * (t - t1) ) ); }
00827 
00828     virtual real get2ndDeriv( ntime_t t ) const
00829                 { return r2 * (exp( -psi1 * (t - t2) ) - exp( -psi2 * (t - t2) ) ); }
00830 
00831     virtual real get3rdDeriv( ntime_t t ) const
00832                 { return r2 * (-psi1 * exp( -psi1 * (t - t2) ) + psi2 * exp( -psi2 * (t - t2) ) ); }
00833 
00834     virtual ntime_t getNextIncontinuity( ntime_t /*from*/ ) const { return mak::Infinity; }
00835 
00836     virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const ;
00837     virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const ;
00838     virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const ;
00839 
00840     virtual func_exp_diff * clone() { return new func_exp_diff(*this); }
00841     virtual std::string getDescription() { std::ostringstream oss; oss << "func_exp_diff r0=" << r0 << ", psi1=" << psi1 << ", psi2=" << psi2 << ", t0=" << t0; return oss.str(); }
00842 
00845 
00846     class message_add_event_time : public message_base
00847     {
00848     public:
00849         message_add_event_time() { }
00850         static const char * const messageId;
00851         virtual const char *getMessageId() const { return messageId; }
00852     };  
00853 
00854     virtual bool processMessage(ntime_t t, const message_base &m);
00855 };
00856 
00857 
00858 } // namespace punnets
00859 
00860 #endif // __func_h

Generated on Mon Jun 16 15:42:26 2003 for Punnets by doxygen1.2.18