aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/math/methods.h
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp/math/methods.h')
-rw-r--r--meowpp/math/methods.h75
1 files changed, 62 insertions, 13 deletions
diff --git a/meowpp/math/methods.h b/meowpp/math/methods.h
index 4a47d33..5b67594 100644
--- a/meowpp/math/methods.h
+++ b/meowpp/math/methods.h
@@ -92,7 +92,7 @@ inline std::vector<Data> ransac(std::vector<Data> const& data,
}
-/*!
+/*
* @brief Run the \b Levenberg-Marquardt method to solve a non-linear
* least squares problem.
*
@@ -159,23 +159,72 @@ inline std::vector<Data> ransac(std::vector<Data> const& data,
*
* @author cat_leopard
*/
-template<class Scalar, class F, class J, class I, class Stop>
-inline Vector<Scalar> levenbergMarquardt(F const& func,
- J const& jaco,
- I const& iden,
+template<class Scalar, class Function>
+inline Vector<Scalar> levenbergMarquardt(Function const& f,
Vector<Scalar> const& init,
- Stop const& stop,
- int counter = -1) {
- Vector<Scalar> ans(init);
- for(Vector<Scalar> rv;
- !stop((rv = func(ans)).length2()) && counter != 0; counter--) {
- Matrix<Scalar> j(jaco(ans)), jt(j.transpose());
- Matrix<Scalar> i(iden(ans));
- ans = ans - Vector<Scalar>((jt * j + i).inverse() * jt * rv.matrix());
+ int counter = -1) {
+ Vector<Scalar> ans(init), residure_v;
+ for ( ; counter != 0 && !f.accept(residure_v = f.residure(ans)); --counter) {
+ Matrix<Scalar> m_j (f.jacobian(ans));
+ Matrix<Scalar> m_jt(m_j.transpose());
+ Matrix<Scalar> m(m_j * m_jt), M;
+ for (int i = 1; M.valid() == false; i++) {
+ M = (m + f.diagonal(ans, i)).inverse();
+ }
+ ans = ans - M * m_jt * residure_v;
}
return ans;
}
+// residure
+// jacobian
+// identity
+template<class Scalar, class Function>
+inline Vector<Scalar> levenbergMarquardtTraining(Function & f,
+ Vector<Scalar> const& init,
+ Scalar const& init_mu,
+ Scalar const& mu_pow,
+ Scalar const& er_max,
+ int retry_number,
+ int counter) {
+ if (retry_number == 0) retry_number = 1;
+ Vector<Scalar> ans_now(init), rv_now(f.residure(ans_now));
+ Vector<Scalar> ans_nxt , rv_nxt;
+ Scalar er_now(rv_now.length2());
+ Scalar er_nxt;
+ Vector<Scalar> ans_best(ans_now);
+ Scalar er_best ( er_now);
+ Matrix<Scalar> m_ja, m_jt, m, iden(f.identity());
+ Scalar mu(init_mu);
+ for ( ; counter != 0 && er_now > er_max; --counter) {
+ m_ja = f.jacobian();
+ m_jt = m_ja.transpose();
+ m = m_jt * m_ja;
+ bool good = false;
+ for (int i = 0; i != retry_number; ++i, mu = mu * mu_pow) {
+ ans_nxt = ans_now + (m + iden * mu).inverse() * m_jt * rv_now.matrix();
+ rv_nxt = f.residure(ans_nxt);
+ er_nxt = rv_nxt.length2();
+ if (er_nxt <= er_now) {
+ good = true;
+ break;
+ }
+ }
+ if (good) {
+ mu = mu / mu_pow;
+ }
+ mu = inRange(0.0000001, 100.0, mu);
+ ans_now = ans_nxt;
+ rv_now = rv_nxt;
+ er_now = er_nxt;
+ if (er_now < er_best) {
+ ans_best = ans_now;
+ er_best = er_now;
+ }
+ }
+ return ans_best;
}
+} // meow
+
#endif // math_methods_H__