Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a vectorized way to calculate the gradient in sympy?

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").

like image 368
Bitwise Avatar asked Jan 16 '14 16:01

Bitwise


People also ask

How do you take the derivative of a SymPy?

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.

How do you evaluate a SymPy expression?

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 .

How do you find the transpose of a matrix in SymPy?

To actually compute the transpose, use the transpose() function, or the . T attribute of matrices. Represents the trace of a matrix expression.

How define SymPy function?

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.


2 Answers

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.

like image 165
asmeurer Avatar answered Sep 28 '22 09:09

asmeurer


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)
like image 41
Alex Walczak Avatar answered Sep 28 '22 10:09

Alex Walczak