ANIMA  4.0
animaDekkerRootFindingAlgorithm.cxx
Go to the documentation of this file.
2 
3 namespace anima
4 {
5 
7 {
8  // Implementation from
9  // https://en.m.wikipedia.org/wiki/Brent's_method
10  bool continueLoop = true;
11  unsigned int nbIterations = 0;
12 
13  unsigned int numParameters = this->GetRootFindingFunction()->GetNumberOfParameters();
14  if (numParameters > 1)
15  throw itk::ExceptionObject(__FILE__, __LINE__, "Dekker algorithm does not implement multi-dimensional optimization. Only one parameter allowed.");
16 
17  ParametersType p(1);
18 
19  double internalLowerBound = this->GetLowerBound();
20  double internalUpperBound = this->GetUpperBound();
21 
22  double fValAtLowerBound = this->GetFunctionValueAtInitialLowerBound();
24  {
25  p[0] = internalLowerBound;
26  fValAtLowerBound = this->GetRootFindingFunction()->GetValue(p);
27  }
28 
29  double fValAtUpperBound = this->GetFunctionValueAtInitialUpperBound();
31  {
32  p[0] = internalUpperBound;
33  fValAtUpperBound = this->GetRootFindingFunction()->GetValue(p);
34  }
35 
36  if (std::abs(fValAtLowerBound) < std::abs(fValAtUpperBound))
37  {
38  double workValue = internalLowerBound;
39  internalLowerBound = internalUpperBound;
40  internalUpperBound = workValue;
41  workValue = fValAtLowerBound;
42  fValAtLowerBound = fValAtUpperBound;
43  fValAtUpperBound = workValue;
44  }
45 
46  double previousUpperBound = internalLowerBound;
47  double previousFValAtUpperBound = fValAtLowerBound;
48 
49  while (continueLoop)
50  {
51  ++nbIterations;
52 
53  double fDiff = fValAtUpperBound - previousFValAtUpperBound;
54 
55  if (fDiff == 0.0)
56  p[0] = (internalLowerBound + internalUpperBound) / 2.0;
57  else
58  p[0] = internalUpperBound - (internalUpperBound - previousUpperBound) * fValAtUpperBound / fDiff;
59 
60  previousUpperBound = internalUpperBound;
61  previousFValAtUpperBound = fValAtUpperBound;
62 
63  internalUpperBound = p[0];
64  fValAtUpperBound = this->GetRootFindingFunction()->GetValue(p);
65 
66  continueLoop = (std::abs(fValAtUpperBound) >= this->GetCostFunctionTolerance());
67 
68  if (fValAtLowerBound * fValAtUpperBound > 0.0)
69  {
70  internalLowerBound = previousUpperBound;
71  fValAtLowerBound = previousFValAtUpperBound;
72  }
73 
74  if (std::abs(fValAtLowerBound) < std::abs(fValAtUpperBound))
75  {
76  double workValue = internalLowerBound;
77  internalLowerBound = internalUpperBound;
78  internalUpperBound = workValue;
79  workValue = fValAtLowerBound;
80  fValAtLowerBound = fValAtUpperBound;
81  fValAtUpperBound = workValue;
82  }
83 
84  if ((nbIterations >= this->GetMaximumNumberOfIterations()) ||
85  (std::abs(internalUpperBound - internalLowerBound) < this->GetRootRelativeTolerance() * (internalLowerBound + internalUpperBound) / 2.0))
86  continueLoop = false;
87  }
88 
89  return p[0];
90 }
91 
92 } // end namespace anima
BaseCostFunctionType::ParametersType ParametersType