ヤコビアンと変数変換(重積分の座標変換公式)

1変数の定積分では、置換積分 $\int f(g(t))g'(t)\,dt$ によって積分変数を変えることができました。多変数の重積分でも同様に変数変換が可能ですが、変数を変えたときに「面積要素」がどう変化するかを正しく反映する必要があります。その変化率を記述するのがヤコビアン(ヤコビ行列式)です。

ヤコビアンは、極座標、球座標、円筒座標など物理学で頻出する座標系での重積分に不可欠な概念です。

本記事の内容

  • ヤコビアンの定義
  • 重積分の変数変換公式
  • 極座標変換でのヤコビアン
  • 円筒座標変換でのヤコビアン
  • 球座標変換でのヤコビアン
  • Pythonでの可視化

前提知識

ヤコビ行列とヤコビアン

ヤコビ行列の定義

変数変換 $(x, y) = T(u, v)$、すなわち $x = x(u, v)$, $y = y(u, v)$ が与えられたとき、ヤコビ行列(Jacobian matrix)は偏微分を並べた行列です:

$$ \boxed{\bm{J} = \frac{\partial(x, y)}{\partial(u, v)} = \begin{pmatrix} \dfrac{\partial x}{\partial u} & \dfrac{\partial x}{\partial v} \\[8pt] \dfrac{\partial y}{\partial u} & \dfrac{\partial y}{\partial v} \end{pmatrix}} $$

ヤコビアンの定義

ヤコビアン(Jacobian determinant)は、ヤコビ行列の行列式です:

$$ \boxed{J = \det\bm{J} = \det\frac{\partial(x, y)}{\partial(u, v)} = \frac{\partial x}{\partial u}\frac{\partial y}{\partial v} – \frac{\partial x}{\partial v}\frac{\partial y}{\partial u}} $$

ヤコビアンの幾何学的意味

ヤコビアンは、変数変換による面積要素の拡大率を表します。

$(u, v)$ 平面の微小矩形 $du \times dv$ が、$(x, y)$ 平面ではどのような面積を持つかを考えます。微小矩形の2辺は:

$$ d\bm{r}_u = \left(\frac{\partial x}{\partial u}du,\; \frac{\partial y}{\partial u}du\right), \quad d\bm{r}_v = \left(\frac{\partial x}{\partial v}dv,\; \frac{\partial y}{\partial v}dv\right) $$

この2ベクトルが張る平行四辺形の面積は:

$$ dA_{xy} = |d\bm{r}_u \times d\bm{r}_v| = \left|\frac{\partial x}{\partial u}\frac{\partial y}{\partial v} – \frac{\partial x}{\partial v}\frac{\partial y}{\partial u}\right| du\,dv = |J|\,du\,dv $$

したがって、面積要素の変換は:

$$ dx\,dy = |J|\,du\,dv $$

$n$ 変数への一般化

変数変換 $(x_1, \dots, x_n) = T(u_1, \dots, u_n)$ のヤコビ行列は $n \times n$ 行列:

$$ J_{ij} = \frac{\partial x_i}{\partial u_j} $$

ヤコビアンはこの行列の行列式 $\det \bm{J}$ です。

重積分の変数変換公式

二重積分

$$ \boxed{\iint_D f(x, y)\,dx\,dy = \iint_{D’} f(x(u,v),\; y(u,v))\,\left|\frac{\partial(x,y)}{\partial(u,v)}\right|\,du\,dv} $$

ここで $D’$ は $D$ を $(u, v)$ 座標で表した領域です。

三重積分

$$ \boxed{\iiint_V f(x,y,z)\,dx\,dy\,dz = \iiint_{V’} f(\dots)\,\left|\frac{\partial(x,y,z)}{\partial(u,v,w)}\right|\,du\,dv\,dw} $$

極座標変換

変換式

$$ x = r\cos\theta, \quad y = r\sin\theta $$

ここで $r \geq 0$, $0 \leq \theta < 2\pi$ です。

ヤコビアンの計算

$$ \bm{J} = \begin{pmatrix} \dfrac{\partial x}{\partial r} & \dfrac{\partial x}{\partial \theta} \\[8pt] \dfrac{\partial y}{\partial r} & \dfrac{\partial y}{\partial \theta} \end{pmatrix} = \begin{pmatrix} \cos\theta & -r\sin\theta \\ \sin\theta & r\cos\theta \end{pmatrix} $$

行列式を計算します:

$$ J = \cos\theta \cdot r\cos\theta – (-r\sin\theta) \cdot \sin\theta $$

$$ = r\cos^2\theta + r\sin^2\theta $$

$$ = r(\cos^2\theta + \sin^2\theta) $$

$$ \boxed{J = r} $$

面積要素

$$ \boxed{dx\,dy = r\,dr\,d\theta} $$

これは直感的にも理解できます。極座標での微小要素は、半径方向の長さ $dr$、角度方向の弧の長さ $r\,d\theta$ の微小矩形であり、その面積は $r\,dr\,d\theta$ です。

具体例:ガウス積分

ガウス積分 $I = \int_{-\infty}^{\infty} e^{-x^2}\,dx$ を極座標を用いて計算します。

$$ I^2 = \int_{-\infty}^{\infty}\int_{-\infty}^{\infty} e^{-(x^2+y^2)}\,dx\,dy $$

極座標に変換すると:

$$ I^2 = \int_0^{2\pi}\int_0^{\infty} e^{-r^2}\,r\,dr\,d\theta $$

$\theta$ の積分は $2\pi$、$r$ の積分は $u = r^2$ として:

$$ \int_0^{\infty} e^{-r^2}\,r\,dr = \frac{1}{2}\int_0^{\infty} e^{-u}\,du = \frac{1}{2} $$

したがって:

$$ I^2 = 2\pi \cdot \frac{1}{2} = \pi $$

$$ \boxed{I = \int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}} $$

円筒座標変換

変換式

$$ x = r\cos\theta, \quad y = r\sin\theta, \quad z = z $$

ここで $r \geq 0$, $0 \leq \theta < 2\pi$, $-\infty < z < \infty$ です。

ヤコビアンの計算

$$ \bm{J} = \begin{pmatrix} \cos\theta & -r\sin\theta & 0 \\ \sin\theta & r\cos\theta & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

第3行で余因子展開すると:

$$ J = 1 \cdot \det\begin{pmatrix} \cos\theta & -r\sin\theta \\ \sin\theta & r\cos\theta \end{pmatrix} = r $$

$$ \boxed{J_{\text{cyl}} = r} $$

体積要素

$$ \boxed{dx\,dy\,dz = r\,dr\,d\theta\,dz} $$

具体例:円柱の体積

半径 $a$、高さ $h$ の円柱の体積:

$$ V = \int_0^{2\pi}\int_0^a\int_0^h r\,dz\,dr\,d\theta = \int_0^{2\pi}d\theta\int_0^a r\,dr\int_0^h dz $$

$$ = 2\pi \cdot \frac{a^2}{2} \cdot h = \pi a^2 h $$

球座標変換

変換式

$$ x = r\sin\phi\cos\theta, \quad y = r\sin\phi\sin\theta, \quad z = r\cos\phi $$

ここで $r \geq 0$, $0 \leq \phi \leq \pi$(天頂角), $0 \leq \theta < 2\pi$(方位角)です。

ヤコビアンの計算

ヤコビ行列は:

$$ \bm{J} = \begin{pmatrix} \dfrac{\partial x}{\partial r} & \dfrac{\partial x}{\partial \phi} & \dfrac{\partial x}{\partial \theta} \\[8pt] \dfrac{\partial y}{\partial r} & \dfrac{\partial y}{\partial \phi} & \dfrac{\partial y}{\partial \theta} \\[8pt] \dfrac{\partial z}{\partial r} & \dfrac{\partial z}{\partial \phi} & \dfrac{\partial z}{\partial \theta} \end{pmatrix} = \begin{pmatrix} \sin\phi\cos\theta & r\cos\phi\cos\theta & -r\sin\phi\sin\theta \\ \sin\phi\sin\theta & r\cos\phi\sin\theta & r\sin\phi\cos\theta \\ \cos\phi & -r\sin\phi & 0 \end{pmatrix} $$

第3行で余因子展開します:

$$ J = \cos\phi \cdot \det\begin{pmatrix} r\cos\phi\cos\theta & -r\sin\phi\sin\theta \\ r\cos\phi\sin\theta & r\sin\phi\cos\theta \end{pmatrix} $$

$$ + r\sin\phi \cdot \det\begin{pmatrix} \sin\phi\cos\theta & -r\sin\phi\sin\theta \\ \sin\phi\sin\theta & r\sin\phi\cos\theta \end{pmatrix} $$

第1項の行列式:

$$ r\cos\phi\cos\theta \cdot r\sin\phi\cos\theta – (-r\sin\phi\sin\theta) \cdot r\cos\phi\sin\theta $$

$$ = r^2\cos\phi\sin\phi\cos^2\theta + r^2\sin\phi\cos\phi\sin^2\theta $$

$$ = r^2\sin\phi\cos\phi(\cos^2\theta + \sin^2\theta) = r^2\sin\phi\cos\phi $$

第2項の行列式:

$$ \sin\phi\cos\theta \cdot r\sin\phi\cos\theta – (-r\sin\phi\sin\theta) \cdot \sin\phi\sin\theta $$

$$ = r\sin^2\phi\cos^2\theta + r\sin^2\phi\sin^2\theta = r\sin^2\phi $$

すべて合わせると:

$$ J = \cos\phi \cdot r^2\sin\phi\cos\phi + r\sin\phi \cdot r\sin^2\phi $$

$$ = r^2\sin\phi\cos^2\phi + r^2\sin^3\phi $$

$$ = r^2\sin\phi(\cos^2\phi + \sin^2\phi) $$

$$ \boxed{J_{\text{sph}} = r^2\sin\phi} $$

体積要素

$$ \boxed{dx\,dy\,dz = r^2\sin\phi\,dr\,d\phi\,d\theta} $$

具体例:球の体積

半径 $R$ の球の体積:

$$ V = \int_0^{2\pi}\int_0^{\pi}\int_0^R r^2\sin\phi\,dr\,d\phi\,d\theta $$

各変数が独立に積分できるので:

$$ V = \left(\int_0^{2\pi}d\theta\right)\left(\int_0^{\pi}\sin\phi\,d\phi\right)\left(\int_0^R r^2\,dr\right) $$

$$ = 2\pi \cdot [-\cos\phi]_0^{\pi} \cdot \left[\frac{r^3}{3}\right]_0^R $$

$$ = 2\pi \cdot 2 \cdot \frac{R^3}{3} $$

$$ \boxed{V = \frac{4}{3}\pi R^3} $$

Pythonでの可視化

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import Axes3D

# ============================
# ヤコビアンと変数変換の可視化
# ============================

fig = plt.figure(figsize=(18, 12))

# === (1) 極座標変換のグリッド変形 ===
ax1 = fig.add_subplot(231)
ax2 = fig.add_subplot(232)

# (u,v) = (r, θ) 空間のグリッド
r_lines = np.linspace(0.2, 2.0, 5)
theta_lines = np.linspace(0, 2*np.pi, 13)

# (u,v)空間: 矩形グリッド
for r in r_lines:
    ax1.plot([0, 2*np.pi], [r, r], 'b-', lw=1)
for th in theta_lines:
    ax1.plot([th, th], [0.2, 2.0], 'r-', lw=1)

ax1.set_xlabel('$\\theta$', fontsize=12)
ax1.set_ylabel('$r$', fontsize=12)
ax1.set_title('$(r, \\theta)$ space\n(rectangular grid)', fontsize=12)
ax1.grid(True, alpha=0.3)

# (x,y)空間: 極座標グリッド
theta_fine = np.linspace(0, 2*np.pi, 200)
for r in r_lines:
    ax2.plot(r*np.cos(theta_fine), r*np.sin(theta_fine), 'b-', lw=1)
for th in theta_lines:
    r_fine = np.linspace(0.2, 2.0, 50)
    ax2.plot(r_fine*np.cos(th), r_fine*np.sin(th), 'r-', lw=1)

ax2.set_xlabel('$x$', fontsize=12)
ax2.set_ylabel('$y$', fontsize=12)
ax2.set_title('$(x, y)$ space\n(polar grid)', fontsize=12)
ax2.set_aspect('equal')
ax2.grid(True, alpha=0.3)

# === (2) 面積要素の拡大率 ===
ax3 = fig.add_subplot(233)

r_grid = np.linspace(0, 3, 100)
theta_grid = np.linspace(0, 2*np.pi, 100)
R, Theta = np.meshgrid(r_grid, theta_grid)
X_p = R * np.cos(Theta)
Y_p = R * np.sin(Theta)
J_polar = R  # ヤコビアン = r

cs = ax3.pcolormesh(X_p, Y_p, J_polar, cmap='YlOrRd', shading='auto')
plt.colorbar(cs, ax=ax3, label='$|J| = r$')
ax3.set_xlabel('$x$', fontsize=12)
ax3.set_ylabel('$y$', fontsize=12)
ax3.set_title('Jacobian magnitude\n(polar coords)', fontsize=12)
ax3.set_aspect('equal')

# === (3) 球座標の体積要素 ===
ax4 = fig.add_subplot(234, projection='3d')

# 球座標のグリッド線を描画
R_val = 1.0
phi_lines = np.linspace(0, np.pi, 7)
theta_lines_3d = np.linspace(0, 2*np.pi, 13)

# θ一定の線(経線)
for th in theta_lines_3d[:-1]:
    phi_fine = np.linspace(0, np.pi, 100)
    ax4.plot(R_val*np.sin(phi_fine)*np.cos(th),
             R_val*np.sin(phi_fine)*np.sin(th),
             R_val*np.cos(phi_fine), 'b-', lw=0.5, alpha=0.5)

# φ一定の線(緯線)
for ph in phi_lines:
    theta_fine = np.linspace(0, 2*np.pi, 100)
    ax4.plot(R_val*np.sin(ph)*np.cos(theta_fine),
             R_val*np.sin(ph)*np.sin(theta_fine),
             R_val*np.cos(ph), 'r-', lw=0.5, alpha=0.5)

# 微小体積要素の可視化
r0, phi0, theta0 = 0.8, np.pi/3, np.pi/4
dr, dphi, dtheta = 0.2, np.pi/8, np.pi/6

r_elem = np.array([r0, r0+dr])
phi_elem = np.linspace(phi0, phi0+dphi, 10)
theta_elem = np.linspace(theta0, theta0+dtheta, 10)

# 微小要素の面を描画
for r_val in r_elem:
    Ph, Th = np.meshgrid(phi_elem, theta_elem)
    ax4.plot_surface(r_val*np.sin(Ph)*np.cos(Th),
                     r_val*np.sin(Ph)*np.sin(Th),
                     r_val*np.cos(Ph),
                     alpha=0.5, color='orange')

ax4.set_xlabel('$x$'); ax4.set_ylabel('$y$'); ax4.set_zlabel('$z$')
ax4.set_title('Spherical coordinate\nvolume element', fontsize=12)

# === (4) ガウス積分の極座標変換 ===
ax5 = fig.add_subplot(235)

x_gauss = np.linspace(-4, 4, 200)
y_gauss = np.linspace(-4, 4, 200)
X_g, Y_g = np.meshgrid(x_gauss, y_gauss)
Z_g = np.exp(-(X_g**2 + Y_g**2))

cs5 = ax5.contourf(X_g, Y_g, Z_g, levels=20, cmap='viridis')
plt.colorbar(cs5, ax=ax5, label='$e^{-(x^2+y^2)}$')

# 同心円(等値線)
for r in [0.5, 1.0, 1.5, 2.0]:
    circle = plt.Circle((0, 0), r, fill=False, color='white',
                         ls='--', lw=1, alpha=0.7)
    ax5.add_patch(circle)

ax5.set_xlabel('$x$', fontsize=12)
ax5.set_ylabel('$y$', fontsize=12)
ax5.set_title('$e^{-(x^2+y^2)}$\n(radial symmetry $\\rightarrow$ polar coords)', fontsize=12)
ax5.set_aspect('equal')

# === (5) 数値検証:球の体積 ===
ax6 = fig.add_subplot(236)

from scipy import integrate

# 球座標で球の体積を数値計算(分割数を変えて精度を確認)
R_sphere = 1.0
V_exact = 4/3 * np.pi * R_sphere**3

# シンプソン則での数値積分
n_values = np.arange(4, 102, 2)
V_numerical = []

for n in n_values:
    # 各方向をn分割
    r_pts = np.linspace(0, R_sphere, n+1)
    phi_pts = np.linspace(0, np.pi, n+1)
    theta_pts = np.linspace(0, 2*np.pi, n+1)

    dr = r_pts[1] - r_pts[0]
    dphi = phi_pts[1] - phi_pts[0]
    dtheta = theta_pts[1] - theta_pts[0]

    V = 0
    for i in range(n):
        r_mid = (r_pts[i] + r_pts[i+1]) / 2
        for j in range(n):
            phi_mid = (phi_pts[j] + phi_pts[j+1]) / 2
            for k in range(n):
                V += r_mid**2 * np.sin(phi_mid) * dr * dphi * dtheta

    V_numerical.append(V)

ax6.plot(n_values, V_numerical, 'b-', lw=1.5, label='Numerical (midpoint)')
ax6.axhline(V_exact, color='r', ls='--', lw=2,
            label=f'Exact = $4\\pi/3$ = {V_exact:.4f}')
ax6.set_xlabel('Subdivisions per axis', fontsize=12)
ax6.set_ylabel('Volume', fontsize=12)
ax6.set_title('Sphere volume via\nspherical coordinates', fontsize=12)
ax6.legend(fontsize=10)
ax6.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('jacobian_variable_transformation.png', dpi=150, bbox_inches='tight')
plt.show()

# === 各座標系のヤコビアンの比較表を出力 ===
print("=== 座標変換とヤコビアン ===")
print(f"極座標:   dx dy    = r dr dθ")
print(f"円筒座標: dx dy dz = r dr dθ dz")
print(f"球座標:   dx dy dz = r² sin(φ) dr dφ dθ")
print(f"\n球の体積(解析): {V_exact:.6f}")
print(f"球の体積(数値, n=100): {V_numerical[-1]:.6f}")
print(f"相対誤差: {abs(V_numerical[-1] - V_exact)/V_exact*100:.4f}%")

上段の左2つの図は、極座標変換によるグリッドの変形を示しています。$(r, \theta)$ 空間の矩形グリッドが $(x, y)$ 空間では同心円と放射状の直線に変換されます。右上の図は、ヤコビアン $|J| = r$ を色で表したもので、原点から離れるほど面積要素が拡大されることを示しています。

下段の左の図は球座標系のグリッド(経線と緯線)と微小体積要素を3Dで表示しています。中央の図は $e^{-(x^2+y^2)}$ の等高線が同心円であることを示しており、極座標変換が自然であることを示唆しています。右下の図は、球座標での数値積分により球の体積 $4\pi R^3/3$ が正しく得られることを検証しています。

まとめ

本記事では、ヤコビアンと重積分の変数変換について解説しました。

  • ヤコビ行列は座標変換の偏微分を並べた行列
  • ヤコビアンはヤコビ行列の行列式で、面積(体積)要素の拡大率を表す
  • 変数変換公式: $dx\,dy = |J|\,du\,dv$
  • 極座標: $dx\,dy = r\,dr\,d\theta$
  • 円筒座標: $dx\,dy\,dz = r\,dr\,d\theta\,dz$
  • 球座標: $dx\,dy\,dz = r^2\sin\phi\,dr\,d\phi\,d\theta$
  • ガウス積分 $\int_{-\infty}^{\infty}e^{-x^2}dx = \sqrt{\pi}$ は極座標変換で導出できる

次のステップとして、以下の記事も参考にしてください。