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 CheckedEvaluation1D(ObjectiveChecker1D checker, IEvaluation1D evaluation) { this.Checker = checker; this.InnerEvaluation = evaluation; }