cmtkBestNeighbourOptimizer.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: 2464 $
00026 //
00027 //  $LastChangedDate: 2010-10-19 09:54:33 -0700 (Tue, 19 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torsten_at_home $
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         // query functional for new parameter steppings if the respective
00129         // optimizer flag is set.
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 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines