Templates -- Meow  1.2.9
A C++ template contains kinds of interesting classes and functions
methods.h
Go to the documentation of this file.
1 #ifndef math_methods_H__
2 #define math_methods_H__
3 
4 #include "Matrix.h"
5 #include "Vector.h"
6 #include "utility.h"
7 
8 #include <cstdlib>
9 #include <vector>
10 
11 namespace meow {
12 
57 template<class Data, class WeightingClass>
58 inline std::vector<Data> ransac(std::vector<Data> const& data,
59  WeightingClass const& w,
60  size_t N,
61  double p0, double P) {
62  if (data.size() < N) {
63  return std::vector<Data>();
64  }
65  double ww = -1.0;
66  std::vector<Data> ret;
67  for (double count = ceil(log(1.0 - P) / log(1.0 - pow(p0, N)));
68  count > 0.0; count -= 1.0) {
69  std::vector<Data> sample;
70  std::vector<int> index(N);
71  for (size_t i = 0; i < N; i++) {
72  for (bool ok = false; !ok; ) {
73  index[i] = rand() % data.size();
74  ok = true;
75  for (size_t j = 0; ok && j < i; j++)
76  if (index[i] == index[j])
77  ok = false;
78  }
79  sample.push_back(data[index[i]]);
80  }
81  double w_now = w(sample, data);
82  if (w_now < 0) {
83  count += 0.5;
84  continue;
85  }
86  if (ww < w_now) {
87  ret = sample;
88  ww = w_now;
89  }
90  }
91  return ret;
92 }
93 
94 
95 /*
96  * @brief Run the \b Levenberg-Marquardt method to solve a non-linear
97  * least squares problem.
98  *
99  * Assume:
100  * - The function we want to optimize is
101  * \f$ F: \mathbb{R} ^N \mapsto \mathbb{R}^M \f$
102  * - We want to find the best solution \f$ v \f$ such that
103  * \f$ F(v)^T F(v) = 0\f$. But there is a gived threshold
104  * \f$ \epsilon \f$, we can just find a \f$ v \f$ such that
105  * \f$ F(v)^T F(v) < \epsilon \f$, which is mush easier.
106  * - User gived a initiial vector \f$ v_0 \f$
107  * .
108  * Then we just iteratilly find \f$ v_1, v_2, v_3, v_4... \f$ until a
109  * vector \f$ v_k \f$ satisified that \f$ F(v_k)^TF(v_k)<\epsilon \f$ .
110  * And each iterator we have:
111  * \f[
112  * v_{i+1} = v_i + (J(v_i)^TJ(v_i)+\lambda I_{N\times N})^{-1} J(v_i)^T F(v_i)
113  * \f]
114  * Where \f$ J(v) \f$ is a jacobian matrix defined below:
115  * \f[
116  * J(v) = \frac{d}{dv}F(v) =
117  * \left[ \begin{array}{ccccc}
118  * \frac{\partial F_1(v)}{\partial v_1} &
119  * \frac{\partial F_1(v)}{\partial v_2} &
120  * \frac{\partial F_1(v)}{\partial v_3} &
121  * ... &
122  * \frac{\partial F_1(v)}{\partial v_N} \\
123  * \frac{\partial F_2(v)}{\partial v_1} &
124  * \frac{\partial F_2(v)}{\partial v_2} &
125  * \frac{\partial F_2(v)}{\partial v_3} &
126  * ... &
127  * \frac{\partial F_2(v)}{\partial v_N} \\
128  * \frac{\partial F_3(v)}{\partial v_1} &
129  * \frac{\partial F_3(v)}{\partial v_2} &
130  * \frac{\partial F_3(v)}{\partial v_3} &
131  * ... &
132  * \frac{\partial F_3(v)}{\partial v_N} \\
133  * . & . & . & & . \\
134  * . & . & . & & . \\
135  * . & . & . & & . \\
136  * \frac{\partial F_M(v)}{\partial v_1} &
137  * \frac{\partial F_M(v)}{\partial v_2} &
138  * \frac{\partial F_M(v)}{\partial v_3} &
139  * ... &
140  * \frac{\partial F_M(v)}{\partial v_N} \\
141  * \end{array} \right]
142  * \f]
143  * And \f$ \lambda \f$ is a magic number....
144  * @param [in] func \f$ F \f$, a function(class with \c operator() )
145  * which input a vector and the output the squares errors.
146  * @param [in] jaco \f$ J \f$, a function which input a vector
147  * and then output \b func derivate by the vector
148  * @param [in] iden \f$ \lambda I_{N \times N} \f$, defined above
149  * @param [in] init \f$ v_0 \f$Initial vector
150  * @param [in] stop A function return a boolean which means the error is
151  * acceptable or not, so \f[
152  * S_{top}(v) = \begin{cases}
153  * true & if~F(v)<\epsilon \\
154  * false & else
155  * \end{cases}
156  * \f]
157  * @param [in] counter To prevent infinit loop.
158  * @return a vector which means the best solution this function found.
159  *
160  * @author cat_leopard
161  */
162 template<class Scalar, class Function>
163 inline Vector<Scalar> levenbergMarquardt(Function const& f,
164  Vector<Scalar> const& init,
165  int counter = -1) {
166  Vector<Scalar> ans(init), residure_v;
167  for ( ; counter != 0 && !f.accept(residure_v = f.residure(ans)); --counter) {
168  Matrix<Scalar> m_j (f.jacobian(ans));
169  Matrix<Scalar> m_jt(m_j.transpose());
170  Matrix<Scalar> m(m_j * m_jt), M;
171  for (int i = 1; M.valid() == false; i++) {
172  M = (m + f.diagonal(ans, i)).inverse();
173  }
174  ans = ans - M * m_jt * residure_v;
175  }
176  return ans;
177 }
178 
179 // residure
180 // jacobian
181 // identity
182 template<class Scalar, class Function>
184  Vector<Scalar> const& init,
185  Scalar const& init_mu,
186  Scalar const& mu_pow,
187  Scalar const& er_max,
188  int retry_number,
189  int counter) {
190  if (retry_number == 0) retry_number = 1;
191  Vector<Scalar> ans_now(init), rv_now(f.residure(ans_now));
192  Vector<Scalar> ans_nxt , rv_nxt;
193  Scalar er_now(rv_now.length2());
194  Scalar er_nxt;
195  Vector<Scalar> ans_best(ans_now);
196  Scalar er_best ( er_now);
197  Matrix<Scalar> m_ja, m_jt, m, iden(f.identity());
198  Scalar mu(init_mu);
199  for ( ; counter != 0 && er_now > er_max; --counter) {
200  m_ja = f.jacobian();
201  m_jt = m_ja.transpose();
202  m = m_jt * m_ja;
203  bool good = false;
204  for (int i = 0; i != retry_number; ++i, mu = mu * mu_pow) {
205  ans_nxt = ans_now + (m + iden * mu).inverse() * m_jt * rv_now.matrix();
206  rv_nxt = f.residure(ans_nxt);
207  er_nxt = rv_nxt.length2();
208  if (er_nxt <= er_now) {
209  good = true;
210  break;
211  }
212  }
213  if (good) {
214  mu = mu / mu_pow;
215  }
216  mu = inRange(0.0000001, 100.0, mu);
217  ans_now = ans_nxt;
218  rv_now = rv_nxt;
219  er_now = er_nxt;
220  if (er_now < er_best) {
221  ans_best = ans_now;
222  er_best = er_now;
223  }
224  }
225  return ans_best;
226 }
227 
228 } // meow
229 
230 #endif // math_methods_H__
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)
Definition: methods.h:183
Scalar length2() const
same as (*this).dot(*this)
Definition: Vector.h:204
Vector< Scalar > levenbergMarquardt(Function const &f, Vector< Scalar > const &init, int counter=-1)
Definition: methods.h:163
bool valid() const
Return whether it is a valid matrix.
Definition: Matrix.h:123
vector
Definition: Vector.h:19
T inRange(T const &mn, T const &mx, T const &v)
std::min(mx,std::max(mn,v))
Definition: utility.h:51
std::vector< Data > ransac(std::vector< Data > const &data, WeightingClass const &w, size_t N, double p0, double P)
Run the RANSAC method to approach the best solution.
Definition: methods.h:58
Matrix transpose() const
return itself's transpose matrix
Definition: Matrix.h:434