Simbody
3.4 (development)
|
00001 #ifndef SimTK_SIMMATH_SPLINE_FITTER_H_ 00002 #define SimTK_SIMMATH_SPLINE_FITTER_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKmath * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2008-12 Stanford University and the Authors. * 00013 * Authors: Peter Eastman * 00014 * Contributors: * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00027 #include "SimTKcommon.h" 00028 #include "simmath/internal/common.h" 00029 #include "simmath/internal/Spline.h" 00030 #include "simmath/internal/GCVSPLUtil.h" 00031 00032 namespace SimTK { 00033 00068 template <class T> 00069 class SplineFitter { 00070 public: 00071 SplineFitter(const SplineFitter& copy) : impl(copy.impl) { 00072 impl->referenceCount++; 00073 } 00074 SplineFitter operator=(const SplineFitter& copy) { 00075 impl = copy.impl; 00076 impl->referenceCount++; 00077 return *this; 00078 } 00079 ~SplineFitter() { 00080 impl->referenceCount--; 00081 if (impl->referenceCount == 0) 00082 delete impl; 00083 } 00084 00092 static SplineFitter fitFromGCV 00093 (int degree, const Vector& x, const Vector_<T>& y) { 00094 Vector_<T> coeff; 00095 Vector wk; 00096 int ier; 00097 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), T(1), 00098 degree, 2, 0, coeff, wk, ier); 00099 return SplineFitter<T>(new SplineFitterImpl 00100 (degree, Spline_<T>(degree, x, coeff), wk[3], wk[4], wk[2])); 00101 } 00102 00111 static SplineFitter fitFromErrorVariance 00112 (int degree, const Vector& x, const Vector_<T>& y, Real error) { 00113 Vector_<T> coeff; 00114 Vector wk; 00115 int ier; 00116 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), T(1), 00117 degree, 3, error, coeff, wk, ier); 00118 return SplineFitter<T>(new SplineFitterImpl 00119 (degree, Spline_<T>(degree, x, coeff), wk[3], wk[4], wk[2])); 00120 } 00121 00130 static SplineFitter fitFromDOF 00131 (int degree, const Vector& x, const Vector_<T>& y, Real dof) { 00132 Vector_<T> coeff; 00133 Vector wk; 00134 int ier; 00135 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), T(1), 00136 degree, 4, dof, coeff, wk, ier); 00137 return SplineFitter<T>(new SplineFitterImpl 00138 (degree, Spline_<T>(degree, x, coeff), wk[3], wk[4], wk[2])); 00139 } 00140 00149 static SplineFitter fitForSmoothingParameter 00150 (int degree, const Vector& x, const Vector_<T>& y, Real p) { 00151 Vector_<T> coeff; 00152 Vector wk; 00153 int ier; 00154 GCVSPLUtil::gcvspl(x, y, Vector(x.size(), 1.0), T(1), 00155 degree, 1, p, coeff, wk, ier); 00156 return SplineFitter<T>(new SplineFitterImpl 00157 (degree, Spline_<T>(degree, x, coeff), wk[3], wk[4], wk[2])); 00158 } 00162 const Spline_<T>& getSpline() { 00163 return impl->spline; 00164 } 00168 Real getSmoothingParameter() { 00169 return impl->p; 00170 } 00174 Real getMeanSquaredError() { 00175 return impl->error; 00176 } 00180 Real getDegreesOfFreedom() { 00181 return impl->dof; 00182 } 00183 private: 00184 class SplineFitterImpl; 00185 SplineFitter(SplineFitterImpl *impl) : impl(impl) { 00186 } 00187 SplineFitterImpl* impl; 00188 }; 00189 00190 template <class T> 00191 class SplineFitter<T>::SplineFitterImpl { 00192 public: 00193 SplineFitterImpl(int degree, const Spline_<T>& spline, Real p, Real error, Real dof) : referenceCount(1), degree(degree), spline(spline), p(p), error(error), dof(dof) { 00194 } 00195 ~SplineFitterImpl() { 00196 assert(referenceCount == 0); 00197 } 00198 int referenceCount; 00199 int degree; 00200 Spline_<T> spline; 00201 Real p, error, dof; 00202 }; 00203 00204 } // namespace SimTK 00205 00206 #endif // SimTK_SIMMATH_SPLINE_FITTER_H_ 00207 00208