diff --git a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs index 9f403286..793113a2 100644 --- a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs @@ -1720,7 +1720,8 @@ namespace MathNet.Numerics.LinearAlgebra /// matrix and a given other matrix being the 'x' of atan2 and the /// 'this' matrix being the 'y' /// - /// + /// The other matrix 'y' + /// The matrix with the result and 'x' /// public void PointwiseAtan2(Matrix other, Matrix result) { diff --git a/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs index cbb9bc03..edc9cb7e 100644 --- a/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs @@ -1028,6 +1028,7 @@ namespace MathNet.Numerics.LinearAlgebra /// /// Function which takes a scalar and a vector, modifies the vector in place and returns void /// The scalar to be passed to the function + /// The vector where the result will be placed /// If this vector and are not the same size. protected void PointwiseBinary(Action> f, T x, Vector result) { diff --git a/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs b/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs index 870aaf4e..f3a3baf4 100644 --- a/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs +++ b/src/Numerics/Optimization/LineSearch/WeakWolfeLineSearch.cs @@ -1,4 +1,4 @@ -// +// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics @@ -36,12 +36,12 @@ namespace MathNet.Numerics.Optimization.LineSearch /// /// Search for a step size alpha that satisfies the weak wolfe conditions. The weak Wolfe /// Conditions are - /// i) Armijo Rule: f(x_k + alpha_k p_k) <= f(x_k) + c1 alpha_k p_k^T g(x_k) - /// ii) Curvature Condition: p_k^T g(x_k + alpha_k p_k) >= c2 p_k^T g(x_k) - /// where g(x) is the gradient of f(x), 0 < c1 < c2 < 1. - /// + /// i) Armijo Rule: f(x_k + alpha_k p_k) <= f(x_k) + c1 alpha_k p_k^T g(x_k) + /// ii) Curvature Condition: p_k^T g(x_k + alpha_k p_k) >= c2 p_k^T g(x_k) + /// where g(x) is the gradient of f(x), 0 < c1 < c2 < 1. + /// /// Implementation is based on http://www.math.washington.edu/~burke/crs/408/lectures/L9-weak-Wolfe.pdf - /// + /// /// references: /// http://en.wikipedia.org/wiki/Wolfe_conditions /// http://www.math.washington.edu/~burke/crs/408/lectures/L9-weak-Wolfe.pdf @@ -54,7 +54,10 @@ namespace MathNet.Numerics.Optimization.LineSearch // Validation in base class } - protected override MinimizationResult.ExitCondition WolfeExitCondition { get { return MinimizationResult.ExitCondition.WeakWolfeCriteria; } } + protected override MinimizationResult.ExitCondition WolfeExitCondition + { + get { return MinimizationResult.ExitCondition.WeakWolfeCriteria; } + } protected override bool WolfeCondition(double stepDd, double initialDd) { diff --git a/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs index 1a3733bf..21b3d029 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs @@ -19,66 +19,66 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions public class ForwardDifferenceGradientObjectiveFunction : IObjectiveFunction { public IObjectiveFunction InnerObjectiveFunction { get; protected set; } - protected Vector _lower_bound; - protected Vector _upper_bound; + protected Vector LowerBound { get; set; } + protected Vector UpperBound { get; set; } - protected Vector _point; - protected bool _value_evaluated = false; - protected bool _gradient_evaluated = false; - protected Vector _gradient; + protected bool ValueEvaluated { get; set; } = false; + protected bool GradientEvaluated { get; set; } = false; + private Vector _gradient; + + public double MinimumIncrement { get; set; } + public double RelativeIncrement { get; set; } - public double MinimumIncrement; - public double RelativeIncrement; - public ForwardDifferenceGradientObjectiveFunction(IObjectiveFunction valueOnlyObj, Vector lowerBound, Vector upperBound, double relativeIncrement=1e-5, double minimumIncrement=1e-8) { - this.InnerObjectiveFunction = valueOnlyObj; - _lower_bound = lowerBound; - _upper_bound = upperBound; - _gradient = new LinearAlgebra.Double.DenseVector(_lower_bound.Count); - this.RelativeIncrement = relativeIncrement; - this.MinimumIncrement = minimumIncrement; + InnerObjectiveFunction = valueOnlyObj; + LowerBound = lowerBound; + UpperBound = upperBound; + _gradient = new LinearAlgebra.Double.DenseVector(LowerBound.Count); + RelativeIncrement = relativeIncrement; + MinimumIncrement = minimumIncrement; } protected void EvaluateValue() { - _value_evaluated = true; + ValueEvaluated = true; } protected void EvaluateGradient() { - if (!_value_evaluated) - this.EvaluateValue(); + if (!ValueEvaluated) + EvaluateValue(); - var tmp_point = _point.Clone(); - var tmp_obj = this.InnerObjectiveFunction.CreateNew(); + var tmp_point = Point.Clone(); + var tmp_obj = InnerObjectiveFunction.CreateNew(); for (int ii = 0; ii < _gradient.Count; ++ii) { var orig_point = tmp_point[ii]; - var rel_incr = orig_point * this.RelativeIncrement; - var h = Math.Max(rel_incr, this.MinimumIncrement); + var rel_incr = orig_point * RelativeIncrement; + var h = Math.Max(rel_incr, MinimumIncrement); var mult = 1; - if (orig_point + h > _upper_bound[ii]) + if (orig_point + 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 * this.InnerObjectiveFunction.Value) / h; + _gradient[ii] = (mult * bumped_value - mult * InnerObjectiveFunction.Value) / h; tmp_point[ii] = orig_point; } - _gradient_evaluated = true; + GradientEvaluated = true; } public Vector Gradient { get { - if (!_gradient_evaluated) - this.EvaluateGradient(); + if (!GradientEvaluated) + EvaluateGradient(); return _gradient; } + protected set { _gradient = value; } } public Matrix Hessian @@ -105,47 +105,41 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions } } - public Vector Point - { - get - { - return _point; - } - } + public Vector Point { get; protected set; } public double Value { get { - if (!_value_evaluated) - this.EvaluateValue(); + if (!ValueEvaluated) + EvaluateValue(); return this.InnerObjectiveFunction.Value; } } public IObjectiveFunction CreateNew() { - var tmp = new ForwardDifferenceGradientObjectiveFunction(this.InnerObjectiveFunction.CreateNew(), _lower_bound, _upper_bound, this.RelativeIncrement, this.MinimumIncrement); + var tmp = new ForwardDifferenceGradientObjectiveFunction(this.InnerObjectiveFunction.CreateNew(), LowerBound, UpperBound, this.RelativeIncrement, this.MinimumIncrement); return tmp; } public void EvaluateAt(Vector point) { - _point = point; - _value_evaluated = false; - _gradient_evaluated = false; - this.InnerObjectiveFunction.EvaluateAt(point); + Point = point; + ValueEvaluated = false; + GradientEvaluated = false; + InnerObjectiveFunction.EvaluateAt(point); } public IObjectiveFunction Fork() { - var tmp = new ForwardDifferenceGradientObjectiveFunction(this.InnerObjectiveFunction.Fork(), _lower_bound, _upper_bound, this.RelativeIncrement, this.MinimumIncrement); - tmp._point = _point?.Clone(); - tmp._gradient_evaluated = _gradient_evaluated; - tmp._value_evaluated = _value_evaluated; - tmp._gradient = _gradient?.Clone(); - - return tmp; + return new ForwardDifferenceGradientObjectiveFunction(this.InnerObjectiveFunction.Fork(), LowerBound, UpperBound, this.RelativeIncrement, this.MinimumIncrement) + { + Point = Point?.Clone(), + GradientEvaluated = GradientEvaluated, + ValueEvaluated = ValueEvaluated, + _gradient = _gradient?.Clone() + }; } } } diff --git a/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs b/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs index 8b629cfd..2639e3a9 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs @@ -1,4 +1,34 @@ -using System; +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2016 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 +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// 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 +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; using MathNet.Numerics.LinearAlgebra; namespace MathNet.Numerics.Optimization.ObjectiveFunctions diff --git a/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunctionBase.cs b/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunctionBase.cs index 5ec0aa0c..d2ea4ad6 100644 --- a/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunctionBase.cs +++ b/src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunctionBase.cs @@ -1,4 +1,34 @@ -using MathNet.Numerics.LinearAlgebra; +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2016 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 +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// 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 +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using MathNet.Numerics.LinearAlgebra; namespace MathNet.Numerics.Optimization.ObjectiveFunctions { @@ -6,14 +36,14 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions { Vector _point; - protected bool _hasFunctionValue; - protected double _functionValue; + protected bool HasFunctionValue { get; set; } + protected double FunctionValue { get; set; } - protected bool _hasGradientValue; - protected Vector _gradientValue; + protected bool HasGradientValue { get; set; } + protected Vector GradientValue { get; set; } - protected bool _hasHessianValue; - protected Matrix _hessianValue; + protected bool HasHessianValue { get; set; } + protected Matrix HessianValue { get; set; } protected LazyObjectiveFunctionBase(bool gradientSupported, bool hessianSupported) { @@ -27,13 +57,13 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions { // we need to deep-clone values since they may be updated inplace on evaluation LazyObjectiveFunctionBase fork = (LazyObjectiveFunctionBase)CreateNew(); - fork._point = _point == null ? null : _point.Clone(); - fork._hasFunctionValue = _hasFunctionValue; - fork._functionValue = _functionValue; - fork._hasGradientValue = _hasGradientValue; - fork._gradientValue = _gradientValue == null ? null : _gradientValue.Clone(); ; - fork._hasHessianValue = _hasHessianValue; - fork._hessianValue = _hessianValue == null ? null : _hessianValue.Clone(); + fork._point = _point?.Clone(); + fork.HasFunctionValue = HasFunctionValue; + fork.FunctionValue = FunctionValue; + fork.HasGradientValue = HasGradientValue; + fork.GradientValue = GradientValue?.Clone(); + fork.HasHessianValue = HasHessianValue; + fork.HessianValue = HessianValue?.Clone(); return fork; } @@ -43,9 +73,9 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions public void EvaluateAt(Vector point) { _point = point; - _hasFunctionValue = false; - _hasGradientValue = false; - _hasHessianValue = false; + HasFunctionValue = false; + HasGradientValue = false; + HasHessianValue = false; } protected abstract void EvaluateValue(); @@ -69,16 +99,16 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions { get { - if (!_hasFunctionValue) + if (!HasFunctionValue) { EvaluateValue(); } - return _functionValue; + return FunctionValue; } protected set { - _functionValue = value; - _hasFunctionValue = true; + FunctionValue = value; + HasFunctionValue = true; } } @@ -86,16 +116,16 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions { get { - if (!_hasGradientValue) + if (!HasGradientValue) { EvaluateGradient(); } - return _gradientValue; + return GradientValue; } protected set { - _gradientValue = value; - _hasGradientValue = true; + GradientValue = value; + HasGradientValue = true; } } @@ -103,16 +133,16 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions { get { - if (!_hasHessianValue) + if (!HasHessianValue) { EvaluateHessian(); } - return _hessianValue; + return HessianValue; } protected set { - _hessianValue = value; - _hasHessianValue = true; + HessianValue = value; + HasHessianValue = true; } } } diff --git a/src/UnitTests/OptimizationTests/TestFunctionAdapters.cs b/src/UnitTests/OptimizationTests/TestFunctionAdapters.cs index 8f20f954..8b5a43ae 100644 --- a/src/UnitTests/OptimizationTests/TestFunctionAdapters.cs +++ b/src/UnitTests/OptimizationTests/TestFunctionAdapters.cs @@ -35,9 +35,9 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests { if (this.IsGradientSupported) { - if (this._gradientValue == null) + if (this.GradientValue == null) this.Gradient = new DenseVector(this.TestFunction.ParameterDimension); - this.TestFunction.SsqGradientByRef(this.Point, _gradientValue); + this.TestFunction.SsqGradientByRef(this.Point, GradientValue); } } @@ -45,9 +45,9 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests { if (this.IsHessianSupported) { - if (this._hessianValue == null) + if (this.HessianValue == null) this.Hessian = new DenseMatrix(this.TestFunction.ParameterDimension, this.TestFunction.ParameterDimension); - this.TestFunction.SsqHessianByRef(this.Point, _hessianValue); + this.TestFunction.SsqHessianByRef(this.Point, HessianValue); } } }