Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

LevenbergMarquardtMinimizer.cpp

Go to the documentation of this file.
00001 // LevenbergMarquardtMinimizer.cpp: implementation of the CLevenbergMarquardtMinimizer class.
00002 //
00004 
00005 #include "LevenbergMarquardtMinimizer.h"
00006 
00008 // Construction/Destruction
00010 
00011 CLevenbergMarquardtMinimizer::CLevenbergMarquardtMinimizer()
00012 {
00013 
00014 }
00015 
00016 CLevenbergMarquardtMinimizer::~CLevenbergMarquardtMinimizer()
00017 {
00018 
00019 }
00020 
00022 // Adds to each diagonal element of the Hessian the scaleParameter, i.e. 
00023 // after calling RescaleDiagonal(alpha) you get
00024 //                              H[i][i] = H[i][i] + alpha; 
00026 
00027 void CLevenbergMarquardtMinimizer::RescaleDiagonal(double scaleParameter)
00028 {
00029         for(int i = 0; i < nParameters; i++)
00030         {
00031                 m_pdAlpha[i][i] = m_pdAlpha[i][i] + scaleParameter;
00032         }
00033 }
00034 
00036 // Restores the diagonal elements of the Hessian to the contents of
00037 // the array m_pdDiagonal
00039 
00040 void CLevenbergMarquardtMinimizer::RestoreDiagonal()
00041 {
00042         int i;
00043         for(i = 0; i < nParameters; i++)
00044         {
00045                 m_pdAlpha[i][i] = m_pdDiagonal[i];
00046         }
00047 }
00048 
00050 // If parameters are required to be positive semidefinite, this function
00051 // ensures they remain so before the objective function is evaluated
00053 
00054 void CLevenbergMarquardtMinimizer::CheckBounds(double *parameters)
00055 {
00056         for(int i = 0; i < nParameters; i++)
00057         {
00058                 if(parameters[i] < 0.0) 
00059                 {
00060                         parameters[i] = 0.0;
00061                         cout << "Parameter " << i << " hit a bound, truncating . . ." << endl;
00062                 }
00063         }
00064 }
00065 
00066 void CLevenbergMarquardtMinimizer::ObtainTrialParameters(double *currentP, double *deltaP, double *trialP)
00067 {
00068         int j;
00069         // forward transform the current parameters, then add and back transform
00070         m_pFilter->ForwardTransformation(currentP,nParameters);
00071         for(j = 0; j < nParameters; j++)
00072         {
00073                 trialP[j] = currentP[j] + deltaP[j];
00074         }
00075         m_pFilter->BackwardTransformation(trialP,nParameters);
00076         m_pFilter->BackwardTransformation(currentP,nParameters);
00077         if(m_bPositiveSemiDef) {this->CheckBounds(trialP);}
00078 /*      // XXX debug
00079         for(j = 0; j < nParameters; j++)
00080         {
00081                 cout << trialP[j] << endl;
00082         }
00083 */
00084 }
00085 
00086 void CLevenbergMarquardtMinimizer::AcceptParameters(double *parameters, double *trialP, double newCost)
00087 {
00088         int i;
00089         for(i = 0; i < nParameters; i++)
00090         {
00091                 parameters[i] = trialP[i];
00092         }
00093 
00094         // write the accepted parameters to a file, because numerically 
00095         // computing the hessian is extremely expensive
00096         fstream *pftemp = new fstream("lstsqrtemp.par",ios::out);
00097         *pftemp << "##################################################################" << endl;
00098         *pftemp << "# BEST PARAMETERS" << endl;
00099         *pftemp << "# COST : " << newCost << endl;
00100         *pftemp << "##################################################################" << endl;
00101         for(i = 0; i < nParameters; i++)
00102         {
00103                 *pftemp << parameters[i] << endl;
00104         }
00105         delete pftemp;
00106         // END WRITE
00107 }
00108 
00109 bool CLevenbergMarquardtMinimizer::ComputeChiSqTol(double oldCost, double newCost)
00110 {
00111         if(m_bCheckChi == false) {return false;}
00112         double fracDeltaC = (oldCost - newCost)/oldCost;
00113         if(fabs(fracDeltaC) < m_dChiSqTol)
00114         {
00115                 return true;
00116         }
00117         return false;
00118 }
00119 
00120 bool CLevenbergMarquardtMinimizer::ComputeGradTol()
00121 {
00122         if(m_bCheckGrad == false) {return false;}
00123         double gradNorm = 0.0;
00124         for(int i = 0; i < nParameters; i++)
00125         {
00126                 gradNorm += m_pdGrad[i]*m_pdGrad[i];
00127         }
00128         gradNorm = sqrt(gradNorm);
00129         if(gradNorm < m_dGradTol)
00130         {
00131                 return true;
00132         }
00133         return false;
00134 }
00135 
00136 bool CLevenbergMarquardtMinimizer::ComputeParTol(double *oldP, double *deltaP)
00137 {
00138         if(m_bCheckPar == false) {return false;}
00139         double parTol = 0.0;
00140         for(int i = 0; i < nParameters; i++)
00141         {
00142                 double tempPar = m_pFilter->Operator(oldP[i]);
00143                 parTol = fabs(deltaP[i])/(m_dTau + fabs(tempPar));
00144                 if(parTol > m_dParTol)
00145                 {
00146                         return false;
00147                 }
00148         }
00149         return true;
00150 }

Generated on Mon Nov 3 09:37:57 2003 by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002