cmtkIterativeDirectionOptimizer.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
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           // query functional for new parameter steppings if the respective
00146           // optimzier flag is set.
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 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines