23 class gsSolutionFitter
26 gsSolutionFitter (
const std::vector<gsVector<T>> & data,
27 const gsVector<T> & times,
32 this->_defaultOptions();
35 GISMO_ENSURE(data.size() == (size_t)times.size(),
"Solution coefs and times should have the same size");
38 for (
index_t k=0; k!=times.size(); k++)
39 m_data.insert({times[k],data[k]});
59 void setDegree(
index_t deg) {m_deg = deg;}
61 void addDataPoint(gsVector<T> & point, T ptime)
63 m_data.insert({ptime,point});
64 gsDebugVar(m_data.size());
67 gsOptionList& options() {
return m_options;}
71 void _defaultOptions()
73 m_options.addInt(
"Parameterization",
"Type of parameterization to be used: 0: uniform, 1: chord-length, 2: centripetal",1);
76 gsBSplineBasis<T> _basis(
const gsKnotVector<T> &kv,
index_t nsteps)
78 gsBSplineBasis<T> tbasis(kv);
84 const gsBSpline<T> & fit()
const {
return m_fit; }
86 gsVector<T> slice(T xi)
90 return m_fit.eval(pt);
93 T nearestParam(
const gsMatrix<T> & solution, gsMatrix<T> & params,
index_t nTrialPoints = 25,
index_t nIterations = 100)
95 gsMatrix<T> supp = m_fit.support();
96 gsVector<T> start = supp.col(0), end = supp.col(1);
98 gsMatrix<T> surfVal, surfDeriv, surfDeriv2;
99 gsMatrix<T> closestParam;
103 T closestSqDist(10e100);
105 for(
int idxTrial = 0; idxTrial < nTrialPoints; idxTrial++)
107 u = trialPoints.col(idxTrial);
114 for(
int iteration = 0; iteration < nIterations; iteration++)
116 m_fit.eval_into(u, surfVal);
117 m_fit.jacobian_into(u, surfDeriv);
118 m_fit.deriv2_into(u, surfDeriv2);
121 gsMatrix<T> sqDistDeriv = -2 * (solution - surfVal).transpose() *
123 GISMO_ASSERT(sqDistDeriv.rows() == 1 && sqDistDeriv.cols() == 1,
"Derivative should be 1x1");
125 gsMatrix<T> sqDistDeriv2 = 2*surfDeriv.transpose() * surfDeriv - 2*(solution - surfVal).transpose() * surfDeriv2;
126 GISMO_ASSERT(sqDistDeriv2.rows() == 1 && sqDistDeriv2.cols() == 1,
"Second derivative should be 1x1");
128 du = sqDistDeriv / sqDistDeriv2(0, 0);
131 if (du.norm()/u.norm() < tol)
134 u(0, 0) = (u(0, 0) < supp(0, 0))? supp(0, 0): ((u(0, 0) > supp(0, 1)? supp(0, 1): u(0, 0)));
137 m_fit.eval_into(u, surfVal);
138 T sqDist = (solution - surfVal).squaredNorm();
139 if(idxTrial == 0 || sqDist < closestSqDist)
142 closestSqDist = sqDist;
145 return closestParam.value();
150 GISMO_ASSERT(m_data.size()>(m_deg),
"Data needs to have more than "<<m_deg<<
" points, but only "<<m_data.size()<<
" are stored!");
151 index_t nsteps = m_data.size();
156 std::vector<T> ptimes(nsteps);
157 gsMatrix<T> rhs(nsteps,m_data.at(0).rows());
159 for(
typename std::map<T,gsVector<T>>::iterator it = m_data.begin(); it != m_data.end(); ++it, ++k)
162 ptimes.at(k) = it->first;
163 rhs.row(k) = it->second;
167 std::vector<T> u_bar(ptimes.size());
172 index_t param = m_options.getInt(
"Parameterization");
175 kv = gsKnotVector<T>(gsAsVector<T>(ptimes).minCoeff(),gsAsVector<T>(ptimes).maxCoeff(),nsteps-(m_deg+1),m_deg+1, 1);
177 else if (param==1 || param==2)
181 for (
typename std::vector<T>::iterator pit = std::next(ptimes.begin()); pit!=ptimes.end(); pit++)
182 d += math::pow(*pit - *std::prev(pit),1./param);
184 typename std::vector<T>::iterator pit = std::next(ptimes.begin());
185 for (
typename std::vector<T>::iterator it=std::next(u_bar.begin()); it!=std::prev(u_bar.end()); it++, pit++)
186 *it = *std::prev(it) + 1. / d * math::pow(*pit - *std::prev(pit),1./param);
188 std::vector<T> u(nsteps+m_deg+1);
189 for (
index_t k=0; k!=m_deg+1; k++)
192 u.at(u.size()-k-1) = 1;
194 for (
index_t j=1; j!=nsteps-m_deg; j++)
197 for (
index_t i=j; i!=j+m_deg; i++)
198 u.at(j+m_deg) += u_bar.at(i);
200 u.at(j+m_deg) /= m_deg;
203 kv = gsKnotVector<T>(u,m_deg);
204 kv.affineTransformTo(ptimes.front(),ptimes.back());
210 m_basis = gsBSplineBasis<T>(kv);
213 gsMatrix<T> anchors = m_basis.anchors();
216 gsSparseMatrix<T> C = m_basis.collocationMatrix(anchors);
224 gsFitting<T> fitter(gsAsMatrix<T>(ptimes,1,ptimes.size()),rhs.transpose(),m_basis);
225 gsSparseMatrix<T> lhs(nsteps,nsteps);
227 fitter.setConstraints(C,rhs);
230 m_fit = gsBSpline<T>(m_basis,
give(fitter.result()->coefs()));
234 std::map<T,gsVector<T>> m_data;
236 gsVector<T> m_ptimes;
239 mutable gsBSplineBasis<T> m_basis;
242 mutable gsBSpline<T> m_fit;
244 gsOptionList m_options;
S give(S &x)
Definition: gsMemory.h:266
Provides declaration of data fitting algorithms by least squares approximation.
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
gsMatrix< T > uniformPointGrid(const gsVector< T > &lower, const gsVector< T > &upper, int numPoints=1000)
Definition: gsPointGrid.hpp:94
Provides a list of labeled parameters/options that can be set and accessed easily.
#define GISMO_ERROR(message)
Definition: gsDebug.h:118