75 #ifndef SLIP_LEVENBERG_MARQUARDT_HPP
76 #define SLIP_LEVENBERG_MARQUARDT_HPP
95 template <
typename Type>
96 struct funLM_bp :
public std::unary_function <slip::Vector<Type>,slip::Vector<Type> >
126 Type x_p = xd-
data_[12];
127 Type y_p = yd-data_[13];
130 Type two_x_p_y_p =
static_cast<Type
>(2.0) * x_p*y_p;
131 Type rhoi2 = x_p2+y_p2;
132 Type rhoi2_2 = rhoi2*rhoi2;
133 Type rhoi2_3 = rhoi2_2*rhoi2;
134 Type three =
static_cast<Type
>(3.0);
135 Type rad = (R1*rhoi2 + R2*rhoi2_2 + R3*rhoi2_3);
136 xd = xd + x_p*rad + D1*two_x_p_y_p + D2*(three*x_p2 + y_p2) + P1*rhoi2;
137 yd = yd + y_p*rad + D2*two_x_p_y_p + D1*(three*y_p2 + x_p2) + P2*rhoi2;
155 template <
typename Type>
156 struct funLM_DLT :
public std::unary_function <slip::Vector<Type>,slip::Vector<Type> >
163 N_((Data.size()-19)/5),
180 Type R2 = p[3]*data_[
_5N_+1];
181 Type R3 = p[4]*data_[
_5N_+2];
182 Type D1 = p[5]*data_[
_5N_+3];
183 Type D2 = p[6]*data_[
_5N_+4];
184 Type P1 = p[7]*data_[
_5N_+5];
185 Type P2 = p[8]*data_[
_5N_+6];
189 Type two =
static_cast<Type
>(2.0);
190 Type three =
static_cast<Type
>(3.0);
192 for(std::size_t i=0, k = 0; i <
N_; ++i,k+=2)
195 Type v =
data_(N_+i);
199 Type den = (
M_[6]*X +
M_[7]*Y +
M_[8]*Z +
M_[11]);
200 Type xr = (
M_[0]*X +
M_[1]*Y +
M_[2]*Z +
M_[9] )/den;
201 Type yr = (
M_[3]*X +
M_[4]*Y +
M_[5]*Z +
M_[10])/den;
205 Type xr_p2 = xr_p * xr_p;
206 Type yr_p2 = yr_p * yr_p;
207 Type two_xr_p_yr_p = two * xr_p * yr_p;
208 Type rhoi2 = xr_p2 + yr_p2;
209 Type rhoi22 = rhoi2 * rhoi2;
210 Type rhoi222 = rhoi22 * rhoi2;
211 Type R123 = (R1*rhoi2 + R2*rhoi22 + R3*rhoi222);
212 Type xd = xr + xr_p*R123 + D1*two_xr_p_yr_p + D2*(yr_p2 + three*xr_p2) + P1*rhoi2;
213 Type yd = yr + yr_p*R123 + D2*two_xr_p_yr_p + D1*(xr_p2 + three*yr_p2) + P2*rhoi2;
241 template <
typename T,
typename RandomAccessIterator>
242 T
LM_chi2(RandomAccessIterator first, RandomAccessIterator last)
245 const T N =
static_cast<T
>(last-first);
246 for(; first != last; ++first)
248 chisq += (*first * *first)/N;
327 template<
typename Function,
329 typename DerivativeFunction>
331 DerivativeFunction& df,
335 const int maxiter = 10000,
336 const Real eps = static_cast<Real>(1e-6))
340 const std::size_t N = r.
size();
341 const std::size_t npar = par.
size();
353 Real lamfac =
static_cast<Real
>(2.0);
354 Real two =
static_cast<Real
>(2.0);
355 Real minus_two = - two;
356 Real zero =
static_cast<Real
>(0.0);
357 Real lambda =
static_cast<Real
>(0.5);
368 Real chisq = LM_chi2<Real>(r.
begin(),r.
end());
374 for(std::size_t i = 0; i < npar; ++i)
377 for(std::size_t k=0; k < N; ++k)
379 b[i] += minus_two*A[i][k]*r[k] ;
387 for (std::size_t k = 0; k < npar; ++k)
389 for (std::size_t i = 0; i < npar; ++i)
391 aprime[i][k] = two * AAt[i][k];
393 aprime[k][k] = (two*AAt[k][k] + lambda);
399 for (std::size_t i = 0; i < npar; ++i)
401 par2[i] = par[i] + delta[i];
406 Real chisq2 = LM_chi2<Real>(r.
begin(),r.
end());
415 if (fabs(((chisq - chisq2)/chisq)) < eps && decrease )
426 for(std::size_t i = 0; i < npar; ++i)
429 for(std::size_t k = 0; k < N; ++k)
431 b[i] += minus_two* A[i][k] * r[k] ;
435 lambda = lambda / lamfac;
452 calchi2 = LM_chi2<Real>(r.
begin(),r.
end());
460 template <
typename Function,
473 rinf_(slip::
Vector<Type>(N,static_cast<Type>(0.0))),
474 rsup_(slip::
Vector<Type>(N,static_cast<Type>(0.0))),
488 rinf_(slip::
Vector<Type>(N,static_cast<Type>(0.0))),
489 rsup_(slip::
Vector<Type>(N,static_cast<Type>(0.0))),
491 delta2_(static_cast<Type>(2.0)*delta)
495 template <
typename RandomAccessIterator>
497 RandomAccessIterator p_last,
500 assert(static_cast<int>(p_last-p_first)==
npar_);
507 for(
int k =0; p_first != p_last; ++k,++p_first, ++it_p_inf,++it_p_sup)
514 for (
int i = 0; i <
N_ ; ++i)
539 #endif // SLIP_LEVENBERG_MARQUARDT_HPP
LMDerivFunctor(const Function &fun, const int N, const int npar, const Type &delta)
void lu_solve(const Matrix LU, const std::size_t nr, const std::size_t nc, const Vector1 &Indx, const std::size_t nv1, const Vector2 &B, const std::size_t nv2, Vector3 &X, const std::size_t nv3)
Solve Linear Equation using LU decomposition.
void matrix_matrixt_multiplies(RandomAccessIterator2d1 M1_up, RandomAccessIterator2d1 M1_bot, RandomAccessIterator2d2 Res_up, RandomAccessIterator2d2 Res_bot)
Computes the multiplication of a matrix with its transposate A^T .
slip::Vector< Type > & operator()(const slip::Vector< Type > &pt)
iterator end()
Returns a read/write iterator that points one past the last element in the Vector. Iteration is done in ordinary element order.
slip::Vector< Type > data_
generic derivative functor
Provides common linear algebra algorithms.
T LM_chi2(RandomAccessIterator first, RandomAccessIterator last)
Computes Chi2 for Lebvenberg Marquardt algorithm.
slip::Vector< Type > p_sup_
Function to compute the backprojection of the 3d world point corresponding to the backprojection of a...
void marquardt(Function &fun, DerivativeFunction &df, slip::Vector< Real > &par, slip::Vector< Real > &r, Real &calchi2, const int maxiter=10000, const Real eps=static_cast< Real >(1e-6))
Optimization of function using the Levenberg-Marquardt algorithm.
funLM_DLT(const slip::Vector< Type > &Data)
slip::Vector< Type > rinf_
Provides a class to manipulate static and generic vectors.
size_type size() const
Returns the number of elements in the Vector.
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
LMDerivFunctor(const Function &fun, const int N, const int npar)
Provides a class to manipulate 3d Vector.
slip::Vector< Type > data_
Numerical matrix class. This container statisfies the BidirectionnalContainer concepts of the STL...
slip::Vector< Type > rsup_
slip::Vector< Type > & operator()(const slip::Vector< Type > &p)
void operator()(RandomAccessIterator p_first, RandomAccessIterator p_last, slip::Matrix< Type > &A)
Function to compute the camera model of distortion using the Levenberg-Marquadt algorithm.
Provides a class to manipulate Numerical Matrix.
funLM_bp(const slip::Vector< Type > &Data)
Function to compute the backprojection of the 3d world point corresponding to the backprojection of a...
slip::Vector< Type > p_inf_
iterator begin()
Returns a read/write iterator that points to the first element in the Vector. Iteration is done in or...