OMKPolator.h

Go to the documentation of this file.
00001 /************************************************************************/
00002 /* This file is part of openMask(c) INRIA, CNRS, Universite de Rennes 1 */
00003 /* 1993-2002, thereinafter the Software                                 */
00004 /*                                                                      */
00005 /* The Software has been developped within the Siames Project.          */
00006 /* INRIA, the University of Rennes 1 and CNRS jointly hold intellectual */
00007 /* property rights                                                      */
00008 /*                                                                      */
00009 /* The Software has been registered with the Agence pour la Protection  */
00010 /* des Programmes (APP) under registration number                       */
00011 /* IDDN.FR.001.510008.00.S.P.2001.000.41200                             */
00012 /*                                                                      */
00013 /* This file may be distributed under the terms of the Q Public License */
00014 /* version 1.0 as defined by Trolltech AS of Norway and appearing in    */
00015 /* the file LICENSE.QPL included in the packaging of this file.         */
00016 /*                                                                      */
00017 /* Licensees holding valid specific licenses issued by INRIA, CNRS or   */
00018 /* Universite Rennes 1 for the software may use this file in            */
00019 /* acordance with that specific license                                 */
00020 /************************************************************************/
00021 #ifndef OMKPolatorHEADER
00022 #define OMKPolatorHEADER
00023 
00024 #include "OMKTracer.h" 
00025 #include <OMKPolatorNT.h>
00026 
00027 namespace OMK 
00028 {
00029 template <typename T> class AbstractFifo ;
00030 namespace Type
00031 {
00032 
00036 template <typename T>
00037 class Polator : public PolatorNT 
00038 {
00039 public:
00041    Polator( AbstractFifo<T> * );
00042 
00044    Polator() ;
00045 
00048    Polator( int numberOfValuesForMaxPrecision ) ;
00049 
00051    virtual ~Polator() ;
00052 
00064    const T & polate( const int requestedPrecisionLevel,
00065                      const Date & t,
00066                      int & timeDistance,
00067                      T & resultPlaceHolder ) const ;
00068 
00079    virtual const T & interpolate( T & resultPlaceHolder,
00080                                   const int interpolateLevel,
00081                                   const Date & dateNeeded,
00082                                   const Date & dateAfter,
00083                                   const T & valueAfter,
00084                                   const Date & dateBefore,
00085                                   int offsetToMostRecentOfDateBefore ) const ;
00086 
00093    virtual const T & extrapolate( T & resultPlaceHolder,
00094                                   const int requestedPrecisionLevel,
00095                                   const Date & t,
00096                                   const Date & tIndex ) const ;
00097 
00104    virtual const T & antepolate( T & resultPlaceHolder,
00105                                  const int requestedPrecisionLevel,
00106                                  const Date & t,
00107                                  const Date & tIndex,
00108                                  unsigned int index ) const ;
00109 
00111    void setFifo( AbstractFifo<T> * fifo ) ;
00112 
00113 protected:
00114    // We get a value based on a given date :
00115    // if date is in the past, we get value in the fifo
00116    // if date is in future, we get last fifo value.
00117    //
00118    // These function calls to fifo are transparents for user.
00119 
00120    //\brief Returns number of values in the fifo.
00121    int getNumberOfPresentValues( int maxNeeded = -1 ) const ;
00122 
00131    const T & get( const int index ) const ;
00132 
00135    const Date & getDate( const int index ) const  ;
00136  
00137 protected:
00139    AbstractFifo<T> * _fifo ; 
00140 
00141 private:
00143    void initialisePolator() ;
00144 
00145 } ;
00146 
00147 } // namespace Type
00148 } // namespace OMK
00149 
00150 
00151 //------------------------------------------------------------------------------
00152 
00153 
00154 #include "OMKTracer.h"
00155 #include <OMKAbstractFifo.h>
00156 #include "OMKEmptyFifoException.h"
00157 
00158 namespace OMK 
00159 {
00160 namespace Type
00161 {
00162 
00163 //------------------------------------------------------------------------------
00164 template <typename T>
00165 inline Polator<T>::Polator() 
00166 : PolatorNT( 0 )
00167 {
00168   OMTRACEID( OMK_DEBUG_OMK_POL, "Polator default constructor without fifo" ) ;
00169   initialisePolator();
00170 }
00171 
00172 //------------------------------------------------------------------------------
00173 template <typename T>
00174 inline Polator<T>::Polator( int numberOfValuesForMaxPrecision ) 
00175 : PolatorNT( numberOfValuesForMaxPrecision )
00176 {
00177   OMTRACEID( OMK_DEBUG_OMK_POL,
00178              "Polator constructor with one parameter and without fifo" ) ;
00179   initialisePolator();
00180 }
00181 
00182 //------------------------------------------------------------------------------
00183 template <typename T>
00184 inline Polator<T>::Polator( AbstractFifo<T> * fifo ) 
00185 : PolatorNT( 0 )
00186 {
00187   OMTRACEID( OMK_DEBUG_OMK_POL, "Polator constructor with fifo" ) ;
00188   initialisePolator();
00189   _fifo = fifo ; 
00190 }
00191 
00192 //------------------------------------------------------------------------------
00193 template  <typename T>
00194 inline void Polator<T>::initialisePolator() 
00195 {
00196   _fifo = NULL ;
00197 }
00198 
00199 //------------------------------------------------------------------------------
00200 template <typename T>
00201 inline Polator<T>::~Polator()
00202 {
00203 }
00204 
00205 //------------------------------------------------------------------------------
00206 template <typename T>
00207 inline const T & Polator<T>::get( const int value ) const
00208 {
00209   return _fifo->getPreceedingValue( value ) ;
00210 }
00211 
00212 //------------------------------------------------------------------------------
00213 template <typename T>
00214 inline const Date & Polator<T>::getDate( const int value ) const
00215 {
00216   OMTRACEID( OMK_DEBUG_OMK_POL,
00217              "Polator<" << typeid( T ).name()
00218              << ">::" << this << "::getDate( " << value << " )");
00219   return _fifo->getPreceedingDate( value ) ;
00220 }
00221 
00222 //------------------------------------------------------------------------------
00223 template <typename T>
00224 inline void Polator<T>::setFifo( AbstractFifo<T> * fifo )
00225 {
00226   OMTRACEID( OMK_DEBUG_OMK_POL, "Polator<" << typeid( T ).name()
00227              << ">::setFifo" ) ;
00228   _fifo = fifo ;
00229 }
00230 
00231 //------------------------------------------------------------------------------
00232 template <typename T>
00233 inline int Polator<T>::getNumberOfPresentValues( int maxNeeded ) const
00234 {
00235   OMTRACEID( OMK_DEBUG_OMK_POL, "Polator<" << typeid( T ).name()
00236              << ">::getNumberOfPresentValues" ) ;
00237   return _fifo->getNumberOfPresentValues( maxNeeded ) ;
00238 }
00239 
00240 //------------------------------------------------------------------------------
00241 template <typename T>
00242 const T & Polator<T>::polate( const int requestedPrecisionLevel,
00243                               const Date & t,
00244                               int & timeDistance,
00245                               T & resultPlaceHolder ) const 
00246 {
00247   OMTRACEID( OMK_DEBUG_OMK_POL,
00248              "Polator<"  << typeid( T ).name()
00249              << ">::" << this << "::polate ("
00250              << requestedPrecisionLevel << "," << t << ") " ) ;
00251 
00252   int requestedPrecisionLevelPossible = requestedPrecisionLevel ;
00253   //_fifo->initialiseContext() ;
00254   int NumberOfPresentValues = getNumberOfPresentValues(
00255     requestedPrecisionLevel + 1 ) ;
00256   
00257   OMTRACEID( OMK_DEBUG_OMK_POL,
00258              "Polator<" << typeid( T ).name()
00259              << ">::" << this << "::polate : NumberOfPresentValues : "
00260              << NumberOfPresentValues ) ;
00261 
00262   if( NumberOfPresentValues == 0 )
00263   {
00264     throw EmptyFifoException( "Polator fifo is empty" ) ;
00265   }
00266 
00267   // Same test for antepolate and extrapolate
00268   // ------------------------------------------------
00269   if( NumberOfPresentValues <= requestedPrecisionLevel )
00270   {
00271     requestedPrecisionLevelPossible = NumberOfPresentValues - 1 ;
00272   }
00273 
00274   const Date & dateOfLastValue( getDate( 0 ) );
00275 
00276   OMASSERTM( dateOfLastValue != -1, "Date of last value not initialised" ) ;
00277 
00278   if( dateOfLastValue < t ||
00279       ( dateOfLastValue == t
00280         && PolatorNT::ConstantContinuous <= requestedPrecisionLevel ) )
00281   {
00282     OMTRACEID( OMK_DEBUG_OMK_POL, "Extrapolation case" ) ;
00283     timeDistance = t - dateOfLastValue ;
00284     
00285     // here, we have to do an extrapolation
00286     // OMASSERT( t != dateOfLastValue ) ;
00287     OMASSERT( NumberOfPresentValues != 1 ||
00288               requestedPrecisionLevelPossible == 0 ) ;
00289     return extrapolate( resultPlaceHolder,
00290                         requestedPrecisionLevelPossible,
00291                         t,
00292                         dateOfLastValue );
00293   }
00294 
00295   // Here, current state is : t <= dateOfLastValues
00296   // So, we have 3 cases :
00297   // - we get a value corresponding to t
00298   // - we interpolate
00299   // - we antepolate
00300   int index = 0 ; // nearest index in the fifo corresponding to date t
00301   unsigned int numberOfValuesInFifoNeededToContinueExamination = 2 ;
00302 
00303   Date const * examinedDate = & dateOfLastValue ;
00304   Date const * dateExaminedBefore = NULL ;
00305   T const * valueExaminedBefore = NULL ;
00306 
00307   bool notFound = true ;  // end of iteration
00308   bool exact = false ;    // interpolation needed
00309   if( *examinedDate == t )
00310   {
00311     notFound = false ;
00312     exact = true ;
00313   }
00314 
00315   OMTRACEID( OMK_DEBUG_OMK_POL,
00316              "Polator<" << typeid( T ).name() 
00317              << ">::polate : finding values loop..." << t ) ;
00318 
00319   while( notFound &&
00320          ( numberOfValuesInFifoNeededToContinueExamination <=
00321            _fifo->getNumberOfPresentValues(
00322              numberOfValuesInFifoNeededToContinueExamination ) ) )
00323   {
00324     OMTRACEID( OMK_DEBUG_OMK_POL, "loop status variables : "
00325                << notFound <<" "
00326                << examinedDate <<" "
00327                << exact <<" "
00328                << t <<" "
00329                << index <<" "
00330                << numberOfValuesInFifoNeededToContinueExamination ) ;
00331     dateExaminedBefore = examinedDate ;
00332     valueExaminedBefore = & get( index ) ;
00333     index++ ;
00334     examinedDate = & getDate( index ) ;
00335 
00336     if( *examinedDate == t )
00337     {
00338       notFound = false ;
00339       exact = true ;
00340     }
00341     else if( *examinedDate < t )
00342     {
00343       notFound = false ;
00344       exact = false ;
00345     }
00346 
00347     ++numberOfValuesInFifoNeededToContinueExamination ;
00348 #ifdef _DEBUGATTRIBUTSMOME
00349     if( 4 < index )
00350       std::cerr << "checking a value further " << NumberOfPresentValues
00351                 << " " << examinedDate << " " << t << std::endl ;
00352 #endif
00353   }
00354 
00355   if( t < *examinedDate )
00356   { //because of relaxed coherance, this can sometimes happen
00357     return antepolate( resultPlaceHolder,
00358                        requestedPrecisionLevelPossible,
00359                        t,
00360                        *examinedDate,
00361                        index );
00362   }
00363 
00364   // Here,
00365   //   dateOfOldestValueAvailable <= examinedDate <= t <= oldExaminedDate <= dateOfLastValue,
00366   // with examinedDate == t if exact
00367 
00368   timeDistance = t - *examinedDate ;
00369   if( !exact )
00370   {
00371     OMASSERTM( dateExaminedBefore != NULL,
00372                "Pointer dateExaminedBefore must be valid" ) ;
00373     OMASSERTM( valueExaminedBefore != NULL,
00374                "Pointer valueExaminedBefore must be valid" ) ;
00375     return interpolate( resultPlaceHolder,
00376                         requestedPrecisionLevelPossible, 
00377                         t, 
00378                         *dateExaminedBefore, 
00379                         *valueExaminedBefore,
00380                         *examinedDate, 
00381                         index ) ;
00382   }
00383   else
00384   {
00385     return get( index ) ;
00386   }
00387 }
00388 
00389 //------------------------------------------------------------------------------
00390 //   t -> date where we are looking for a value
00391 //   tIndex -> date of index that we will use to find a new value
00392 //   
00393 //                       -tIndex depends on linear, PolatorNT::Quadratic ,etc.
00394 //
00395 //           l   q  c
00396 //       ------------- 
00397 //       |t |tI|tI|tI|
00398 //       -------------
00399 //
00400 //
00401 //   t < tIndex
00402 //
00403 
00404 //------------------------------------------------------------------------------
00405 template <typename T>
00406 inline 
00407 const T & Polator<T>::interpolate( T & resultPlaceHolder,
00408                                    const int interprecisionLevel,
00409                                    const Date& dateNeeded,
00410                                    const Date& dateAfter,
00411                                    const T& valueAfter,
00412                                    const Date& dateBefore,
00413                                    int offsetToMostRecentOfDateBefore ) const 
00414 {
00415   OMTRACEID( OMK_DEBUG_OMK_POL,
00416              "*********************************************" << std::endl 
00417              << "Polator<" << typeid( T ).name()
00418              << ">::interpolate (Default)" << std::endl
00419              << "Date dateAfter <----- : " << dateAfter << std::endl
00420              << "Date dateNeeded <----- : " << dateNeeded << std::endl
00421              << "Date dateBefore <----- : " << dateBefore << std::endl
00422              << "T : valueAfter " << valueAfter << std::endl
00423              << "int : offsetToMostRecentOfDateBefore "
00424              << offsetToMostRecentOfDateBefore ) ;
00425   resultPlaceHolder =
00426     ( ( dateAfter - dateNeeded ) <= ( dateNeeded - dateBefore ) ) ?
00427     valueAfter : get( offsetToMostRecentOfDateBefore ) ;
00428   return resultPlaceHolder ; 
00429 }
00430 
00431 //------------------------------------------------------------------------------
00432 template <typename T>
00433 inline 
00434 const T & Polator<T>::extrapolate( T & resultPlaceHolder,
00435                                    const int requestedPrecisionLevel,
00436                                    const Date& t,
00437                                    const Date& tIndex ) const
00438 {
00439   OMTRACEID( OMK_DEBUG_OMK_POL,
00440              "*********************************************" << std::endl
00441              << "Polator<" << typeid( T ).name()
00442              << ">::extrapolate (Default)" << std::endl
00443              << "Date t <----- : " << t << std::endl 
00444              << "Date tIndex <----- : " << tIndex << std::endl
00445              << "Interpolation level : "
00446              << requestedPrecisionLevel << std::endl
00447              << "*********************************************" ) ;
00448   return get( 0 ); 
00449 }
00450 
00451 //------------------------------------------------------------------------------
00452 template <typename T>
00453 inline 
00454 const T & Polator<T>::antepolate( T& resultPlaceHolder,
00455                                   const int requestedPrecisionLevel,
00456                                   const Date& t,
00457                                   const Date& tIndex,
00458                                   unsigned int index ) const
00459 {
00460   OMTRACEID( OMK_DEBUG_OMK_POL,
00461              "*********************************************" << std::endl 
00462              << "Polator<" << typeid( T ).name() << ">::antepolate" << std::endl
00463              << "Date t <----- : " << t << std::endl
00464              << "Date tIndex <----- : " << tIndex << std::endl 
00465              << "Interpolation level : " << requestedPrecisionLevel
00466              << std::endl 
00467              << "index of last element : " << index << std::endl 
00468              << "*********************************************" ) ;
00469   return get( index );
00470 }
00471 
00472 //------------------------------------------------------------------------------
00473 } // namespace Type
00474 } // namespace OMK
00475 
00476 #endif

logo OpenMask

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

Generated with doxygen by Dimitri van Heesch ,   1997-2007