前言
有時候,你可能會遇到較復雜的方程(組),希望用MATLAB來求解。MATLAB的符號運算正好可用於求解方程(組)。此外,它還有許多其他功能。例如,展開和簡化、因式分解以及微積分運算等。MATLAB的符號運算雖然是數值運算的補充,但是它仍然是科學計算研究中不可替代的重要內容。與數值運算相比,符號運算不需要預先對變量賦值,其運算結果以標准的符號形式表達。比如說計算sin(π),數值運算的結果是1.2246e-16,符號運算的結果是0。前者是近似的,后者是精確的。
正文
MATLAB符號運算功能非常強大,本文只介紹大部分常用的符號運算功能。注:本文代碼的運行環境是MATLAB R2016b。
1. 創建符號數、符號變量和符號矩陣
這一步驟是符號運算的第一步,后面的步驟都是在此基礎上進行的。
%創建符號數 (只能用sym函數) s0 = 1 / sym(7) %符號數,不適合大型符號數 s1 = sym('1/7') %符號數 s2 = sym('3 + 4i') %符號復數 %創建符號變量 (sym函數和syms函數都行) %--sym函數 s3 = sym('x') %符號變量 %--syms函數 syms a b c %創建多個符號變量,值為本身 syms(sym('[d e; e d]')) %用已存在的符號變量矩陣創建多個符號變量 %創建符號矩陣 (sym函數和syms函數都行) s4 = sym('[2 5 6; 9 8 6]') %符號數矩陣 s5 = sym('x', [2 3]) %符號變量矩陣,矩陣內的元素不會被創建為符號變量 A = [a b c; c b a] %用已存在的符號變量創建符號變量矩陣 % syms A B [2 3] %僅2017及以上版本支持,同時創建多個符號矩陣
代碼運行結果如下。可以看到s5是一個2x3的符號變量矩陣,但矩陣內元素不會被創建成符號變量。

2. 創建符號表達式、符號函數
要表達一個數學函數可以用符號函數或符號表達式。
%創建符號表達式 syms x y f = x^2 + 5*x + 4 %符號表達式 subs(f, x, [2 1]) %分別將f中的x換成2和1
f2 = sym('x^2 + 2*x + 1 = 0') %創建方程 k = piecewise(x <= 0, x + y, x > 0, x - y); %分段符號表達式
%更多分段符號表達式/函數的介紹詳見:https://ww2.mathworks.cn/help/symbolic/piecewise.html#responsive_offcanvas %創建符號函數 %--用syms函數 syms G(x, y) F(z) %創建多個符號函數,變量名為括號前字母, 值為本身,其自變量也創建對應的符號變量 F(z) = z^2 + 5*z + 4 %符號函數 F([2 1]) %分別計算F(2)和F(1) G(x, y) = piecewise(x <= 0, x + y, x > 0, x - y); %分段符號函數,有多個條件用&&連接 %--用symfun函數 syms x y g = symfun(x^2 + y^2, [x y]) %因變量 = symfun(公式,[自變量1 自變量2]) g([2 3], [1 2]) %分別計算g(2, 1)和g(3, 2)
代碼運行結果如下。從圖中可以看出符號表達式與符號函數之間的區別,它們的類型不同,且計算函數值的方式的也不同。

3. 符號運算中的基本運算
符號運算是精確計算,不會產生截斷誤差。並且可以根據需要,給出完全的封閉解或任意精度的數值解。本節討論符號運算中的基本運算,可分為算術運算和關系運算。
3.1. 算術運算
數值運算中的一些運算符,例如‘+’、‘-’、‘*’、‘/’、’.*‘、’./‘、‘^’等,在符號運算中也可以使用。由於比較簡單,且和數值運算相同,這里不做展示。
3.2 關系運算
關系運算符在符號運算中也可以使用,包括’>‘、’>=‘、’<‘、’<=‘、’==‘、’~=‘等。但是,在符號運算中這些運算並不是用來做關系比較,而是通過這些關系運算符構建關系式,作為后續操作(例如,解方程)的限制條件。若要對兩個符號式做關系比較,可以使用函數isAlways、isequal或isequaln。
%關系運算 syms x assume(x > 2); %假設x是大於2的 solve((x + 1)*(x - 1)*(x - 2)*(x - 4)*(x - 6) == 0) %在設定的條件下,解方程 %函數isAlways、isequal以及isequaln %--isAlways:判斷兩個符號式構成的關系比較式的真假 A1 = [x, sym(9); 2*x^2, tan(x)]; B1 = [2*x, sym(6); x^2, sin(x)/cos(x)]; res1 = isAlways(A1 > B1) %對於數組情況,分別比較相應元素,結果為同等大小的logical數組 %--isequal和isequaln:都是判斷輸入的兩個符號式是否相等。但前者將NAN視為不相等,后者將NAN視為相等 A2 = [x+1, nan] B2 = [x+1, nan] res2 = isequal(A2, B2) res3 = isequaln(A2, B2) %對於數組情況,相應元素全部相等,返回1;反之,返回0
代碼運行結果如下。

4. 符號運算的主要功能
MATLAB符號運算提供了許多數學操作,例如解方程、微積分、線性代數運算、簡化、變換等。本節將簡單介紹微積分、解方程以及變換,更多詳細功能介紹請看官方幫助文檔。
4.1 微積分
微積分是數學中非常重要的分析工具。MATALB提供了許多微積分的相關操作,這里簡單介紹求極限、微分以及積分。詳細功能見微積分幫助文檔。
%求極限 syms x f1 = limit((exp(x) - 1) / x, x, 0) %計算x逼近0時,f的雙向極限值 %微分 syms x y f2 = diff(sin(x*y), x, y) %f先對x求導,再對y求導 %積分 syms x y f3 = x / (y^2 + 1); res1 = int(f3, x) %f關於x的不定積分 res2 = int(f3, x, 1, 3) %f關於x在[1, 3]上的定積分 %changeIntegrationVariable函數:換元積分法 %integrateByParts函數:分部積分法
代碼運行結果如下。

4.2 解方程
利用MATALB可以求解多種方程(組),例如線性方程、非線性方程、微分方程等。詳見方程求解幫助文檔。
%線性方程:所有未知數都是一次的。可用矩陣形式表示。(用linsolve) syms x y z eqns = [x+y-2*z == 0, x+y+z == 1, 2*y-z == -5]; [A, b] = equationsToMatrix(eqns) %將線性方程轉為矩陣形式 X = linsolve(A, b) %linsolve函數的參數是矩陣形式的線性方程 %非線性方程:(用solve函數或vpasolve函數) %--求解析解 syms x y eqns = [2*x^2 + y^2 == 0, 2*x - y == 4]; [solx soly] = solve(eqns, [x y]) %--求數值解 syms x eqn = x^6 - x^2 == 2; s1 = vpasolve(eqn, x) %不指定求解范圍 s2 = vpasolve(eqn, x, [-3, 3]) %指定求解范圍 %常微分方程:未知函數是一元函數的微分方程稱作常微分方程 syms y(t) a b eqn = diff(y, t, 2) == 2 * a^2 * y; %二階常微分方程 diffY = diff(y, t); cond = [y(0)==b, diffY(0)==1]; %初始條件 ySol(t) = dsolve(eqn, cond)
代碼運行結果如下。

4.3 變換
傅里葉變換、拉普拉斯變換以及Z變換是數學中的常用變換,也是對於工科學生很重要的變換。MATLBA為上述變換都提供了相應的函數來實現。下面開始介紹這些函數的簡單使用,每個變換的定義不進行說明,詳細說明見變換函數的幫助文檔。
%傅里葉變換 syms t f = cos(2 * t); f_FT = fourier(f) %傅里葉變換 f_IFT = ifourier(f_FT) %傅里葉逆變換 % fourier(f, y) %指定變換變量,默認是w % fourier(f, t, y) %指定自變量和變換變量,默認自變量可以用symvar查看 %拉普拉斯變換 syms t f = 2 * t; f_LT = laplace(f) %拉普拉斯變換 f_ILT = ilaplace(f_LFT) %拉普拉斯逆變換 % laplace(f, y) %指定變換變量,默認是s % laplace(f, t, y) %指定自變量和變換變量 %Z變換 syms n z f = sin(n); f_ZT = ztrans(f) %Z變換 f_IZT = iztrans(f_ZT) %逆Z變換 % ztrans(f, y) %指定變換變量,默認是z % ztrans(f, t, y) %指定自變量和變換變量
代碼運行結果如下。

5. 繪圖
對於前面提到的符號表達式、符號方程、符號函數等,MATLBA提供了豐富的繪圖函數來繪制它們。這些圖可以是2D或3D形式的直線、輪廓線、曲面或網格。甚至,還可以創建動畫圖。下面展示2D和3D形式的曲線圖,更詳細說明見繪圖幫助文檔。
syms x fplot(tan(x) * sin(x)); %2D曲線 syms t xt = exp(-t/10).*sin(5*t); %參數方程 yt = exp(-t/10).*cos(5*t); zt = t; figure fplot3(xt, yt, zt) %3D曲線
代碼運行結果如下。

