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.
我正在阅读jacobian Matrix,尝试构建一个,从我到目前为止所读到的,这个python代码应该被视为jacobian。我明白了吗?
您可以使用哈佛autograd
库(link),其中grad
和jacobian
将函数作为他们的参数:
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]))
否则,您可以使用jacobian
中可用于矩阵的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)
此外,您可能也有兴趣看到这个低级变体(link)。
雅可比行列式仅为向量值函数定义。你不能使用填充常量的数组来计算雅可比矩阵;你必须知道基础函数及其偏导数,或者这些函数的数值近似。当你考虑常数(相对于某些东西)的(部分)导数为0时,这是显而易见的。
在Python中,您可以使用符号数学模块(如SymPy
或SymEngine
)来计算函数的雅可比行列式。以下是维基百科示例的简单演示:
使用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
在python 3中,你可以试试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'])
这给出了:
Matrix([[2, 3],[2, -3]])
这是一个矢量函数f(x)
的mathamatical Jacobian的python实现,它被假定为返回1-D numpy数组。
import numpy as np
def J(f, x, dx=10^-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
建议使dx~10 ^ -8。