简体   繁体   中英

Differentiation of a list of functions with respect to a list of variables

Suppose I have a list of functions

f = ['m','n', 'z']

and a list of variables

v = ['x', 'y', 'z'] 

Now

m = x**2
n = y**2
z = x*y

Two important things here:

  • They are lists, so "string" has to converted into "symbols" or "Function"
  • 'z' is a function and also a variable! So they are different and dz/dz is not unity. It depends on what function 'z' is. In this case dz/dx should be y and dz/dz should be 0. (Assume d is the partial derivative)

Now I want to differentiate all the elements of the function list with respect to all the elements of the variable list and the output will be an multidimensional array. I am trying this without same variable and function name(here only printing one derivative, but ultimately I need a full array):

from sympy import *

f = ['m', 'n']
v = ['x', 'y']

variable = [var(i) for i in v]
Funct = [Function(i) for i in f]

m = x**2
n = y**2

print(diff(Funct[0], variable[0]))

it is giving this error:

print(diff(Funct[0], variable[0]))
File "/usr/local/lib/python2.7/site-packages/sympy/core/function.py", line 1837, in diff
return Derivative(f, *symbols, **kwargs)
File "/usr/local/lib/python2.7/site-packages/sympy/core/function.py", line 1136, in __new__
if symbol_set.difference(expr.free_symbols):
TypeError: 'property' object is not iterable

What you're looking for is called the Jacobian, and can be computed with SymPy like this:

>>> x, y, z = symbols('x y z')
>>> Matrix([x**2, y**2, x*y]).jacobian([x, y, z])
Matrix([
[2*x,   0, 0],
[  0, 2*y, 0],
[  y,   x, 0]])

One thing to realize is that the strings we use when creating symbols have nothing to do with names of those symbols. You can have

a = Symbol('b')

and now a is a symbol whose string representation is 'b'. In your code, this symbol is referred to as a , not as b . In particular, creating Funct = [Function('m'), Function('n')] and then assigning m = x**2 does nothing for the functions you created: there is no connection between m and Function('m') .

Also, SymPy does not really differentiate functions , it differentiates expressions (functions in which something is plugged in). The following creates a double list of derivatives, given expressions and variables:

variables = symbols("x y z")
expressions = [x**2, y**2, x*y]
print([[diff(e, v) for v in variables] for e in expressions])

Output:

[[2*x, 0, 0], [0, 2*y, 0], [y, x, 0]] 

Why not doing something as simple as the following?

import sympy as sp

x, y = sp.symbols('x, y')
m, n, z = x**2, y**2, x*y
f = [m, n, z]
v = [x, y]

H = [[fun.diff(var) for var in v] for fun in f]
print(H)

在此处输入图片说明

You can try derive_by_array :

In [3]: f = [i(x, y, z) for i in symbols(['m','n', 'z'], cls=Function)]

In [4]: f
Out[4]: [m(x, y, z), n(x, y, z), z(x, y, z)]

In [5]: derive_by_array(f, [x, y, z])
Out[5]: 
⎡∂               ∂               ∂             ⎤
⎢──(m(x, y, z))  ──(n(x, y, z))  ──(z(x, y, z))⎥
⎢∂x              ∂x              ∂x            ⎥
⎢                                              ⎥
⎢∂               ∂               ∂             ⎥
⎢──(m(x, y, z))  ──(n(x, y, z))  ──(z(x, y, z))⎥
⎢∂y              ∂y              ∂y            ⎥
⎢                                              ⎥
⎢∂               ∂               ∂             ⎥
⎢──(m(x, y, z))  ──(n(x, y, z))  ──(z(x, y, z))⎥
⎣∂z              ∂z              ∂z            ⎦

The next version of SymPy will support an even more compact syntax:

diff(f, [[x, y, z]])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM