public void ItemGradientAtStart(TestFunctions.TestCase test_case) { for (var item_index = 0; item_index < test_case.Function.ItemDimension; ++item_index) { var a_grad = test_case.Function.ItemGradient(test_case.InitialGuess, item_index); var h = 1e-4; var fd_grad = Vector <double> .Build.Dense(test_case.Function.ParameterDimension, 0.0); for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { var bump_up = test_case.InitialGuess.Clone(); bump_up[ii] += h; var bump_down = test_case.InitialGuess.Clone(); bump_down[ii] -= h; var up_val = test_case.Function.ItemValue(bump_up, item_index); var down_val = test_case.Function.ItemValue(bump_down, item_index); fd_grad[ii] = 0.5 * (up_val - down_val) / h; } for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { Assert.That(Math.Abs(fd_grad[ii] - a_grad[ii]) < 1e-3, $"Failed for parameter {ii}"); } } }
public void GradientAtStart(TestFunctions.TestCase test_case) { var a_grad = test_case.Function.SsqGradient(test_case.InitialGuess); var fd_grad = Vector <double> .Build.Dense(test_case.Function.ParameterDimension, 0.0); for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { var h = 1e-6; var bump_up = test_case.InitialGuess.Clone(); bump_up[ii] += h; var bump_down = test_case.InitialGuess.Clone(); bump_down[ii] -= h; var up_val = test_case.Function.SsqValue(bump_up); var down_val = test_case.Function.SsqValue(bump_down); fd_grad[ii] = 0.5 * (up_val - down_val) / h; } for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { var val1 = a_grad[ii]; var val2 = fd_grad[ii]; var min_abs_val = Math.Min(Math.Abs(val1), Math.Abs(val2)); if (min_abs_val <= 1) { Assert.That(Math.Abs(val1 - val2) < 1e-3, $"Problem with gradient value at start point."); } else { Assert.That(Math.Abs(val1 - val2) / min_abs_val < 1e-3, $"Problem with gradient value at start point."); } } }
public void ItemHessianAtStart(TestFunctions.TestCase test_case) { for (var item_index = 0; item_index < test_case.Function.ItemDimension; ++item_index) { var a_hess = test_case.Function.ItemHessian(test_case.InitialGuess, item_index); var h = 1e-4; var fd_hess = Matrix <double> .Build.Dense(test_case.Function.ParameterDimension, test_case.Function.ParameterDimension); for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj) { var bump_uu = test_case.InitialGuess.Clone(); bump_uu[ii] += h; bump_uu[jj] += h; var bump_dd = test_case.InitialGuess.Clone(); bump_dd[ii] -= h; bump_dd[jj] -= h; var bump_ud = test_case.InitialGuess.Clone(); bump_ud[ii] += h; bump_ud[jj] -= h; var bump_du = test_case.InitialGuess.Clone(); bump_du[ii] -= h; bump_du[jj] += h; var val_uu = test_case.Function.ItemValue(bump_uu, item_index); var val_dd = test_case.Function.ItemValue(bump_dd, item_index); var val_ud = test_case.Function.ItemValue(bump_ud, item_index); var val_du = test_case.Function.ItemValue(bump_du, item_index); fd_hess[ii, jj] = (val_uu - val_ud + val_dd - val_du) / (4 * h * h); } } for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj) { var val1 = fd_hess[ii, jj]; var val2 = a_hess[ii, jj]; var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2)); if (abs_min <= 1) { Assert.That(Math.Abs(val1 - val2) < 1e-3, $"Problem with hessian at start point."); } else { Assert.That(Math.Abs(val1 - val2) / abs_min < 0.05, $"Problem with hessian at start point."); } } } } }
public void HessianAtStart(TestFunctions.TestCase test_case) { var a_hess = test_case.Function.SsqHessian(test_case.InitialGuess); var fd_hess = Matrix <double> .Build.Dense(test_case.Function.ParameterDimension, test_case.Function.ParameterDimension); for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj) { var h1 = 1e-3 * Math.Max(1.0, Math.Abs(test_case.InitialGuess[ii])); var h2 = 1e-3 * Math.Max(1.0, Math.Abs(test_case.InitialGuess[jj])); var bump_uu = test_case.InitialGuess.Clone(); bump_uu[ii] += h1; bump_uu[jj] += h2; var bump_dd = test_case.InitialGuess.Clone(); bump_dd[ii] -= h1; bump_dd[jj] -= h2; var bump_ud = test_case.InitialGuess.Clone(); bump_ud[ii] += h1; bump_ud[jj] -= h2; var bump_du = test_case.InitialGuess.Clone(); bump_du[ii] -= h1; bump_du[jj] += h2; var val_uu = test_case.Function.SsqValue(bump_uu); var val_dd = test_case.Function.SsqValue(bump_dd); var val_ud = test_case.Function.SsqValue(bump_ud); var val_du = test_case.Function.SsqValue(bump_du); fd_hess[ii, jj] = (val_uu - val_ud + val_dd - val_du) / (4 * h1 * h2); } } for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii) { for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj) { var val1 = fd_hess[ii, jj]; var val2 = a_hess[ii, jj]; var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2)); if (abs_min <= 1) { Assert.That(Math.Abs(val1 - val2) < 1e-3, $"Problem with hessian at start point."); } else { Assert.That(Math.Abs(val1 - val2) / abs_min < 0.05, $"Problem with hessian at start point."); } } } }
public void ValueAtMinimum(TestFunctions.TestCase test_case) { if (test_case.MinimizingPoint != null) { var value_at_minimum = test_case.Function.SsqValue(test_case.MinimizingPoint); Assert.That( Math.Abs(value_at_minimum - test_case.MinimalValue) < 1e-3, $"Function value at minimum not as expected." ); } }
public void Mgh_Tests(TestFunctions.TestCase test_case) { var obj = new MghObjectiveFunction(test_case.Function, true, true); var result = ConjugateGradientMinimizer.Minimum(obj, test_case.InitialGuess, 1e-8, 10000); if (test_case.MinimizingPoint != null) { Assert.That((result.MinimizingPoint - test_case.MinimizingPoint).L2Norm(), Is.LessThan(1e-3)); } var val1 = result.FunctionInfoAtMinimum.Value; var val2 = test_case.MinimalValue; var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2)); var abs_err = Math.Abs(val1 - val2); var rel_err = abs_err / abs_min; var success = (abs_min <= 1 && abs_err < 1e-3) || (abs_min > 1 && rel_err < 1e-3); Assert.That(success, "Minimal function value is not as expected."); }
public void Mgh_FiniteDifference_Tests(TestFunctions.TestCase test_case) { var obj1 = new MghObjectiveFunction(test_case.Function, true, true); var obj = new ForwardDifferenceGradientObjectiveFunction(obj1, test_case.LowerBound, test_case.UpperBound, 1e-10, 1e-10); var solver = new BfgsBMinimizer(1e-8, 1e-8, 1e-8, 10000); var result = solver.FindMinimum(obj, test_case.LowerBound, test_case.UpperBound, test_case.InitialGuess); if (test_case.MinimizingPoint != null) { Assert.That((result.MinimizingPoint - test_case.MinimizingPoint).L2Norm(), Is.LessThan(1e-3)); } var val1 = result.FunctionInfoAtMinimum.Value; var val2 = test_case.MinimalValue; var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2)); var abs_err = Math.Abs(val1 - val2); var rel_err = abs_err / abs_min; var success = (abs_min <= 1 && abs_err < 1e-3) || (abs_min > 1 && rel_err < 1e-3); Assert.That(success, "Minimal function value is not as expected."); }