00001 #ifndef SimTK_SIMMATH_SPLINE_FITTER_H_
00002 #define SimTK_SIMMATH_SPLINE_FITTER_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "simmath/internal/Spline.h"
00036 #include "simmath/internal/GCVSPLUtil.h"
00037
00038 namespace SimTK {
00039
00072 template <int N>
00073 class SplineFitter {
00074 public:
00075 SplineFitter(const SplineFitter& copy) : impl(copy.impl) {
00076 impl->referenceCount++;
00077 }
00078 SplineFitter operator=(const SplineFitter& copy) {
00079 impl = copy.impl;
00080 impl->referenceCount++;
00081 return *this;
00082 }
00083 ~SplineFitter() {
00084 impl->referenceCount--;
00085 if (impl->referenceCount == 0)
00086 delete impl;
00087 }
00095 static SplineFitter fitFromGCV(int degree, const Vector& x, const Vector_<Vec<N> >& y) {
00096 Vector_<Vec<N> > coeff;
00097 Vector wk;
00098 int ier;
00099 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), Vec<N>(1.0), degree, 2, 0, coeff, wk, ier);
00100 return SplineFitter<N>(new SplineFitterImpl(degree, Spline<N>(degree, x, coeff), wk[3], wk[4], wk[2]));
00101 }
00110 static SplineFitter fitFromErrorVariance(int degree, const Vector& x, const Vector_<Vec<N> >& y, Real error) {
00111 Vector_<Vec<N> > coeff;
00112 Vector wk;
00113 int ier;
00114 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), Vec<N>(1.0), degree, 3, error, coeff, wk, ier);
00115 return SplineFitter<N>(new SplineFitterImpl(degree, Spline<N>(degree, x, coeff), wk[3], wk[4], wk[2]));
00116 }
00126 static SplineFitter fitFromDOF(int degree, const Vector& x, const Vector_<Vec<N> >& y, Real dof) {
00127 Vector_<Vec<N> > coeff;
00128 Vector wk;
00129 int ier;
00130 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), Vec<N>(1.0), degree, 4, dof, coeff, wk, ier);
00131 return SplineFitter<N>(new SplineFitterImpl(degree, Spline<N>(degree, x, coeff), wk[3], wk[4], wk[2]));
00132 }
00141 static SplineFitter fitForSmoothingParameter(int degree, const Vector& x, const Vector_<Vec<N> >& y, Real p) {
00142 Vector_<Vec<N> > coeff;
00143 Vector wk;
00144 int ier;
00145 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), Vec<N>(1.0), degree, 1, p, coeff, wk, ier);
00146 return SplineFitter<N>(new SplineFitterImpl(degree, Spline<N>(degree, x, coeff), wk[3], wk[4], wk[2]));
00147 }
00151 const Spline<N>& getSpline() {
00152 return impl->spline;
00153 }
00157 Real getSmoothingParameter() {
00158 return impl->p;
00159 }
00163 Real getMeanSquaredError() {
00164 return impl->error;
00165 }
00169 Real getDegreesOfFreedom() {
00170 return impl->dof;
00171 }
00172 private:
00173 class SplineFitterImpl;
00174 SplineFitter(SplineFitterImpl *impl) : impl(impl) {
00175 }
00176 SplineFitterImpl* impl;
00177 };
00178
00179 template <int N>
00180 class SplineFitter<N>::SplineFitterImpl {
00181 public:
00182 SplineFitterImpl(int degree, const Spline<N>& spline, Real p, Real error, Real dof) : degree(degree), spline(spline), p(p), error(error), dof(dof), referenceCount(1) {
00183 }
00184 ~SplineFitterImpl() {
00185 assert(referenceCount == 0);
00186 }
00187 int referenceCount;
00188 int degree;
00189 Spline<N> spline;
00190 Real p, error, dof;
00191 };
00192
00193 }
00194
00195 #endif // SimTK_SIMMATH_SPLINE_FITTER_H_
00196
00197