Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_SPLINE_SPLINE_INITIALIZE_M_TABLE_H
00002 #define OPENTISSUE_CORE_SPLINE_SPLINE_INITIALIZE_M_TABLE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_value_traits.h>
00013
00014 #include <stdexcept>
00015
00016 namespace OpenTissue
00017 {
00018 namespace spline
00019 {
00020 namespace detail
00021 {
00035 template<typename matrix_type, typename knot_container>
00036 inline void initialize_m_table(
00037 int const & i
00038 , typename knot_container::value_type const & u
00039 , int const & k
00040 , knot_container const & U
00041 , matrix_type & M
00042 )
00043 {
00044 typedef typename knot_container::value_type T;
00045 typedef OpenTissue::math::ValueTraits<T> value_traits;
00046
00047 if(k<1)
00048 throw std::invalid_argument( "order must be greater than zero" );
00049
00050 if( U.size() < 2u*k)
00051 throw std::invalid_argument( "knot vector did not have enough entries" );
00052
00053 if( u < U[0] )
00054 throw std::invalid_argument( "u-parameter was out of lower bound" );
00055
00056 if( u > U[ U.size() - 1 ] )
00057 throw std::invalid_argument( "u-parameter was out of upper bound" );
00058
00059 if(i<0)
00060 throw std::invalid_argument( "basis function index must be non-negative" );
00061
00062 knot_container left(k+1);
00063 knot_container right(k+1);
00064
00065 M.resize(k,k,false);
00066 M(0,0) = value_traits::one();
00067
00068 for (int j=1; j<k; ++j)
00069 {
00070 left[j] = u-U[i+1-j];
00071 right[j] = U[i+j]-u;
00072
00073 T saved = value_traits::zero();
00074
00075 for(int r = 0; r<j; ++r)
00076 {
00077
00078 M(j,r) = right[r+1] + left[j-r];
00079 T temp = M(r,j-1)/M(j,r);
00080
00081
00082 M(r,j) = saved+right[r+1]*temp;
00083 saved = left[j-r]*temp;
00084 }
00085 M(j,j) = saved;
00086 }
00087 }
00088
00089 }
00090 }
00091 }
00092
00093
00094 #endif