raw Software
RAW Software Libraries Symbolic Mathematics

Compute a Symbolic Gradient with SymPy

Robert Eisele

For a scalar function of explicitly ordered variables, the gradient is the column vector of its partial derivatives:

\[ \nabla f(x_1,\ldots,x_n)= \begin{pmatrix} \frac{\partial f}{\partial x_1}\\ \vdots\\ \frac{\partial f}{\partial x_n} \end{pmatrix}. \]

SymPy's matrix Jacobian provides a compact implementation. A scalar function is represented as a one-element matrix, so its Jacobian is a row matrix; transposing it produces the conventional column gradient.

from sympy import Matrix, symbols

x, y = symbols("x y", real=True)
variables = Matrix([x, y])

f = 8 * x**2 + 4 * y**2 - 9
gradient_f = Matrix([f]).jacobian(variables).T

print(gradient_f)
# Matrix([[16*x], [8*y]])

The order of variables defines the meaning of the components. This is important: f.free_symbols is a set, not a coordinate system. Constructing the variable list with list(f.free_symbols) therefore does not establish whether the first component means \(\partial f/\partial x\) or \(\partial f/\partial y\).

Direct differentiation

The same gradient can be written directly from the definition. This form is useful when the code should make the component construction obvious:

from sympy import Matrix, diff

gradient_f = Matrix([diff(f, variable) for variable in variables])

Both forms return a \(2\times1\) matrix. For a vector-valued function \(F:\mathbb{R}^n\to\mathbb{R}^m\), keep the full \(m\times n\) Jacobian instead of transposing it:

from sympy import Matrix

F = Matrix([x**2 + y, x * y])
jacobian_F = F.jacobian(variables)

print(jacobian_F)
# Matrix([[2*x, 1], [y, x]])

Gradient in a coordinate system

sympy.vector.gradient() is a different interface for scalar fields expressed in a CoordSys3D coordinate system. Its result includes basis vectors:

from sympy.vector import CoordSys3D, gradient

N = CoordSys3D("N")
scalar_field = N.x**2 + N.y**2

print(gradient(scalar_field))
# 2*N.x*N.i + 2*N.y*N.j

Use the matrix form when variables and component order are the relevant representation. Use the vector module when basis vectors, coordinate systems, divergence, curl, or related vector-calculus operations are part of the model.

Second derivatives

The derivative of the gradient is the Hessian. SymPy exposes it directly and uses the same explicit variable order:

from sympy import hessian

hessian_f = hessian(f, variables)

print(hessian_f)
# Matrix([[16, 0], [0, 8]])

The positive diagonal entries show that the example function is strictly convex. Its only stationary point, obtained from gradient_f = 0, is \((0,0)\), and the Hessian confirms that this point is the global minimum.