LinearIpol.hpp

00001 #ifndef __IPOL_LINEAR_HPP
00002 #define __IPOL_LINEAR_HPP
00003 
00004 //#include <iostream>
00005 #include "IpolDelimiter.hpp"
00006 #include <assert.h>
00007 
00008 namespace Fiber
00009 {
00010 //using namespace std;
00011 
00023 template <class T>
00024 struct  LinearIpolZeroDerivativeTrait
00025 {
00026 static  T zero()
00027         {
00028                 return T(0);
00029         }
00030 };
00031 
00038 template <class T, bool Vectorial = false>
00039 class   LinearIpol
00040 {
00041 public:
00043         typedef T value_type;
00044 
00045         template <class Storage1D, class Limiter>
00046 static  T interpolate(const Storage1D&Data, double t, index_t size, const Limiter&L)
00047         {
00048                 assert(size > 0); 
00049 
00050 //              cout << "LinearIpol @ "<< t << " of " << size << endl;
00051 //              printf("LinearIpol():%lg of %d\n", t, int(size) ); 
00052 
00053                 if (t<=0      ) return L.limit(Data[ 0 ]   );
00054                 if (t+1>=size ) return L.limit(Data[size-1]);
00055 
00056         index_t i = index_t(t); 
00057                 t = t - floor(t); 
00058 
00059                 if (t==0.0)
00060                         return L.limit(Data[i]); 
00061 
00062 //              cout << "   LinearIpol: [" << i << "]=" << Data[i] << ", [" << i+1 << "]="<<Data[i+1]<<" @ " << t << endl; 
00063 
00064 //              printf("LinearIpol(%d,%d)@%lg\n",i,i+1, t);
00065                 return L.limit(Data[i]) * (1-t) + L.limit(Data[i+1]) * t;
00066         }
00067 
00068         template <class Storage1D, class Limiter>
00069 static  T derivative(const Storage1D&Data, double t, index_t size, const Limiter&L)
00070         {
00071 //              assert(size > 1); 
00072 
00073 // need to think about return value here, since T might not always have a constructor with 0 value
00074 // maybe need a type trait here
00075                 if (t<0       ) return LinearIpolZeroDerivativeTrait<T>::zero();
00076                 if (t>=size-1 ) return LinearIpolZeroDerivativeTrait<T>::zero();
00077 
00078         index_t i = index_t(t); 
00079 //              printf("LinearIpol Derivative(%d,%d)@%lg\n",i,i+1, t);
00080                 return L.limit(Data[i+1]) - L.limit(Data[i]);
00081         }
00082 };
00083 
00084 
00090 template <class T>
00091 class   LinearIpol<T, true>
00092 {
00093 public:
00095         typedef T value_type;
00096 
00097         template <class Storage1D, class Limiter>
00098 static  T interpolate(const Storage1D&Data, double t, index_t size, const Limiter&L)
00099         {
00100                 assert(size > 0); 
00101 
00102                 if (t<=0      ) return L.limit(Data[ 0 ]   );
00103                 if (t+1>=size ) return L.limit(Data[size-1]);
00104 
00105         index_t i = index_t(t); 
00106                 t = t - floor(t); 
00107 
00108                 if (t==0.0)
00109                         return L.limit(Data[i]);
00110 
00111                 return L.limit(Data[i]) + (L.limit(Data[i+1]) - L.limit(Data[i])) * t;
00112         }
00113 
00114         template <class Storage1D, class Limiter>
00115 static  T derivative(const Storage1D&Data, double t, index_t size, const Limiter&L)
00116         {
00117 //              assert(size > 1); 
00118 
00119                 //if (t<0       ) return T(0); 
00120                 //if (t>=size-1 ) return T(0);
00121 
00122         index_t i = index_t(t); 
00123         //      printf("LinearIpol Derivative(%d,%d)@%lg\n",i,i+1, t);
00124                 return L.limit(Data[i+1]) - L.limit(Data[i]);
00125         }
00126 };
00127 
00128 } /* namespace Fiber */ 
00129 
00130 #endif /* __IPOL_LINEAR_HPP */