web-dev-qa-db-fra.com

Calculez la matrice jacobienne en Python

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?

10
filtertips

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 jacobianici .

10
Adam Erickson

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:

enter image description here

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
7
dROOOze

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]])
5
OliverQ

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.

3
James Carter