/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkExhaustiveOptimizerv4_hxx #define itkExhaustiveOptimizerv4_hxx namespace itk { template ExhaustiveOptimizerv4::ExhaustiveOptimizerv4() { this->m_NumberOfIterations = 0; } template void ExhaustiveOptimizerv4::StartOptimization(bool /* doOnlyInitialization */) { this->StartWalking(); } template void ExhaustiveOptimizerv4::StartWalking() { itkDebugMacro("StartWalking"); this->InvokeEvent(StartEvent()); m_StopConditionDescription.str(""); m_StopConditionDescription << this->GetNameOfClass() << ": Running"; ParametersType initialPos = this->m_Metric->GetParameters(); if (this->m_InitialPosition.GetSize() == initialPos.GetSize()) { initialPos = this->m_InitialPosition; // correct size, so must have been set by the user } m_MinimumMetricValuePosition = initialPos; m_MaximumMetricValuePosition = initialPos; this->SetInitialPosition(initialPos); // store the initial position MeasureType initialValue = this->m_Metric->GetValue(); m_MaximumMetricValue = initialValue; m_MinimumMetricValue = initialValue; this->m_CurrentIteration = 0; this->m_NumberOfIterations = 1; const unsigned int spaceDimension = this->m_Metric->GetParameters().GetSize(); for (unsigned int i = 0; i < spaceDimension; ++i) { this->m_NumberOfIterations *= (2 * m_NumberOfSteps[i] + 1); } m_CurrentIndex.SetSize(spaceDimension); m_CurrentIndex.Fill(0); const ScalesType & scales = this->GetScales(); // Make sure the scales have been set properly if (scales.size() != spaceDimension) { itkExceptionMacro("The size of Scales is " << scales.size() << ", but the NumberOfParameters is " << spaceDimension << '.'); } // Setup first grid position. ParametersType position(spaceDimension); for (unsigned int i = 0; i < spaceDimension; ++i) { position[i] = this->GetCurrentPosition()[i] - m_NumberOfSteps[i] * m_StepLength * scales[i]; } this->m_Metric->SetParameters(position); itkDebugMacro("Calling ResumeWalking"); this->ResumeWalking(); } template void ExhaustiveOptimizerv4::ResumeWalking() { itkDebugMacro("ResumeWalk"); m_Stop = false; while (!m_Stop) { ParametersType currentPosition = this->GetCurrentPosition(); if (m_Stop) { StopWalking(); break; } m_CurrentValue = this->m_Metric->GetValue(); if (m_CurrentValue > m_MaximumMetricValue) { m_MaximumMetricValue = m_CurrentValue; m_MaximumMetricValuePosition = currentPosition; } if (m_CurrentValue < m_MinimumMetricValue) { m_MinimumMetricValue = m_CurrentValue; m_MinimumMetricValuePosition = currentPosition; } if (m_Stop) { this->StopWalking(); break; } m_StopConditionDescription.str(""); m_StopConditionDescription << this->GetNameOfClass() << ": Running. " << "@ index " << this->GetCurrentIndex() << " value is " << m_CurrentValue; this->InvokeEvent(IterationEvent()); this->AdvanceOneStep(); this->m_CurrentIteration++; } } template void ExhaustiveOptimizerv4::StopWalking() { itkDebugMacro("StopWalking"); m_Stop = true; this->InvokeEvent(EndEvent()); } template void ExhaustiveOptimizerv4::AdvanceOneStep() { itkDebugMacro("AdvanceOneStep"); const unsigned int spaceDimension = this->m_Metric->GetParameters().GetSize(); ParametersType newPosition(spaceDimension); this->IncrementIndex(newPosition); itkDebugMacro("new position = " << newPosition); this->m_Metric->SetParameters(newPosition); } template void ExhaustiveOptimizerv4::IncrementIndex(ParametersType & newPosition) { unsigned int idx = 0; const unsigned int spaceDimension = this->m_Metric->GetParameters().GetSize(); while (idx < spaceDimension) { m_CurrentIndex[idx]++; if (m_CurrentIndex[idx] > (2 * m_NumberOfSteps[idx])) { m_CurrentIndex[idx] = 0; ++idx; } else { break; } } if (idx == spaceDimension) { m_Stop = true; m_StopConditionDescription.str(""); m_StopConditionDescription << this->GetNameOfClass() << ": " << "Completed sampling of parametric space of size " << spaceDimension; } const ScalesType & scales = this->GetScales(); for (unsigned int i = 0; i < spaceDimension; ++i) { newPosition[i] = (m_CurrentIndex[i] - m_NumberOfSteps[i]) * m_StepLength * scales[i] + this->GetInitialPosition()[i]; } } template const std::string ExhaustiveOptimizerv4::GetStopConditionDescription() const { return m_StopConditionDescription.str(); } template void ExhaustiveOptimizerv4::SetInitialPosition(const ParametersType & param) { m_InitialPosition = param; this->Modified(); } template void ExhaustiveOptimizerv4::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "InitialPosition: " << m_InitialPosition << std::endl; os << indent << "CurrentValue: " << static_cast::PrintType>(m_CurrentValue) << std::endl; os << indent << "NumberOfSteps: " << static_cast::PrintType>(m_NumberOfSteps) << std::endl; os << indent << "Stop: " << (m_Stop ? "On" : "Off") << std::endl; os << indent << "StepLength: " << m_StepLength << std::endl; os << indent << "CurrentIndex: " << m_CurrentIndex << std::endl; os << indent << "MaximumMetricValue: " << static_cast::PrintType>(m_MaximumMetricValue) << std::endl; os << indent << "MinimumMetricValue: " << static_cast::PrintType>(m_MinimumMetricValue) << std::endl; os << indent << "MinimumMetricValuePosition: " << m_MinimumMetricValuePosition << std::endl; os << indent << "MaximumMetricValuePosition: " << m_MaximumMetricValuePosition << std::endl; os << indent << "StopConditionDescription: " << m_StopConditionDescription.str() << std::endl; } } // end namespace itk #endif