00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 00019 #ifndef OMKPolatorNUMERIQUEHEADER 00020 #define OMKPolatorNUMERIQUEHEADER 00021 00022 //template <class Type> class AbstractFifo; 00023 #include <OMKPolator.h> 00024 #include "OMKUserException.h" 00025 #include "OMKTracer.h" 00026 //------------------------------------------------------------------------ 00027 namespace OMK 00028 { 00029 namespace Type 00030 { 00031 00035 template <typename Type> 00036 class NumericPolatorT : public Polator< SimpleTypeT< Type > > 00037 { 00038 public: 00039 using Polator< SimpleTypeT<Type> >::get ; 00040 using Polator< SimpleTypeT<Type> >::getDate ; 00041 using Polator< SimpleTypeT<Type> >::getNumberOfPresentValues ; 00042 00043 public: 00044 00045 NumericPolatorT(void) ; 00046 virtual ~NumericPolatorT(void) ; 00047 00048 virtual const SimpleTypeT< Type > & 00049 interpolate( SimpleTypeT< Type > & resultPlaceHolder, 00050 const int interprecisionLevel, 00051 const Date & dateNeeded, 00052 const Date & dateAfter, 00053 const SimpleTypeT<Type> & valueAfter, 00054 const Date & dateBefore, 00055 int offsetToMostRecentOfDateBefore ) const ; 00056 00057 virtual const SimpleTypeT< Type > & 00058 extrapolate( SimpleTypeT< Type > & resultPlaceHolder, 00059 const int requestedPrecisionLevel, 00060 const Date & t, 00061 const Date & tIndice ) const ; 00062 virtual const SimpleTypeT< Type > & 00063 antepolate( SimpleTypeT< Type > & resultPlaceHolder, 00064 const int requestedPrecisionLevel, 00065 const Date & t, 00066 const Date & tIndice, 00067 unsigned int indice ) const ; 00068 private: 00070 static Type convert( double v ) ; 00071 public: 00078 static Type linearInterpolate( long t, 00079 long t1, Type v1, 00080 long t0, Type v0 ) 00081 { 00082 return linearExtrapolate( t, t1, v1, t0, v0 ) ; 00083 } 00084 00093 static Type quadraticInterpolate( long t, 00094 long t2, Type v2, 00095 long t1, Type v1, 00096 long t0, Type v0 ) 00097 { 00098 return quadraticExtrapolate( t, t2, v2, t1, v1, t0, v0 ) ; 00099 } 00100 00101 00112 static Type cubicInterpolate( long t, 00113 long t3, Type v3, 00114 long t2, Type v2, 00115 long t1, Type v1, 00116 long t0, Type v0 ) 00117 { 00118 return cubicExtrapolate( t, t3, v3, t2, v2, t1, v1, t0, v0 ) ; 00119 } 00120 00121 00122 00130 static Type linearExtrapolate( long t, 00131 long t1, Type v1, 00132 long t0, Type v0 ) 00133 { 00134 double d0 = t1 - t0 ; OMASSERTM ( d0, "Will divide by 0" ) ; 00135 double f0 = t - t0 ; 00136 // formula : ((t - t0) / d0) * v1 +((t1 - t) / d0)* v0 ; 00137 return convert( ( v1 - v0 ) * ( f0 / d0 ) + v0 ) ; 00138 } 00139 00140 00150 static Type quadraticExtrapolate( long t, 00151 long t2, Type v2, 00152 long t1, Type v1, 00153 long t0, Type v0 ) 00154 { 00155 double d0 = t1 - t0 ; OMASSERTM( d0, "Will divide by 0" ) ; 00156 double d1 = t2 - t0 ; OMASSERTM( d1, "Will divide by 0" ) ; 00157 double d2 = t1 - t2 ; OMASSERTM( d2, "Will divide by 0" ) ; 00158 00159 double k0 = ( t - t1 ) / d1 ; 00160 double k1 = ( t - t2 ) / d0 ; 00161 double k2 = ( t - t0 ) / d2 ; 00162 // formula : (v1*(k2*k1)) - (v2*(k2*k0)) + ((k0*k1)*v0) 00163 return convert( ( ( v1 - v0 ) * k1 - ( v2 - v0 ) * k0 ) * k2 + v0 ) ; 00164 } 00165 00166 00178 static Type cubicExtrapolate( long t, 00179 long t3, Type v3, 00180 long t2, Type v2, 00181 long t1, Type v1, 00182 long t0, Type v0 ) 00183 { 00184 double d0 = t0 - t1 ; OMASSERTM( d0, "Will divide by 0" ) ; 00185 double d1 = t2 - t0 ; OMASSERTM( d1, "Will divide by 0" ) ; 00186 double d2 = t0 - t3 ; OMASSERTM( d2, "Will divide by 0" ) ; 00187 double d3 = t1 - t2 ; OMASSERTM( d3, "Will divide by 0" ) ; 00188 double d4 = t1 - t3 ; OMASSERTM( d4, "Will divide by 0" ) ; 00189 double d5 = t3 - t2 ; OMASSERTM( d5, "Will divide by 0" ) ; 00190 00191 double f0 = t - t0 ; 00192 double f1 = t - t1 ; 00193 double f2 = t - t2 ; 00194 double f3 = t - t3 ; 00195 00196 double k0 = f1 * ( f2 / d2 ) ; 00197 double k1 = f0 * ( f3 / d3 ) ; 00198 // formula : v3*((f0/d5)*(k0/d4))+v2*((f1/d1)*(k1/d5))-v1*((k1/d0)*(f2/d4))-v0*((k0/d0)*(f3/d1)) 00199 return convert( ( v3 - v0 ) * ( ( f0 / d5 ) * ( k0 / d4 ) ) 00200 + ( v2 - v0 ) * ( ( f1 / d1 ) * ( k1 / d5 ) ) 00201 - ( v1 - v0 ) * ( ( k1 / d0 ) * ( f2 / d4 ) ) 00202 + v0 ) ; 00203 } 00204 }; 00206 template <> 00207 inline int NumericPolatorT<int>::convert( double v ) 00208 { 00209 return (int)v ; 00210 } 00212 template <> 00213 inline float NumericPolatorT<float>::convert( double v ) 00214 { 00215 return (float)v ; 00216 } 00218 template <> 00219 inline double NumericPolatorT<double>::convert( double v ) 00220 { 00221 return v ; 00222 } 00223 /* 00225 template < typename Type > 00226 inline Type NumericPolatorT< Type >::convert( double v ) 00227 { 00228 return (Type)v ; 00229 } 00230 */ 00231 00232 //--------------------------------------------------------------- 00233 template <typename Type> 00234 inline NumericPolatorT<Type>::NumericPolatorT() : Polator< SimpleTypeT<Type> > (3) 00235 { 00236 } 00237 00238 //--------------------------------------------------------------- 00239 template <typename Type> 00240 inline NumericPolatorT<Type>::~NumericPolatorT() 00241 { 00242 } 00243 //------------------------------------------------------------------------ 00244 00245 template <typename Type> 00246 inline const SimpleTypeT<Type> & 00247 NumericPolatorT<Type>::interpolate( SimpleTypeT< Type >& resultPlaceHolder, 00248 const int interprecisionLevel, 00249 const Date & dateNeeded, 00250 const Date & dateAfter, 00251 const SimpleTypeT<Type> & valueAfter, 00252 const Date & dateBefore, 00253 int offsetToMostRecentOfDateBefore ) const 00254 { 00255 00256 #ifdef _DEBUGTYPEUTIL 00257 cout << "*********************************************" << endl ; 00258 cout << "NumericPolatorT<Type>::interpolate" << endl; 00259 cout << "interpolate level : " << interprecisionLevel <<endl ; 00260 cout << "Date dateAfter <----- : " << dateAfter << endl ; 00261 cout << "Date dateNeeded <----- : " << dateNeeded << endl ; 00262 cout << "Date dateBefore <----- : " << dateBefore << endl ; 00263 cout << "Type : valueAfter " << valueAfter << endl ; 00264 cout << "int : offsetToMostRecentOfDateBefore " << offsetToMostRecentOfDateBefore << endl ; 00265 cout << "*********************************************" << endl ; 00266 #endif 00267 00268 switch ( interprecisionLevel ) 00269 { 00270 case PolatorNT::Constant : 00271 case PolatorNT::ConstantContinuous : 00272 resultPlaceHolder = ( ( dateAfter - dateNeeded ) <= ( dateNeeded - dateBefore ) ) ? 00273 valueAfter : get (offsetToMostRecentOfDateBefore) ; 00274 break ; 00275 case PolatorNT::Linear : 00276 case PolatorNT::LinearContinuous : 00277 resultPlaceHolder = 00278 linearInterpolate( dateNeeded, 00279 dateAfter, (Type)valueAfter, 00280 dateBefore, (Type)get( offsetToMostRecentOfDateBefore ) ) ; 00281 break ; 00282 case PolatorNT::Quadratic : 00283 case PolatorNT::QuadraticContinuous : 00284 resultPlaceHolder = 00285 quadraticInterpolate( dateNeeded, 00286 dateAfter, (Type)valueAfter, 00287 dateBefore, (Type)get (offsetToMostRecentOfDateBefore) , 00288 getDate( offsetToMostRecentOfDateBefore + 1 ), 00289 (Type)get( offsetToMostRecentOfDateBefore + 1 ) ) ; 00290 break ; 00291 case PolatorNT::Cubic : 00292 case PolatorNT::CubicContinuous : 00293 resultPlaceHolder = 00294 cubicInterpolate( dateNeeded, 00295 dateAfter, (Type)valueAfter, 00296 dateBefore, (Type)get( offsetToMostRecentOfDateBefore ), 00297 getDate( offsetToMostRecentOfDateBefore + 1 ), 00298 (Type)get( offsetToMostRecentOfDateBefore + 1 ), 00299 getDate( offsetToMostRecentOfDateBefore + 2 ), 00300 (Type)get( offsetToMostRecentOfDateBefore + 2 ) ) ; 00301 break ; 00302 default : 00303 OMTRACEID( OMK_DEBUG_OMK_TYPE, "NumericPolatorT<Type>::interpolate : unknown polation level, using PolatorNT::Constant" ) ; 00304 resultPlaceHolder = ( ( dateAfter - dateNeeded ) <= ( dateNeeded - dateBefore ) ) ? 00305 valueAfter : get( offsetToMostRecentOfDateBefore ) ; 00306 break ; 00307 } 00308 return resultPlaceHolder ; 00309 } 00310 00311 //------------------------------------------------------------------------ 00312 template <typename Type> 00313 inline 00314 const SimpleTypeT<Type>& 00315 NumericPolatorT<Type>::extrapolate( SimpleTypeT<Type> & resultPlaceHolder, 00316 const int requestedPrecisionLevel, 00317 const Date & t, 00318 const Date & tIndice ) const 00319 { 00320 //extrapolate ŕ la sauce David Margery 00321 //il s'agit d'une extrapolation par morceaux 00322 //on cherche ŕ trouver la valeur ŕ t 00323 #ifdef _DEBUGPOLATION 00324 cerr << "NumericPolatorT<Type>::extrapolate (" <<requestedPrecisionLevel<<", "<<t<<", "<<tIndice<<")"<<endl; 00325 #endif 00326 switch (requestedPrecisionLevel) 00327 { 00328 case PolatorNT::Constant : 00329 resultPlaceHolder = get( 0 ) ; 00330 break ; 00331 case PolatorNT::ConstantContinuous : 00332 resultPlaceHolder = get( 0 ) ; 00333 if( 1 < getNumberOfPresentValues() ) 00334 { 00335 resultPlaceHolder.setValue( 00336 linearInterpolate( t, tIndice, (Type)get( 1 ), 00337 2 * tIndice - getDate( 1 ), (Type)get( 0 ) ) ) ; 00338 } 00339 break ; 00340 case PolatorNT::Linear : 00341 resultPlaceHolder.setValue( 00342 linearExtrapolate( t, tIndice, (Type)get( 0 ), 00343 getDate( 1 ), (Type)get( 1 ) ) ) ; 00344 break ; 00345 case PolatorNT::LinearContinuous : 00346 resultPlaceHolder.setValue( 00347 linearExtrapolate( t, tIndice, (Type)get( 0 ), 00348 getDate( 1 ), (Type)get( 1 ) ) ) ; 00349 if( 2 < getNumberOfPresentValues() ) 00350 { 00351 Type oldResult = 00352 linearExtrapolate( t, getDate( 1 ), (Type)get( 1 ), 00353 getDate( 2 ), (Type)get( 2 ) ) ; 00354 resultPlaceHolder.setValue( 00355 linearInterpolate( t, tIndice, oldResult, 00356 2 * tIndice - getDate( 1 ), (Type)resultPlaceHolder ) ) ; 00357 } 00358 break ; 00359 00360 case PolatorNT::Quadratic : 00361 resultPlaceHolder.setValue( 00362 quadraticExtrapolate( t, tIndice, (Type)get( 0 ), 00363 getDate( 1 ), (Type)get( 1 ), 00364 getDate( 2 ), (Type)get( 2 ) ) ) ; 00365 break; 00366 case PolatorNT::QuadraticContinuous : 00367 resultPlaceHolder.setValue( 00368 quadraticExtrapolate( t, tIndice, (Type)get( 0 ), 00369 getDate( 1 ), (Type)get( 1 ), 00370 getDate( 2 ), (Type)get( 2 ) ) ) ; 00371 00372 if( getNumberOfPresentValues() > 3 ) 00373 { 00374 Type oldResult= 00375 quadraticExtrapolate( t, getDate( 1 ), (Type)get( 1 ), 00376 getDate( 2 ), (Type)get( 2 ), 00377 getDate( 3 ), (Type)get( 3 ) ) ; 00378 resultPlaceHolder.setValue( 00379 linearInterpolate( t, tIndice, oldResult, 00380 2 * tIndice - getDate( 1 ), (Type)resultPlaceHolder ) ) ; 00381 } 00382 break; 00383 00384 case PolatorNT::Cubic : 00385 resultPlaceHolder.setValue( cubicExtrapolate( t, tIndice, (Type)get( 0 ), 00386 getDate( 1 ), (Type)get( 1 ), 00387 getDate( 2 ), (Type)get( 2 ), 00388 getDate( 3 ), (Type)get( 3 ) ) ) ; 00389 break; 00390 00391 case PolatorNT::CubicContinuous : 00392 resultPlaceHolder.setValue( cubicExtrapolate( t, tIndice, (Type)get( 0 ), 00393 getDate( 1 ), (Type)get( 1 ), 00394 getDate( 2 ), (Type)get( 2 ), 00395 getDate( 3 ), (Type)get( 3 ) ) ) ; 00396 if( 4 < getNumberOfPresentValues() ) 00397 { 00398 Type oldResult= 00399 cubicExtrapolate( t, getDate( 1 ), (Type)get( 1 ), 00400 getDate( 2 ), (Type)get( 2 ), 00401 getDate( 3 ), (Type)get( 3 ), 00402 getDate( 4 ), (Type)get( 4 ) ) ; 00403 resultPlaceHolder.setValue( 00404 linearInterpolate( t, tIndice, oldResult, 00405 2*tIndice - getDate( 1 ), (Type)resultPlaceHolder ) ) ; 00406 } 00407 00408 break; 00409 default : 00410 OMTRACEID( OMK_DEBUG_OMK_TYPE, "NumericPolatorT<Type>::interpolate : unknown polation level, using PolatorNT::Constant" ) ; 00411 resultPlaceHolder = get( 0 ) ; 00412 } 00413 return resultPlaceHolder ; 00414 } 00415 //------------------------------------------------------------------------ 00416 template <typename Type> 00417 inline 00418 const SimpleTypeT<Type> & 00419 NumericPolatorT<Type>::antepolate ( SimpleTypeT< Type >& resultPlaceHolder, 00420 const int requestedPrecisionLevel, 00421 const Date& t, 00422 const Date& tIndice, 00423 unsigned int indice ) const 00424 { 00425 00426 #ifdef _DEBUGTYPEUTIL 00427 cout << "*********************************************" << endl ; 00428 cout << "NumericPolatorT<Type>::antepolate" << endl; 00429 cout << "Date t <----- : " << t << endl ; 00430 cout << "Date tIndice <----- : " << tIndice << endl ; 00431 cout << "polation level : " << requestedPrecisionLevel << endl ; 00432 cout << "index " << indice << endl ; 00433 cout << "*********************************************" << endl ; 00434 #endif 00435 00436 switch (requestedPrecisionLevel) 00437 { 00438 case PolatorNT::Constant : 00439 case PolatorNT::ConstantContinuous : 00440 resultPlaceHolder = get( indice ) ; 00441 break ; 00442 case PolatorNT::Linear : 00443 case PolatorNT::LinearContinuous : 00444 resultPlaceHolder = 00445 linearExtrapolate( t, tIndice, (Type)get( indice ), 00446 getDate( indice - 1 ), (Type)get( indice - 1 ) ) ; 00447 break ; 00448 case PolatorNT::Quadratic : 00449 case PolatorNT::QuadraticContinuous : 00450 resultPlaceHolder = 00451 quadraticExtrapolate( t, tIndice, (Type)get( indice ), 00452 getDate( indice - 1 ), (Type)get( indice - 1 ), 00453 getDate( indice - 2 ), (Type)get( indice - 2 ) ) ; 00454 break; 00455 case PolatorNT::Cubic : 00456 case PolatorNT::CubicContinuous : 00457 resultPlaceHolder = 00458 cubicExtrapolate( t, tIndice, (Type)get( indice ), 00459 getDate( indice - 1 ), (Type)get( indice - 1 ), 00460 getDate( indice - 2 ), (Type)get( indice - 2 ), 00461 getDate( indice - 3 ), (Type)get( indice - 3 ) ) ; 00462 break; 00463 default : 00464 OMTRACEID( OMK_DEBUG_OMK_TYPE, "NumericPolatorT<Type>::interpolate : unknown polation level, using PolatorNT::Constant" ) ; 00465 resultPlaceHolder = get(indice) ; 00466 } 00467 return resultPlaceHolder ; 00468 } 00469 } // namespace Type 00470 } // namespace OMK 00471 00472 00473 #endif 00474 00475 00476 00477 00478 00479 00480 00481 00482 00483
Documentation generated on Mon Jun 9 11:45:57 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |