/// <summary> /// Finds the minimum value of a function. The solution vector /// will be made available at the <see cref="IOptimizationMethod.Solution"/> property. /// </summary> /// /// <returns>Returns <c>true</c> if the method converged to a <see cref="IOptimizationMethod.Solution"/>. /// In this case, the found value will also be available at the <see cref="IOptimizationMethod.Value"/> /// property.</returns> /// public override bool Minimize() { if (Gradient == null) { throw new InvalidOperationException("gradient"); } NonlinearObjectiveFunction.CheckGradient(Gradient, Solution); return(base.Minimize()); }
/// <summary> /// Finds the maximum value of a function. The solution vector /// will be made available at the <see cref="IOptimizationMethod.Solution"/> property. /// </summary> /// /// <returns>Returns <c>true</c> if the method converged to a <see cref="IOptimizationMethod.Solution"/>. /// In this case, the found value will also be available at the <see cref="IOptimizationMethod.Value"/> /// property.</returns> /// public override bool Maximize() { if (Gradient == null) { throw new InvalidOperationException("gradient"); } NonlinearObjectiveFunction.CheckGradient(Gradient, Solution); var g = Gradient; Gradient = (x) => g(x).Multiply(-1); bool success = base.Maximize(); Gradient = g; return(success); }
/// <summary> /// Implements the actual optimization algorithm. This /// method should try to minimize the objective function. /// </summary> protected override bool Optimize() { if (Function == null) { throw new InvalidOperationException("function"); } if (Gradient == null) { throw new InvalidOperationException("gradient"); } NonlinearObjectiveFunction.CheckGradient(Gradient, Solution); int n = NumberOfVariables; int m = corrections; String task = ""; String csave = ""; bool[] lsave = new bool[4]; int iprint = 101; int[] nbd = new int[n]; int[] iwa = new int[3 * n]; int[] isave = new int[44]; double f = 0.0d; double[] x = new double[n]; double[] l = new double[n]; double[] u = new double[n]; double[] g = new double[n]; double[] dsave = new double[29]; int totalSize = 2 * m * n + 11 * m * m + 5 * n + 8 * m; if (work == null || work.Length < totalSize) { work = new double[totalSize]; } int i = 0; { for (i = 0; i < UpperBounds.Length; i++) { bool hasUpper = !Double.IsInfinity(UpperBounds[i]); bool hasLower = !Double.IsInfinity(LowerBounds[i]); if (hasUpper && hasLower) { nbd[i] = 2; } else if (hasUpper) { nbd[i] = 3; } else if (hasLower) { nbd[i] = 1; } else { nbd[i] = 0; // unbounded } if (hasLower) { l[i] = LowerBounds[i]; } if (hasUpper) { u[i] = UpperBounds[i]; } } } // We now define the starting point. { for (i = 0; i < n; i++) { x[i] = Solution[i]; } } double newF = 0; double[] newG = null; // We start the iteration by initializing task. task = "START"; iterations = 0; // // c ------- the beginning of the loop ---------- // L111: iterations++; // // c This is the call to the L-BFGS-B code. // setulb(n, m, x, 0, l, 0, u, 0, nbd, 0, ref f, g, 0, factr, pgtol, work, 0, iwa, 0, ref task, iprint, ref csave, lsave, 0, isave, 0, dsave, 0); // if ((task.StartsWith("FG", StringComparison.OrdinalIgnoreCase))) { newF = Function(x); newG = Gradient(x); evaluations++; f = newF; for (int j = 0; j < newG.Length; j++) { g[j] = newG[j]; } } // c else if ((task.StartsWith("NEW_X", StringComparison.OrdinalIgnoreCase))) { } else { if (task == "ABNORMAL_TERMINATION_IN_LNSRCH") { Status = BoundedBroydenFletcherGoldfarbShannoStatus.LineSearchFailed; } else if (task == "CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH") { Status = BoundedBroydenFletcherGoldfarbShannoStatus.FunctionConvergence; } else if (task == "CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL") { Status = BoundedBroydenFletcherGoldfarbShannoStatus.GradientConvergence; } else { throw OperationException(task, task); } for (int j = 0; j < Solution.Length; j++) { Solution[j] = x[j]; } newF = Function(x); newG = Gradient(x); evaluations++; if (Progress != null) { Progress(this, new OptimizationProgressEventArgs(iterations, 0, newG, 0, null, 0, newF, 0, true) { Tag = new BoundedBroydenFletcherGoldfarbShannoInnerStatus( isave, dsave, lsave, csave, work) }); } return(true); } if (Progress != null) { Progress(this, new OptimizationProgressEventArgs(iterations, 0, newG, 0, null, 0, f, 0, false) { Tag = new BoundedBroydenFletcherGoldfarbShannoInnerStatus( isave, dsave, lsave, csave, work) }); } goto L111; }