| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef FLANN_SIMPLEX_DOWNHILL_H_ |
| #define FLANN_SIMPLEX_DOWNHILL_H_ |
|
|
| namespace flann |
| { |
|
|
| |
| |
| |
| template <typename T> |
| void addValue(int pos, float val, float* vals, T* point, T* points, int n) |
| { |
| vals[pos] = val; |
| for (int i=0; i<n; ++i) { |
| points[pos*n+i] = point[i]; |
| } |
|
|
| |
| int j=pos; |
| while (j>0 && vals[j]<vals[j-1]) { |
| swap(vals[j],vals[j-1]); |
| for (int i=0; i<n; ++i) { |
| swap(points[j*n+i],points[(j-1)*n+i]); |
| } |
| --j; |
| } |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| template <typename T, typename F> |
| float optimizeSimplexDownhill(T* points, int n, F func, float* vals = NULL ) |
| { |
| const int MAX_ITERATIONS = 10; |
|
|
| assert(n>0); |
|
|
| T* p_o = new T[n]; |
| T* p_r = new T[n]; |
| T* p_e = new T[n]; |
|
|
| int alpha = 1; |
|
|
| int iterations = 0; |
|
|
| bool ownVals = false; |
| if (vals == NULL) { |
| ownVals = true; |
| vals = new float[n+1]; |
| for (int i=0; i<n+1; ++i) { |
| float val = func(points+i*n); |
| addValue(i, val, vals, points+i*n, points, n); |
| } |
| } |
| int nn = n*n; |
|
|
| while (true) { |
|
|
| if (iterations++ > MAX_ITERATIONS) break; |
|
|
| |
| for (int j=0; j<n; ++j) { |
| p_o[j] = 0; |
| for (int i=0; i<n; ++i) { |
| p_o[i] += points[j*n+i]; |
| } |
| } |
| for (int i=0; i<n; ++i) { |
| p_o[i] /= n; |
| } |
|
|
| bool converged = true; |
| for (int i=0; i<n; ++i) { |
| if (p_o[i] != points[nn+i]) { |
| converged = false; |
| } |
| } |
| if (converged) break; |
|
|
| |
| for (int i=0; i<n; ++i) { |
| p_r[i] = p_o[i] + alpha*(p_o[i]-points[nn+i]); |
| } |
| float val_r = func(p_r); |
|
|
| if ((val_r>=vals[0])&&(val_r<vals[n])) { |
| |
| |
| Logger::info("Choosing reflection\n"); |
| addValue(n, val_r,vals, p_r, points, n); |
| continue; |
| } |
|
|
| if (val_r<vals[0]) { |
| |
|
|
| |
| for (int i=0; i<n; ++i) { |
| p_e[i] = 2*p_r[i]-p_o[i]; |
| } |
| float val_e = func(p_e); |
|
|
| if (val_e<val_r) { |
| Logger::info("Choosing reflection and expansion\n"); |
| addValue(n, val_e,vals,p_e,points,n); |
| } |
| else { |
| Logger::info("Choosing reflection\n"); |
| addValue(n, val_r,vals,p_r,points,n); |
| } |
| continue; |
| } |
| if (val_r>=vals[n]) { |
| for (int i=0; i<n; ++i) { |
| p_e[i] = (p_o[i]+points[nn+i])/2; |
| } |
| float val_e = func(p_e); |
|
|
| if (val_e<vals[n]) { |
| Logger::info("Choosing contraction\n"); |
| addValue(n,val_e,vals,p_e,points,n); |
| continue; |
| } |
| } |
| { |
| Logger::info("Full contraction\n"); |
| for (int j=1; j<=n; ++j) { |
| for (int i=0; i<n; ++i) { |
| points[j*n+i] = (points[j*n+i]+points[i])/2; |
| } |
| float val = func(points+j*n); |
| addValue(j,val,vals,points+j*n,points,n); |
| } |
| } |
| } |
|
|
| float bestVal = vals[0]; |
|
|
| delete[] p_r; |
| delete[] p_o; |
| delete[] p_e; |
| if (ownVals) delete[] vals; |
|
|
| return bestVal; |
| } |
|
|
| } |
|
|
| #endif |
|
|