OMKNumericPolator.h

Go to the documentation of this file.
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 

logo OpenMask

Documentation generated on Mon Jun 9 11:45:57 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007