From 2f9913921cd27be3a9472cd528f416f098e2f096 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Wed, 1 May 2013 18:30:00 +0200 Subject: [PATCH] RootFinding: extract bracketing to separate class --- src/Numerics/Numerics.csproj | 1 + src/Numerics/RootFinding/Bracketing.cs | 48 +++++++++++++++++ src/Numerics/RootFinding/BrentRootFinder.cs | 12 +++++ src/Numerics/RootFinding/RootFinder.cs | 59 --------------------- 4 files changed, 61 insertions(+), 59 deletions(-) create mode 100644 src/Numerics/RootFinding/Bracketing.cs diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 23c22630..f3f830c6 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -109,6 +109,7 @@ + diff --git a/src/Numerics/RootFinding/Bracketing.cs b/src/Numerics/RootFinding/Bracketing.cs new file mode 100644 index 00000000..0cc1f603 --- /dev/null +++ b/src/Numerics/RootFinding/Bracketing.cs @@ -0,0 +1,48 @@ +using System; +using MathNet.Numerics.Properties; + +namespace MathNet.Numerics.RootFinding +{ + public static class Bracketing + { + /// Detect a range containing at least one root. + /// The function to detect roots from. + /// Lower value of the range. + /// Upper value of the range + /// The growing factor of research. Usually 1.6. + /// Maximum number of iterations. Usually 50. + /// True if the bracketing operation succeeded, false otherwise. + /// This iterative methods stops when two values with opposite signs are found. + public static bool SearchOutward(Func f, ref double xmin, ref double xmax, double factor = 1.6, int maxIterations = 50) + { + if (xmin >= xmax) + { + throw new ArgumentOutOfRangeException("xmax", string.Format(Resources.ArgumentOutOfRangeGreater, "xmax", "xmin")); + } + + double fmin = f(xmin); + double fmax = f(xmax); + + for(int i=0;iHelper method useful for preventing rounding errors. + /// a*sign(b) + static double Sign(double a, double b) + { + return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a); + } + + static bool Close(double d1, double d2) + { + return Math.Abs(d1 - d2) <= double.Epsilon; + } } } diff --git a/src/Numerics/RootFinding/RootFinder.cs b/src/Numerics/RootFinding/RootFinder.cs index 024bcac4..71c3e8f0 100644 --- a/src/Numerics/RootFinding/RootFinder.cs +++ b/src/Numerics/RootFinding/RootFinder.cs @@ -1,5 +1,4 @@ using System; -using MathNet.Numerics.Properties; namespace MathNet.Numerics.RootFinding { @@ -13,7 +12,6 @@ namespace MathNet.Numerics.RootFinding double _xmin = double.MinValue; double _xmax = double.MaxValue; Func _func; - private double _bracketingFactor = 1.6; public RootFinder() : this(DefaultMaxIterations, DefaultAccuracy) { @@ -36,16 +34,6 @@ namespace MathNet.Numerics.RootFinding public double Accuracy { get; set; } - public double BracketingFactor - { - get { return _bracketingFactor; } - set - { - if (value <= 0.0) throw new ArgumentOutOfRangeException(); - _bracketingFactor = value; - } - } - public int Iterations { set @@ -56,41 +44,6 @@ namespace MathNet.Numerics.RootFinding protected get { return _maxNumIters; } } - /// Detect a range containing at least one root. - /// Lower value of the range. - /// Upper value of the range - /// The growing factor of research. Usually 1.6. - /// True if the bracketing operation succeeded, else otherwise. - /// This iterative methods stops when two values with opposite signs are found. - public bool SearchBracketsOutward(ref double xmin, ref double xmax, double factor) - { - if (xmin >= xmax) - { - throw new RootFindingException(string.Format(Resources.ArgumentOutOfRangeGreater,"xmax","xmin"), 0, xmin, xmax, 0.0); - } - - double fmin = _func(xmin); - double fmax = _func(xmax); - - int i = 0; - while (i++ < _maxNumIters) - { - if (Math.Sign(fmin) != Math.Sign(fmax)) return true; - if (Math.Abs(fmin) < Math.Abs(fmax)) - { - xmin += factor * (xmin - xmax); - fmin = _func(xmin); - } - else - { - xmax += factor * (xmax - xmin); - fmax = _func(xmax); - } - } - - throw new RootFindingException(Resources.RootNotFound, i, fmin, fmax, 0.0); - } - /// Prototype algorithm for solving the equation f(x)=0. /// The low value of the range where the root is supposed to be. /// The high value of the range where the root is supposed to be. @@ -103,17 +56,5 @@ namespace MathNet.Numerics.RootFinding } protected abstract double Find(); - - /// Helper method useful for preventing rounding errors. - /// a*sign(b) - protected static double Sign(double a, double b) - { - return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a); - } - - protected static bool Close(double d1, double d2) - { - return Math.Abs(d1 - d2) <= double.Epsilon; - } } }