web-dev-qa-db-ja.com

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.

私はjacobian Matrixについて読んでいます。これを作成しようとしていますが、これまでに読んだことから、これはpythonコードをjacobianと見なす必要があります。この権利を理解していますか?

10
filtertips

Harvard 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 )もご覧ください。 MATLABは、jacobian関数 here に関するニースのドキュメントを提供しています。

10
Adam Erickson

ヤコビアンはベクトル値関数に対してのみ定義されます。定数で満たされた配列を使用してヤコビ行列を計算することはできません。基礎となる関数とその偏微分、またはこれらの数値近似を知っている必要があります。これは、(何かに関して)定数の(部分)導関数が0であると考えると明白です。

Pythonでは、SymPySymEngineなどのシンボリック数学モジュールを使用して、関数のヤコビアンを計算できます。 Wikipediaの例の簡単なデモを次に示します。

enter image description here

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

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

Pythonベクトル関数の数学的なヤコビアンの実装f(x)は、1次元のnumpy配列を返すと想定されています。

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

dx〜10にすることをお勧めします-8

3
James Carter