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 "cmtkIterativeDirectionOptimizer.h"
00034
00035 #include <System/cmtkProgress.h>
00036
00037 #include <vector>
00038
00039 namespace
00040 cmtk
00041 {
00042
00045
00046 CallbackResult
00047 IterativeDirectionOptimizer::Optimize
00048 ( CoordinateVector& v, const Types::Coordinate exploration, const Types::Coordinate accuracy )
00049 {
00050 int Dim = this->GetSearchSpaceDimension();
00051
00052 Types::Coordinate optimum = this->Evaluate( v );
00053 CoordinateVector optimumV(v);
00054
00055 const double real_accuracy = std::min<Types::Coordinate>( exploration, accuracy );
00056 int numOfSteps = 1+static_cast<int>(log(real_accuracy/exploration)/log(StepFactor));
00057 Types::Coordinate step = real_accuracy * pow( StepFactor, 1-numOfSteps );
00058
00059 std::vector<Types::Coordinate> stepScaleVector( Dim );
00060 for ( int idx=0; idx<Dim; ++idx )
00061 stepScaleVector[idx] = this->GetParamStep( idx );
00062
00063 Progress::Begin( 0, numOfSteps, 1, "Multi-resolution optimization" );
00064
00065 CallbackResult irq = this->CallbackExecuteWithData( v, optimum );
00066 for ( int stepIdx = 0; (stepIdx < numOfSteps) && ( irq == CALLBACK_OK ); ++stepIdx, step *= StepFactor )
00067 {
00068 Progress::SetProgress( stepIdx );
00069
00070 char comment[128];
00071 snprintf( comment, sizeof( comment ), "Setting step size to %4g [mm]", step );
00072 this->CallbackComment( comment );
00073
00074 bool update = true;
00075 while ( update && ( irq == CALLBACK_OK ) )
00076 {
00077 update = false;
00078
00079 for ( int dim = 0; (dim < Dim) && ( irq == CALLBACK_OK ); ++dim )
00080 {
00081 bool updateThisDim = true;
00082 while ( updateThisDim && ( irq == CALLBACK_OK ) )
00083 {
00084 updateThisDim = false;
00085
00086 Types::Coordinate vOld = v[dim];
00087
00088 if ( (irq = this->CallbackExecute()) ) break;
00089
00090 v[dim] += step * stepScaleVector[dim];
00091 const Self::ReturnType fUpper = this->Evaluate( v );
00092
00093 Types::Coordinate optimumStep = 0;
00094
00095 if ( fUpper > optimum )
00096 {
00097 optimum = fUpper;
00098 optimumV = v;
00099 updateThisDim = true;
00100 optimumStep = step;
00101 }
00102
00103 if ( (irq = this->CallbackExecute()) ) break;
00104
00105 v[dim] = vOld - (step * stepScaleVector[dim]);
00106 const Self::ReturnType fLower = this->Evaluate( v );
00107
00108 if ( fLower > optimum )
00109 {
00110 optimum = fLower;
00111 optimumV = v;
00112 updateThisDim = true;
00113 optimumStep = -step;
00114 }
00115
00116 if ( updateThisDim )
00117 {
00118 update = true;
00119 while ( updateThisDim )
00120 {
00121 updateThisDim = false;
00122 vOld = v[dim];
00123 v[dim] += optimumStep * stepScaleVector[dim];
00124 const Self::ReturnType f = this->Evaluate( v );
00125
00126 if ( f > optimum )
00127 {
00128 optimum = f;
00129 optimumV = v;
00130 updateThisDim = true;
00131 }
00132
00133 if ( (irq = this->CallbackExecute()) ) break;
00134 }
00135 updateThisDim = true;
00136 }
00137
00138 v[dim] = vOld;
00139 }
00140
00141 if ( update )
00142 {
00143 v = optimumV;
00144 irq = this->CallbackExecuteWithData( v, optimum );
00145
00146
00147 if ( this->m_UpdateStepScaleVector )
00148 for ( int idx=0; idx<Dim; ++idx )
00149 stepScaleVector[idx] = this->GetParamStep( idx );
00150 }
00151 }
00152 }
00153 }
00154
00155 Progress::Done();
00156
00157 return irq;
00158 }
00159
00160 }