- MATLAB金融風險管理師FRM(高階實戰)
- 姜偉生 涂升 李蓉
- 1568字
- 2021-03-26 23:39:49
1.2 符號變量
MATLAB定義符號變量有兩個函數sym() 和syms()。比如下例,用sym() 創建x和y兩個符號變量,相應代碼如下:
x = sym('x'); y = sym('y');
syms() 也可以創建這兩個符號變量:
syms x y
另外,符號變量可以創建表達式。比如下例,首先創建a、b、c和x這四個符號變量,然后用它們構造一個一元二次多項式,并賦值給f。latex() 函數將f變成Latex字符串。symvar() 在表達式中查找符號變量。舊版MATLAB曾采用findsym()函數來查找符號變量,新版已經停止更新支持。
syms a b c x f = a*x^2 + b*x + c latex(f) % converted to a Latex string % 'a\,x^2+b\,x+c' symvar(f) % [ a, b, c, x]
除了簡單多項式,符號變量還能構造復雜符號多項式。比如下例,先構建了符號變量t,后定義f1和f2兩個三角函數,并且用expand() 展開。
syms t f1 = sin(2*t) expand(f1) % 2*cos(t)*sin(t) f2 = cos(2*t) expand(f2) % 2*cos(t)^2 – 1
sym()和syms()函數在定義符號變量時,還可以設置這些變量的假定條件,比如下例:
x = sym('x','real'); y = sym('y','positive'); z = sym('z','rational'); assumptions % [ in(x, 'real'), in(z, 'rational'), 0 < y] syms x y integer syms z rational assumptions % ans = % [ in(x, 'integer'), in(y, 'integer'), in(z, 'rational')]
另外,MATLAB有專門函數assume() 設置符號變量假定條件,assumeAlso() 追加假設條件,assumptions() 函數返回這些條件,比如下例:
%% multiple assumptions syms x assume(x > 5) assumeAlso(x < 10) % assume(x>5 & x<10) assumeAlso(x,'integer') assumptions % [ in(x, 'integer'), 5 < x, x < 10]
通過如下代碼給x設置若干假設。
assume(in(x,'integer') & x>2 & x<10)
配合solve() 函數,下例測試假設條件。
syms x assume(x/2,'integer') solve(x>0,x<10,x) % ans = % % 2 % 4 % 6 % 8 assume((x-1)/2,'integer') solve(x>0,x<10,x) % ans = % % 1 % 3 % 5 % 7 % 9
如下代碼清除有關x的所有假設條件。
assume(x,'clear')
表1.4給出了利用assume() 函數設定符號變量假定條件的一些例子。
表1.4 用assume() 給符號變量假設條件

另外,whos() 函數把workspace當前變量列出來,比如下例:
clc; clear all; syms a x b = 2; c = 1; f = a*x^2 + b*x + c latex(f) % converted to a Latex string % 'a\,x^2+b\,x+c' symvar(f) % [ a, b, c, x] whos
運行代碼,函數whos() 得到結果如下:
ans 1x2 8 sym b 1x1 8 double c 1x1 8 double f 1x1 8 sym x 1x1 8 sym
與普通運算相比較,MATLAB符號運算一般較慢。請大家比較下列加法運算時間:
a = 1/2; b = 1/3; c = sym(a); d = sym(b); tic a + b toc tic c + d toc
新版MATLAB sym()函數不再支持表達式輸入,比如f1 = sym('x + 1')在新版MATLAB不合法。解決這個問題有如下幾種方式。第一種方法是先用syms定義符號變量x,然后再定義函數,即:
syms x f1 = x + 1
或者:
syms f1(x) f1(x) = x + 1;
再或者:
f1 = sym('x') + 1;
加、減、乘、右除(forward slash, /)、左除(backward slash, \)和乘冪均可用在符號表達式上。
f1 + f2 % x^3 + 2*x^2 + 2*x + 2 f1 - f2 % x^3 f1*f2 % (x^2 + x + 1)*(x^3 + x^2 + x + 1) f1/f2 % (x^3 + x^2 + x + 1)/(x^2 + x + 1) f1\f2 % (x^2 + x + 1)/(x^3 + x^2 + x + 1) f1^2 % (x^3 + x^2 + x + 1)^2
MATLAB函數numden() 提取符號數值和表達式中的分子(numerator)和分母(denominator),比如下面三個例子:
[n, d] = numden(sym(4/5)) % n = 4 % d = 5 syms x y [n,d] = numden(x/y + y/x) % n = x^2 + y^2 % d = x*y f = (x^2 + 1)/(x + 1) + x/(x - 1); [n,d] = numden(f) % n = x^3 + 2*x - 1 % d = (x - 1)*(x + 1)
compose() 函數構造復合函數。例如下面兩個函數:

如下代碼定義上式:
syms x y t f = 1/(x + 1); g = sin(y);
compose(f, g)將返回復合函數f(g(?))。

如下代碼構造上式。
f1 = compose(f,g) % returns f(g(y)) where f = f(x) and g = g(y) % f1 = 1/(sin(y) + 1)
compose(f, g, t)則返回復合函數f(g(t))。

如下代碼構造上式。
f2 = compose(f,g,t) % returns f(g(z)) % f2 = 1/(sin(t) + 1)
compose()函數的更多用法請參考鏈接:
https://www.mathworks.com/help/symbolic/compose.html
函數finverse()用來求解反函數,比如下例:
syms x f(x) = 1/tan(x); g = finverse(f) % g(x) = atan(1/x)
本叢書經常用matlabFunction() 把符號表達轉換成函數句柄,比如函數:

下例用matlabFunction() 將符號表達式轉換為函數句柄cone() 和quadratic()。
syms a b c x y f1 = sqrt(x^2 + y^2); cone = matlabFunction(f1) % @(x,y)sqrt(x.^2+y.^2) cone(1,1) f2 = a*x^2 + b*x + c quadratic = matlabFunction(f2) % f2 = @(a,b,c,x)c+b.*x+a.*x.^2 % anonymous function quadratic(1,1,1,1) % 3 quadratic(1,1,1,sym('x')) % x^2 + x + 1
更多有關matlabFunction() 函數的用法,請參考鏈接:
https://ww2.mathworks.cn/help/symbolic/matlabfunction.html
MATLAB提供solve() 求解符號方程解。請讀者注意,新版本的solve() 已經不再支持字符向量或字符串輸入,比如solve('x^2 -1')或solve('x^2 -1 = 0')或solve('x^2 -1 = 0', 'x')均不合法。
比如求解如下一元二次方程:

可這樣使用solve()函數:
syms x eqn = x^2 + x - 2 == 0 S = solve(eqn)
結果如下:
S = -2 1
又如,求解符號一元二次方程:

以下代碼求解該一元二次等式:
syms a b c x eqn = a*x^2 + b*x + c == 0 S = solve(eqn)
結果如下:
S = -(b + (b^2 - 4*a*c)^(1/2))/(2*a) -(b - (b^2 - 4*a*c)^(1/2))/(2*a)
請讀者注意,solve() 默認以x為未知量。而solve(eqn, a)則會以a為未知量,比如下例:
syms a b c x eqn = a*x^2 + b*x + c == 0 S = solve(eqn, a)
結果如下:
S = -(c + b*x)/x^2
solve()函數還可以用于求解方程組,比如如下二元一次方程組:

求解代碼如下:
syms x y eqns = [x + y == 1, 2*x - y == 5]; vars = [x, y]; [sol_x, sol_y] = solve(eqns,vars)
結果如下:
sol_x = 2 sol_y = -1
solve() 函數也可以這樣用:
S = solve(eqns,vars) S.x S.y
solve()函數的更多用法,請參考鏈接:
https://ww2.mathworks.cn/help/symbolic/solve.html
本叢書中經常使用MATLAB函數subs(),它將符號或數值代入符號表達式,如以下幾個例子:
syms x y a b subs(x + y, a) % ans = % a + y subs(x + y, x, a) % ans = % a + y subs(x + y, y, a) % ans = % a + x subs(a + b, a, 4) % ans = % b + 4 subs(a*b^2, a*b, 5) % ans = % 5*b