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").
To take derivatives, use the diff function. diff can take multiple derivatives at once. To take multiple derivatives, pass the variable as many times as you wish to differentiate, or pass a number after the variable.
To evaluate a numerical expression into a floating point number, use evalf . SymPy can evaluate floating point expressions to arbitrary precision. By default, 15 digits of precision are used, but you can pass any number as the argument to evalf .
To actually compute the transpose, use the transpose() function, or the . T attribute of matrices. Represents the trace of a matrix expression.
SymPy variables are objects of Symbols class. Symbol() function's argument is a string containing symbol which can be assigned to a variable. A symbol may be of more than one alphabets. SymPy also has a Symbols() function that can define multiple symbols at once.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With