Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "cmtkBestNeighbourOptimizer.h"
00034
00035 #include <Registration/cmtkSearchTrace.h>
00036
00037 #include <System/cmtkConsole.h>
00038 #include <System/cmtkProgress.h>
00039
00040 #include <vector>
00041
00042 namespace
00043 cmtk
00044 {
00045
00048
00049 CallbackResult
00050 BestNeighbourOptimizer::Optimize
00051 ( CoordinateVector& v, const Self::ParameterType exploration, const Self::ParameterType accuracy )
00052 {
00053 this->m_LastOptimizeChangedParameters = false;
00054
00055 int Dim = this->GetSearchSpaceDimension();
00056
00057 Self::ReturnType optimum = this->Evaluate( v );
00058 CoordinateVector optimumV(v);
00059
00060 int optimumDim = -1;
00061 Types::Coordinate optimumDir = 0;
00062
00063 const Self::ParameterType real_accuracy = std::min<Self::ParameterType>( exploration, accuracy );
00064 int numOfSteps = 1+static_cast<int>(log(real_accuracy/exploration)/log(StepFactor));
00065 Self::ParameterType step = real_accuracy * pow( StepFactor, 1-numOfSteps );
00066
00067 std::vector<Self::ParameterType> stepScaleVector( Dim );
00068 for ( int idx=0; idx<Dim; ++idx )
00069 stepScaleVector[idx] = this->GetParamStep( idx );
00070
00071 SearchTrace<Self::ParameterType> searchTrace ( Dim );
00072
00073 Progress::Begin( 0, numOfSteps, 1, "Multi-resolution optimization" );
00074
00075 CallbackResult irq = this->CallbackExecuteWithData( v, optimum );
00076 for ( int stepIdx = 0; (stepIdx < numOfSteps) && ( irq == CALLBACK_OK ); ++stepIdx, step *= StepFactor )
00077 {
00078 Progress::SetProgress( stepIdx );
00079
00080 char comment[128];
00081 snprintf( comment, sizeof( comment ), "Setting step size to %4g [mm]", step );
00082 this->CallbackComment( comment );
00083
00084 int update = 1;
00085 while ( update && ( irq == CALLBACK_OK ) )
00086 {
00087 update = 0;
00088
00089 const Self::ReturnType previous = optimum;
00090
00091 for ( int dim = 0; dim < Dim; ++dim )
00092 {
00093 double next;
00094
00095 const Self::ParameterType vOld = v[dim];
00096
00097 for ( int direction = -1; direction <= 1; direction += 2 )
00098 {
00099 if ( (irq = this->CallbackExecute()) ) break;
00100
00101 v[dim] = vOld + direction * step * stepScaleVector[dim];
00102 if ( !searchTrace.Get( next, dim, step ) )
00103 next = this->Evaluate( v );
00104
00105 if ( next > optimum )
00106 {
00107 optimum = next;
00108 optimumV = v;
00109 update = 1;
00110 optimumDim = dim;
00111 optimumDir = direction * step;
00112 }
00113 }
00114
00115 v[dim] = vOld;
00116 }
00117
00118 if (update)
00119 {
00120 #ifdef CMTK_BUILD_DEMO
00121 this->m_Functional->SnapshotAt( optimumV );
00122 #endif
00123 v = optimumV;
00124 searchTrace.Move( optimumDim, optimumDir );
00125 irq = this->CallbackExecuteWithData( v, optimum );
00126 this->m_LastOptimizeChangedParameters = true;
00127
00128
00129
00130 if ( this->m_UpdateStepScaleVector )
00131 for ( int idx=0; idx<Dim; ++idx )
00132 stepScaleVector[idx] = this->GetParamStep( idx );
00133 }
00134
00135 if ( (fabs(previous-optimum) / (fabs(previous)+fabs(optimum)) ) < this->m_DeltaFThreshold )
00136 update = false;
00137 }
00138 }
00139
00140 Progress::Done();
00141
00142 this->SetFinalValue( optimum );
00143 return irq;
00144 }
00145
00146 }