昨天的手寫字把等時性寫成 v ∝ L^s,結尾說明天接 Sigma-Lognormal。今天先只做它的最小單位:單一筆畫的對數常態(lognormal)速度曲線。結論先給:對數常態的兩個時間參數裡,μ 管筆畫的時間尺度、σ 管形狀的不對稱,於是昨天的等時性可以精確改寫成「字放大 λ 倍,D 乘 λ、μ 加 (1−s)·ln λ、σ 不變」。s = 0.75 時放大一倍,μ 只加 0.173,峰值速度乘 1.68。這是恆等式,我用數值驗過(峰值比 1.6818,時間比 1.1892,各與 2^0.75、2^0.25 吻合)。但實作上有一個大陷阱:起始時間 t0 與 σ 的估計值相關係數高達 0.97,t0 設錯 50 毫秒,σ 就低估 13%,而且誤差棒還縮小到看起來很準。

昨天待辦的對帳:Lacquaniti、Terzuolo 與 Viviani 1983 年的原文我今天又搜了一次,仍然只找到引用它的文章,沒有全文,維持待辦。Raphaël 與 de Gennes 1999 年的原文今天沒碰,10-07 的墨膜實驗需要實際拍照,我做不了,也維持待辦。昨天的 iso.html 實測 s 同樣沒人跑過,所以今天沒有任何真人書寫資料,下面所有數字不是文獻(會標出處)就是我的合成資料模擬。

📖 學

一、單一筆畫的對數常態曲線

今天實際讀到全文的是 Plamondon 與 Alimi 1997 年《Behavioral and Brain Sciences》第 20 卷 279–349 頁的〈Speed/accuracy trade-offs in target-directed movements〉(Lehigh 大學網站的 PDF,我把它轉成文字後讀了第 38 至 47 式與幾則評論,不是全篇逐行讀)。他們的運動動力學理論(kinematic theory)把一次快速的定向動作看成激動肌與拮抗肌兩個神經肌肉系統同時在 t0 被啟動,各自的脈衝響應是對數常態曲線,速度是兩者的加權差(第 39 式):v(t) = D1·Λ(t; t0, μ1, σ1²) − D2·Λ(t; t0, μ2, σ2²)。其中單一對數常態是(第 40 式):

Λ(t) = 1 / (σ·√(2π)·(t − t0)) · exp( −[ln(t − t0) − μ]² / (2σ²) ),t > t0。

D 是指令幅度(它在一個主要脈衝裡約等於走過的距離,原文第 47 式寫 MA ≈ D1 − D2),t0 是指令時刻,μ 與 σ 原文叫「總對數延遲」與「對數反應時間」,屬於系統參數。為什麼會是對數常態:原文的假設(第 38 式)是系統由 n 級串接的元件組成,第 j 級的時間尺度與前一級成比例,T_j = (1 + ε_j)·T_(j−1),ε_j 各自獨立。時間尺度是連乘的,取對數就變連加,於是用中央極限定理類比,總響應的對數趨近高斯,也就是對數常態。這是「類比」,我下面會講它被批評的地方。

單一對數常態只有一個主峰,另一個拮抗項在這裡不討論。今天的分析一律只用單一項,筆畫的起、收都視為一次單脈衝,這是我為了今天的題目做的簡化,真的書寫資料常有第二個脈衝。

二、形狀由 σ 決定,和最小急動度的對稱鐘形比

對數常態有幾個封閉解:峰值發生在 t0 + e^(μ−σ²),平均時間在 t0 + e^(μ+σ²/2),偏度 = (e^(σ²) + 2)·√(e^(σ²) − 1)。因為曲線沒有有限終點,「動作時間」得自己定義,我取 1% 到 99% 面積的區間(即 μ ± 2.326σ 在對數時間上的範圍),這個窗口是我選的,不是文獻的定義。以 μ = 0、t0 = 0 算:

σ偏度峰值 / 窗口平均速度峰值落在窗口的位置
0.10.301.920.42
0.20.612.000.35
0.30.952.150.27
0.41.322.360.21
0.62.263.080.12
最小急動度01.8750.50

最小急動度的速度 v ∝ 30(τ² − 2τ³ + τ⁴),在 τ = 0.5 取峰值 30 × 0.0625 = 1.875 倍平均速度,左右對稱。σ = 0.1 時對數常態已幾乎對稱(1.92 對 1.875),σ = 0.3 時峰值提早到窗口的 27% 處,比平均速度高 2.15 倍。算例的驗算:σ = 0.3、μ = 0 時峰值 = 1/(0.3 × 2.5066 × 0.9139) × exp(−0.0081/0.18) = 1.455 × 0.956 = 1.391,窗口平均 0.98 ÷ 1.512 = 0.648,比值 2.146,與表一致。

Frontiers 2026 年有一篇 Assila、Braithwaite、Begon 與 Plamondon 的〈Interpreting the kinematic theory of rapid human movement as an optimal control theory〉,我只有抓取工具對它的整理,沒讀全文:測試的 σ 範圍是 0.1 到 0.6、μ 範圍 −3.0 到 1.5;一位受試者做 29 次快速伸臂,平均時間 0.74 ± 0.05 秒;結論是把時間納入急動度成本後,最佳 σ 會在生理範圍內出現,且複合成本函數比純最小急動度更接近對數常態的不對稱。上表 σ 的 0.1 到 0.6 就是照這個範圍取的。這篇是伸臂,不是寫字,所以只能當作「σ 在這個量級」的參考。

三、等時性在對數常態裡的精確寫法

對數常態有一條縮放性質:把 μ 加上 c,等於把整條曲線在時間軸上拉長 e^c 倍,同時高度除以 e^c(面積不變)。字放大 λ 倍,走的距離 D 乘 λ;若等時性 v ∝ L^s 成立,則動作時間乘 λ^(1−s),因此 μ 要加 (1−s)·ln λ,σ 不用動(形狀相似)。峰值速度 = λ ÷ λ^(1−s) = λ^s,與昨天的式子一致。

代數字:s = 0.75、λ = 2,Δμ = 0.25 × 0.693 = 0.173,時間乘 e^0.173 = 1.189(吻合昨天的 1.19),峰值乘 2 × 0.8409 = 1.682(吻合 2^0.75)。放大 4 倍:Δμ = 0.347(s = 1 時為 0,s = 0.5 時為 0.693)。這讓「等時性指數」有了第二種量法:不用算速度,直接比不同大小時的 μ 變化,Δμ = (1−s)·ln λ,反推 s = 1 − Δμ/ln λ。這是我的推導,前提是形狀相似、σ 與 t0 不隨大小變。

四、批評要記:這是描述模型,不是機制證明

原文後面附的評論,我讀到兩則重要的。Latash 與 Schöner 指出,從串接系統推導對數常態的過程有數學問題:時間尺度連乘取對數沒錯,但「串接」得到的是指數項的和,對數與和不能互換,所以推不出所宣稱的形式;他們並說模型把某個參數組合「叫做變異」,並沒有交代變異的來源。Gielen 則說中央極限定理只保證高斯分布,但高斯的平均與標準差由底層分布決定,這本身可以拿來檢驗;他並要求模型要能預測新實驗,不只是擬合舊資料。我的整理是:對數常態是一個擬合得很好的描述形式,「σ 與 μ 對應神經肌肉系統的哪個部分」仍是假設,不要把擬合出的 σ 當成生理量。

另有一點我要預先標明:arXiv 2401.16519(Ferrer 等人)我昨天只讀到摘要層級,它說 Sigma-Lognormal 是「虛擬目標點之間曲線的時間重疊」,並提出用其他分布(高斯、Beta、Gamma 等)取代對數常態。我沒有讀它的公式,今天沒用。

五、量測陷阱:t0 與 σ 的共線,以及用累積長度避開微分

先看共線。我模擬一條單一對數常態速度曲線:D = 1、t0 = 0.05 秒、μ = −1.0、σ = 0.3,100 Hz 取樣、0 到 1.5 秒,在速度上直接加標準差為峰值 5% 的高斯雜訊(這是簡化,真實雜訊來自位置而不是速度),重複 300 次,四個參數全自由擬合。結果 σ = 0.301 ± 0.026、μ = −0.999 ± 0.079、t0 = 0.049 ± 0.030,幾乎無偏,但 t0 與 σ 的相關係數 0.972、μ 與 σ 的相關係數 −0.971。三個參數其實是同一個自由度的三種說法:晚一點起跑(t0 大)可以靠更寬的 σ 與更小的 μ 補回來。

如果為了「穩定」把 t0 固定在 0(真值 0.05),結果是 σ = 0.262 ± 0.0046、μ = −0.875。σ 低估 13%,偏度從 0.95 掉到 0.82,但標準差縮成原本的六分之一,看起來更精確。固定一個錯的參數,是把偏差藏進誤差棒的典型做法。結論是 t0 一定要自由擬合,且要看三個參數的相關,單報 σ 的人要附上 t0 的來源。

再看微分。昨天的教訓是對含雜訊的座標微分會放大雜訊,所以今天的做法是不擬合速度,而是擬合累積路徑長:速度的對數常態積分是 S(t) = D·Φ((ln(t − t0) − μ)/σ),Φ 是標準常態累積分布(用互補誤差函數表示),整個流程不做任何微分。但昨天的另一個陷阱仍在:路徑長度會被座標抖動灌水。我模擬一條 100 像素長的直線筆畫(σ = 0.3、μ = −1.0、t0 = 0.04,時間戳記間隔隨機 8 到 12 毫秒),每次 200 重複,先用 Savitzky–Golay(視窗 9、三次)平滑座標再累加長度,最後擬合:

座標雜訊 SD占筆畫長擬合的 σ(真值 0.30)擬合的 D(真值 100)
0.3 像素0.3%0.309 ± 0.010100.5
1.0 像素1%0.365 ± 0.038105.6
3.0 像素3%0.64 ± 0.143147.7

雜訊只有筆畫長的 1% 時,σ 已偏高 22%;3% 時路徑被灌水約 48%,σ 完全不可信。這個表只在我的假設(單純高斯座標雜訊、直線、窗口 9)下成立,沒有量過真實觸控筆的雜訊。直線筆畫的另一個辦法是改用「投影到起訖點連線上的位置」代替累加路徑,理論上不受側向抖動影響,但我今天沒有測,不列為結論。

另一個容易誤解的地方:t0 是模型裡指令發出的時刻,不是筆尖開始動的時刻。我的合成資料裡 t0 = 0.04 秒,但紀錄從筆尖碰到畫面(累積長度約筆畫的 0.05%)才開始,第一個樣本比 t0 晚了約 0.18 秒,所以擬合出的 t0 相對於第一個樣本是負的(約 −0.14 秒)。看到負的 t0 不是程式錯了。

🧠 記

**一、單一對數常態:v(t) = D / (σ√(2π)(t−t0)) · exp(−[ln(t−t0) − μ]²/(2σ²)),**出自 Plamondon 與 Alimi 1997 第 40 式。峰值時間 t0 + e^(μ−σ²),偏度 (e^(σ²)+2)√(e^(σ²)−1)。σ = 0.3 時峰值是平均速度的 2.15 倍(最小急動度 1.875),峰值在 1%–99% 窗口的 27% 處(最小急動度 50%)。

**二、等時性的精確版(我推,形狀相似為前提):**字放大 λ 倍,D 乘 λ,μ 加 (1−s)·ln λ,σ 不變。s = 0.75、放大一倍:Δμ = 0.173、時間 × 1.189、峰值速度 × 1.682。

**三、量測:t0 必須自由擬合並看相關。**t0、σ 相關 0.97;t0 固定錯 0.05 秒,σ 從 0.30 變 0.26 且誤差棒縮成六分之一。用累積長度擬合避開微分,但座標雜訊占筆畫長 1% 就讓 σ 偏高 22%。

**邊界:**Plamondon 與 Alimi 1997 我讀的是 PDF 轉文字,只讀第 38 至 47 式與兩則評論;Frontiers 2026 與 arXiv 2401.16519 只有摘要層級;所有模擬是合成資料,雜訊是假設值;模型被批評是描述性而非機制性;只有單一脈衝,沒處理拮抗項與多筆畫的向量疊加。

✍️ 實踐

用 40 分鐘量自己「一長筆」的 σ 與 μ,需要昨天的 iso.html(它的輸出欄位就是 k,標籤,時間毫秒,x,y,d,不用改)與 scipy。

第一步,存成 ln_fit.py。這支我用合成資料測過:15 筆筆畫(長度 100、200、400 像素各 5 筆,真值 σ = 0.30、s = 0.75、座標雜訊 0.3 像素),算出 σ = 0.302 到 0.307、s = 0.74;沒有在真實筆跡或實機觸控筆上跑過。

import numpy as np, sys, csv
from collections import defaultdict
from scipy.optimize import curve_fit
from scipy.special import erfc
def sg(x, w, p):                              # Savitzky-Golay 平滑(0 階)
    h = w // 2
    C = np.linalg.pinv(np.vander(np.arange(-h, h + 1), p + 1, increasing=True))[0]
    return np.convolve(np.pad(x, h, mode="edge"), C[::-1], mode="valid")
def cdf(t, D, t0, mu, s):                     # 對數常態速度的積分 = 累積路徑長
    x = np.maximum(t - t0, 1e-9)
    return D * 0.5 * erfc(-(np.log(x) - mu) / (s * np.sqrt(2)))
strokes = defaultdict(list); cur = defaultdict(list)
for k, lab, t, x, y, d in csv.reader(open(sys.argv[1])):
    cur[(k, lab)].append((float(t), float(x), float(y)))
    if int(d) == 0:
        strokes[lab].append(cur.pop((k, lab)))   # d=0 是一筆的最後一點
out = defaultdict(list)
for lab, lst in strokes.items():
    for pts in lst:
        t, x, y = map(np.array, zip(*pts)); t = (t - t[0]) / 1000.0
        if len(t) < 15: continue
        w = min(len(t) // 2 * 2 - 1, 9); x, y = sg(x, w, 3), sg(y, w, 3)
        S = np.concatenate([[0], np.cumsum(np.hypot(np.diff(x), np.diff(y)))])
        T = t[-1]
        try:
            p, _ = curve_fit(cdf, t, S, p0=[S[-1] * 1.02, -0.1, np.log(T * 0.4), 0.3],
                             bounds=([S[-1] * .5, -0.5, -5, 0.05], [S[-1] * 1.6, 0.3, 2, 1.2]), maxfev=5000)
        except Exception: continue
        D, t0, mu, s = p
        q01, q99 = t0 + np.exp(mu - 2.326 * s), t0 + np.exp(mu + 2.326 * s)
        frac = (t0 + np.exp(mu - s * s) - q01) / (q99 - q01)   # 峰值落在「1%–99% 面積」窗口的位置
        out[lab].append((S[-1], D, t0, mu, s, frac))
print("%-8s %3s %8s %7s %7s %7s %8s" % ("標籤", "n", "路徑長", "t0(s)", "mu", "sigma", "峰值位置"))
rows = []
for lab in sorted(out, key=lambda l: np.mean([r[0] for r in out[l]])):
    a = np.array(out[lab]); m = a.mean(0); rows.append((m[0], m[3], m[4]))
    print("%-8s %3d %8.1f %7.3f %7.3f %7.3f %8.3f" % (lab, len(a), m[0], m[2], m[3], m[4], m[5]))
if len(rows) >= 2:
    (L1, m1, _), (L2, m2, _) = rows[0], rows[-1]
    print("最小到最大: 放大 %.2f 倍, mu 變化 %.3f  =>  s = 1 - dmu/ln(放大) = %.2f" % (L2 / L1, m2 - m1, 1 - (m2 - m1) / np.log(L2 / L1)))

第二步,寫字。用 iso.html,每次只寫「一長筆」,例如一條橫畫(漢字的「一」),盡量不停頓、不回鋒。三種長度約 2、4、8 公分,每種 5 次,共 15 筆,順序打散;「大小標籤」欄填 2cm、4cm、8cm。每寫完一筆按「下一次」。指示只有「用平常寫字的速度寫」。寫完存檔,執行 python3 ln_fit.py iso.csv。

第三步,判讀,對照下面三個預測。

預測一:σ 與大小無關。三種長度的 σ 平均值彼此差距在 0.03 以內(我模擬的每組 5 筆平均相差約 0.005,真人資料變異一定更大,所以放寬到 0.03 是我訂的)。若 σ 隨長度單調變化超過 0.05,形狀相似的前提失敗,等時性的 μ 位移式不能用。 預測二:Δμ = (1−s)·ln λ。2 公分到 8 公分是放大 4 倍,s = 0.75 對應 Δμ = 0.35,s = 1 對應 0,s = 0.5 對應 0.69。腳本最後一行會直接給 s,與昨天用速度斜率量到的 s 相比;兩個方法不該差超過 0.1,差更多,先懷疑路徑長被抖動灌水。 預測三:峰值位置。對數常態預測 σ 約 0.3 時峰值在窗口的 0.27 處,若你的筆畫擬合出的 σ 小於 0.1 且峰值位置聚在 0.5 附近,代表這種筆畫其實是對稱鐘形,最小急動度就夠用。

第四步,檢查品質:每組 5 筆的 σ 標準差若超過 0.05,多半是有筆畫中途遲疑或帶了回鋒;t0 若全部落在 −0.5 或 0.3 的邊界上,代表擬合撞牆,筆畫可能不是單脈衝(例如有明顯的二段式加速)。這兩種情況下,結果當作「模型不適用」記下來,不要硬報數字。

限制:一個人、一種裝置,螢幕上寫字與紙上不同;單一長橫畫比一般字簡單得多,多筆畫連寫的字需要 Sigma-Lognormal 的向量疊加,今天沒碰;累積路徑會被抖動灌水,座標雜訊超過筆畫長的 1% 就不要相信 σ。

🔗 延伸學習


💬 問 AI

我在學運動動力學理論(Plamondon 的 kinematic theory)的對數常態筆畫模型,請逐項回答,並嚴格區分三類:(一)原文明確寫了的、(二)你能查證或憑訓練資料確定的、(三)純屬推論的,每項標明把握程度(高/中/低);查不到或不確定就直說,不要編造文獻、數字或公式。這是學習與實驗設計。
 
【A 組:模型與文獻】
1. 我用 v(t) = D / (σ√(2π)(t−t0)) · exp(−[ln(t−t0) − μ]²/(2σ²)),峰值時間 t0 + e^(μ−σ²),偏度 (e^(σ²)+2)√(e^(σ²)−1)。請檢查這三條式子。
2. Plamondon 與 Alimi 1997(BBS 20:279–349)從 T_j = (1+ε_j)T_(j−1) 推出對數常態,Latash 與 Schöner 說對數與和不能互換、推導有問題。請說明誰對,以及現在文獻怎麼看這個推導。
3. Plamondon 後來有沒有對 σ 與 μ 給出生理對應(例如與肌肉或神經傳導時間的關係)?成人手寫的典型 σ 與 μ 範圍是多少?
 
【B 組:與等時性的關係】
4. 我推:形狀相似放大 λ 倍,若 v ∝ L^s,則 D 乘 λ、μ 加 (1−s)·ln λ、σ 不變。請檢查;文獻裡有沒有報告過 μ 隨大小的變化或 σ 隨大小不變?
5. 最小急動度(對稱)與對數常態(不對稱)在手寫筆畫的資料上,哪一個擬合更好?有沒有直接比較的研究?
 
【C 組:量測】
6. 我模擬:t0 與 σ 的擬合相關係數 0.97,t0 固定錯 0.05 秒使 σ 低估 13% 且誤差棒縮小。這個共線性合理嗎?常見的處理方式是什麼(例如固定 t0、提取起點的方法)?
7. 我用累積路徑長的對數常態 CDF 擬合避開微分,但路徑長被座標抖動灌水(雜訊占筆畫長 1% 時 σ 偏高 22%)。直線筆畫改用投影到起訖點連線的位置是否合理?觸控筆實際的座標雜訊量級是多少?
8. 多筆畫連寫時,Sigma-Lognormal 怎麼把多個向量化的對數常態疊加?怎麼決定筆畫數?
 
【D 組】
9. 把所有存疑項目分成三堆:(一)憑訓練資料就能判斷的、(二)必須查一手文獻的(請列出先查哪幾篇)、(三)必須用實際書寫資料才能回答的。