1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkExhaustiveOptimizerv4_h
19 #define itkExhaustiveOptimizerv4_h
20 
21 #include "itkIntTypes.h"
22 #include "itkObjectToObjectOptimizerBase.h"
23 
24 namespace itk
25 {
26 /** \class ExhaustiveOptimizerv4
27  * \brief Optimizer that fully samples a grid on the parametric space.
28  *
29  * This optimizer is equivalent to an exahaustive search in a discrete grid
30  * defined over the parametric space. The grid is centered on the initial
31  * position. The subdivisions of the grid along each one of the dimensions
32  * of the parametric space is defined by an array of number of steps.
33  *
34  * A typical use is to plot the metric space to get an idea of how noisy it
35  * is. An example is given below, where it is desired to plot the metric
36  * space with respect to translations along x, y and z in a 3D registration
37  * application:
38  *     Here it is assumed that the transform is Euler3DTransform.
39  *
40    \code
41     OptimizerType::StepsType steps( m_Transform->GetNumberOfParameters() );
42     steps[0] = 10;
43     steps[1] = 10;
44     steps[2] = 10;
45     m_Optimizer->SetNumberOfSteps( steps );
46     m_Optimizer->SetStepLength( 2 );
47    \endcode
48  *
49  * The optimizer throws IterationEvents after every iteration. We use this to plot
50  * the metric space in an image as follows:
51  *
52    \code
53     if( itk::IterationEvent().CheckEvent(& event ) )
54     {
55       IndexType index;
56       index[0] = m_Optimizer->GetCurrentIndex()[0];
57       index[1] = m_Optimizer->GetCurrentIndex()[1];
58       index[2] = m_Optimizer->GetCurrentIndex()[2];
59       image->SetPixel( index, m_Optimizer->GetCurrentValue() );
60     }
61    \endcode
62  *
63  * The image size is expected to be 11 x 11 x 11.
64  *
65  * If you wish to use different step lengths along each parametric axis,
66  * you can use the SetScales() method. This accepts an array, each element
67  * represents the number of subdivisions per step length. For instance scales
68  * of [0.5 1 4] along with a step length of 2 will cause the optimizer
69  * to search the metric space on a grid with x,y,z spacing of [1 2 8].
70  *
71  * Physical dimensions of the grid are influenced by both the scales and
72  * the number of steps along each dimension, a side of the region is
73  * stepLength*(2*numberOfSteps[d]+1)*scaling[d].
74  *
75  * \ingroup ITKOptimizersv4
76  */
77 template<typename TInternalComputationValueType>
78 class ITK_TEMPLATE_EXPORT ExhaustiveOptimizerv4:
79   public ObjectToObjectOptimizerBaseTemplate<TInternalComputationValueType>
80 {
81 public:
82   ITK_DISALLOW_COPY_AND_ASSIGN(ExhaustiveOptimizerv4);
83 
84   /** Standard "Self" type alias. */
85   using Self = ExhaustiveOptimizerv4;
86   using Superclass = ObjectToObjectOptimizerBaseTemplate<TInternalComputationValueType>;
87   using Pointer = SmartPointer< Self >;
88   using ConstPointer = SmartPointer< const Self >;
89 
90   /** Method for creation through the object factory. */
91   itkNewMacro(Self);
92 
93   /** Run-time type information (and related methods). */
94   itkTypeMacro(ExhaustiveOptimizerv4, Superclass);
95 
96   /** Steps type */
97   using StepsType = Array< SizeValueType >;
98 
99   /** Measure type */
100   using MeasureType = typename Superclass::MeasureType;
101 
102   /** Parameters type */
103   using ParametersType = typename Superclass::ParametersType;
104 
105   /** Scales type */
106   using ScalesType = typename Superclass::ScalesType;
107 
108   void StartOptimization(bool doOnlyInitialization = false) override;
109 
110   /** Start optimization */
111   void StartWalking();
112 
113   /** Resume the optimization */
114   void ResumeWalking();
115 
116   /** Stop optimization */
117   void StopWalking();
118 
119   itkSetMacro(StepLength, double);
120   itkSetMacro(NumberOfSteps, StepsType);
121   itkGetConstReferenceMacro(StepLength, double);
122   itkGetConstReferenceMacro(NumberOfSteps, StepsType);
123   itkGetConstReferenceMacro(CurrentValue, MeasureType);
124   itkGetConstReferenceMacro(MaximumMetricValue, MeasureType);
125   itkGetConstReferenceMacro(MinimumMetricValue, MeasureType);
126   itkGetConstReferenceMacro(MinimumMetricValuePosition, ParametersType);
127   itkGetConstReferenceMacro(MaximumMetricValuePosition, ParametersType);
128   itkGetConstReferenceMacro(CurrentIndex, ParametersType);
129 
130   /** Get the reason for termination */
131   const std::string GetStopConditionDescription() const override;
132 
133   /**  Set the position to initialize the optimization. */
134   void SetInitialPosition(const ParametersType & param);
135 
136   /** Get the position to initialize the optimization. */
GetInitialPosition()137   ParametersType & GetInitialPosition()
138   {
139     return m_InitialPosition;
140   }
141 
142 protected:
143   ExhaustiveOptimizerv4();
144   ~ExhaustiveOptimizerv4() override = default;
145   void PrintSelf(std::ostream & os, Indent indent) const override;
146 
147   /** Advance to the next grid position. */
148   void AdvanceOneStep();
149 
150   void IncrementIndex(ParametersType & param);
151 
152 protected:
153   ParametersType  m_InitialPosition;
154   MeasureType     m_CurrentValue;
155   StepsType       m_NumberOfSteps;
156   bool            m_Stop{false};
157   double          m_StepLength{1.0};
158   ParametersType  m_CurrentIndex;
159   MeasureType     m_MaximumMetricValue;
160   MeasureType     m_MinimumMetricValue;
161   ParametersType  m_MinimumMetricValuePosition;
162   ParametersType  m_MaximumMetricValuePosition;
163 
164 private:
165   std::ostringstream m_StopConditionDescription;
166 };
167 } // end namespace itk
168 
169 #ifndef ITK_MANUAL_INSTANTIATION
170 #include "itkExhaustiveOptimizerv4.hxx"
171 #endif
172 
173 #endif
174