public virtual ContinuousSolution Minimize(CostFunction f, int max_iterations) { return(Minimize((x, lower_bounds, upper_bounds, constraints) => { return f.Evaluate(x); }, (x, gradX, lower_bounds, upper_bounds, constraints) => { f.CalcGradient(x, gradX); }, (improvement, iterations) => { return iterations > max_iterations; })); }
public void Minimize(double x_0, CostFunction f, int max_iterations) { double x = x_0; double fx = f.Evaluate(x); double newtonX = 0; double denominator = 0; ContinuousSolution best_solution = new ContinuousSolution(new double[] { x }, fx); double?improvement = null; for (int k = 0; k < max_iterations; ++k) { f.CalcGradient(x, out denominator); if (Math.Abs(denominator) < ZERO) { break; } newtonX = x - fx / denominator; if (Math.Abs(newtonX - x) < SIGMA) { break; } x = newtonX; fx = f.Evaluate(x); if (best_solution.TryUpdateSolution(new double[] { x }, fx, out improvement)) { OnSolutionUpdated(best_solution, k); } OnStepped(new ContinuousSolution(new double[] { x }, fx), k); } }
public static bool LineSearch(double[] x_0, double fx_0, double[] direction, out double[] x_out, out double fx_out, out double alpha, CostFunction f) { int dimension = x_0.Length; double[] Vfx = new double[dimension]; x_out = new double[dimension]; alpha = 1.0; fx_out = double.MaxValue; f.CalcGradient(x_0, Vfx); double direction_length = 0; for (int d = 0; d < dimension; ++d) { direction_length += direction[d] * direction[d]; } direction_length = Math.Sqrt(direction_length); if (direction_length > 0) { for (int d = 0; d < dimension; ++d) { direction[d] /= direction_length; } } double p = 0.0; for (int d = 0; d < dimension; ++d) { p += (direction[d] * Vfx[d]); } //Console.WriteLine("p: {0}", p); if (double.IsNaN(p)) { return(false); } if (p >= 0.0) // not in the descending direction return false; { return(false); } for (int k = 0; ; ++k) { for (int d = 0; d < dimension; ++d) { x_out[d] = x_0[d] + alpha * direction[d]; } fx_out = f.Evaluate(x_out); if (fx_out < fx_0 + SIGMA * alpha * p) { return(true); } else { if (k == 0) { double enumerator = (p + fx_0 - fx_out); if (enumerator == 0) { alpha = 0.5 * p / enumerator; } else { alpha = 0.5 * p; } //Console.WriteLine("alpha: {0}", alpha); } else { alpha *= BETA; } } //Console.WriteLine("alpha: {0}", alpha); if (alpha < ZERO) { if (fx_out > fx_0) { for (int d = 0; d < dimension; ++d) { x_out[d] = x_0[d]; } fx_out = fx_0; return(true); } else { return(true); } } } }