Skip to content

Commit 5b1eab1

Browse files
committed
RobustNewtonRaphson returns the mean value of the search range for degenerate cases, in which the function is tautologically 0 everywhere.
1 parent 271a4ea commit 5b1eab1

2 files changed

Lines changed: 25 additions & 7 deletions

File tree

src/Numerics.Tests/RootFindingTests/RobustNewtonRaphsonTest.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,24 @@ public void Cubic()
115115
Assert.AreEqual(4.0254088477485, RobustNewtonRaphson.FindRoot(f2, df2, 3, 5, 1e-10, 100, 20), 1e-6);
116116
}
117117

118+
[Test]
119+
public void InfinitelyManyRoots()
120+
{
121+
// degenerate case with infinitely many roots
122+
Func<double, double> f1 = x => 0.0;
123+
Func<double, double> df1 = x => 0.0;
124+
Assert.AreEqual(-50, RobustNewtonRaphson.FindRoot(f1, df1, -200, 100), 1e-6);
125+
}
126+
127+
[Test]
128+
public void InfinitelyManyRootsWithGivenAccuracy()
129+
{
130+
// degenerate case with infinitely many roots
131+
Func<double, double> f1 = x => 1e-10;
132+
Func<double, double> df1 = x => 1e-6;
133+
Assert.AreEqual(-50, RobustNewtonRaphson.FindRoot(f1, df1, -200, 100, 1e-8), 1e-6);
134+
}
135+
118136
[Test]
119137
public void NoRoot()
120138
{

src/Numerics/RootFinding/RobustNewtonRaphson.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,22 +77,22 @@ public static bool TryFindRoot(Func<double, double> f, Func<double, double> df,
7777
double fmin = f(lowerBound);
7878
double fmax = f(upperBound);
7979

80-
if (Math.Abs(fmin) < accuracy)
80+
root = 0.5 * (lowerBound + upperBound);
81+
double fx = f(root);
82+
if (Math.Abs(fx) < accuracy)
8183
{
82-
root = lowerBound;
8384
return true;
8485
}
8586

86-
if (Math.Abs(fmax) < accuracy)
87+
if (Math.Abs(fmin) < accuracy)
8788
{
88-
root = upperBound;
89+
root = lowerBound;
8990
return true;
9091
}
9192

92-
root = 0.5*(lowerBound + upperBound);
93-
double fx = f(root);
94-
if (fx == 0.0)
93+
if (Math.Abs(fmax) < accuracy)
9594
{
95+
root = upperBound;
9696
return true;
9797
}
9898

0 commit comments

Comments
 (0)