CubicIpol.hpp

00001 
00002 //
00003 // $Id: CubicIpol.hpp,v 1.3 2007/02/22 19:55:34 werner Exp $
00004 //
00005 // $Log: CubicIpol.hpp,v $
00006 // Revision 1.3  2007/02/22 19:55:34  werner
00007 // adjusted fixed array interface
00008 //
00009 // Revision 1.2  2006/07/30 20:43:42  werner
00010 // Partial Derivative of multidimensional arrays enabled.
00011 //
00012 // Revision 1.1  2006/07/07 14:10:53  werner
00013 // Intermediate state: multidimensional interpolation with on-demand
00014 // fractional loading appears to work, but still problem with vectorfield
00015 // interpolation.
00016 //
00017 // Revision 1.9  2004/08/17 16:59:52  werner
00018 // Towards compilation with gcc 3.3.3
00019 //
00020 // Revision 1.8  2004/08/12 16:08:45  werner
00021 // Various improvements for implementing the tangential space
00022 //
00023 // Revision 1.7  2004/07/14 15:45:14  werner
00024 // Outsourcing of quadratic matrices into its own header file.
00025 // Added great gaus decomposition from Marcus Weber that allows
00026 // multiple right-hand sides.
00027 //
00028 // Revision 1.6  2004/07/12 10:29:24  werner
00029 // Computing Lower Christoffels in demo application.
00030 //
00031 // Revision 1.5  2004/07/09 20:15:26  werner
00032 // Added local alignment capability when interpolating vector fields and
00033 // option to compute the interpolated derivative.
00034 //
00035 // Revision 1.4  2004/07/04 17:24:03  werner
00036 // Recursive multidimensional Interpolation interface implemented.
00037 //
00038 // Revision 1.3  2004/06/18 23:29:46  werner
00039 // Intermediate version that supports the recursive interpolation scheme.
00040 // Need to beautify the interface, fix some indexing bug, and make it to
00041 // work with the ViewPtr.
00042 //
00043 // Revision 1.2  2004/06/15 22:45:31  werner
00044 // Enhanced the fixed array member functions.
00045 // Using better name for interpolation template parameters.
00046 //
00047 // Revision 1.1  2004/06/14 22:42:00  werner
00048 // Moved interpolation files from light++ to VecAl and Multindex from Fiber to VecAl.
00049 //
00051 #ifndef __IPOL_CUBIC_HPP
00052 #define __IPOL_CUBIC_HPP "Created 11.06.2004 22:28:21 by bzfbenge"
00053 
00054 #include "Index.hpp"
00055 #include <eagle/vecmath.hpp>
00056 #include <assert.h>
00057 
00058 namespace Fiber
00059 {
00060 
00068 template <class T>
00069 class   CubicIpol
00070 {
00071 public:
00073         typedef T value_type;
00074 
00075         template <class Storage1D, class Limiter>
00076 static  T interpolate(const Storage1D&Data, double t, index_t size, const Limiter&L)
00077         {
00078                 // TODO: Check for Samplings.size() < 2 !
00079                 assert(size > 2);
00080 
00081         //      printf("CubicIpol[%lg]\n", t);
00082 
00083                 if (t<0     ) return L.limit(Data[0]     );
00084                 if (t>=size ) return L.limit(Data[size-1]);
00085 
00086         const double derivation_factor = 2;
00087 
00088         index_t i = index_t(t); 
00089         double  x = t - floor(t); 
00090         double  x2 = x*x,
00091                 x3 = x2*x,
00092 
00093                 // Hermite'sche Polynome
00094                 h00 =  2*x3 - 3*x2 + 1,
00095                 h10 =  1 - h00,
00096                 h01 = x3 - 2*x2 + x,
00097                 h11 = x3 - x2;
00098 
00099                 // Boundary conditions.
00100         index_t i_1 = i-1, i1 = i+1, i2 = i+2;
00101                 if (i_1<0 || i_1>=size) i_1 = 0;
00102                 if (i < 0   )           i  = 0;
00103                 if (i >=size)           i  = size-1;
00104                 if (i1<0)               i1 = 0;
00105                 if (i2<0)               i2 = 0;
00106                 if (i1>=size)           i1 = size-1;
00107                 if (i2>=size)           i2 = size-1;
00108 
00109         //      printf("CubicIpol[%d,%d,%d,%d]\n", i_1, i, i1, i2);
00110 
00111 /*
00112                 // Estimate the Derivatives at A and B
00113         T       d0 = ( Data[i+1]  - Data[i-1] ) * (1./derivation_factor);
00114                 d1 = ( Data[i+2] -  Data[i  ] ) * (1./derivation_factor);
00115 
00116                 //         < linear term >             < cubic term >
00117                 return Data[i]*h00 + Data[i+1]*h10 + d0 * h01 + d1 * h11;
00118 
00119         Reordering to reduce the number of data array evaluations yields:
00120 */
00121                 return T(   L.limit( Data[i  ] )*(h00 - (1./derivation_factor) * h11 )
00122                           + L.limit( Data[i1 ] )*(h10 + (1./derivation_factor) * h01 )
00123                           - L.limit( Data[i_1] )*       (1./derivation_factor) * h01 
00124                           + L.limit( Data[i2 ] )*       (1./derivation_factor) * h11 );
00125         }
00126 
00127 
00128         template <class Storage1D, class Limiter>
00129 static  T derivative(const Storage1D&Data, double t, index_t size, const Limiter&L)
00130         {
00131         index_t i = index_t(t); 
00132         double  x = t - floor(t),
00133                 x2 = x*x,
00134 
00135                 // Ableitungen der Hermite'schen Polynome
00136                 h00 =  6*x*(x - 1) ,
00137                 h10 =    - h00,
00138                 h01 = 3*x2 - 4*x + 1,
00139                 h11 = 3*x2 - 2*x;
00140 
00141         //      printf("Deriv CubicIpol[%lg] ->", t);
00142 
00143         const double derivation_factor = 2;
00144 
00145                 // Boundary conditions.
00146         index_t i_1 = i-1, i1 = i+1, i2 = i+2;
00147                 if (i_1<0 || i_1>=size) i_1 = 0;
00148                 if (i < 0   )           i  = 0;
00149                 if (i >=size)           i  = size-1;
00150                 if (i1<0)               i1 = 0;
00151                 if (i2<0)               i2 = 0;
00152                 if (i1>=size)           i1 = size-1;
00153                 if (i2>=size)           i2 = size-1;
00154 
00155         //      printf("Indices: [%d,%d,%d,%d]", i_1, i, i1, i2);
00156         //      printf("Values:  [%lg %lg %lg %lg]\n", Data[i_1], Data[i], Data[i1], Data[i2]);
00157 
00158         T       Di_1 = L.limit(Data[i_1]),
00159                 Di   = L.limit(Data[i ]),
00160                 Di1  = L.limit(Data[i1]),
00161                 Di2  = L.limit(Data[i2]);
00162 
00163         //      printf("SValues:  [%lg %lg %lg %lg] %s\n", 
00164         //              double(Di_1), double(Di), double(Di1), double(Di2), typeid(Data).name() );
00165 
00166                 // Estimate the Derivatives at A and B
00167         T       d0 = ( Di1 - Di_1 ) * (1./derivation_factor),
00168                 d1 = ( Di2 - Di   ) * (1./derivation_factor);
00169 
00170                 return Di*h00 + Di1*h10 + d0 * h01 + d1 * h11;
00171         }
00172 };
00173 
00174 } /* namespace VecAl */ 
00175 
00176 #endif /* __IPOL_CUBIC_HPP */