MathTL
numerics/splines.h
00001 // -*- c++ -*-
00002 
00003 // +--------------------------------------------------------------------+
00004 // | This file is part of MathTL - the Mathematical Template Library    |
00005 // |                                                                    |
00006 // | Copyright (c) 2002-2009                                            |
00007 // | Thorsten Raasch, Manuel Werner                                     |
00008 // +--------------------------------------------------------------------+
00009 
00010 #ifndef _MATHTL_SPLINES_H
00011 #define _MATHTL_SPLINES_H
00012 
00013 #include <cmath>
00014 #include <iostream>
00015 #include <utils/array1d.h>
00016 #include <utils/function.h>
00017 #include <algebra/matrix.h>
00018 
00019 namespace MathTL
00020 {
00026   class KnotSequence
00027   {
00028   public:
00029     virtual ~KnotSequence() = 0;
00030     
00031     /*
00032       index of the first knot
00033      */
00034     virtual int k0() const = 0;
00035     
00039     virtual double knot(const int k) const = 0;
00040   };
00041 
00042   KnotSequence::~KnotSequence() {}
00043 
00047   template <int d>
00048   double evaluate_Bspline(const KnotSequence* knots, const int j, const double x)
00049   {
00050     double r(0);
00051 
00052     // take care of multiple knots
00053     double diff = knots->knot(j+d-1) - knots->knot(j);
00054     if (diff > 0) r += (x - knots->knot(j)) * evaluate_Bspline<d-1>(knots, j, x) / diff;
00055     diff = knots->knot(j+d) - knots->knot(j+1);
00056     if (diff > 0) r += (knots->knot(j+d) - x) * evaluate_Bspline<d-1>(knots, j+1, x) / diff;
00057     
00058     return r;
00059   }
00060   
00064   template <>
00065   inline
00066   double evaluate_Bspline<1>(const KnotSequence* knots, const int j, const double x)
00067   {
00068     return (x >= knots->knot(j) && x < knots->knot(j+1) ? 1.0 : 0.0);
00069   }
00070 
00087   template <int d>
00088   void
00089   compute_Bspline_refinement_matrix(const KnotSequence* knots, Matrix<double>& M);
00090 
00091 
00095   template <int d>
00096   double evaluate_Bspline(const Array1D<double>& knots, const unsigned int j, const double x)
00097   {
00098     double r(0);
00099 
00100     // take care of multiple knots
00101     double diff = knots[j+d-1] - knots[j];
00102     if (diff > 0) r += (x - knots[j]) * evaluate_Bspline<d-1>(knots, j, x) / diff;
00103     diff = knots[j+d] - knots[j+1];
00104     if (diff > 0) r += (knots[j+d] - x) * evaluate_Bspline<d-1>(knots, j+1, x) / diff;
00105     
00106     return r;
00107   }
00108 
00112   template <>
00113   inline
00114   double evaluate_Bspline<1>(const Array1D<double>& knots, const unsigned int j, const double x)
00115   {
00116     return (x >= knots[j] && x < knots[j+1] ? 1.0 : 0.0);
00117   }
00118 
00131   template <unsigned int d>
00132   class Spline : public Function<1>
00133   {
00134   public:
00140     Spline()
00141       : Function<1>(1), knots_(d+1), coeffs_(1)
00142     {
00143       for (unsigned int i(0); i <= d; i++)
00144         knots_[i] = i;
00145 
00146       coeffs_[0] = 1.0;
00147     }
00148 
00152     Spline(const Array1D<double>& knots, const Array1D<double>& coeffs)
00153       : Function<1>(1), knots_(knots), coeffs_(coeffs)
00154     {
00155       assert(knots.size() == coeffs.size()+d);
00156     }
00157 
00161     virtual ~Spline() {}
00162 
00166     inline double value(const Point<1>& p,
00167                         const unsigned int component = 0) const
00168     {
00169       double r(0);
00170       
00171       for (unsigned int i(0); i < coeffs_.size(); i++) {
00172         if (coeffs_[i] != 0)
00173           r += coeffs_[i] * evaluate_Bspline<d>(knots_, i, p(0));
00174       }
00175 
00176       return r;
00177     }
00178   
00182     void vector_value(const Point<1> &p,
00183                       Vector<double>& values) const
00184     {
00185       values.resize(1, false);
00186       values[0] = value(p);
00187     }
00188     
00189   protected:
00193     Array1D<double> knots_;
00194 
00198     Array1D<double> coeffs_;
00199   };
00200 }
00201 
00202 #include <numerics/splines.cpp>
00203 
00204 #endif
 All Classes Functions Variables Typedefs Enumerations