00001
00026 #include "func.h"
00027 #include <iostream>
00028
00029 namespace punnets_common {
00030
00031 using namespace mak;
00032
00033
00034 const char * const func_deriveq_base::message_set_lambda::messageId = "message_set_lambda";
00035 const char * const func_deriveq_base::message_set_zero_point::messageId = "message_set_zerop";
00036 const char * const func_delta_int::message_add_pulse::messageId = "message_add_pulse";
00037 const char * const func_sineshot::message_set_t0::messageId = "message_set_t0";
00038 const char * const func_exp_diff::message_add_event_time::messageId = "message_add_event_time";
00039
00040
00041
00042
00043
00044 void func_const_int::getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00045 {
00046 if( c > 0 ) { upslope = func_const_int::get1stDeriv(t); downslope = 0; ceil = limit; floor = 0; }
00047 else { downslope = func_const_int::get1stDeriv(t); upslope = 0; floor = limit; ceil = 0; }
00048 }
00049
00050 void func_const_int::get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00051 {
00052 if( c > 0 ) { upslope = 0; downslope = func_const_int::get2ndDeriv(t); ceil = limit * lambda; floor = 0; }
00053 else { downslope = 0; upslope = func_const_int::get2ndDeriv(t); floor = limit * lambda; ceil = 0; }
00054 }
00055
00056 void func_const_int::get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00057 {
00058 if( c > 0 ) { upslope = func_const_int::get3rdDeriv(t); downslope = 0; ceil = 0; floor = -Infinity; }
00059 else { downslope = func_const_int::get3rdDeriv(t); upslope = 0; floor = 0; ceil = Infinity; }
00060 }
00061
00062
00063
00064
00065
00066 void func_delta_int::getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00067 {
00068 if( zerop >= t0 || t0 > t ) { upslope = downslope = 0; ceil = floor = 0; }
00069 else if( r >= 0 ) { upslope = 0; ceil = Infinity; downslope = get1stDeriv(t); floor = 0.0; }
00070 else { downslope = 0; floor= -Infinity; upslope = get1stDeriv(t); ceil = 0.0; }
00071 }
00072
00073 void func_delta_int::get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00074 {
00075 if( zerop >= t0 || t0 > t ) { upslope = downslope = 0; ceil = floor = 0; }
00076 else if( r <= 0 ) { upslope = 0; ceil = Infinity; downslope = get2ndDeriv(t); floor = 0.0; }
00077 else { downslope = 0; floor= -Infinity; upslope = get2ndDeriv(t); ceil = 0.0; }
00078 }
00079
00080 void func_delta_int::get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00081 {
00082 if( zerop >= t0 || t0 > t ) { upslope = downslope = 0; ceil = floor = 0; }
00083 else if( r >= 0 ) { upslope = 0; ceil = Infinity; downslope = get3rdDeriv(t); floor = 0.0; }
00084 else { downslope = 0; floor= -Infinity; upslope = get3rdDeriv(t); ceil = 0.0; }
00085 }
00086
00087
00088
00089
00090
00091 void func_response::getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00092 {
00093 if( r >= 0 ) { upslope = 0; ceil = Infinity; downslope = get1stDeriv(t); floor = 0.0; }
00094 else { downslope = 0; floor= -Infinity; upslope = get1stDeriv(t); ceil = 0.0; }
00095 }
00096
00097 void func_response::get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00098 {
00099 if( r <= 0 ) { upslope = 0; ceil = Infinity; downslope = get2ndDeriv(t); floor = 0.0; }
00100 else { downslope = 0; floor= -Infinity; upslope = get2ndDeriv(t); ceil = 0.0; }
00101 }
00102
00103 void func_response::get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00104 {
00105 if( r >= 0 ) { upslope = 0; ceil = Infinity; downslope = get3rdDeriv(t); floor = 0.0; }
00106 else { downslope = 0; floor= -Infinity; upslope = get3rdDeriv(t); ceil = 0.0; }
00107 }
00108
00109
00110
00111
00112
00113 void func_sine::getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00114 {
00115 real phi = omega * t + theta;
00116 if( phi < 0.0 ) phi -= ::floor(phi / (2*M_PI)) * 2*M_PI;
00117 phi = fmod(phi, 2*M_PI);
00118 phi -= M_PI;
00119 if( phi + 0.5*M_PI >= 0 )
00120 upslope = omega * r * cos( alpha * cos( beta * (phi + 0.5*M_PI)) + 0.5*M_PI - alpha);
00121 else
00122 upslope = omega * r * cos(omega * t + theta);
00123 phi += M_PI;
00124 if( phi >= M_PI ) phi -= 2*M_PI;
00125 if( phi + 0.5*M_PI >= 0 )
00126 downslope = - omega * r * cos( alpha * cos( beta * (phi + 0.5*M_PI)) + 0.5*M_PI - alpha);
00127 else
00128 downslope = omega * r * cos(omega * t + theta);
00129 ceil = r; floor = -r;
00130 }
00131
00132 void func_sine::get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00133 {
00134 real phi = omega * t + theta + 0.5*M_PI;
00135 if( phi < 0.0 ) phi -= ::floor(phi / (2*M_PI)) * 2*M_PI;
00136 phi = fmod(phi, 2*M_PI);
00137 phi -= M_PI;
00138 if( phi + 0.5*M_PI >= 0 )
00139 upslope = omega * omega * r * cos( alpha * cos( beta * (phi + 0.5*M_PI)) + 0.5*M_PI - alpha);
00140 else
00141 upslope = -omega * omega * r * cos(phi);
00142 phi += M_PI;
00143 if( phi >= M_PI ) phi -= 2*M_PI;
00144 if( phi + 0.5*M_PI >= 0 )
00145 downslope = - omega * omega * r * cos( alpha * cos( beta * (phi + 0.5*M_PI)) + 0.5*M_PI - alpha);
00146 else
00147 downslope = omega * omega * r * cos(phi);
00148 ceil = r*omega; floor = -r*omega;
00149 }
00150
00151 void func_sine::get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00152 {
00153 real phi = omega * t + theta + M_PI;
00154 if( phi < 0.0 ) phi -= ::floor(phi / (2*M_PI)) * 2*M_PI;
00155 phi = fmod(phi, 2*M_PI);
00156 phi -= M_PI;
00157 if( phi + 0.5*M_PI >= 0 )
00158 upslope = omega * omega * omega * r * cos( alpha * cos( beta * (phi + 0.5*M_PI)) + 0.5*M_PI - alpha);
00159 else
00160 upslope = -omega * omega * omega * r * cos(phi);
00161 phi += M_PI;
00162 if( phi >= M_PI ) phi -= 2*M_PI;
00163 if( phi + 0.5*M_PI >= 0 )
00164 downslope = - omega * omega * omega * r * cos( alpha * cos( beta * (phi + 0.5*M_PI)) + 0.5*M_PI - alpha);
00165 else
00166 downslope = omega * omega * omega * r * cos(phi);
00167 ceil = r*omega*omega; floor = -r*omega*omega;
00168 }
00169
00170
00171
00172
00173
00174
00175 void func_sineshot::getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00176 {
00177 upslope = ceil = downslope = floor = 0.0;
00178 if( t < t0 || t >= t0 + duration )
00179 return;
00180 else
00181 {
00182 real phase = omega_2 * (t - t0);
00183 real phi = phase + M_PI;
00184 if( phi >= 2*M_PI ) phi -= 2*M_PI;
00185 ( r > 0 ? ceil : floor ) = r;
00186 if( phase < 0.5 * M_PI )
00187 {
00188 ( r > 0 ? upslope : downslope ) = omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00189 ( r > 0 ? downslope : upslope ) = - omega_2 * r_div_2 * cos( alpha * cos( beta * (phi-M_PI) ) + 0.5*M_PI - alpha);
00190 }
00191 else if( phase < M_PI )
00192 {
00193 ( r > 0 ? upslope : downslope ) = r_div_2 * omega_2 * sin(phase );
00194 ( r > 0 ? downslope : upslope ) = - omega_2 * r_div_2 * cos( alpha * cos( beta * (phi-M_PI) ) + 0.5*M_PI - alpha);
00195 }
00196 else if( phase < 1.5*M_PI )
00197 {
00198 ( r > 0 ? downslope : upslope ) = - omega_2 * r_div_2 * cos( alpha * cos( beta * (phi+M_PI) ) + 0.5*M_PI - alpha);
00199 }
00200 else
00201 {
00202 ( r > 0 ? downslope : upslope ) = r_div_2 * omega_2 * sin(phase);
00203 }
00204 }
00205 }
00206
00207 void func_sineshot::get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00208 {
00209 upslope = ceil = downslope = floor = 0.0;
00210 if( t < t0 || t >= t0 + duration )
00211 return;
00212 else
00213 {
00214 real phase = omega_2 * (t - t0);
00215 real phi = phase + 1.5*M_PI;
00216 if( phi >= 2*M_PI ) phi -= 2*M_PI;
00217 ceil = fabs(r_div_2) * omega_2;
00218 floor = -ceil;
00219 if( phase < 0.5 * M_PI )
00220 {
00221 ( r > 0 ? upslope : downslope ) = r_div_2 * omega_2 * omega_2 * cos(phase );
00222 ( r > 0 ? downslope : upslope ) = - omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * (phi - M_PI) ) + 0.5*M_PI - alpha);
00223 }
00224 else if( phase < M_PI )
00225 {
00226
00227 ( r > 0 ? downslope : upslope ) = - omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * (phi + M_PI) ) + 0.5*M_PI - alpha);
00228 }
00229 else if( phase < 1.5*M_PI )
00230 {
00231 ( r > 0 ? ceil : floor ) = 0;
00232 ( r > 0 ? upslope : downslope ) = (- r_div_2 * omega_2 * sin(phase )) / (duration - (t-t0));
00233 ( r > 0 ? downslope : upslope ) = r_div_2 * omega_2 * omega_2 * cos(phase );
00234 }
00235 else
00236 {
00237 ( r > 0 ? ceil : floor ) = 0;
00238 ( r > 0 ? upslope : downslope ) = (- r_div_2 * omega_2 * sin(phase )) / (duration - (t-t0));
00239 }
00240 }
00241 }
00242
00243 void func_sineshot::get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00244 {
00245 upslope = ceil = downslope = floor = 0.0;
00246 if( t < t0 || t >= t0 + duration )
00247 return;
00248 else
00249 {
00250 real phase = omega_2 * (t - t0);
00251 real phi = phase;
00252 ceil = fabs(r_div_2 * omega_2 * omega_2);
00253 floor = -ceil;
00254 if( phase < 0.5 * M_PI )
00255 {
00256 ( r > 0 ? upslope : downslope ) = omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00257 ( r > 0 ? downslope : upslope ) = - omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * (phi + M_PI) ) + 0.5*M_PI - alpha);
00258 }
00259 else if( phase < M_PI )
00260 {
00261 ( r > 0 ? upslope : downslope ) = omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00262 ( r > 0 ? downslope : upslope ) = - r_div_2 * omega_2 * omega_2 * omega_2 * sin( phase );
00263 }
00264 else if( phase < 1.5*M_PI )
00265 {
00266 ( r > 0 ? upslope : downslope ) = omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00267 }
00268 else
00269 {
00270 ( r > 0 ? upslope : downslope ) = - r_div_2 * omega_2 * omega_2 * omega_2 * sin( phase );
00271 ( r > 0 ? downslope : upslope ) = - (r_div_2 * omega_2 * omega_2 * cos(phase )) / (duration - (t-t0));
00272 ( r > 0 ? floor : ceil ) = 0;
00273 }
00274 }
00275 }
00276
00277
00278
00279
00280
00281
00282 void func_sineshot_int::getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00283 {
00284 const real t0 = zerop;
00285 upslope = ceil = downslope = floor = 0.0;
00286 if( t < t0 || t >= t0 + duration )
00287 return;
00288 else
00289 {
00290 real phase = omega_2 * (t - t0);
00291 real phi = phase + M_PI;
00292 if( phi >= 2*M_PI ) phi -= 2*M_PI;
00293 ( r > 0 ? ceil : floor ) = r;
00294 if( phase < 0.5 * M_PI )
00295 {
00296 ( r > 0 ? upslope : downslope ) = omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00297 ( r > 0 ? downslope : upslope ) = - omega_2 * r_div_2 * cos( alpha * cos( beta * (phi-M_PI) ) + 0.5*M_PI - alpha);
00298 }
00299 else if( phase < M_PI )
00300 {
00301 ( r > 0 ? upslope : downslope ) = r_div_2 * omega_2 * sin(phase );
00302 ( r > 0 ? downslope : upslope ) = - omega_2 * r_div_2 * cos( alpha * cos( beta * (phi-M_PI) ) + 0.5*M_PI - alpha);
00303 }
00304 else if( phase < 1.5*M_PI )
00305 {
00306 ( r > 0 ? downslope : upslope ) = - omega_2 * r_div_2 * cos( alpha * cos( beta * (phi+M_PI) ) + 0.5*M_PI - alpha);
00307 }
00308 else
00309 {
00310 ( r > 0 ? downslope : upslope ) = r_div_2 * omega_2 * sin(phase);
00311 }
00312 }
00313 }
00314
00315 void func_sineshot_int::get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00316 {
00317 const real t0 = zerop;
00318 upslope = ceil = downslope = floor = 0.0;
00319 if( t < t0 || t >= t0 + duration )
00320 return;
00321 else
00322 {
00323 real phase = omega_2 * (t - t0);
00324 real phi = phase + 1.5*M_PI;
00325 if( phi >= 2*M_PI ) phi -= 2*M_PI;
00326 ceil = fabs(r_div_2) * omega_2;
00327 floor = -ceil;
00328 if( phase < 0.5 * M_PI )
00329 {
00330 ( r > 0 ? upslope : downslope ) = r_div_2 * omega_2 * omega_2 * cos(phase );
00331 ( r > 0 ? downslope : upslope ) = - omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * (phi - M_PI) ) + 0.5*M_PI - alpha);
00332 }
00333 else if( phase < M_PI )
00334 {
00335
00336 ( r > 0 ? downslope : upslope ) = - omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * (phi + M_PI) ) + 0.5*M_PI - alpha);
00337 }
00338 else if( phase < 1.5*M_PI )
00339 {
00340 ( r > 0 ? ceil : floor ) = 0;
00341 ( r > 0 ? upslope : downslope ) = (- r_div_2 * omega_2 * sin(phase )) / (duration - (t-t0));
00342 ( r > 0 ? downslope : upslope ) = r_div_2 * omega_2 * omega_2 * cos(phase );
00343 }
00344 else
00345 {
00346 ( r > 0 ? ceil : floor ) = 0;
00347 ( r > 0 ? upslope : downslope ) = (- r_div_2 * omega_2 * sin(phase )) / (duration - (t-t0));
00348 }
00349 }
00350 }
00351
00352 void func_sineshot_int::get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00353 {
00354 const real t0 = zerop;
00355 upslope = ceil = downslope = floor = 0.0;
00356 if( t < t0 || t >= t0 + duration )
00357 return;
00358 else
00359 {
00360 real phase = omega_2 * (t - t0);
00361 real phi = phase;
00362 ceil = fabs(r_div_2 * omega_2 * omega_2);
00363 floor = -ceil;
00364 if( phase < 0.5 * M_PI )
00365 {
00366 ( r > 0 ? upslope : downslope ) = omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00367 ( r > 0 ? downslope : upslope ) = - omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * (phi + M_PI) ) + 0.5*M_PI - alpha);
00368 }
00369 else if( phase < M_PI )
00370 {
00371 ( r > 0 ? upslope : downslope ) = omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00372 ( r > 0 ? downslope : upslope ) = - r_div_2 * omega_2 * omega_2 * omega_2 * sin( phase );
00373 }
00374 else if( phase < 1.5*M_PI )
00375 {
00376 ( r > 0 ? upslope : downslope ) = omega_2 * omega_2 * omega_2 * r_div_2 * cos( alpha * cos( beta * phi ) + 0.5*M_PI - alpha);
00377 }
00378 else
00379 {
00380 ( r > 0 ? upslope : downslope ) = - r_div_2 * omega_2 * omega_2 * omega_2 * sin( phase );
00381 ( r > 0 ? downslope : upslope ) = - (r_div_2 * omega_2 * omega_2 * cos(phase )) / (duration - (t-t0));
00382 ( r > 0 ? floor : ceil ) = 0;
00383 }
00384 }
00385 }
00386
00387
00388
00389
00390
00391 func_exp_diff::func_exp_diff(real iir1, real ipsi1, real iir2, real ipsi2, real iit0)
00392 : func_base(), psi1(ipsi1), psi2(ipsi2), t0orig(iit0), r1orig(iir1), r2orig(iir2)
00393 {
00394 it0 = t0orig;
00395 ir1 = r1orig;
00396 ir2 = r2orig;
00397 valueChange();
00398 };
00399
00400 void func_exp_diff::valueChange()
00401 {
00402 if( psi1 < 0.0 || psi2 <= psi1 || ir1 *ir2 <= 0.0 )
00403 {
00404 std::cout << "Abort!! bad condition!! " << std::endl;
00405 std::cout << "psi1 = " << psi1 << ", psi2 = "<< psi2 << ", ir1 = " << ir1 << ", ir2 = " << ir2 << std::endl;
00406 throw "func_exp_diff";
00407 }
00408
00409 phi = psi2 / psi1;
00410 real z = 2 * log( phi ) / (phi - 1);
00411 scale = psi1 / z;
00412 invscale = z / psi1;
00413 maxval = exp(-psi1 * 0.5 * invscale) - exp(-psi2 * 0.5 * invscale);
00414 xi = - psi1 * exp(-psi1 * invscale) + psi2 * exp(-psi2 * invscale);
00415
00416 t0 = (log(ir1/ir2))/(psi1-psi2);
00417 r0 = ir1 * exp( -psi1 * t0 );
00418
00419 t1 = (log(ir1*psi1/(ir2*psi2)))/(psi1-psi2);
00420 r1 = - ir1 * psi1 * exp( -psi1 * t1 );
00421
00422 t2 = (log(ir1*psi1*psi1/(ir2*psi2*psi2)))/(psi1-psi2);
00423 r2 = ir1 * psi1 * psi1 * exp( -psi1 * t2 );
00424
00425 if( fabs( ir1 * exp( -psi1 * t0 ) - ir2 * exp( -psi2 * t0 ) ) > 1e-5 )
00426 std::cout << "komatta 0! " << ir1 * exp( -psi1 * t0 ) << ", " << ir2 * exp( -psi2 * t0 ) << std::endl << getDescription() << std::endl;
00427 if( fabs( ir1 * psi1 * exp( -psi1 * t1 ) - ir2 * psi2 * exp( -psi2 * t1 ) ) > 1e-5 )
00428 std::cout << "komatta 1! " << ir1 * psi1 * exp( -psi1 * t1 ) << ", " << ir2 * psi2 * exp( -psi2 * t1 ) << std::endl;
00429 if( fabs( ir1 * psi1 * psi1 * exp( -psi1 * t2 ) - ir2 * psi2 * psi2 * exp( -psi2 * t2 ) ) > 1e-5 )
00430 std::cout << "komatta 2! " << ir1 * psi1 * psi1 * exp( -psi1 * t2 ) << ", " << ir2 * psi2 * psi2 * exp( -psi2 * t2 ) << std::endl;
00431
00432
00433
00434
00435 t0 += it0; t1 += it0; t2 += it0;
00436 phi = 0.3 *(log(phi)/log(10)) * (log(phi)/log(10)) + 2.45;
00437 }
00438
00439 void func_exp_diff::getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00440 {
00441 real val = getValue(t);
00442 real der = get1stDeriv(t);
00443
00444 if( t < t0 + 0.5 * invscale )
00445 {
00446 if( t < t0 )
00447 {
00448 if( r0 > 0 ) { ceil = maxval * r0; floor = val; upslope = der; downslope = 0; }
00449 else { floor = maxval * r0; ceil = val; downslope = der; upslope = 0; }
00450 }
00451 else
00452 {
00453 if( r0 > 0 ) { ceil = maxval * r0; floor = 0; upslope = der; downslope = r0 * xi * (1.0 - pow(1.0 - (t-t0)*scale, phi)); }
00454 else { floor = maxval * r0; ceil = 0; downslope = der; upslope = r0 * xi * (1.0 - pow(1.0 - (t-t0)*scale, phi)); }
00455 }
00456 }
00457 else if( t < t0 + 1.0 * invscale )
00458 {
00459 if( r0 > 0 ) { ceil = val; floor = 0; upslope = 0; downslope = r0 * xi * (1.0 - pow(1.0 - (t-t0)*scale, phi)); }
00460 else { floor = val; ceil = 0; downslope = 0; upslope = r0 * xi * (1.0 - pow(1.0 - (t-t0)*scale, phi)); }
00461 }
00462 else
00463 {
00464 if( r0 > 0 ) { ceil = val; floor = 0; upslope = 0; downslope = der; }
00465 else { floor = val; ceil = 0; downslope = 0; upslope = der; }
00466 }
00467 }
00468
00469 void func_exp_diff::get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00470 {
00471 real val = get1stDeriv(t);
00472 real der = get2ndDeriv(t);
00473
00474 if( t < t1 + 0.5 * invscale )
00475 {
00476 if( t < t1 )
00477 {
00478 if( r1 > 0 ) { ceil = maxval * r1; floor = val; upslope = der; downslope = 0; }
00479 else { floor = maxval * r1; ceil = val; downslope = der; upslope = 0; }
00480 }
00481 else
00482 {
00483 if( r1 > 0 ) { ceil = maxval * r1; floor = 0; upslope = der; downslope = r1 * xi * (1.0 - pow(1.0 - (t-t1)*scale, phi)); }
00484 else { floor = maxval * r1; ceil = 0; downslope = der; upslope = r1 * xi * (1.0 - pow(1.0 - (t-t1)*scale, phi)); }
00485 }
00486 }
00487 else if( t < t1 + 1.0 * invscale )
00488 {
00489 if( r1 > 0 ) { ceil = val; floor = 0; upslope = 0; downslope = r1 * xi * (1.0 - pow(1.0 - (t-t1)*scale, phi)); }
00490 else { floor = val; ceil = 0; downslope = 0; upslope = r1 * xi * (1.0 - pow(1.0 - (t-t1)*scale, phi)); }
00491 }
00492 else
00493 {
00494 if( r1 > 0 ) { ceil = val; floor = 0; upslope = 0; downslope = der; }
00495 else { floor = val; ceil = 0; downslope = 0; upslope = der; }
00496 }
00497 }
00498
00499 void func_exp_diff::get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const
00500 {
00501 real val = get2ndDeriv(t);
00502 real der = get3rdDeriv(t);
00503
00504 if( t < t2 + 0.5 * invscale )
00505 {
00506 if( t < t2 )
00507 {
00508 if( r2 > 0 ) { ceil = maxval * r2; floor = val; upslope = der; downslope = 0; }
00509 else { floor = maxval * r2; ceil = val; downslope = der; upslope = 0; }
00510 }
00511 else
00512 {
00513 if( r2 > 0 ) { ceil = maxval * r2; floor = 0; upslope = der; downslope = r2 * xi * (1.0 - pow(1.0 - (t-t2)*scale, phi)); }
00514 else { floor = maxval * r2; ceil = 0; downslope = der; upslope = r2 * xi * (1.0 - pow(1.0 - (t-t2)*scale, phi)); }
00515 }
00516 }
00517 else if( t < t2 + 1.0 * invscale )
00518 {
00519 if( r2 > 0 ) { ceil = val; floor = 0; upslope = 0; downslope = r2 * xi * (1.0 - pow(1.0 - (t-t2)*scale, phi)); }
00520 else { floor = val; ceil = 0; downslope = 0; upslope = r2 * xi * (1.0 - pow(1.0 - (t-t2)*scale, phi)); }
00521 }
00522 else
00523 {
00524 if( r2 > 0 ) { ceil = val; floor = 0; upslope = 0; downslope = der; }
00525 else { floor = val; ceil = 0; downslope = 0; upslope = der; }
00526 }
00527 }
00528
00529 bool func_exp_diff::processMessage(ntime_t t, const message_base &m)
00530 {
00531 #ifdef USE_DYNAMIC
00532 if( dynamic_cast<const message_add_event_time *>(&m) != NULL )
00533 #else
00534 if( m.getMessageId() == message_add_event_time::messageId )
00535 #endif
00536 {
00537 ir1 = r1orig + ir1 * exp( - psi1 * (t-it0) );
00538 ir2 = r2orig + ir2 * exp( - psi2 * (t-it0) );
00539 it0 = t;
00540 valueChange();
00541 return true;
00542 }
00543 return func_base::processMessage(t, m);
00544 }
00545
00546
00547 }