11 m_CurrentPosition = this->GetInitialPosition();
12 ParametersType parameters(m_CurrentPosition);
14 unsigned int nbParams = parameters.size();
19 unsigned int numResiduals = m_ResidualValues.size();
21 unsigned int numIterations = 0;
22 bool stopConditionReached =
false;
23 bool rejectedStep =
false;
25 DerivativeType derivativeMatrix(numResiduals,nbParams);
26 DerivativeType derivativeMatrixCopy;
27 ParametersType oldParameters = parameters;
28 ParametersType dValues(nbParams);
33 m_CostFunction->GetDerivative(parameters,derivativeMatrix);
34 derivativeMatrixCopy = derivativeMatrix;
36 bool derivativeCheck =
false;
37 for (
unsigned int i = 0;i < nbParams;++i)
39 for (
unsigned int j = 0;j < numResiduals;++j)
41 if (std::abs(derivativeMatrix.get(i,j)) > std::sqrt(std::numeric_limits <double>::epsilon()))
43 derivativeCheck =
true;
55 m_DeltaParameter = 0.0;
56 double maxDValue = 0.0;
58 for (
unsigned int i = 0;i < nbParams;++i)
60 double normValue = 0.0;
61 for (
unsigned int j = 0;j < numResiduals;++j)
63 double tmpVal = derivativeMatrix.get(j,i);
64 normValue += tmpVal * tmpVal;
67 dValues[i] = std::sqrt(normValue);
68 if (dValues[i] != 0.0)
70 if ((i == 0) || (dValues[i] > maxDValue))
71 maxDValue = dValues[i];
75 double basePower = std::floor(std::log(maxDValue) / std::log(2.0));
76 double epsilon = 20.0 * std::numeric_limits <double>::epsilon() * (numResiduals + nbParams) * std::pow(2.0,basePower);
79 for (
unsigned int i = 0;i < nbParams;++i)
81 if (dValues[i] < epsilon)
84 m_DeltaParameter += dValues[i] * parameters[i] * parameters[i];
87 m_DeltaParameter = std::sqrt(m_DeltaParameter);
89 unsigned int rank = 0;
91 std::vector <unsigned int> pivotVector(nbParams);
93 std::vector <unsigned int> inversePivotVector(nbParams);
94 std::vector <double> qrBetaValues(nbParams);
95 ParametersType qtResiduals = m_ResidualValues;
96 ParametersType lowerBoundsPermutted(nbParams);
97 ParametersType oldParametersPermutted(nbParams);
98 ParametersType upperBoundsPermutted(nbParams);
101 for (
unsigned int i = 0;i < nbParams;++i)
102 inversePivotVector[pivotVector[i]] = i;
104 m_LambdaCostFunction->SetInputWorkMatricesAndVectorsFromQRDerivative(derivativeMatrix,qtResiduals,rank);
105 m_LambdaCostFunction->SetJRank(rank);
106 m_LambdaCostFunction->SetDValues(dValues);
107 m_LambdaCostFunction->SetPivotVector(pivotVector);
108 m_LambdaCostFunction->SetInversePivotVector(inversePivotVector);
110 while (!stopConditionReached)
114 for (
unsigned int i = 0;i < nbParams;++i)
116 lowerBoundsPermutted[i] = m_LowerBounds[pivotVector[i]];
117 upperBoundsPermutted[i] = m_UpperBounds[pivotVector[i]];
118 oldParametersPermutted[i] = oldParameters[pivotVector[i]];
121 m_LambdaCostFunction->SetLowerBoundsPermutted(lowerBoundsPermutted);
122 m_LambdaCostFunction->SetUpperBoundsPermutted(upperBoundsPermutted);
123 m_LambdaCostFunction->SetPreviousParametersPermutted(oldParametersPermutted);
128 parameters = oldParameters;
129 parameters += m_CurrentAddonVector;
133 rejectedStep = (tentativeNewCostValue > m_CurrentValue);
135 double acceptRatio = 0.0;
139 acceptRatio = 1.0 - tentativeNewCostValue / m_CurrentValue;
142 double fjpNorm = 0.0;
143 for (
unsigned int i = 0;i < numResiduals;++i)
145 double fjpAddonValue = m_ResidualValues[i];
147 for (
unsigned int j = 0;j < nbParams;++j)
148 fjpAddonValue += derivativeMatrixCopy.get(i,j) * m_CurrentAddonVector[j];
150 fjpNorm += fjpAddonValue * fjpAddonValue;
153 double denomAcceptRatio = 1.0 - fjpNorm / m_CurrentValue;
155 if (denomAcceptRatio > 0.0)
156 acceptRatio /= denomAcceptRatio;
161 if (acceptRatio >= 0.75)
164 m_DeltaParameter *= 2.0;
166 else if (acceptRatio <= 0.25)
169 if (tentativeNewCostValue > 100.0 * m_CurrentValue)
171 else if (tentativeNewCostValue > m_CurrentValue)
175 for (
unsigned int i = 0;i < nbParams;++i)
177 double jtFValue = 0.0;
178 for (
unsigned int j = 0;j < numResiduals;++j)
179 jtFValue += derivativeMatrixCopy.get(j,i) * m_ResidualValues[i];
181 gamma += m_CurrentAddonVector[i] * jtFValue / m_CurrentValue;
186 else if (gamma > 0.0)
190 double denomMu = gamma + 0.5 * (1.0 - tentativeNewCostValue / m_CurrentValue);
193 mu = std::min(0.5,std::max(0.1,mu));
196 m_DeltaParameter *= mu;
201 m_ResidualValues = newResidualValues;
202 m_CostFunction->GetDerivative(parameters,derivativeMatrix);
204 for (
unsigned int i = 0;i < nbParams;++i)
206 double normValue = 0;
207 for (
unsigned int j = 0;j < numResiduals;++j)
209 double tmpVal = derivativeMatrix.get(j,i);
210 normValue += tmpVal * tmpVal;
213 normValue = std::sqrt(normValue);
214 dValues[i] = std::max(dValues[i], normValue);
217 derivativeMatrixCopy = derivativeMatrix;
219 qtResiduals = m_ResidualValues;
222 for (
unsigned int i = 0;i < nbParams;++i)
223 inversePivotVector[pivotVector[i]] = i;
225 m_LambdaCostFunction->SetInputWorkMatricesAndVectorsFromQRDerivative(derivativeMatrix,qtResiduals,rank);
226 m_LambdaCostFunction->SetJRank(rank);
227 m_LambdaCostFunction->SetDValues(dValues);
228 m_LambdaCostFunction->SetPivotVector(pivotVector);
229 m_LambdaCostFunction->SetInversePivotVector(inversePivotVector);
232 if (numIterations != 1)
233 stopConditionReached = this->
CheckConditions(numIterations,parameters,oldParameters,dValues,
234 tentativeNewCostValue);
238 oldParameters = parameters;
239 m_CurrentValue = tentativeNewCostValue;
243 this->SetCurrentPosition(oldParameters);
247 ParametersType &upperBounds,
unsigned int rank)
249 for (
unsigned int i = 0;i < rank;++i)
251 if (solutionVector[i] < lowerBounds[i])
254 if (solutionVector[i] > upperBounds[i])
262 std::vector <unsigned int> &pivotVector,
263 ParametersType &qtResiduals,
unsigned int rank)
265 m_LambdaCostFunction->SetDeltaParameter(m_DeltaParameter);
267 ParametersType p(m_LambdaCostFunction->GetNumberOfParameters());
270 double zeroCost = m_LambdaCostFunction->GetValue(p);
273 m_LambdaParameter = 0.0;
274 m_CurrentAddonVector = m_LambdaCostFunction->GetSolutionVector();
278 double lowerBoundLambda, upperBoundLambda;
279 lowerBoundLambda = 0.0;
280 upperBoundLambda = 0.0;
282 unsigned int n = derivative.cols();
285 double u0InVectorPart;
286 for (
unsigned int i = 0;i < n;++i)
288 u0InVectorPart = 0.0;
289 unsigned int maxIndex = std::min(i + 1,rank);
290 for (
unsigned int j = 0;j < maxIndex;++j)
291 u0InVectorPart += derivative.get(j,i) * qtResiduals[j];
294 upperBoundLambda += (u0InVectorPart / dValues[pivotVector[i]]) * (u0InVectorPart / dValues[pivotVector[i]]);
297 upperBoundLambda = std::sqrt(upperBoundLambda) / m_DeltaParameter;
303 double fTolAbs = 2.0 * std::sqrt(std::numeric_limits<double>::epsilon());
304 double xTolRel = 2.0 * std::sqrt(std::numeric_limits<double>::epsilon());
306 double logsDiff = std::log(upperBoundLambda) - 0.5 * std::log(std::numeric_limits<double>::epsilon());
307 unsigned int maxCount =
static_cast<unsigned int> (1.0 + logsDiff / std::log(2.0));
319 m_LambdaParameter = algorithm.
Optimize();
320 m_CurrentAddonVector = m_LambdaCostFunction->GetSolutionVector();
325 residualValues = m_CostFunction->GetValue(parameters);
327 unsigned int numResiduals = residualValues.size();
328 double costValue = 0.0;
329 for (
unsigned int i = 0;i < numResiduals;++i)
330 costValue += residualValues[i] * residualValues[i];
336 ParametersType &oldParams, ParametersType &dValues,
double newCostValue)
338 if (numIterations == m_NumberOfIterations)
342 unsigned int numParams = newParams.size();
345 for (
unsigned int i = 0;i < numParams;++i)
347 double oldValue = dValues[i] * oldParams[i];
348 double newValue = dValues[i] * newParams[i];
349 dxNew += newValue * newValue;
350 dxDiff += (newValue - oldValue) * (newValue - oldValue);
353 dxNew = std::sqrt(dxNew);
355 if (m_DeltaParameter <= m_ValueTolerance * dxNew)
359 double fDiff = m_CurrentValue - newCostValue;
361 if ((fDiff >= 0.0) && (fDiff <= m_CostTolerance * m_CurrentValue))
365 dxDiff = std::sqrt(dxDiff);
367 if (dxDiff <= m_ValueTolerance * dxNew)
void QRPivotDecomposition(vnl_matrix< ScalarType > &aMatrix, std::vector< unsigned int > &pivotVector, std::vector< ScalarType > &houseBetaValues, unsigned int &rank)
double Optimize() ITK_OVERRIDE
void GetQtBFromQRPivotDecomposition(vnl_matrix< ScalarType > &qrMatrix, vnl_vector< ScalarType > &bVector, std::vector< ScalarType > &houseBetaValues, unsigned int rank)
void SetUpperBound(const double &val)
void SetFunctionValueAtInitialLowerBound(const double &val)
bool CheckSolutionIsInBounds(ParametersType &solutionVector, ParametersType &lowerBounds, ParametersType &upperBounds, unsigned int rank)
Superclass::MeasureType MeasureType
void UpdateLambdaParameter(DerivativeType &derivative, ParametersType &dValues, std::vector< unsigned int > &pivotVector, ParametersType &qtResiduals, unsigned int rank)
void SetLowerBound(const double &val)
void SetRootRelativeTolerance(const double &val)
bool CheckConditions(unsigned int numIterations, ParametersType &newParams, ParametersType &oldParams, ParametersType &dValues, double newCostValue)
double EvaluateCostFunctionAtParameters(ParametersType ¶meters, MeasureType &residualValues)
void SetCostFunctionTolerance(const double &val)
void StartOptimization() ITK_OVERRIDE
void SetMaximumNumberOfIterations(const unsigned int &val)
void SetRootFindingFunction(BaseCostFunctionType *f)