def value_and_grad(fun, argnum=0): """Returns a function that returns both value and gradient. Suitable for use in scipy.optimize""" def double_val_fun(*args, **kwargs): val = fun(*args, **kwargs) return make_tuple(val, unbox_if_possible(val)) gradval_and_val = grad_and_aux(double_val_fun, argnum) flip = lambda x, y: make_tuple(y, x) return lambda *args, **kwargs: flip(*gradval_and_val(*args, **kwargs))
def double_val_fun(*args, **kwargs): val = fun(*args, **kwargs) return make_tuple(val, unbox_if_possible(val))
def gradfun_rearranged(*args, **kwargs): multi_arg = make_tuple(*[args[i] for i in argnums]) return gradfun(multi_arg, *args, **kwargs)
def outer_fun(x): def inner_fun(y): return y[0] * y[1] return np.sum(np.sin(np.array(grad(inner_fun)(make_tuple(x, x)))))
def outer_fun(x): def inner_fun(y): return y[0] * y[1] return np.sum(np.sin(np.array(grad(inner_fun)(make_tuple(x,x)))))