MathTL
|
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