diff --git a/src/Numerics/Optimization/BfgsBMinimizer.cs b/src/Numerics/Optimization/BfgsBMinimizer.cs index cd53a380..20b29a13 100644 --- a/src/Numerics/Optimization/BfgsBMinimizer.cs +++ b/src/Numerics/Optimization/BfgsBMinimizer.cs @@ -158,9 +158,9 @@ namespace MathNet.Numerics.Optimization protected override Vector CalculateSearchDirection(ref Matrix pseudoHessian, out double maxLineSearchStep, - out double startingStepSize, - IObjectiveFunction previousPoint, - IObjectiveFunction candidatePoint, + out double startingStepSize, + IObjectiveFunction previousPoint, + IObjectiveFunction candidatePoint, Vector step) { Vector lineSearchDirection; @@ -170,7 +170,7 @@ namespace MathNet.Numerics.Optimization if (sy > 0.0) // only do update if it will create a positive definite matrix { double sts = step * step; - + var Hs = pseudoHessian * step; var sHs = step * pseudoHessian * step; pseudoHessian = pseudoHessian + y.OuterProduct(y) * (1.0 / sy) - Hs.OuterProduct(Hs) * (1.0 / sHs); @@ -285,7 +285,7 @@ namespace MathNet.Numerics.Optimization } } - protected override double GetProjectedGradient(IObjectiveFunction candidatePoint, int ii) + protected override double GetProjectedGradient(IObjectiveFunctionEvaluation candidatePoint, int ii) { double projectedGradient; bool atLowerBound = candidatePoint.Point[ii] - _lowerBound[ii] < VerySmall; diff --git a/src/Numerics/Optimization/BfgsMinimizerBase.cs b/src/Numerics/Optimization/BfgsMinimizerBase.cs index c46d914e..bd97bce1 100644 --- a/src/Numerics/Optimization/BfgsMinimizerBase.cs +++ b/src/Numerics/Optimization/BfgsMinimizerBase.cs @@ -59,7 +59,7 @@ namespace MathNet.Numerics.Optimization MaximumIterations = maximumIterations; } - protected MinimizationResult.ExitCondition ExitCriteriaSatisfied(IObjectiveFunction candidatePoint, IObjectiveFunction lastPoint, int iterations) + protected MinimizationResult.ExitCondition ExitCriteriaSatisfied(IObjectiveFunctionEvaluation candidatePoint, IObjectiveFunctionEvaluation lastPoint, int iterations) { Vector relGrad = new DenseVector(candidatePoint.Point.Count); double relativeGradient = 0.0; @@ -99,12 +99,12 @@ namespace MathNet.Numerics.Optimization return MinimizationResult.ExitCondition.None; } - protected virtual double GetProjectedGradient(IObjectiveFunction candidatePoint, int ii) + protected virtual double GetProjectedGradient(IObjectiveFunctionEvaluation candidatePoint, int ii) { return candidatePoint.Gradient[ii]; } - protected void ValidateGradientAndObjective(IObjectiveFunction eval) + protected void ValidateGradientAndObjective(IObjectiveFunctionEvaluation eval) { foreach (var x in eval.Gradient) { diff --git a/src/Numerics/Optimization/ConjugateGradientMinimizer.cs b/src/Numerics/Optimization/ConjugateGradientMinimizer.cs index 9f9b37ce..52621e64 100644 --- a/src/Numerics/Optimization/ConjugateGradientMinimizer.cs +++ b/src/Numerics/Optimization/ConjugateGradientMinimizer.cs @@ -127,7 +127,7 @@ namespace MathNet.Numerics.Optimization return gradient.Norm(2.0) < GradientTolerance; } - void ValidateGradient(IObjectiveFunction objective) + void ValidateGradient(IObjectiveFunctionEvaluation objective) { foreach (var x in objective.Gradient) { @@ -136,7 +136,7 @@ namespace MathNet.Numerics.Optimization } } - void ValidateObjective(IObjectiveFunction objective) + void ValidateObjective(IObjectiveFunctionEvaluation objective) { if (Double.IsNaN(objective.Value) || Double.IsInfinity(objective.Value)) throw new EvaluationException("Non-finite objective function returned.", objective); diff --git a/src/Numerics/Optimization/Exceptions.cs b/src/Numerics/Optimization/Exceptions.cs index 41c552e5..e1db30a6 100644 --- a/src/Numerics/Optimization/Exceptions.cs +++ b/src/Numerics/Optimization/Exceptions.cs @@ -49,15 +49,15 @@ namespace MathNet.Numerics.Optimization public class EvaluationException : OptimizationException { - public IObjectiveFunction ObjectiveFunction { get; private set; } + public IObjectiveFunctionEvaluation ObjectiveFunction { get; private set; } - public EvaluationException(string message, IObjectiveFunction eval) + public EvaluationException(string message, IObjectiveFunctionEvaluation eval) : base(message) { ObjectiveFunction = eval; } - public EvaluationException(string message, IObjectiveFunction eval, Exception innerException) + public EvaluationException(string message, IObjectiveFunctionEvaluation eval, Exception innerException) : base(message, innerException) { ObjectiveFunction = eval; diff --git a/src/Numerics/Optimization/LineSearch/StrongWolfeLineSearch.cs b/src/Numerics/Optimization/LineSearch/StrongWolfeLineSearch.cs index 96b228a1..21838356 100644 --- a/src/Numerics/Optimization/LineSearch/StrongWolfeLineSearch.cs +++ b/src/Numerics/Optimization/LineSearch/StrongWolfeLineSearch.cs @@ -40,7 +40,10 @@ namespace MathNet.Numerics.Optimization.LineSearch // Argument validation in base class } - protected override MinimizationResult.ExitCondition WolfeExitCondition { get { return MinimizationResult.ExitCondition.StrongWolfeCriteria; } } + protected override MinimizationResult.ExitCondition WolfeExitCondition + { + get { return MinimizationResult.ExitCondition.StrongWolfeCriteria; } + } protected override bool WolfeCondition(double stepDd, double initialDd) { diff --git a/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs b/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs index 5d08eec3..807ede1d 100644 --- a/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs +++ b/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs @@ -64,7 +64,7 @@ namespace MathNet.Numerics.Optimization.LineSearch return stepDd < C2 * initialDd; } - protected override void ValidateValue(IObjectiveFunction eval) + protected override void ValidateValue(IObjectiveFunctionEvaluation eval) { if (!IsFinite(eval.Value)) { @@ -78,7 +78,7 @@ namespace MathNet.Numerics.Optimization.LineSearch throw new ArgumentException("objective function does not support gradient"); } - protected override void ValidateGradient(IObjectiveFunction eval) + protected override void ValidateGradient(IObjectiveFunctionEvaluation eval) { foreach (double x in eval.Gradient) { diff --git a/src/Numerics/Optimization/LineSearch/WolfeLineSearch.cs b/src/Numerics/Optimization/LineSearch/WolfeLineSearch.cs index be226a52..0e2faf15 100644 --- a/src/Numerics/Optimization/LineSearch/WolfeLineSearch.cs +++ b/src/Numerics/Optimization/LineSearch/WolfeLineSearch.cs @@ -87,8 +87,8 @@ namespace MathNet.Numerics.Optimization.LineSearch for (ii = 0; ii < MaximumIterations; ++ii) { objective.EvaluateAt(startingPoint.Point + searchDirection * step); - ValidateGradient(objective); - ValidateValue(objective); + ValidateGradient(objective); + ValidateValue(objective); double stepDd = searchDirection * objective.Gradient; @@ -104,7 +104,7 @@ namespace MathNet.Numerics.Optimization.LineSearch } else { - reasonForExit = WolfeExitCondition; + reasonForExit = WolfeExitCondition; break; } @@ -136,23 +136,21 @@ namespace MathNet.Numerics.Optimization.LineSearch return new LineSearchResult(objective, ii, step, reasonForExit); } + protected abstract MinimizationResult.ExitCondition WolfeExitCondition { get; } protected abstract bool WolfeCondition(double stepDd, double initialDd); - protected virtual void ValidateGradient(IObjectiveFunction objective) + protected virtual void ValidateGradient(IObjectiveFunctionEvaluation objective) { } - protected virtual void ValidateValue(IObjectiveFunction objective) + + protected virtual void ValidateValue(IObjectiveFunctionEvaluation objective) { } protected virtual void ValidateInputArguments(IObjectiveFunctionEvaluation startingPoint, Vector searchDirection, double initialStep, double upperBound) { - } } - - - } diff --git a/src/Numerics/Optimization/NelderMeadSimplex.cs b/src/Numerics/Optimization/NelderMeadSimplex.cs index 908a465d..d83cbfac 100644 --- a/src/Numerics/Optimization/NelderMeadSimplex.cs +++ b/src/Numerics/Optimization/NelderMeadSimplex.cs @@ -32,15 +32,12 @@ using MathNet.Numerics.LinearAlgebra; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace MathNet.Numerics.Optimization { /// - /// Class implementing the Nelder-Mead simplex algorithm, used to find a minima when no gradient is available. - /// Called fminsearch() in Matlab. A description of the algorithm can be found at + /// Class implementing the Nelder-Mead simplex algorithm, used to find a minima when no gradient is available. + /// Called fminsearch() in Matlab. A description of the algorithm can be found at /// http://se.mathworks.com/help/matlab/math/optimizing-nonlinear-functions.html#bsgpq6p-11 /// or /// https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method @@ -68,7 +65,7 @@ namespace MathNet.Numerics.Optimization /// The minimum point public MinimizationResult FindMinimum(IObjectiveFunction objectiveFunction, Vector initialGuess) { - var initalPertubation = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(initialGuess.Count); + var initalPertubation = new LinearAlgebra.Double.DenseVector(initialGuess.Count); for (int i = 0; i < initialGuess.Count; i++) { initalPertubation[i] = initialGuess[i] == 0.0 ? 0.00025 : initialGuess[i] * 0.05; @@ -249,7 +246,7 @@ namespace MathNet.Numerics.Optimization Vector[] vertices = new Vector[numDimensions + 1]; // define one point of the simplex as the given initial guesses - var p0 = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(numDimensions); + var p0 = new LinearAlgebra.Double.DenseVector(numDimensions); for (int i = 0; i < numDimensions; i++) { p0[i] = simplexConstants[i].Value; @@ -261,7 +258,7 @@ namespace MathNet.Numerics.Optimization for (int i = 0; i < numDimensions; i++) { double scale = simplexConstants[i].InitialPerturbation; - Vector unitVector = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(numDimensions); + Vector unitVector = new LinearAlgebra.Double.DenseVector(numDimensions); unitVector[i] = 1; vertices[i + 1] = p0.Add(unitVector.Multiply(scale)); } @@ -335,7 +332,7 @@ namespace MathNet.Numerics.Optimization { int numVertices = vertices.Length; // find the centroid of all points except the worst one - Vector centroid = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(numVertices - 1); + Vector centroid = new LinearAlgebra.Double.DenseVector(numVertices - 1); for (int i = 0; i < numVertices; i++) { if (i != errorProfile.HighestIndex) @@ -409,7 +406,4 @@ namespace MathNet.Numerics.Optimization } } } - - - } diff --git a/src/Numerics/Optimization/NewtonMinimizer.cs b/src/Numerics/Optimization/NewtonMinimizer.cs index ee6fd23c..05347159 100644 --- a/src/Numerics/Optimization/NewtonMinimizer.cs +++ b/src/Numerics/Optimization/NewtonMinimizer.cs @@ -126,7 +126,7 @@ namespace MathNet.Numerics.Optimization return gradient.Norm(2.0) < GradientTolerance; } - static void ValidateGradient(IObjectiveFunction eval) + static void ValidateGradient(IObjectiveFunctionEvaluation eval) { foreach (var x in eval.Gradient) { @@ -137,13 +137,13 @@ namespace MathNet.Numerics.Optimization } } - private void ValidateObjective(IObjectiveFunction eval) + private void ValidateObjective(IObjectiveFunctionEvaluation eval) { if (Double.IsNaN(eval.Value) || Double.IsInfinity(eval.Value)) throw new EvaluationException("Non-finite objective function returned.", eval); } - private void ValidateHessian(IObjectiveFunction eval) + private void ValidateHessian(IObjectiveFunctionEvaluation eval) { for (int ii = 0; ii < eval.Hessian.RowCount; ++ii) { diff --git a/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs index 9cc100fc..acf28cf7 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs @@ -76,23 +76,23 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions if (!ValueEvaluated) EvaluateValue(); - var tmp_point = Point.Clone(); - var tmp_obj = InnerObjectiveFunction.CreateNew(); + var tmpPoint = Point.Clone(); + var tmpObj = InnerObjectiveFunction.CreateNew(); for (int ii = 0; ii < _gradient.Count; ++ii) { - var orig_point = tmp_point[ii]; - var rel_incr = orig_point * RelativeIncrement; - var h = Math.Max(rel_incr, MinimumIncrement); + var origPoint = tmpPoint[ii]; + var relIncr = origPoint * RelativeIncrement; + var h = Math.Max(relIncr, MinimumIncrement); var mult = 1; - if (orig_point + h > UpperBound[ii]) + if (origPoint + h > UpperBound[ii]) mult = -1; - tmp_point[ii] = orig_point + mult*h; - tmp_obj.EvaluateAt(tmp_point); - double bumped_value = tmp_obj.Value; - _gradient[ii] = (mult * bumped_value - mult * InnerObjectiveFunction.Value) / h; + tmpPoint[ii] = origPoint + mult*h; + tmpObj.EvaluateAt(tmpPoint); + double bumpedValue = tmpObj.Value; + _gradient[ii] = (mult * bumpedValue - mult * InnerObjectiveFunction.Value) / h; - tmp_point[ii] = orig_point; + tmpPoint[ii] = origPoint; } GradientEvaluated = true; } diff --git a/src/Numerics/Optimization/ObjectiveFunctions/GradientHessianObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/GradientHessianObjectiveFunction.cs index fb13d489..30e53358 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/GradientHessianObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/GradientHessianObjectiveFunction.cs @@ -84,4 +84,4 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions public Vector Gradient { get; private set; } public Matrix Hessian { get; private set; } } -} \ No newline at end of file +} diff --git a/src/Numerics/Optimization/ObjectiveFunctions/GradientObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/GradientObjectiveFunction.cs index 1cfaab87..084bedef 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/GradientObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/GradientObjectiveFunction.cs @@ -86,4 +86,4 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions get { throw new NotSupportedException(); } } } -} \ No newline at end of file +} diff --git a/src/Numerics/Optimization/ObjectiveFunctions/HessianObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/HessianObjectiveFunction.cs index 66f0143c..2548bf56 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/HessianObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/HessianObjectiveFunction.cs @@ -86,4 +86,4 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions get { throw new NotSupportedException(); } } } -} \ No newline at end of file +} diff --git a/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs index 41b9ee88..257b28c2 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs @@ -139,4 +139,4 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions } } } -} \ No newline at end of file +} diff --git a/src/Numerics/Optimization/ObjectiveFunctions/ValueObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/ValueObjectiveFunction.cs index 80314db9..568c0c77 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/ValueObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/ValueObjectiveFunction.cs @@ -86,4 +86,4 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions get { throw new NotSupportedException(); } } } -} \ No newline at end of file +}