鴨川のはりねずみ

[SymPy] Laplace-Runge-LenzベクトルのPoisson括弧

Kepler 問題の Hamiltonian は次式により与えられます. $$H = \frac{ \boldsymbol{p}^2 }{ 2 m } - \frac{ k }{ | \boldsymbol{r} | }$$ この系には Hamiltonian $H$, 角運動量 $\boldsymbol{L} = \boldsymbol{x} \times \boldsymbol{p}$ に加えて, Laplace-Runge-Lenz ベクトル として知られる運動の積分 $$\boldsymbol{A} = \boldsymbol{p} \times \boldsymbol{L} - m k \frac{ \boldsymbol{x} }{ | \boldsymbol{x} }$$ が存在します. 角運動量および Laplace-Runge-Lenz ベクトルの Poisson 括弧は $$[ L_i, L_j ] = \epsilon_{i j k} L_k$$ $$[ L_i, A_j ] = \epsilon_{i j k} A_k$$ $$[ A_i, A_j ] = - 2 m H \epsilon_{i j k} L_k$$ を満足し, $\mathfrak{so}(4)$ (あるいは $\mathfrak{so} ( 3, 1 )$) との対応関係が見て取れます. この Poisson 括弧を手計算でチェックすることはすこし面倒なのですが, SymPy を使えば数秒で終わります.

from sympy import symbols, sqrt, simplify
from sympy.combinatorics.permutations import Permutation

x, y, z, u, v, w, m, k = symbols("x, y, z, u, v, w, m, k")

def pb(f, g):
    X = f.diff(x) * g.diff(u) - f.diff(u) * g.diff(x)
    Y = f.diff(y) * g.diff(v) - f.diff(v) * g.diff(y)
    Z = f.diff(z) * g.diff(w) - f.diff(w) * g.diff(z)
    return X + Y + Z

X = [ x, y, z ]
P = [ u, v, w ]

def dot(a, b):
    return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]

def cross(a, b):
    return [
        a[1]*b[2] - a[2]*b[1],
        a[2]*b[0] - a[0]*b[2],
        a[0]*b[1] - a[1]*b[0],
    ]

def epsilon(i, j, k):
    if {i, j, k} != {0, 1, 2}:
        return 0
    elif Permutation([i, j, k]).is_even:
        return 1
    else:
        return -1

def hodge(i, j, a):
    return sum(list(epsilon(i,j,k)*a[k] for k in range(3)))

r = sqrt(x*x + y*y + z*z)
L = cross(X, P)

A = cross(P, L)
for i in range(3):
    A[i] = A[i] - m*k*X[i]/r

H = dot(P,P)/(2*m) - k/r


for i in range(3):
    assert simplify(pb(H, A[i])) == 0
    
    for j in range(3):
        rhs = -2*m*H*hodge(i, j, L)
        assert simplify(pb(A[i], A[j]) - rhs) == 0

        rhs = hodge(i, j, A)
        assert simplify(pb(L[i], A[j]) - rhs) == 0