freSPSASOOptimizerController.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freSPSASOOptimizerController.cxx,v $
00007   Language:  C++
00008 
00009 
00010 
00011   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00012   Institute for Medical Biometry and Informatics, University of Heidelberg,
00013   Germany). All rights reserved.
00014   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00015   for details.
00016 
00017      This software is distributed WITHOUT ANY WARRANTY; without even 
00018      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00019      PURPOSE.  See the above copyright notices for more information.
00020 
00021 =========================================================================*/
00022 
00023 #include "freSPSASOOptimizerController.h"
00024 #include "freSPSAOptimizerController.h"
00025 #include "freExceptions.h"
00026 
00027 namespace FREE
00028 {
00029 
00033 
00034 
00035 
00036 DefineParameterMacro(SPSASOOptimizerController,MinimumNumberOfIteration,"MinimumNumberOfIteration","Minimum number of iteration the optimizer will compute.");
00037 DefineParameterMacro(SPSASOOptimizerController,MaximumNumberOfIteration,"MaximumNumberOfIteration","Maximum number of iterations the optimizer will compute before terminating, even if no convergence is achieved.");
00038 DefineParameterMacro(SPSASOOptimizerController,a,"a","a is a factor that scales the estimated gradient before substracting it from the current position to achive the next position. Should be non-negative. Can be estimated via GuessParameters.");
00039 DefineParameterMacro(SPSASOOptimizerController,A,"A","A is a non-negative coefficient used to calculate the a of the next iteration step. Can be estimated via GuessParameters.");
00040 DefineParameterMacro(SPSASOOptimizerController,c,"c","c is a factor that scales the pertubation vector, which will be added to the current position to estimate the gradient");
00041 DefineParameterMacro(SPSASOOptimizerController,Alpha,"Alpha","Alpha is used to calculate the gain sequence a k.");
00042 DefineParameterMacro(SPSASOOptimizerController,Gamma,"Gamma","Gamma is used to calculate the gain sequence c k.");
00043 DefineParameterMacro(SPSASOOptimizerController,NumberOfPertubations,"NumberOfPertubations","Number of pertubations used to estimate the gradient at the current position.");
00044 DefineParameterMacro(SPSASOOptimizerController,ConvergenceDecayRate,"ConvergenceDecayRate","The convergence value (magnitute of the gradient) will be multiplied every iteration step with this factor.");
00045 DefineParameterMacro(SPSASOOptimizerController,Tolerance,"Tolerance","if the convergence value is below the tolerance the optimizer will terminate.");
00046 DefineParameterMacro(SPSASOOptimizerController,GuessParameters,"GuessParameters","Indicates if the parameters a and A will be guessed (in this case any given value for both will be ignored).");
00047 DefineParameterMacro(SPSASOOptimizerController,Guess_GradientEstimates,"Guess_GradientEstimates","Number of gradient estimations used to guess the parameters.");
00048 DefineParameterMacro(SPSASOOptimizerController,Guess_InitialStepSize,"Guess_InitialStepSize","Maximum of the absolute values of the parameter update.");
00049 DefineParameterMacro(SPSASOOptimizerController,ValueUpdateRate,"ValueUpdateRate","Because the value of the current position is not calculated explicitly by SPSA, Updating the actual optimizer value cost the evaluation of the objective function. Hence it can be adjusted how often the value should be updated (1 = every step; 5 = every fifth step etc.)");
00050 
00051 SPSASOOptimizerController::
00052 SPSASOOptimizerController()
00053 {
00054   //Profile settings
00055   this->UpdateControllerID(ControllerID::SPSASOOptimizerController);
00056   this->m_Description = "Optimizes registration setups by SPSA optimizer approach using Brent line search.";
00057 };
00058 
00059 void
00060 SPSASOOptimizerController::
00061 GenerateProfile(CtrlProfile::ControllerProfile& profile,
00062                   const SessionComponentCache* pComponentCache,
00063                   bool bRegardOldSetup) const
00064 {
00065   Superclass::GenerateProfile(profile,pComponentCache,bRegardOldSetup);
00066 
00067         //Parameters
00068   profile.Parameters().AddParameter(cParam_MinimumNumberOfIteration,Parameter::PVTULong,cParamDsc_MinimumNumberOfIteration,1,"10",-1,true);
00069   profile.Parameters().AddParameter(cParam_MaximumNumberOfIteration,Parameter::PVTULong,cParamDsc_MaximumNumberOfIteration,1,"100",-1,true);
00070   profile.Parameters().AddParameter(cParam_ValueUpdateRate,Parameter::PVTLong,cParamDsc_ValueUpdateRate,1,"10",-1,true);
00071   profile.Parameters().AddParameter(cParam_a,Parameter::PVTDouble,cParamDsc_a,1,"1.0",-1,true);
00072   profile.Parameters().AddParameter(cParam_A,Parameter::PVTDouble,cParamDsc_A,1,"10",-1,true);
00073   profile.Parameters().AddParameter(cParam_c,Parameter::PVTDouble,cParamDsc_c,1,"1.0",-1,true);
00074   profile.Parameters().AddParameter(cParam_Alpha,Parameter::PVTDouble,cParamDsc_Alpha,1,"0.602",-1,true);
00075   profile.Parameters().AddParameter(cParam_Gamma,Parameter::PVTDouble,cParamDsc_Gamma,1,"0.101",-1,true);
00076   profile.Parameters().AddParameter(cParam_NumberOfPertubations,Parameter::PVTLong,cParamDsc_NumberOfPertubations,1,"1",-1,true);
00077   profile.Parameters().AddParameter(cParam_ConvergenceDecayRate,Parameter::PVTDouble,cParamDsc_ConvergenceDecayRate,1,"0.9",-1,true);
00078   profile.Parameters().AddParameter(cParam_Tolerance,Parameter::PVTDouble,cParamDsc_Tolerance,1,"1e-06",-1,true);
00079         profile.Parameters().AddParameter(cParam_GuessParameters,Parameter::PVTBool,cParamDsc_GuessParameters,1,"false",1);
00080   profile.Parameters().AddParameter(cParam_Guess_GradientEstimates,Parameter::PVTULong,cParamDsc_Guess_GradientEstimates,1,"2",-1,true);
00081   profile.Parameters().AddParameter(cParam_Guess_InitialStepSize,Parameter::PVTDouble,cParamDsc_Guess_InitialStepSize,1,"1.0",-1,true);
00082 };
00083 
00084 long
00085 SPSASOOptimizerController::
00086 GetMaxIterationCount(const SessionComponentCache* pComponentCache, unsigned int iResolutionLevel) const
00087 {
00088         if (!pComponentCache) throwCtrlExceptionMacro("","Passed pComponentCache is NULL.");
00089         if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Cache has no setup assigned.");
00090 
00091   long lResult = 1;
00092   try
00093   {
00094     SessionAccessor::GetParameterValue(pComponentCache,cParam_Iterations,lResult);
00095   }
00096   catchAllNPassMacro("Unknown error while retrieving max interation count.")
00097 
00098   return lResult;
00099 };
00100 
00101 void
00102 SPSASOOptimizerController::
00103 ActualizeMainComponent(ComponentType* pMainComponent,
00104                        SessionComponentCache* pComponentCache, SessionInfo* pSessionInfo,
00105                                                                                          const unsigned int& iActLevel) const
00106 {
00107         Superclass::ActualizeMainComponent(pMainComponent, pComponentCache,
00108                                                                                                                                                  pSessionInfo, iActLevel);
00109 
00110         unsigned long lMinIterations;
00111         unsigned long lMaxIterations;
00112   long lValueUpdateRate;
00113   double da;
00114   double dA;
00115   double dc;
00116   double dAlpha;
00117   double dGamma;
00118         long lNrOfPertubations;
00119   double dDecayRate;
00120         double dTolerance;
00121   
00122   try
00123   {
00124     SessionAccessor::GetParameterValue(pComponentCache,cParam_ValueUpdateRate,lValueUpdateRate,0,iActLevel,true);
00125     SessionAccessor::GetParameterValue(pComponentCache,cParam_MinimumNumberOfIteration,lMinIterations,0,iActLevel,true);
00126     SessionAccessor::GetParameterValue(pComponentCache,cParam_MaximumNumberOfIteration,lMaxIterations,0,iActLevel,true);
00127     SessionAccessor::GetParameterValue(pComponentCache,cParam_a,da,0,iActLevel,true);
00128     SessionAccessor::GetParameterValue(pComponentCache,cParam_A,dA,0,iActLevel,true);
00129     SessionAccessor::GetParameterValue(pComponentCache,cParam_c,dc,0,iActLevel,true);
00130     SessionAccessor::GetParameterValue(pComponentCache,cParam_Alpha,dAlpha,0,iActLevel,true);
00131     SessionAccessor::GetParameterValue(pComponentCache,cParam_Gamma,dGamma,0,iActLevel,true);
00132     SessionAccessor::GetParameterValue(pComponentCache,cParam_NumberOfPertubations,lNrOfPertubations,0,iActLevel,true);
00133     SessionAccessor::GetParameterValue(pComponentCache,cParam_ConvergenceDecayRate,dDecayRate,0,iActLevel,true);
00134     SessionAccessor::GetParameterValue(pComponentCache,cParam_Tolerance,dTolerance,0,iActLevel,true);
00135   }
00136   catchAllNPassMacro("Error while retrieving parameter values.");
00137 
00138   pMainComponent->SetMinimumNumberOfIterations(lMinIterations);
00139         pMainComponent->SetMaximumNumberOfIterations(lMaxIterations);
00140         pMainComponent->Seta(da);
00141         pMainComponent->SetA(dA);
00142         pMainComponent->Setc(dc);
00143         pMainComponent->SetAlpha(dAlpha);
00144         pMainComponent->SetGamma(dGamma);
00145         pMainComponent->SetNumberOfPerturbations(lNrOfPertubations);
00146         pMainComponent->SetStateOfConvergenceDecayRate(dDecayRate);
00147         pMainComponent->SetTolerance(dTolerance);
00148   pMainComponent->SetValueUpdateRate(lValueUpdateRate);
00149   
00150         //get metric "orientation"
00151   Parameter::Pointer param = SessionAccessor::GetParameterByIDPath(pComponentCache,cIDPParent+IDPath(cComp_MainMetric+std::string("/@")+std::string(cParam_MetricMinimize)));
00152         bool bMin = true;
00153         if (param.IsNotNull())
00154         {
00155                 param->GetParameterValue(bMin);
00156         }
00157         pMainComponent->SetMaximize(!bMin);
00158 };
00159 
00160 void
00161 SPSASOOptimizerController::
00162 SetStatisticEntryMainComponent(StatisticEntry& rStatisticEntry,
00163                                              ComponentType* pMainComponent,
00164                                              SessionComponentCache* pMainComponentCache,
00165                                              SessionInfo* pSessionInfo,
00166                                              StatisticDictionary& rDictionary) const
00167 {
00168         ParameterArrayType parameters = pMainComponent->GetCurrentPosition();
00169 
00170   std::string sName = "Position #";
00171   std::string sIDPath = pMainComponentCache->GetIDPath();
00172   std::string sCommment = "Optimizer current position. Meaning depends on chosen transformation";
00173   StatisticValueDefinition* pEntry = rDictionary.GetValueDefinitionByName(sIDPath,sName+"0");
00174     
00175   if (!pEntry) //Entry is not recorded yet, so do so.
00176   {
00177     std::string sName = "Position #";
00178     pEntry = rDictionary.AddValueDefinition(sIDPath,sName+"0", sCommment);
00179     for (unsigned int i = 1; i<parameters.Size(); i++)
00180     {
00181       rDictionary.AddValueDefinition(sIDPath,sName+Convert::ToStr(i),sCommment);
00182     }
00183     rDictionary.AddValueDefinition(sIDPath,"LearningRate","The current a_k");
00184     rDictionary.AddValueDefinition(sIDPath,"GradientMagnitude","GradientMagnitude of the latest computed gradient.");
00185     rDictionary.AddValueDefinition(sIDPath,"StateOfConvergence","Get the state of convergence in the last iteration. When the StateOfConvergence is lower than the Tolerance the optimization stops.");
00186     rDictionary.AddValueDefinition(sIDPath,"OptimizerValue","Composed value of the current optimizer position");
00187   }
00188   
00189   for (unsigned int i = 0; i<parameters.Size(); i++)
00190   {
00191     rStatisticEntry.AddValue(Convert::ToStr(parameters.GetElement(i)),pEntry->GetRefID()+i);
00192   }
00193 
00194   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetLearningRate()),pEntry->GetRefID()+parameters.Size());
00195   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetGradientMagnitude()),pEntry->GetRefID()+parameters.Size()+1);
00196   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetStateOfConvergence()),pEntry->GetRefID()+parameters.Size()+2);
00197   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetCurrentValue()),pEntry->GetRefID()+parameters.Size()+3);
00198 };
00199 
00200 void
00201 SPSASOOptimizerController::
00202 ActualizeFinalization(ComponentType* pMainComponent, SessionComponentCache* pComponentCache,
00203                       SessionInfo* pSessionInfo, const unsigned int& iActLevel) const
00204 {
00205   if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Error. Cannot finalize component actualization; setup is missing in cache.");
00206   ComponentSetup* pComponentSetup = pComponentCache->Setup();
00207 
00208   // now all subcomponents are build and setup with there parameters, so parameters of spsa can be guessed if wanted.
00209   bool bGuess;
00210         unsigned long lGuess_NrOfEstimates;
00211         double dGuess_StepSize;
00212   
00213   try
00214   {
00215     SessionAccessor::GetParameterValue(pComponentCache,cParam_GuessParameters,bGuess);
00216     SessionAccessor::GetParameterValue(pComponentCache,cParam_Guess_GradientEstimates,lGuess_NrOfEstimates);
00217     SessionAccessor::GetParameterValue(pComponentCache,cParam_Guess_InitialStepSize,dGuess_StepSize);
00218   }
00219   catchAllNPassMacro("Error while retrieving parameter values.");
00220 
00221         if (bGuess)
00222         {
00223                 pMainComponent->GuessParameters(lGuess_NrOfEstimates,dGuess_StepSize);
00224         }
00225 };
00226 
00227 } //end of namespace free

Generated at Sat Oct 13 17:41:41 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000