兩個方向,兩種難度
到這裡你已經掌握了本級的精神:電腦代數系統用精確的符號來計算,而不是用近似的數字,所以它的答案不帶捨入誤差,真正的敵人不是誤差而是表達式膨脹。微積分正是這份精神最閃耀的舞台,因為在這裡,機器能做到數值方法根本做不到的事——直接還你一條公式。求 x^3 的導數,你拿到的不是「在 x=2 處約為 12」,而是精確的函數 3*x^2,一次就在每一點都成立。這就是符號微積分的承諾,而它清楚地裂成兩半,脾性截然不同。
微分是溫馴的那一半。導數由一小組封閉的規則定義——冪法則、乘積法則、商法則、連鎖法則——而關鍵在於,每條規則都是組合性的:整體的導數,是由各部分的導數機械地組裝出來。沒有需要靈光一閃的抉擇,也沒有會讓你掉進去的死胡同。餵進任何初等表達式,吐出來的是有限、可預測的一番記帳功夫。這正是為什麼微分從不像積分那樣讓學生吃驚。
積分是狂野的那一半。沒有倒著跑的連鎖法則,沒有組合性的食譜,而且——這部分讓每個人都吃驚——有些看來人畜無害的初等函數,其原函數根本不是初等的。exp(-x^2)(鐘形曲線的核心)的積分,就是無法用多項式、根式、指數、對數與三角函數的任何有限組合寫出來。這不是我們不夠聰明,而是可以證明:它的初等形式根本不存在。所以符號積分的深層問題,不只是「把答案找出來」,而是更奇怪的「判定這一類的答案究竟存不存在」。
微分:照本宣科、精確,卻悄悄會爆炸
讓我們看看容易的那一半怎麼運作,因為即使在這裡,也有一個誠實的轉折值得認識。要對一個符號表達式微分,系統會由上而下走訪它的樹,每個節點套用一條規則,並向子節點遞迴。乘積節點觸發乘積法則;複合節點觸發連鎖法則;像 x 或常數這樣的葉節點,導數只有一行。這個遞迴一定會終止,因為每一步都剝掉一層,所以整個過程保證會結束——符號微分真的沒有卡住的可能。
diff( f(x) * g(x) ) -> diff(f)*g + f*diff(g) (product rule) diff( f(g(x)) ) -> diff(f)(g(x)) * diff(g) (chain rule) diff( x ) -> 1 diff( constant ) -> 0 The product rule turns ONE node into a SUM of TWO products, each still containing a near-copy of f and g.
這裡就是上一篇講膨脹時許諾的那個誠實轉折,現在說具體了。仔細看乘積法則:它把單一的乘積節點變成兩個乘積的和,而那兩個各自仍帶著 f 與 g 的近似副本。對一個有 n 個因式的長乘積微分,未經整理的原始結果就有約 n^2 個項;再微分一次,又進一步膨脹。像 (x^2 + 1)^10 * sin(x) 這樣的課本函數,導出來的導數是對的,但在化簡之前視覺上像個怪物。所以連溫馴的那一半也會孳生表達式膨脹——答案是精確的,但可能巨大地抵達,馴服它的代價落在化簡上,而不在微分本身。
把積分當成一個判定問題
現在來談深的那一半。在 1960 年代以前,電腦做符號積分是一袋啟發式招數——試試這個代換、跟一張表做模式比對、嘗試分部積分,若全都不行,就放棄並回報「找不到答案」。最後那則訊息令人不滿,因為它含糊:是原函數不存在,還是程式只是沒找到一個確實存在的?一袋小把戲永遠分不清這兩者,而正是這份含糊,讓這個問題感覺像門藝術,而非科學。
看待積分的正確方式,是把它當成一個判定問題,而這個重新框定,正是整場思想上的躍進。先把「初等」的意思釘死——你能從有理函數出發,用有限次的加、乘、除、開根、取指數與取對數所建出來的函數(三角函數透過複數,其實是喬裝的指數)。於是問題變得鋒利:給定一個初等函數 f,是否存在一個初等函數 F,使得 F'(x) = f(x)?一個真正的演算法必須回答「是,連同公式」,或一個確定且可證的「不」——而絕不是含糊的「我找不到」。
這是一個截然不同的抱負。完整解決一個判定問題,意味著每當答案是「不」時,你都要證出一個不存在性結果——你得排除每一個可能想像得到的初等原函數,而不只是你碰巧試過的那些。這件事居然辦得到、初等可積性這個問題居然是可判定的,正是二十世紀數學一項安靜的勝利。這就是「一個會許多積分的聰明學生」與「一個知道積分可能性邊界的定理」之間的差別。
Risch 演算法:判定那看似不可判定的
把積分變成一個判定程序的那件工具,就是 Risch 演算法,由 Robert Risch 於 1969 年發表。它的主導想法既優美又出人意料:把 f 中已經出現的那些函數所組成的「域」,建成一座一層層的塔,每一層在底下的有理函數之上,再添一個新的指數或對數。接著證明一個結構定理——如果初等原函數真的存在,它必定就住在大致同一座塔裡,至多容許多一個對數,而且只能添入特定的新常數。原本感覺無限大的搜尋空間,突然被釘死成一個有限、可描述的形狀。
- 建塔。用一串固定的積木把 f 表達出來——先是 x,再層層疊上指數與對數,把每個新層當成一個坐在底下代數之上的新變數。這就記下了你正在積分的函數究竟是「哪一類」。
- 套用結構定理。它保證任何初等原函數都是同一座塔的成員,外加至多一組對數的常數倍之和——於是未知的 F 有一個已知的模板,裡頭只剩有限個未知零件。
- 化約成代數。把模板對 f 做符號微分來比對;比對條件會塌縮成「解出未知係數的多項式與有理方程組」——正是前幾篇講最大公因式與葛羅布納基底所為你預備好的那種工作。
- 判定。若那些方程有解,就把它組裝成原函數 F 回傳——精確、保證正確(你可以微分回去驗證)。若可證明它們無解,就回傳一個確定的「不」:f 沒有初等原函數,而這是一個定理,不是聳聳肩。
這就是為什麼一個真正的系統能確定地告訴你 exp(-x^2) 沒有初等原函數——它不是放棄,而是跑完了判定、證出了那個否定。第三步對多項式機制的倚賴並非偶然:那些有理與多項式方程,正是用上一篇的多項式最大公因式與因式分解工具去解的,這也是為什麼葛羅布納基底與最大公因式是符號微積分底下的基岩,而不是旁枝末節。
這給你帶來什麼,以及該記住什麼
退一步,去感受那份不對稱。微分容易到我們把它當機械練習丟給大一學生;積分難到「判定它」需要一個深刻的域論定理,以及在問題終於被正確提出之後又花上的十年工夫。這道鴻溝不是課本偷懶——它是關於這兩個運算的真實結構性事實,而正面迎上它,是電腦代數真正的樂趣之一。
也別忘了那道反覆出現的陰影:就算答案存在,它也可能膨脹著抵達。一個不起眼的被積函數,原函數印出來可能填滿一整頁,而 Risch 程序內部的中間表達式在抵消之前甚至更龐大。這把你直接繞回整級的主題——符號方法精確,卻不隨規模擴張,而表達式膨脹正是「拒絕做捨入」所付的代價。本級最後一篇就把這個限制當成標題:為什麼精確計算儘管美麗,卻撞上一面牆,而近似計算只是繞了過去。
那麼,到底什麼時候該動用符號微積分?當你需要那條公式時——一條要代進穩定性分析的導數、一個定積分所需的精確原函數、一個能讓你讀出結構的封閉形式——而且當表達式小到能保持理智時。一旦你只需要一個數字、一個又快又準的數字,數值方法就在速度與穩健上勝出:數值微分與數值積分在幾微秒內給你一個近似答案,而符號路線可能給你一個像電話簿那麼厚的精確答案,或者根本給不出來。知道自己身處哪條車道,就是全部的本事。