14

How does one calculate the (symbolic) gradient of a multivariate function in sympy?

Obviously I could calculate separately the derivative for each variable, but is there a vectorized operation that does this?

For example

m=sympy.Matrix(sympy.symbols('a b c d'))

Now for i=0..3 I can do:

sympy.diff(np.sum(m*m.T),m[i])

which will work, but I rather do something like:

sympy.diff(np.sum(m*m.T),m)

Which does not work ("AttributeError: ImmutableMatrix has no attribute _diff_wrt").

Bitwise
  • 7,577
  • 6
  • 33
  • 50
  • This doesn't work because it would expect to take the derivative with respect to `m` as a variable, which it does not know how to do. Just use a list comprehension over `m`. – asmeurer Jan 17 '14 at 01:06

2 Answers2

10

Just use a list comprehension over m:

[sympy.diff(sum(m*m.T), i) for i in m]

Also, don't use np.sum unless you are working with numeric values. The builtin sum is better.

asmeurer
  • 86,894
  • 26
  • 169
  • 240
8

Here is an alternative to @asmeurer. I prefer this way because it returns a SymPy object instead of a Python list.

def gradient(scalar_function, variables):
    matrix_scalar_function = Matrix([scalar_function])
    return matrix_scalar_function.jacobian(variables)

mf = sum(m*m.T)
gradient(mf, m)
Alex Walczak
  • 1,276
  • 1
  • 12
  • 27