def hessian_vector(fn=None, **kwargs): """ Wraps a function with an AutoDiff HessianVector instance, converting it to a symbolic representation that returns the result with respect to either all inputs or a subset (if specified with the 'wrt' keyword). A tuple of the required vectors must be passed to the resulting function with the keyword '_vectors'. The function is compiled the first time it is called. Use: @gradient def python_function(...): return do_something() python_function(...) # returns the gradient of python_function Pass keywords to Gradient: @gradient(wrt = ['x', 'y']) def python_function(x=1, y=2): return do_something() """ if callable(fn): return HessianVector(fn, **kwargs) else: def hv_wrapper(pyfn): return HessianVector(pyfn, **kwargs) return hv_wrapper
def test_hv(self): def fn(x): return np.dot(x, x).sum() x = np.ones((3, 3)) F = HessianVector(fn) self.assertTrue(np.allclose(x * 6, F(x, vectors=x))) self.assertTrue(np.allclose(x * 2, F(x[0], vectors=x[0])))
def hv_wrapper(pyfn): return HessianVector(pyfn, **kwargs)
def test_hv_no_scalar(self): def fn(x): return np.dot(x, x) x = np.ones((3, 3)) F = HessianVector(fn) self.assertRaises(TypeError, F, x, vectors=x[0])
def test_hv_missing_vectors(self): def fn(x): return x F = HessianVector(fn) self.assertRaises(ValueError, F, np.array([[1, 1]]))