'Calculates the Jacobian matrix (derivative of a vector-valued function).
Parameters
self : vector of expressions representing functions f_i(x_1, ..., x_n).
X : set of x_i\'s in order, it can be a list or a Matrix
Both self and X can be a row or a column matrix in any order
(i.e., jacobian() should always work).
Examples
>>> from sympy import sin, cos, Matrix
>>> from sympy.abc import rho, phi
>>> X = Matrix([rho*cos(phi), rho*sin(phi), rho**2])
>>> Y = Matrix([rho, phi])
>>> X.jacobian(Y)
Matrix([
[cos(phi), -rho*sin(phi)],
[sin(phi),  rho*cos(phi)],
[   2*rho,             0]])
>>> X = Matrix([rho*cos(phi), rho*sin(phi)])
>>> X.jacobian(Y)
Matrix([
[cos(phi), -rho*sin(phi)],
[sin(phi),  rho*cos(phi)]])
See Also
hessian
wronskian'

def jacobian(self, X):

    if (not isinstance(X, MatrixBase)):
        X = self._new(X)
    if (self.shape[0] == 1):
        m = self.shape[1]
    elif (self.shape[1] == 1):
        m = self.shape[0]
    else:
        raise TypeError('self    must    be    a    row    or    a    column    matrix')
    if (X.shape[0] == 1):
        n = X.shape[1]
    elif (X.shape[1] == 1):
        n = X.shape[0]
    else:
        raise TypeError('X    must    be    a    row    or    a    column    matrix')
    return self._new(m, n, (lambda j, i: self[j].diff(X[i])))
