public ObjectiveChecker1D(IObjectiveFunction1D objective, Action <IEvaluation1D> value_checker, Action <IEvaluation1D> gradient_checker, Action <IEvaluation1D> hessian_checker) { this.InnerObjective = objective; this.ValueChecker = value_checker; this.DerivativeChecker = gradient_checker; this.SecondDerivativeChecker = hessian_checker; }
public MinimizationOutput1D FindMinimum(IObjectiveFunction1D objective, double lower_bound, double upper_bound) { if (!(objective is ObjectiveChecker1D)) { objective = new ObjectiveChecker1D(objective, this.ValueChecker, null, null); } if (upper_bound <= lower_bound) { throw new OptimizationException("Lower bound must be lower than upper bound."); } double middle_point_x = lower_bound + (upper_bound - lower_bound) / (1 + _golden_ratio); IEvaluation1D lower = objective.Evaluate(lower_bound); IEvaluation1D middle = objective.Evaluate(middle_point_x); IEvaluation1D upper = objective.Evaluate(upper_bound); int expansion_steps = 0; while ((expansion_steps < this.MaximumExpansionSteps) && (upper.Value < middle.Value || lower.Value < middle.Value)) { if (lower.Value < middle.Value) { lower_bound = 0.5 * (upper_bound + lower_bound) - this.LowerExpansionFactor * 0.5 * (upper_bound - lower_bound); lower = objective.Evaluate(lower_bound); } if (upper.Value < middle.Value) { upper_bound = 0.5 * (upper_bound + lower_bound) + this.UpperExpansionFactor * 0.5 * (upper_bound - lower_bound); upper = objective.Evaluate(upper_bound); } middle_point_x = lower_bound + (upper_bound - lower_bound) / (1 + _golden_ratio); middle = objective.Evaluate(middle_point_x); expansion_steps += 1; } if (upper.Value < middle.Value || lower.Value < middle.Value) { throw new OptimizationException("Lower and upper bounds do not necessarily bound a minimum."); } int iterations = 0; while (Math.Abs(upper.Point - lower.Point) > this.XTolerance && iterations < this.MaximumIterations) { double test_x = lower.Point + (upper.Point - middle.Point); var test = objective.Evaluate(test_x); if (test.Point < middle.Point) { if (test.Value > middle.Value) { lower = test; } else { upper = middle; middle = test; } } else { if (test.Value > middle.Value) { upper = test; } else { lower = middle; middle = test; } } iterations += 1; } if (iterations == this.MaximumIterations) { throw new MaximumIterationsException("Max iterations reached."); } else { return(new MinimizationOutput1D(middle, iterations, ExitCondition.BoundTolerance)); } }
public MinimizationResult1D FindMinimum(IObjectiveFunction1D objective, double lowerBound, double upperBound) { if (upperBound <= lowerBound) { throw new OptimizationException("Lower bound must be lower than upper bound."); } double middlePointX = lowerBound + (upperBound - lowerBound) / (1 + Constants.GoldenRatio); IEvaluation1D lower = objective.Evaluate(lowerBound); IEvaluation1D middle = objective.Evaluate(middlePointX); IEvaluation1D upper = objective.Evaluate(upperBound); ValueChecker(lower.Value, lowerBound); ValueChecker(middle.Value, middlePointX); ValueChecker(upper.Value, upperBound); int expansion_steps = 0; while ((expansion_steps < this.MaximumExpansionSteps) && (upper.Value < middle.Value || lower.Value < middle.Value)) { if (lower.Value < middle.Value) { lowerBound = 0.5 * (upperBound + lowerBound) - this.LowerExpansionFactor * 0.5 * (upperBound - lowerBound); lower = objective.Evaluate(lowerBound); } if (upper.Value < middle.Value) { upperBound = 0.5 * (upperBound + lowerBound) + this.UpperExpansionFactor * 0.5 * (upperBound - lowerBound); upper = objective.Evaluate(upperBound); } middlePointX = lowerBound + (upperBound - lowerBound) / (1 + Constants.GoldenRatio); middle = objective.Evaluate(middlePointX); expansion_steps += 1; } if (upper.Value < middle.Value || lower.Value < middle.Value) { throw new OptimizationException("Lower and upper bounds do not necessarily bound a minimum."); } int iterations = 0; while (Math.Abs(upper.Point - lower.Point) > XTolerance && iterations < MaximumIterations) { double testX = lower.Point + (upper.Point - middle.Point); var test = objective.Evaluate(testX); ValueChecker(test.Value, testX); if (test.Point < middle.Point) { if (test.Value > middle.Value) { lower = test; } else { upper = middle; middle = test; } } else { if (test.Value > middle.Value) { upper = test; } else { lower = middle; middle = test; } } iterations += 1; } if (iterations == MaximumIterations) { throw new MaximumIterationsException("Max iterations reached."); } return(new MinimizationResult1D(middle, iterations, ExitCondition.BoundTolerance)); }