protected override void ValidateInputArguments(IObjectiveFunctionEvaluation startingPoint, Vector <double> searchDirection, double initialStep, double upperBound) { if (!startingPoint.IsGradientSupported) { throw new ArgumentException("objective function does not support gradient"); } }
static void ValidateObjective(IObjectiveFunctionEvaluation objective) { if (Double.IsNaN(objective.Value) || Double.IsInfinity(objective.Value)) { throw new EvaluationException("Non-finite objective function returned.", objective); } }
protected override void ValidateValue(IObjectiveFunctionEvaluation eval) { if (!IsFinite(eval.Value)) { throw new EvaluationException(String.Format("Non-finite value returned by objective function: {0}", eval.Value), eval); } }
private void ValidateObjective(IObjectiveFunctionEvaluation eval) { if (Double.IsNaN(eval.Value) || Double.IsInfinity(eval.Value)) { throw new EvaluationException("Non-finite objective function returned.", eval); } }
protected override void ValidateValue(IObjectiveFunctionEvaluation eval) { if (!IsFinite(eval.Value)) { throw new EvaluationException(FormattableString.Invariant($"Non-finite value returned by objective function: {eval.Value}"), eval); } }
protected override void ValidateGradient(IObjectiveFunctionEvaluation eval) { foreach (double x in eval.Gradient) { if (!IsFinite(x)) { throw new EvaluationException(string.Format("Non-finite value returned by gradient: {0}", x), eval); } } }
protected override void ValidateGradient(IObjectiveFunctionEvaluation eval) { foreach (double x in eval.Gradient) { if (!IsFinite(x)) { throw new EvaluationException(FormattableString.Invariant($"Non-finite value returned by gradient: {x}"), eval); } } }
static void ValidateGradient(IObjectiveFunctionEvaluation eval) { foreach (var x in eval.Gradient) { if (Double.IsNaN(x) || Double.IsInfinity(x)) { throw new EvaluationException("Non-finite gradient returned.", eval); } } }
private void ValidateHessian(IObjectiveFunctionEvaluation eval) { for (int ii = 0; ii < eval.Hessian.RowCount; ++ii) { for (int jj = 0; jj < eval.Hessian.ColumnCount; ++jj) { if (Double.IsNaN(eval.Hessian[ii, jj]) || Double.IsInfinity(eval.Hessian[ii, jj])) { throw new EvaluationException("Non-finite Hessian returned.", eval); } } } }
protected void ValidateGradientAndObjective(IObjectiveFunctionEvaluation eval) { foreach (var x in eval.Gradient) { if (Double.IsNaN(x) || Double.IsInfinity(x)) { throw new EvaluationException("Non-finite gradient returned.", eval); } } if (Double.IsNaN(eval.Value) || Double.IsInfinity(eval.Value)) { throw new EvaluationException("Non-finite objective function returned.", eval); } }
static void ValidateHessian(IObjectiveFunctionEvaluation eval) { var hessian = eval.Hessian; for (int ii = 0; ii < hessian.RowCount; ++ii) { for (int jj = 0; jj < hessian.ColumnCount; ++jj) { if (double.IsNaN(hessian[ii, jj]) || double.IsInfinity(hessian[ii, jj])) { throw new EvaluationException("Non-finite Hessian returned.", eval); } } } }
protected ExitCondition ExitCriteriaSatisfied(IObjectiveFunctionEvaluation candidatePoint, IObjectiveFunctionEvaluation lastPoint, int iterations) { var candidatePointPoint = candidatePoint.Point; double relativeGradient = 0.0; double normalizer = Math.Max(Math.Abs(candidatePoint.Value), 1.0); for (int ii = 0; ii < candidatePointPoint.Count; ++ii) { double projectedGradient = GetProjectedGradient(candidatePoint, ii); double tmp = projectedGradient * Math.Max(Math.Abs(candidatePointPoint[ii]), 1.0) / normalizer; relativeGradient = Math.Max(relativeGradient, Math.Abs(tmp)); } if (relativeGradient < GradientTolerance) { return(ExitCondition.RelativeGradient); } if (lastPoint != null) { var lastPointPoint = lastPoint.Point; double mostProgress = 0.0; for (int ii = 0; ii < candidatePointPoint.Count; ++ii) { var tmp = Math.Abs(candidatePointPoint[ii] - lastPointPoint[ii]) / Math.Max(Math.Abs(lastPointPoint[ii]), 1.0); mostProgress = Math.Max(mostProgress, tmp); } if (mostProgress < ParameterTolerance) { return(ExitCondition.LackOfProgress); } double functionChange = candidatePoint.Value - lastPoint.Value; if (iterations > 500 && functionChange < 0 && Math.Abs(functionChange) < FunctionProgressTolerance) { return(ExitCondition.LackOfProgress); } } return(ExitCondition.None); }
protected override double GetProjectedGradient(IObjectiveFunctionEvaluation candidatePoint, int ii) { double projectedGradient; bool atLowerBound = candidatePoint.Point[ii] - _lowerBound[ii] < VerySmall; bool atUpperBound = _upperBound[ii] - candidatePoint.Point[ii] < VerySmall; if (atLowerBound && atUpperBound) { projectedGradient = 0.0; } else if (atLowerBound) { projectedGradient = Math.Min(candidatePoint.Gradient[ii], 0.0); } else if (atUpperBound) { projectedGradient = Math.Max(candidatePoint.Gradient[ii], 0.0); } else { projectedGradient = base.GetProjectedGradient(candidatePoint, ii); } return(projectedGradient); }
public EvaluationException(string message, IObjectiveFunctionEvaluation eval) : base(message) { ObjectiveFunction = eval; }
/// <summary></summary> /// <param name="startingPoint">The objective function being optimized, evaluated at the starting point of the search</param> /// <param name="searchDirection">Search direction</param> /// <param name="initialStep">Initial size of the step in the search direction</param> /// <param name="upperBound">The upper bound</param> public LineSearchResult FindConformingStep(IObjectiveFunctionEvaluation startingPoint, Vector <double> searchDirection, double initialStep, double upperBound) { ValidateInputArguments(startingPoint, searchDirection, initialStep, upperBound); double lowerBound = 0.0; double step = initialStep; double initialValue = startingPoint.Value; Vector <double> initialGradient = startingPoint.Gradient; double initialDd = searchDirection * initialGradient; IObjectiveFunction objective = startingPoint.CreateNew(); int ii; ExitCondition reasonForExit = ExitCondition.None; for (ii = 0; ii < MaximumIterations; ++ii) { objective.EvaluateAt(startingPoint.Point + searchDirection * step); ValidateGradient(objective); ValidateValue(objective); double stepDd = searchDirection * objective.Gradient; if (objective.Value > initialValue + C1 * step * initialDd) { upperBound = step; step = 0.5 * (lowerBound + upperBound); } else if (WolfeCondition(stepDd, initialDd)) { lowerBound = step; step = double.IsPositiveInfinity(upperBound) ? 2 * lowerBound : 0.5 * (lowerBound + upperBound); } else { reasonForExit = WolfeExitCondition; break; } if (!double.IsInfinity(upperBound)) { double maxRelChange = 0.0; for (int jj = 0; jj < objective.Point.Count; ++jj) { double tmp = Math.Abs(searchDirection[jj] * (upperBound - lowerBound)) / Math.Max(Math.Abs(objective.Point[jj]), 1.0); maxRelChange = Math.Max(maxRelChange, tmp); } if (maxRelChange < ParameterTolerance) { reasonForExit = ExitCondition.LackOfProgress; break; } } } if (ii == MaximumIterations && Double.IsPositiveInfinity(upperBound)) { throw new MaximumIterationsException(String.Format("Maximum iterations ({0}) reached. Function appears to be unbounded in search direction.", MaximumIterations)); } if (ii == MaximumIterations) { throw new MaximumIterationsException(String.Format("Maximum iterations ({0}) reached.", MaximumIterations)); } return(new LineSearchResult(objective, ii, step, reasonForExit)); }
/// <summary>Implemented following http://www.math.washington.edu/~burke/crs/408/lectures/L9-weak-Wolfe.pdf</summary> /// <param name="startingPoint">The objective function being optimized, evaluated at the starting point of the search</param> /// <param name="searchDirection">Search direction</param> /// <param name="initialStep">Initial size of the step in the search direction</param> public LineSearchResult FindConformingStep(IObjectiveFunctionEvaluation startingPoint, Vector <double> searchDirection, double initialStep) { return(FindConformingStep(startingPoint, searchDirection, initialStep, double.PositiveInfinity)); }
protected virtual void ValidateInputArguments(IObjectiveFunctionEvaluation startingPoint, Vector <double> searchDirection, double initialStep, double upperBound) { }
protected virtual void ValidateValue(IObjectiveFunctionEvaluation objective) { }
protected virtual void ValidateGradient(IObjectiveFunctionEvaluation objective) { }
public EvaluationException(string message, IObjectiveFunctionEvaluation eval, Exception innerException) : base(message, innerException) { ObjectiveFunction = eval; }
protected virtual double GetProjectedGradient(IObjectiveFunctionEvaluation candidatePoint, int ii) { return(candidatePoint.Gradient[ii]); }