def test_num_jac(): def fun(t, y): return np.vstack([ -0.04 * y[0] + 1e4 * y[1] * y[2], 0.04 * y[0] - 1e4 * y[1] * y[2] - 3e7 * y[1] ** 2, 3e7 * y[1] ** 2 ]) def jac(t, y): return np.array([ [-0.04, 1e4 * y[2], 1e4 * y[1]], [0.04, -1e4 * y[2] - 6e7 * y[1], -1e4 * y[1]], [0, 6e7 * y[1], 0] ]) t = 1 y = np.array([1, 0, 0]) J_true = jac(t, y) threshold = 1e-5 f = fun(t, y).ravel() J_num, factor = num_jac(fun, t, y, f, threshold, None) assert_allclose(J_num, J_true, rtol=1e-5, atol=1e-5) J_num, factor = num_jac(fun, t, y, f, threshold, factor) assert_allclose(J_num, J_true, rtol=1e-5, atol=1e-5)
def test_num_jac(): def fun(t, y): return np.vstack([ -0.04 * y[0] + 1e4 * y[1] * y[2], 0.04 * y[0] - 1e4 * y[1] * y[2] - 3e7 * y[1] ** 2, 3e7 * y[1] ** 2 ]) def jac(t, y): return np.array([ [-0.04, 1e4 * y[2], 1e4 * y[1]], [0.04, -1e4 * y[2] - 6e7 * y[1], -1e4 * y[1]], [0, 6e7 * y[1], 0] ]) t = 1 y = np.array([1, 0, 0]) J_true = jac(t, y) threshold = 1e-5 f = fun(t, y).ravel() J_num, factor = num_jac(fun, t, y, f, threshold, None) assert_allclose(J_num, J_true, rtol=1e-5, atol=1e-5) J_num, factor = num_jac(fun, t, y, f, threshold, factor) assert_allclose(J_num, J_true, rtol=1e-5, atol=1e-5)
def test_num_jac_sparse(): def fun(t, y): e = y[1:]**3 - y[:-1]**2 z = np.zeros(y.shape[1]) return np.vstack((z, 3 * e)) + np.vstack((2 * e, z)) def structure(n): A = np.zeros((n, n), dtype=int) A[0, 0] = 1 A[0, 1] = 1 for i in range(1, n - 1): A[i, i - 1:i + 2] = 1 A[-1, -1] = 1 A[-1, -2] = 1 return A np.random.seed(0) n = 20 y = np.random.randn(n) A = structure(n) groups = group_columns(A) f = fun(0, y[:, None]).ravel() # Compare dense and sparse results, assuming that dense implementation # is correct (as it is straightforward). J_num_sparse, factor_sparse = num_jac(fun, 0, y.ravel(), f, 1e-8, None, sparsity=(A, groups)) J_num_dense, factor_dense = num_jac(fun, 0, y.ravel(), f, 1e-8, None) assert_allclose(J_num_dense, J_num_sparse.toarray(), rtol=1e-12, atol=1e-14) assert_allclose(factor_dense, factor_sparse, rtol=1e-12, atol=1e-14) # Take small factors to trigger their recomputing inside. factor = np.random.uniform(0, 1e-12, size=n) J_num_sparse, factor_sparse = num_jac(fun, 0, y.ravel(), f, 1e-8, factor, sparsity=(A, groups)) J_num_dense, factor_dense = num_jac(fun, 0, y.ravel(), f, 1e-8, factor) assert_allclose(J_num_dense, J_num_sparse.toarray(), rtol=1e-12, atol=1e-14) assert_allclose(factor_dense, factor_sparse, rtol=1e-12, atol=1e-14)
def test_num_jac_sparse(): def fun(t, y): e = y[1:]**3 - y[:-1]**2 z = np.zeros(y.shape[1]) return np.vstack((z, 3 * e)) + np.vstack((2 * e, z)) def structure(n): A = np.zeros((n, n), dtype=int) A[0, 0] = 1 A[0, 1] = 1 for i in range(1, n - 1): A[i, i - 1: i + 2] = 1 A[-1, -1] = 1 A[-1, -2] = 1 return A np.random.seed(0) n = 20 y = np.random.randn(n) A = structure(n) groups = group_columns(A) f = fun(0, y[:, None]).ravel() # Compare dense and sparse results, assuming that dense implementation # is correct (as it is straightforward). J_num_sparse, factor_sparse = num_jac(fun, 0, y.ravel(), f, 1e-8, None, sparsity=(A, groups)) J_num_dense, factor_dense = num_jac(fun, 0, y.ravel(), f, 1e-8, None) assert_allclose(J_num_dense, J_num_sparse.toarray(), rtol=1e-12, atol=1e-14) assert_allclose(factor_dense, factor_sparse, rtol=1e-12, atol=1e-14) # Take small factors to trigger their recomputing inside. factor = np.random.uniform(0, 1e-12, size=n) J_num_sparse, factor_sparse = num_jac(fun, 0, y.ravel(), f, 1e-8, factor, sparsity=(A, groups)) J_num_dense, factor_dense = num_jac(fun, 0, y.ravel(), f, 1e-8, factor) assert_allclose(J_num_dense, J_num_sparse.toarray(), rtol=1e-12, atol=1e-14) assert_allclose(factor_dense, factor_sparse, rtol=1e-12, atol=1e-14)
def jac_wrapped(y): f = fun_vectorized(y) t = None # Scipy's numjac method assumes time is a separate variable global jac_factor # TODO: object oriented implementation of the Newton solver ? J, jac_factor = num_jac(fun=lambda t, y: fun_vectorized(y), t=t, y=y, f=f, threshold=atol, factor=jac_factor, sparsity=sparsity) return J
def jac_wrapped(t, y, f): self.njev += 1 J, self.jac_factor = num_jac(self.fun_vectorized, t, y, f, self.atol, self.jac_factor, sparsity) return J