@parameterized.named_parameters({'testcase_name': 'nonsymmetric', 'symmetric': False}, {'testcase_name': 'symmetric', 'symmetric': True})
@jtu.skip_on_flag('jax_skip_slow_tests', True)
def test_custom_linear_solve(self, symmetric):

    def explicit_jacobian_solve(matvec, b):
        return lax.stop_gradient(jnp.linalg.solve(api.jacobian(matvec)(b), b))

    def matrix_free_solve(matvec, b):
        return lax.custom_linear_solve(matvec, b, explicit_jacobian_solve, explicit_jacobian_solve, symmetric=symmetric)

    def linear_solve(a, b):
        return matrix_free_solve(partial(high_precision_dot, a), b)
    rng = np.random.RandomState(0)
    a = rng.randn(3, 3)
    if symmetric:
        a = (a + a.T)
    b = rng.randn(3)
    jtu.check_grads(linear_solve, (a, b), order=2, rtol=0.002)
    expected = jnp.linalg.solve(a, b)
    actual = api.jit(linear_solve)(a, b)
    self.assertAllClose(expected, actual)
    c = rng.randn(3, 2)
    expected = jnp.linalg.solve(a, c)
    actual = api.vmap(linear_solve, (None, 1), 1)(a, c)
    self.assertAllClose(expected, actual)
@parameterized.named_parameters({'testcase_name': 'nonsymmetric', 'symmetric': False}, {'testcase_name': 'symmetric', 'symmetric': True})
@jtu.skip_on_flag('jax_skip_slow_tests', True)
def test_custom_linear_solve(self, symmetric):

    def explicit_jacobian_solve(matvec, b):
        return lax.stop_gradient(jnp.linalg.solve(api.jacobian(matvec)(b), b))

    def matrix_free_solve(matvec, b):
        return lax.custom_linear_solve(matvec, b, explicit_jacobian_solve, explicit_jacobian_solve, symmetric=symmetric)

    def linear_solve(a, b):
        return matrix_free_solve(partial(high_precision_dot, a), b)
    rng = np.random.RandomState(0)
    a = rng.randn(3, 3)
    if symmetric:
        a = (a + a.T)
    b = rng.randn(3)
    jtu.check_grads(linear_solve, (a, b), order=2, rtol=0.002)
    expected = jnp.linalg.solve(a, b)
    actual = api.jit(linear_solve)(a, b)
    self.assertAllClose(expected, actual)
    c = rng.randn(3, 2)
    expected = jnp.linalg.solve(a, c)
    actual = api.vmap(linear_solve, (None, 1), 1)(a, c)
    self.assertAllClose(expected, actual)