// -*- Mode: c++ -*- // copyright (c) 2006 by Christos Dimitrakakis /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include "Trajectory.h" /// Return a point Point Trajectory::GetPoint (Segment& s, float w) { float v = 1.0f - w; return Point (w*s.left.x + v*s.right.x, w*s.left.y + v*s.right.y, w*s.left.z + v*s.right.z); } #define EXP_COST #undef DBG_OPTIMISE /// Optimise a track trajectory void Trajectory::Optimise(SegmentList track, int max_iter, float alpha, char* fname, bool reset) { int N = track.size(); clock_t start_time = clock(); int min_iter = max_iter/2; // minimum number of iterations to do float time_limit = 2.0f; // if more than min_iter have been done, exit when time elapsed is larger than the time limit float beta = 0.75f; // amount to reduce alpha to when it seems to be too large w.resize(N); dw.resize(N); dw2.resize(N); indices.resize(N); accel.resize(N); // initialise vectors for (int i=0; i 1.0 -b) { penalty += K*((1.0-b) - w[i]); } } P+= K*penalty*penalty; dCdw += K*penalty; dw2[i] = lambda*dw2[i] + (1.0-lambda)*dCdw*dCdw; direction += dCdw * dw[i]; float delta = dCdw/(dw2[i] + 1.0); dw[i] = delta; w[i] += alpha * delta; if (1) { float b = 0.0; if (w[i] < b) { w[i] = b; } else if (w[i] > 1.0 -b) { w[i] = 1.0 - b; } } dCdw2 += dCdw*dCdw; EdCdw += delta/(float) N; } // indices if (direction<0) { alpha *= beta; #ifdef DBG_OPTIMISE fprintf (stderr, "# Reducing alpha to %f\n", alpha); #endif } Z = (dCdw2); if (Z<0.01) { Z = 0.01; } bool early_exit = false; delta_C = 0.9*delta_C + 0.1*fabs(EdCdw-prev_dCdw2); prev_dCdw2 = EdCdw; if (delta_C < 0.001f) { early_exit = true; } if (iter%100==0) { clock_t current_time = clock(); float elapsed_time = (float) (current_time-start_time) / (float) CLOCKS_PER_SEC; if (elapsed_time > time_limit) { early_exit = true; } #ifdef DBG_OPTIMISE fprintf (stderr, "%d %f %f %f %f %f %f\n", iter, C / (float) N, P / (float) N, dCdw2, EdCdw, delta_C, elapsed_time); #endif } if (iter>min_iter && early_exit) { #ifdef DBG_OPTIMISE fprintf (stderr, "# Time to break\n"); fflush (stderr); #endif break; } prevC = C; } if (fname && strcmp(fname, "")) { #ifdef DBG_OPTIMISE fprintf (stderr, "# writing output to %s\n", fname); #endif FILE* f = fopen (fname, "w"); for (int i=0; i