Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_SPLINE_SPLINE_COMPUTE_NONZERO_BASIS_H
00002 #define OPENTISSUE_CORE_SPLINE_SPLINE_COMPUTE_NONZERO_BASIS_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 <OpenTissue/core/spline/spline_compute_knot_span.h>
00015
00016 #include <stdexcept>
00017
00018 namespace OpenTissue
00019 {
00020 namespace spline
00021 {
00022 namespace detail
00023 {
00038 template<typename vector_type, typename knot_container>
00039 inline void compute_nonzero_basis(
00040 typename knot_container::value_type const & u
00041 , int const k
00042 , knot_container const & U
00043 , vector_type & N
00044 )
00045 {
00046 using std::fabs;
00047
00048 typedef typename knot_container::value_type T;
00049 typedef OpenTissue::math::ValueTraits<T> value_traits;
00050
00051 if(k<1)
00052 throw std::invalid_argument( "order must be greater than zero" );
00053
00054 if( U.size() < 2u*k)
00055 throw std::invalid_argument( "knot vector did not have enough entries" );
00056
00057 if( u < U[0] )
00058 throw std::invalid_argument( "u-parameter was out of lower bound" );
00059
00060 if( u > U[ U.size() - 1 ] )
00061 throw std::invalid_argument( "u-parameter was out of upper bound" );
00062
00063 int const i = compute_knot_span(u, k, U);
00064
00065 vector_type left(k+1);
00066 vector_type right(k+1);
00067
00068 N.resize(k, false);
00069
00070 N(0) = value_traits::one();
00071
00072 for(int j=1; j<k; ++j)
00073 {
00074 left(j) = u - U[i+1-j];
00075 right(j) = U[i+j] - u;
00076
00077 T saved = value_traits::zero();
00078
00079 for(int r=0; r<j; ++r)
00080 {
00081
00082 T tmp = value_traits::zero();
00083 T nominator = right(r+1) + left(j-r);
00084
00085 if(fabs( nominator ) > value_traits::zero() )
00086 {
00087 tmp = N(r)/nominator;
00088 N(r) = saved + right(r+1)*tmp;
00089 saved = left(j-r)*tmp;
00090 }
00091 else
00092 {
00093 N(r) = saved;
00094 saved = value_traits::zero();
00095 }
00096
00097 }
00098 N(j) = saved;
00099 }
00100
00101
00102 }
00103
00104 }
00105 }
00106 }
00107
00108
00109 #endif