From b545e274ba5de4ecd525255663759cf86542c022 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Wed, 29 Apr 2020 14:34:57 +0200 Subject: [PATCH] Root Finding: argument checking also for other algorithms --- src/Numerics/RootFinding/Broyden.cs | 13 ++++++++---- src/Numerics/RootFinding/NewtonRaphson.cs | 21 ++++++++++++------- .../RootFinding/RobustNewtonRaphson.cs | 11 +++++++--- src/Numerics/RootFinding/Secant.cs | 19 ++++++++++------- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/Numerics/RootFinding/Broyden.cs b/src/Numerics/RootFinding/Broyden.cs index d6b15e6a..84b1d464 100644 --- a/src/Numerics/RootFinding/Broyden.cs +++ b/src/Numerics/RootFinding/Broyden.cs @@ -3,7 +3,7 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2020 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -43,7 +43,7 @@ namespace MathNet.Numerics.RootFinding /// Find a solution of the equation f(x)=0. /// The function to find roots from. /// Initial guess of the root. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. Must be greater than 0. /// Maximum number of iterations. Default 100. /// Relative step size for calculating the Jacobian matrix at first step. Default 1.0e-4 /// Returns the root with the specified accuracy. @@ -62,13 +62,18 @@ namespace MathNet.Numerics.RootFinding /// Find a solution of the equation f(x)=0. /// The function to find roots from. /// Initial guess of the root. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Must be greater than 0. /// Maximum number of iterations. Usually 100. /// Relative step size for calculating the Jacobian matrix at first step. /// The root that was found, if any. Undefined if the function returns false. /// True if a root with the specified accuracy was found, else false. public static bool TryFindRootWithJacobianStep(Func f, double[] initialGuess, double accuracy, int maxIterations, double jacobianStepSize, out double[] root) { + if (accuracy <= 0) + { + throw new ArgumentOutOfRangeException(nameof(accuracy), "Must be greater than zero."); + } + var x = new DenseVector(initialGuess); double[] y0 = f(initialGuess); @@ -121,7 +126,7 @@ namespace MathNet.Numerics.RootFinding /// Find a solution of the equation f(x)=0. /// The function to find roots from. /// Initial guess of the root. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Must be greater than 0. /// Maximum number of iterations. Usually 100. /// The root that was found, if any. Undefined if the function returns false. /// True if a root with the specified accuracy was found, else false. diff --git a/src/Numerics/RootFinding/NewtonRaphson.cs b/src/Numerics/RootFinding/NewtonRaphson.cs index f1c0f72a..948da0fd 100644 --- a/src/Numerics/RootFinding/NewtonRaphson.cs +++ b/src/Numerics/RootFinding/NewtonRaphson.cs @@ -2,9 +2,9 @@ // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics -// -// Copyright (c) 2009-2013 Math.NET -// +// +// Copyright (c) 2009-2020 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -13,10 +13,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -44,7 +44,7 @@ namespace MathNet.Numerics.RootFinding /// The first derivative of the function to find roots from. /// The low value of the range where the root is supposed to be. Aborts if it leaves the interval. /// The high value of the range where the root is supposed to be. Aborts if it leaves the interval. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. Must be greater than 0. /// Maximum number of iterations. Default 100. /// Returns the root with the specified accuracy. /// @@ -65,7 +65,7 @@ namespace MathNet.Numerics.RootFinding /// Initial guess of the root. /// The low value of the range where the root is supposed to be. Aborts if it leaves the interval. Default MinValue. /// The high value of the range where the root is supposed to be. Aborts if it leaves the interval. Default MaxValue. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. Must be greater than 0. /// Maximum number of iterations. Default 100. /// Returns the root with the specified accuracy. /// @@ -86,12 +86,17 @@ namespace MathNet.Numerics.RootFinding /// Initial guess of the root. /// The low value of the range where the root is supposed to be. Aborts if it leaves the interval. /// The high value of the range where the root is supposed to be. Aborts if it leaves the interval. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14. Must be greater than 0. /// Maximum number of iterations. Example: 100. /// The root that was found, if any. Undefined if the function returns false. /// True if a root with the specified accuracy was found, else false. public static bool TryFindRoot(Func f, Func df, double initialGuess, double lowerBound, double upperBound, double accuracy, int maxIterations, out double root) { + if (accuracy <= 0) + { + throw new ArgumentOutOfRangeException(nameof(accuracy), "Must be greater than zero."); + } + root = initialGuess; for (int i = 0; i < maxIterations && root >= lowerBound && root <= upperBound; i++) { diff --git a/src/Numerics/RootFinding/RobustNewtonRaphson.cs b/src/Numerics/RootFinding/RobustNewtonRaphson.cs index dcd31d73..9dce9661 100644 --- a/src/Numerics/RootFinding/RobustNewtonRaphson.cs +++ b/src/Numerics/RootFinding/RobustNewtonRaphson.cs @@ -3,7 +3,7 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2020 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -43,7 +43,7 @@ namespace MathNet.Numerics.RootFinding /// The first derivative of the function to find roots from. /// 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. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. Must be greater than 0. /// Maximum number of iterations. Default 100. /// How many parts an interval should be split into for zero crossing scanning in case of lacking bracketing. Default 20. /// Returns the root with the specified accuracy. @@ -64,13 +64,18 @@ namespace MathNet.Numerics.RootFinding /// The first derivative of the function to find roots from. /// 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. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14. Must be greater than 0. /// Maximum number of iterations. Example: 100. /// How many parts an interval should be split into for zero crossing scanning in case of lacking bracketing. Example: 20. /// The root that was found, if any. Undefined if the function returns false. /// True if a root with the specified accuracy was found, else false. public static bool TryFindRoot(Func f, Func df, double lowerBound, double upperBound, double accuracy, int maxIterations, int subdivision, out double root) { + if (accuracy <= 0) + { + throw new ArgumentOutOfRangeException(nameof(accuracy), "Must be greater than zero."); + } + double fmin = f(lowerBound); double fmax = f(upperBound); diff --git a/src/Numerics/RootFinding/Secant.cs b/src/Numerics/RootFinding/Secant.cs index 7199c831..5a8ef5cd 100644 --- a/src/Numerics/RootFinding/Secant.cs +++ b/src/Numerics/RootFinding/Secant.cs @@ -2,9 +2,9 @@ // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics -// -// Copyright (c) 2009-2013 Math.NET -// +// +// Copyright (c) 2009-2020 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -13,10 +13,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -45,7 +45,7 @@ namespace MathNet.Numerics.RootFinding /// The second guess of the root within the bounds specified. /// The low value of the range where the root is supposed to be. Aborts if it leaves the interval. Default MinValue. /// The high value of the range where the root is supposed to be. Aborts if it leaves the interval. Default MaxValue. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Default 1e-8. Must be greater than 0. /// Maximum number of iterations. Default 100. /// Returns the root with the specified accuracy. /// @@ -66,12 +66,17 @@ namespace MathNet.Numerics.RootFinding /// The second guess of the root within the bounds specified. /// The low value of the range where the root is supposed to be. Aborts if it leaves the interval. /// The low value of the range where the root is supposed to be. Aborts if it leaves the interval. - /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14. + /// Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached. Example: 1e-14. Must be greater than 0. /// Maximum number of iterations. Example: 100. /// The root that was found, if any. Undefined if the function returns false. /// True if a root with the specified accuracy was found, else false public static bool TryFindRoot(Func f, double guess, double secondGuess, double lowerBound, double upperBound, double accuracy, int maxIterations, out double root) { + if (accuracy <= 0) + { + throw new ArgumentOutOfRangeException(nameof(accuracy), "Must be greater than zero."); + } + root = secondGuess; // Either guess is outside of bounds