/// <summary> /// Evaluates the Jacobian of a multivariate function f at vector x. /// </summary> /// <remarks> /// This function assumes that the length of vector x consistent with the argument count of f. /// </remarks> /// <param name="f">Multivariate function handle.</param> /// <param name="x">Points at which to evaluate Jacobian.</param> /// <returns>Jacobian vector.</returns> public double[] Evaluate(Func <double[], double> f, double[] x) { var jacobian = new double[x.Length]; for (var i = 0; i < jacobian.Length; i++) { jacobian[i] = _df.EvaluatePartialDerivative(f, x, i, 1); } return(jacobian); }
/// <summary> /// Evaluates the Hessian of a multivariate function f at points x. /// </summary> /// <remarks> /// This method of computing the Hessian is only valid for Lipschitz continuous functions. /// The function mirrors the Hessian along the diagonal since d2f/dxdy = d2f/dydx for continuously differentiable functions. /// </remarks> /// <param name="f">Multivariate function handle.></param> /// <param name="x">Points at which to evaluate Hessian.></param> /// <returns>Hessian tensor.</returns> public double[,] Evaluate(Func <double[], double> f, double[] x) { var hessian = new double[x.Length, x.Length]; // Compute diagonal elements for (var row = 0; row < x.Length; row++) { hessian[row, row] = _df.EvaluatePartialDerivative(f, x, row, 2); } // Compute non-diagonal elements for (var row = 0; row < x.Length; row++) { for (var col = 0; col < row; col++) { var mixedPartial = _df.EvaluateMixedPartialDerivative(f, x, new[] { row, col }, 2); hessian[row, col] = mixedPartial; hessian[col, row] = mixedPartial; } } return(hessian); }
public void VectorFunction1PartialDerivativeTest() { Func<double[], double>[] f = { (x) => Math.Pow(x[0],2) - 3*x[1], (x) => x[1]*x[1] + 2*x[0]*x[1] }; var x0 = new double[] { 2, 2 }; var g = new double[] { 4, 4 }; var df = new NumericalDerivative(); Assert.AreEqual(g, df.EvaluatePartialDerivative(f, x0, 0, 1)); Assert.AreEqual(new double[] { 2, 0 }, df.EvaluatePartialDerivative(f, x0, 0, 2)); Assert.AreEqual(new double[] { -3, 8 }, df.EvaluatePartialDerivative(f, x0, 1, 1)); }
public void RosenbrockFunctionMixedDerivativeOneVariableSecondOrderTest() { Func<double[], double> f = x => Math.Pow(1 - x[0], 2) + 100 * Math.Pow(x[1] - Math.Pow(x[0], 2), 2); var df = new NumericalDerivative(); var x0 = new double[] { 2, 2 }; var parameterindex = new int[] { 0, 0 }; Assert.AreEqual(1602, df.EvaluatePartialDerivative(f, x0, 0, 1), 1e-6); Assert.AreEqual(4002, df.EvaluateMixedPartialDerivative(f, x0, parameterindex, 2)); }
public void ExponentialFunctionPartialDerivativeCurrentValueTest() { //Test Function Func<double[], double> f = (x) => Math.Sin(x[0] * x[1]) + Math.Exp(-x[0] / 2) + x[1] / x[0]; //Analytical partial dfdx Func<double[], double> dfdx = (x) => Math.Cos(x[0] * x[1]) * x[1] - Math.Exp(-x[0] / 2) / 2 - x[1] / Math.Pow(x[0], 2); //Analytical partial dfdy Func<double[], double> dfdy = (x) => Math.Cos(x[0] * x[1]) * x[0] + 1 / x[0]; // Current value var x1 = new double[] { 3, 3 }; var current = f(x1); var df = new NumericalDerivative(5, 2); Assert.AreEqual(dfdx(x1), df.EvaluatePartialDerivative(f, x1, 0, 1, current), 1e-8); Assert.AreEqual(dfdy(x1), df.EvaluatePartialDerivative(f, x1, 1, 1, current), 1e-8); }
public void ExponentialFunctionPartialDerivativeTest() { //Test Function Func<double[], double> f = (x) => Math.Sin(x[0] * x[1]) + Math.Exp(-x[0] / 2) + x[1] / x[0]; //Analytical partial dfdx Func<double[], double> dfdx = (x) => Math.Cos(x[0] * x[1]) * x[1] - Math.Exp(-x[0] / 2) / 2 - x[1] / Math.Pow(x[0], 2); //Analytical partial dfdy Func<double[], double> dfdy = (x) => Math.Cos(x[0] * x[1]) * x[0] + 1 / x[0]; var df = new NumericalDerivative(3, 1); var x1 = new double[] { 3, 3 }; Assert.AreEqual(dfdx(x1), df.EvaluatePartialDerivative(f, x1, 0, 1), 1e-8); Assert.AreEqual(dfdy(x1), df.EvaluatePartialDerivative(f, x1, 1, 1), 1e-8); var x2 = new double[] { 300, -50 }; df.StepType = StepType.Absolute; Assert.AreEqual(dfdx(x2), df.EvaluatePartialDerivative(f, x2, 0, 1), 1e-5); Assert.AreEqual(dfdy(x2), df.EvaluatePartialDerivative(f, x2, 1, 1), 1e-2); }