M2.2 站內人數變化 = 進 − 出:Continuity Equation
本篇重用M0.1閘門的進出:Divergence 與通量·M2.1從一片葉子到一群葉子:Flow Map 與 Pushforward·M0.3漂流的溫度計:全導數、微分穿過積分與 JVP
捷運站,再看一次
M0.1 用捷運站問過一個問題:每個閘門的進出人數都知道,站內人數是在增加還是減少?答案是把所有閘門的淨流量加起來,這個總和就是 divergence 的積分。
現在把問題推遠一步。站內不是一個點,是一整片大廳:有人往月台走、有人往出口走、有人在售票機前停下來。假設你有一張「人流地圖」——大廳每個位置、每個時刻,人往哪個方向走、走多快。你也知道此刻大廳裡人群的分佈:哪裡擠、哪裡空。十分鐘後,人群的分佈會變成什麼樣?
直覺的答案通常是「每個人順著人流地圖走,所以分佈就是被搬過去」——這正是上一篇(M2.1)的 pushforward。它是對的,但要用它就得先算出每個起點的終點 。這一篇問一個不同的問題:能不能不追任何一個人,直接寫下「分佈本身」隨時間變化的規則?請先寫下你覺得可不可以、依據是什麼。
課堂提問Q1
把「站內人數變化 = 進 − 出」這句話,從整個車站縮小到大廳裡一塊 的地磚上。這塊地磚上的人數怎麼變?「進」與「出」由哪些量決定?
先想一想,再展開看整理後的答案
最直覺的想法是「看有多少人踩進來、多少人踩出去」,接著就能推得很順:
地磚上的人數 , 是人群的密度(每平方公尺幾個人)。人怎麼進出?沿著地磚的四條邊。看左邊那條邊:邊上的人以速度 走,所以每秒穿過這條邊的人數是「密度 × 速度的垂直分量 × 邊長」——這個量叫 flux(單位時間穿過單位邊長的質量),寫成 。
進 − 出就是四條邊的 flux 的淨和。 左邊進、右邊出:淨流入是 ;上下同理。地磚很小時,「右邊的值減左邊的值」就是 ,所以淨流入 。
這就把 M0.1 的結論搬到了每一塊地磚上:地磚上人數的變化率,等於 flux 的 divergence 取負號。 這裡的隨機變數是「隨機抓一個人,他在哪」,我們想知道的量是它的密度 隨時間的變化。
先看畫面:每塊地磚都在記帳
把大廳鋪滿地磚,每塊地磚上站一個記帳員。他不需要知道任何人從哪來、要去哪;他只盯著自己四條邊,數每秒有幾個人跨進來、幾個人跨出去,然後更新自己這塊的人數。
一千個記帳員各自記帳,加起來就是整個分佈的演化。沒有任何一個記帳員追蹤過任何一個人。這就是 continuity equation 的視角:從「每個人走到哪」(Lagrangian,追粒子)換成「每個位置有多少」(Eulerian,守著格子)。兩種視角描述的是同一件事——上一篇的 flow map 是追粒子,這一篇是守格子。
寫成數學:一個方塊,十行推導
設 是密度, 是 vector field(M2.0),flux 是 。取一個固定的小區域 (不隨時間動),裡面的質量是 。假設質量守恆——沒有人憑空出現或消失——那麼質量變化只能來自穿過邊界 的 flux:
第一個等號是守恆( 是向外的法向量,向外流為正,所以取負號);第二個等號是 M0.1 的 Gauss 定理。左邊因為 不動,微分可以穿過積分(M0.3),變成 。於是對任何小區域 都有
一個 continuous 的函數若在每個小區域上積分都是零,它本身必為零。所以
這就是 continuity equation。讀法:密度的變化率 flux 的 divergence;flux 往外散的地方密度下降,往內收的地方密度上升。
它是一條 PDE(partial differential equation:同時對 與 微分)。要用它,給定 與 ,就能往前解出所有 ——不需要 flow map。
和 pushforward 的關係。 若 是 Lipschitz 的,這條 PDE 的解就是 ([3] 第 8 章)。兩種寫法、同一個 。可以在一維例子上直接驗證:M2.1 算過 、 給出 ,把它代進 ,兩項恰好相消(推導放在展開框)。
展開細節一維代入驗證:p_t = N(0, σ²),σ² = e^(−2t),u = −x
記 p = (2πσ²)^(−1/2) exp(−x²/(2σ²))。先算對 x 的導數:∂ₓp = −(x/σ²)p,所以 ∂ₓ(u p) = ∂ₓ(−x p) = −p − x·∂ₓp = −p + (x²/σ²) p。 再算對 t 的導數。log p = −½ log(2πσ²) − x²/(2σ²),對 t 微分得 ∂ₜ log p = −½·(σ²)′/σ² + (x²/2)·(σ²)′/σ⁴。 代入 (σ²)′ = −2σ²:第一項是 1,第二項是 −x²/σ²,所以 ∂ₜ log p = 1 − x²/σ²,即 ∂ₜp = (1 − x²/σ²) p。 相加:∂ₜp + ∂ₓ(up) = (1 − x²/σ²)p + (−1 + x²/σ²)p = 0 ✓。
順帶一提,把 continuity equation 沿著一片葉子的軌跡展開(用全導數 d/dt p(x(t),t) = ∂ₜp + u·∇p,並注意 ∇·(pu) = u·∇p + p∇·u),會得到 d/dt log p(x(t),t) = −∇·u(x(t),t):跟著葉子走,密度的對數變化率就是 divergence 取負。這是 change of variables 裡 log|det ∇Φ_t| 的微分版本。
回到大廳:直覺對了,但它給的比你想的多
回到起點問題。「分佈被搬過去」是對的,而 continuity equation 告訴我們不追人也能算——只要 已知, 由一條 PDE 決定。它依賴的假設就兩個:質量守恆(人不會憑空消失;出口要另外當成「吸走質量」的邊界條件處理)、 夠 smooth(否則 divergence 沒定義,要退回集合版的 pushforward)。
但這條方程式還說了一件直覺說不出的事。給定一條分佈的路徑 ,產生它的 不唯一。設 滿足方程式,再任取一個 vector field 使 ,那麼 也滿足:
這樣的 有無限多個——例如任何讓 沿著等高線打轉的場(M2.1 最後一題的旋轉場就是一個)。人怎麼走,與人群的分佈怎麼變,是兩件不同的事:分佈只看得到淨流量,看不到人在同一密度的地方互換位置。反過來說,若你只關心 ,就有很大的自由去挑一個對你方便的 。
回到大廳:算一次,再弄壞一次
一維版本 可以用幾行程式往前解(有限差分,upwind 格式)。用 、 對答案:
import numpy as np
x = np.linspace(-4, 4, 801); dx = x[1]-x[0]; dt = 0.002
p = np.exp(-x**2/2)/np.sqrt(2*np.pi); u = -x
for _ in range(int(1.0/dt)): # 解到 t = 1
J = p*u # flux
dJ = np.where(u > 0, np.diff(J, prepend=J[0]),
np.diff(J, append=J[-1])) / dx # upwind 差分
p = p - dt*dJ
s2 = np.exp(-2.0) # 理論:N(0, e^{-2t})
print(np.abs(p - np.exp(-x**2/(2*s2))/np.sqrt(2*np.pi*s2)).max())
數值解與理論的 對得上(差距隨 、 縮小)。接著故意違反假設:把 換成在 跳躍的 (人流在中央分兩邊走)。divergence 在 沒定義,方程式在那裡不成立;數值解會在中央挖出一個越來越深的洞,而兩側各自被搬走——質量仍守恆,但「 是 smooth 密度」這件事壞了。
先消化一下
參考文獻
- Evans, L. C. Partial Differential Equations. AMS Graduate Studies in Mathematics 19, 2nd ed., 2010.(第 3 章:一階 PDE 與守恆律的基本理論。)
- Villani, C. Topics in Optimal Transportation. AMS Graduate Studies in Mathematics 58, 2003.(第 8 章:continuity equation 與 Benamou–Brenier 公式;pushforward 與 continuity equation 的等價在此脈絡下使用。)
- Ambrosio, L., Gigli, N., Savaré, G. Gradient Flows in Metric Spaces and in the Space of Probability Measures. Birkhäuser, 2nd ed., 2008.(第 8 章:continuity equation 的解與 flow map 的 pushforward 相同(superposition principle)。)