def jacobian(fun, argnum=0):
    dummy = lambda: None

    def getshape(val):
        val = getval(val)
        assert np.isscalar(val) or isinstance(val, np.ndarray), \
            'Jacobian requires input and output to be scalar- or array-valued'
        return np.shape(val)

    def list_fun(*args, **kwargs):
        val = fun(*args, **kwargs)
        dummy.outshape = getshape(val)
        return list(np.ravel(val))

    concatenate = lambda lst: np.concatenate(list(map(np.atleast_1d, lst)))

    @attach_name_and_doc(fun, argnum, 'Jacobian')
    def jacfun(*args, **kwargs):
        start_node, end_nodes, tape = forward_pass(list_fun, args, kwargs, argnum)
        grads = list(map(partial(backward_pass, start_node, tape=tape), end_nodes))
        shape = dummy.outshape + getshape(args[argnum])
        return np.reshape(concatenate(grads), shape) if shape else grads[0]
    return jacfun
Returns a function which computes the Jacobian of `fun` with respect to
dataset/ETHPy150Open HIPS/autograd/autograd/convenience_wrappers.py/jacobian