import numpy as np
a = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
b = np.array([[1,2,3]]).T
c = a.dot(b) #function
jacobian = a # as partial derivative of c w.r.t to b is a.
Je lis sur jacobian Matrix, j'essaye d'en construire une et d'après ce que j'ai lu jusqu'à présent, ce code python doit être considéré comme jacobian. Est-ce que je comprends bien?
Vous pouvez utiliser la bibliothèque Harvard autograd
( link ), où grad
et jacobian
prennent une fonction comme argument:
import autograd.numpy as np
from autograd import grad, jacobian
x = np.array([5,3], dtype=float)
def cost(x):
return x[0]**2 / x[1] - np.log(x[1])
gradient_cost = grad(cost)
jacobian_cost = jacobian(cost)
gradient_cost(x)
jacobian_cost(np.array([x,x,x]))
Sinon, vous pouvez utiliser la méthode jacobian
disponible pour les matrices dans sympy
:
from sympy import sin, cos, Matrix
from sympy.abc import rho, phi
X = Matrix([rho*cos(phi), rho*sin(phi), rho**2])
Y = Matrix([rho, phi])
X.jacobian(Y)
En outre, vous pouvez également être intéressé par cette variante de bas niveau ( link ). MATLAB fournit une documentation agréable sur sa fonction jacobian
ici .
Le jacobien n'est défini que pour les fonctions à valeur vectorielle . Vous ne pouvez pas travailler avec des tableaux remplis de constantes pour calculer le jacobien; vous devez connaître la fonction sous-jacente et ses dérivées partielles, ou leur approximation numérique. Cela est évident lorsque l'on considère que la dérivée (partielle) d'une constante (par rapport à quelque chose) est 0.
En Python, vous pouvez travailler avec des modules mathématiques symboliques tels que SymPy
ou SymEngine
pour calculer les jacobiens des fonctions. Voici une simple démonstration d'un exemple de Wikipedia:
Utilisation du module SymEngine
:
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:40:30) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import symengine
>>>
>>>
>>> vars = symengine.symbols('x y') # Define x and y variables
>>> f = symengine.sympify(['y*x**2', '5*x + sin(y)']) # Define function
>>> J = symengine.zeros(len(f),len(vars)) # Initialise Jacobian matrix
>>>
>>> # Fill Jacobian matrix with entries
... for i, fi in enumerate(f):
... for j, s in enumerate(vars):
... J[i,j] = symengine.diff(fi, s)
...
>>> print J
[2*x*y, x**2]
[5, cos(y)]
>>>
>>> print symengine.Matrix.det(J)
2*x*y*cos(y) - 5*x**2
Dans python 3, vous pouvez essayer le package sympy :
import sympy as sym
def Jacobian(v_str, f_list):
vars = sym.symbols(v_str)
f = sym.sympify(f_list)
J = sym.zeros(len(f),len(vars))
for i, fi in enumerate(f):
for j, s in enumerate(vars):
J[i,j] = sym.diff(fi, s)
return J
Jacobian('u1 u2', ['2*u1 + 3*u2','2*u1 - 3*u2'])
ce qui donne:
Matrix([[2, 3],[2, -3]])
Voici une implémentation Python du jacobien mathématique d'une fonction vectorielle f(x)
, qui est supposée renvoyer un tableau numpy 1-D.
import numpy as np
def J(f, x, dx=1e-8):
n = len(x)
func = f(x)
jac = np.zeros((n, n))
for j in range(n): # through columns to allow for vector addition
Dxj = (abs(x[j])*dx if x[j] != 0 else dx)
x_plus = [(xi if k != j else xi + Dxj) for k, xi in enumerate(x)]
jac[:, j] = (f(x_plus) - func)/Dxj
return jac
Il est recommandé de faire dx
~ 10-8.