微積分では関数 $f(x)$ という「実数を入力として実数を返す対応」を扱いますが、物理学や工学では「関数を入力として実数を返す対応」が必要になる場面が多くあります。この「関数から実数への写像」を汎関数と呼びます。
汎関数は、変分法、最適制御理論、量子力学など、理工学の幅広い分野で登場する重要な概念です。
本記事の内容
- 汎関数の定義と直感的な理解
- 代表的な汎関数の具体例
- 汎関数の変分(汎関数微分)
- Pythonでの数値的な汎関数計算
汎関数とは
関数と汎関数の違い
まず、通常の関数と汎関数の違いを整理しましょう。
通常の関数は、数値を受け取って数値を返す写像です。
$$ f: \mathbb{R} \to \mathbb{R}, \quad x \mapsto f(x) $$
一方、汎関数は関数を受け取って実数値を返す写像です。
$$ J: \mathcal{F} \to \mathbb{R}, \quad y(x) \mapsto J[y] $$
ここで、$\mathcal{F}$ は関数の集合(関数空間)であり、角括弧 $[\cdot]$ は汎関数の引数が関数であることを明示するために使われる慣例的な記法です。
イメージとしては、「関数という無限次元のものを1つの実数にまとめる操作」が汎関数です。
汎関数の具体例
例1: 曲線の長さ
平面上の曲線 $y(x)$($a \leq x \leq b$)の長さは、次の汎関数で表されます。
$$ L[y] = \int_a^b \sqrt{1 + \left(\frac{dy}{dx}\right)^2} \, dx $$
この汎関数は、関数 $y(x)$ を入力として、その曲線の長さという実数を返します。例えば $y(x) = x$ ならば直線の長さ、$y(x) = \sin(x)$ ならばサイン曲線の長さが得られます。
例2: 定積分
最も単純な汎関数の例として、定積分があります。
$$ I[f] = \int_a^b f(x) \, dx $$
関数 $f(x)$ を入力として、その定積分値という実数を返します。
例3: 作用積分(力学)
解析力学では、ラグランジアン $\mathcal{L}(q, \dot{q}, t)$ を用いた作用積分が重要な汎関数です。
$$ S[q] = \int_{t_1}^{t_2} \mathcal{L}(q(t), \dot{q}(t), t) \, dt $$
物理系の実際の運動は、この作用積分 $S[q]$ を停留させる経路 $q(t)$ として決定されます。これが最小作用の原理(ハミルトンの原理)です。
例4: 汎関数のノルム
関数空間における $L^2$ ノルムも汎関数の例です。
$$ \|f\|_{L^2} = \left(\int_a^b |f(x)|^2 \, dx\right)^{1/2} $$
汎関数の変分
変分の定義
汎関数を「微分」に相当する操作で解析するのが変分法です。関数 $y(x)$ に微小な変化 $\delta y(x)$ を加えたときの汎関数の変化を考えます。
$$ \delta J = J[y + \delta y] – J[y] $$
$\delta y$ が十分小さいとき、$\delta J$ を $\delta y$ の1次の項まで展開したものを汎関数の第一変分と呼びます。
オイラー-ラグランジュ方程式
次の形の汎関数を考えます。
$$ J[y] = \int_a^b F(x, y, y’) \, dx $$
ここで $y’ = dy/dx$ です。この汎関数の停留条件($\delta J = 0$)を求めると、オイラー-ラグランジュ方程式が得られます。
変分を計算します。$y(x)$ を $y(x) + \epsilon \eta(x)$ に置き換えます。ここで $\eta(a) = \eta(b) = 0$ (端点は固定)です。
$$ J[y + \epsilon \eta] = \int_a^b F(x, y + \epsilon \eta, y’ + \epsilon \eta’) \, dx $$
$\epsilon$ について微分して $\epsilon = 0$ とおくと、
$$ \left.\frac{d}{d\epsilon} J[y + \epsilon \eta]\right|_{\epsilon=0} = \int_a^b \left(\frac{\partial F}{\partial y}\eta + \frac{\partial F}{\partial y’}\eta’\right) dx = 0 $$
第2項を部分積分すると、
$$ \int_a^b \left(\frac{\partial F}{\partial y} – \frac{d}{dx}\frac{\partial F}{\partial y’}\right) \eta(x) \, dx = 0 $$
$\eta(x)$ は任意の関数なので、被積分関数がゼロでなければなりません。これがオイラー-ラグランジュ方程式です。
$$ \frac{\partial F}{\partial y} – \frac{d}{dx}\frac{\partial F}{\partial y’} = 0 $$
Pythonでの実装
曲線の長さの汎関数を数値的に計算し、異なる関数でどう変化するか可視化します。
import numpy as np
import matplotlib.pyplot as plt
def curve_length(y_func, x, dx):
"""曲線の長さを数値的に計算する汎関数"""
# 数値微分で dy/dx を近似
dy_dx = np.gradient(y_func(x), dx)
# 曲線の長さの被積分関数
integrand = np.sqrt(1 + dy_dx**2)
# 台形公式で積分
length = np.trapz(integrand, x)
return length
# パラメータ設定
a, b = 0, 2 * np.pi
N = 1000
x = np.linspace(a, b, N)
dx = x[1] - x[0]
# 様々な関数とその曲線長
functions = {
'$y = 0$ (straight line)': lambda x: np.zeros_like(x),
'$y = \sin(x)$': lambda x: np.sin(x),
'$y = \sin(2x)$': lambda x: np.sin(2 * x),
'$y = 2\sin(x)$': lambda x: 2 * np.sin(x),
'$y = x / \pi - 1$': lambda x: x / np.pi - 1,
}
# 曲線長の計算と可視化
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
lengths = {}
for name, func in functions.items():
L = curve_length(func, x, dx)
lengths[name] = L
axes[0].plot(x, func(x), label=f'{name}, L={L:.3f}')
axes[0].set_xlabel('x')
axes[0].set_ylabel('y')
axes[0].set_title('Curves and Their Arc Lengths')
axes[0].legend(fontsize=8)
axes[0].grid(True, alpha=0.3)
# 棒グラフで曲線長を比較
names = list(lengths.keys())
values = list(lengths.values())
colors = plt.cm.viridis(np.linspace(0.2, 0.8, len(names)))
axes[1].barh(range(len(names)), values, color=colors)
axes[1].set_yticks(range(len(names)))
axes[1].set_yticklabels(names, fontsize=8)
axes[1].set_xlabel('Arc Length')
axes[1].set_title('Comparison of Arc Lengths')
axes[1].grid(True, alpha=0.3, axis='x')
plt.tight_layout()
plt.show()
このコードでは、同じ区間 $[0, 2\pi]$ 上の異なる関数に対して曲線長(汎関数)の値を計算しています。振幅や周波数が大きい関数ほど曲線長が大きくなることが確認できます。
まとめ
本記事では、汎関数の定義と基本的な概念について解説しました。
- 汎関数は「関数を入力として実数を返す写像」であり、通常の関数の概念を拡張したものである
- 曲線の長さ、定積分、作用積分などが代表的な汎関数の例である
- 汎関数の停留条件を求めるとオイラー-ラグランジュ方程式が得られる
- オイラー-ラグランジュ方程式は解析力学の基礎であり、物理法則を変分原理から導出できる
汎関数と変分法の理解は、解析力学、最適制御理論、有限要素法など、多くの分野への入口となります。