### Question:
Jacobian { public static double[][] approxJacobian(double[] x, Vector2VectorFunc func, double... arg) { final int n = x.length; final double[] f0; if (arg != null && arg.length > 0) { f0 = func.apply(x, arg); } else { f0 = func.apply(x); } final double[][] jac = new double[n][f0.length]; final double[] dx = new double[n]; for (int i = 0; i < n; i++) { dx[i] = Jacobian.epsilon; final double[] add = new double[n]; for (int j = 0; j < n; j++) { add[j] = x[j] + dx[j]; } for (int j = 0; j < f0.length; j++) { if (arg != null && arg.length > 0) { jac[i][j] = (func.apply(add, arg)[j] - f0[j]) / Jacobian.epsilon; } else { jac[i][j] = (func.apply(add)[j] - f0[j]) / Jacobian.epsilon; } } dx[i] = 0; } return jac; }  static double[][] approxJacobian(double[] x, Vector2VectorFunc func, double... arg); static double[] approxJacobian(double[] x, Vector2ScalarFunc func, double... arg); static double[][] transpose(double[][] mat); static double epsilon; }### Answer:
@Test public void testJacobian() { final TestFunc testFunc = new TestFunc(); final double[] inputArr = new double[]{-1, -1}; final double[] fprime = Jacobian.approxJacobian(inputArr, testFunc); final double[] exactJac = testFunc.exactJac(inputArr); for (int i = 0; i < inputArr.length; i++) { assertTrue(Math.abs(fprime[i] - exactJac[i]) < TestUtil.ERROR); } }
@Test public void testIdentity() { final Vector2VectorFunc testFunc = (x, arg) -> x; final double[] inputArr = new double[]{-1, -1, 2, 4, 5, 6, 8}; final double[][] fprime = Jacobian.approxJacobian(inputArr, testFunc); for (int i = 0; i < fprime.length; i++) { for (int j = 0; j < fprime[0].length; j++) { if (i == j) { assertTrue(Math.abs(fprime[i][j] - 1) < TestUtil.ERROR); } else { assertTrue(Math.abs(fprime[i][j] - 0) < TestUtil.ERROR); } } } }