1 #ifndef LEVMARFITTING_HEADER
2 #define LEVMARFITTING_HEADER
10 template<
class ScalarT >
19 for (i = 0; i < n; ++i)
21 for (j = i; j < n; ++j)
23 for (sum =
a[i * n + j], k = i - 1; k != -1; --k)
25 sum -=
a[i * n + k] *
a[j * n + k];
29 if (sum <= ScalarT(0))
38 a[j * n + i] = sum / p[i];
45 template<
class ScalarT,
unsigned int N >
54 for (i = 0; i < N; ++i)
56 for (j = i; j < N; ++j)
58 for (sum =
a[i * N + j], k = i - 1; k != -1; --k)
60 sum -=
a[i * N + k] *
a[j * N + k];
64 if (sum <= ScalarT(0))
73 a[j * N + i] = sum / p[i];
80 template<
class ScalarT >
81 void CholeskySolve(ScalarT*
a,
size_t n, ScalarT p[], ScalarT b[], ScalarT x[])
91 for (i = 0; i < n; i++)
94 for (sum = b[i], k = i - 1; k != -1; --k)
96 sum -=
a[i * n + k] * x[k];
100 for (i = n - 1; i != -1; --i)
103 for (sum = x[i], k = i + 1; k < n; ++k)
105 sum -=
a[k * n + i] * x[k];
111 template<
class ScalarT,
unsigned int N >
122 for (i = 0; i < N; i++)
125 for (sum = b[i], k = i - 1; k != -1; --k)
127 sum -=
a[i * N + k] * x[k];
131 for (i = N - 1; i != -1; --i)
134 for (sum = x[i], k = i + 1; k < N; ++k)
136 sum -=
a[k * N + i] * x[k];
142 template<
class IteratorT,
class FuncT >
143 bool LevMar(IteratorT begin, IteratorT end, FuncT& func,
144 typename FuncT::ScalarType* param)
146 typedef typename FuncT::ScalarType ScalarType;
147 enum { paramDim = FuncT::NumParams };
149 unsigned int totalSize = end - begin;
154 ScalarType lambda = ScalarType(0.0001);
155 ScalarType* F0 =
new ScalarType[totalSize * paramDim];
156 ScalarType* U =
new ScalarType[paramDim * paramDim];
157 ScalarType* H =
new ScalarType[paramDim * paramDim];
158 ScalarType*
v =
new ScalarType[paramDim];
159 ScalarType* d =
new ScalarType[totalSize];
160 ScalarType* temp =
new ScalarType[totalSize];
161 ScalarType* x =
new ScalarType[paramDim];
162 ScalarType* p =
new ScalarType[paramDim];
163 ScalarType* paramNew =
new ScalarType[paramDim];
165 func.Normalize(param);
166 ScalarType paramNorm = 0;
169 unsigned int subsets =
std::max(
int(std::floor(std::log((
float)totalSize) / std::log(2.f))) - 8, 1);
170 #ifdef PRECISIONLEVMAR
174 for (
unsigned int i = subsetSizes.
size(); i;)
177 subsetSizes[i] = totalSize;
180 subsetSizes[i] = subsetSizes[i] >> 1;
182 totalSize -= subsetSizes[i];
184 unsigned int curSubset = 0;
185 unsigned int size = 0;
188 ScalarType chi = 0, newChi = 0;
190 unsigned int outerIter = 0,
191 #ifndef PRECISIONLEVMAR
192 maxOuterIter = 200 / subsetSizes.
size(),
196 usefulIter = 0, totalIter = 0;;
200 size += subsetSizes[curSubset];
201 newChi = func.Chi(param, begin, begin + size, d, temp);
202 for (
unsigned int i = 0; i < paramDim; ++i)
204 paramNew[i] = param[i];
219 for (
size_t i = 0; i < paramDim; ++i)
221 param[i] = paramNew[i];
223 #ifndef PRECISIONLEVMAR
224 if (
std::sqrt(chi / size) < ScalarType(1e-5))
231 for (
size_t i = 0; i < paramDim; ++i)
233 paramNorm += param[i] * param[i];
239 func.Derivatives(param, begin, begin + size, d, temp, F0);
242 #pragma omp parallel for
243 for (
int i = 0; i < paramDim; ++i)
245 for (
size_t j = i; j < paramDim; ++j)
247 U[i * paramDim + j] = 0;
248 for (
size_t k = 0; k < size; ++k)
250 U[i * paramDim + j] += F0[k * paramDim + i] *
251 F0[k * paramDim + j];
256 #pragma omp parallel for
257 for (
int i = 0; i < paramDim; ++i)
260 for (
size_t k = 0; k < size; ++k)
262 v[i] += F0[k * paramDim + i] * d[k];
270 for (
unsigned int i = 0; i < paramDim; ++i)
276 #ifndef PRECISIONLEVMAR
277 if (vmag < ScalarType(1e-6))
279 if (vmag < ScalarType(1e-8))
290 ScalarType fmag =
abs(F0[0]);
291 for (
size_t i = 1; i < paramDim * size; ++i)
292 if (fmag <
abs(F0[i]))
296 lambda = 1e-3f * fmag;
300 lambda *=
std::max(ScalarType(.3), ScalarType(1 - std::pow(2 * rho - 1, 3)));
304 memcpy(H, U,
sizeof(ScalarType) * paramDim * paramDim);
305 for (
size_t i = 0; i < paramDim; ++i)
307 H[i * paramDim + i] += lambda;
311 ScalarType xNorm = 0, L = 0;
312 if (!Cholesky< ScalarType, paramDim >(H, p))
316 CholeskySolve< ScalarType, paramDim >(H, p,
v, x);
319 for (
size_t i = 0; i < paramDim; ++i)
321 xNorm += x[i] * x[i];
324 #ifndef PRECISIONLEVMAR
325 if (xNorm <= ScalarType(1e-6) * (paramNorm + ScalarType(1e-6)))
327 if (xNorm <= ScalarType(1e-8) * (paramNorm + ScalarType(1e-8)))
335 for (
size_t i = 0; i < paramDim; ++i)
337 paramNew[i] = param[i] + x[i];
339 func.Normalize(paramNew);
342 newChi = func.Chi(paramNew, begin, begin + size, d, temp);
348 for (
size_t i = 0; i < paramDim; ++i)
350 L += .5f * x[i] * (lambda * x[i] +
v[i]);
352 rho = (chi - newChi) / L;
356 #ifndef PRECISIONLEVMAR
357 if ((chi - newChi) < 1e-4 * chi)
361 for (
size_t i = 0; i < paramDim; ++i)
363 param[i] = paramNew[i];
374 lambda = nu * lambda;
375 size_t nu2 = nu << 1;
382 while (outerIter < maxOuterIter);
385 while (curSubset < subsetSizes.
size());
386 retVal = usefulIter > 0;
399 template<
class ScalarT >
400 ScalarT
LevMar(
unsigned int paramDim,
unsigned int imgDim,
404 size_t size = imgDim;
405 float lambda = ScalarT(0.0001);
406 ScalarT* F0 =
new ScalarT[size * paramDim];
407 ScalarT* U =
new ScalarT[paramDim * paramDim];
408 ScalarT* H =
new ScalarT[paramDim * paramDim];
409 ScalarT*
v =
new ScalarT[paramDim];
410 ScalarT* d =
new ScalarT[size];
411 ScalarT* dNew =
new ScalarT[size];
412 ScalarT* x =
new ScalarT[paramDim];
413 ScalarT* p =
new ScalarT[paramDim];
414 ScalarT* paramNew =
new ScalarT[paramDim];
415 size_t outerIter = 0, maxOuterIter = 10;
417 ScalarT chi = 0, newChi;
418 for (
size_t i = 0; i < size; ++i)
420 d[i] = (*(funcs[i]))(param);
426 lambda *= ScalarT(0.04);
430 for (
size_t i = 0; i < size; ++i)
432 (*(funcs[i]))(param, &F0[i * paramDim]);
435 for (
size_t i = 0; i < paramDim; ++i)
436 for (
size_t j = i; j < paramDim; ++j)
438 U[i * paramDim + j] = 0;
439 for (
size_t k = 0; k < size; ++k)
440 U[i * paramDim + j] += F0[k * paramDim + i] *
441 F0[k * paramDim + j];
444 for (
size_t i = 0; i < paramDim; ++i)
447 for (
size_t k = 0; k < size; ++k)
449 v[i] += F0[k * paramDim + i] * d[k];
453 size_t iter = 0, maxIter = 10;
458 lambda = 10 * lambda;
459 memcpy(H, U,
sizeof(ScalarT) * paramDim * paramDim);
460 for (
size_t i = 0; i < paramDim; ++i)
462 H[i * paramDim + i] += lambda * (ScalarT(1) + H[i * paramDim + i]);
471 for (
size_t i = 0; i < paramDim; ++i)
473 paramNew[i] = param[i] + x[i];
477 for (
size_t i = 0; i < size; ++i)
479 dNew[i] = (*(funcs[i]))(paramNew);
480 newChi += dNew[i] * dNew[i];
495 if (
abs(chi - newChi)
496 / chi < ScalarT(1e-4))
498 for (
size_t i = 0; i < paramDim; ++i)
500 param[i] = paramNew[i];
506 while (newChi > chi && iter < maxIter);
510 for (
size_t i = 0; i < paramDim; ++i)
512 param[i] = paramNew[i];
517 while (outerIter < maxOuterIter);