MATLAB Symbolic Math Toolbox

Symbolic Math Toolbox 是MATLAB進行符號運算的工具箱,其符號運算引擎是MuPAD,具有比較強大的符號計算功能。但與專業的符號運算軟件Mathematics比較,還是有欠缺,具體的比較不在本文考慮範圍。


符號變量及普通變量的差別

符號變量是一個精確的值,而普通的變量是一個近似數值。比如在 matlab 中運行如下代碼:

sin(sym(pi))
sin(pi)

第一個是符號變量,第二個是普通的變量,結果的差別非常明顯。


sym 及 syms 函數

matlab 中使用 sym 以及 syms 函數來定義符號變量,比如使用

x = sym('x');
syms x

來定義符號變量 x,兩種方法是等價的。我比較喜歡第二種,可以簡便地定義多個符號變量,如

syms x y z

但在定義一個符號常數時,一般使用 sym 函數,比如

f = sym(5)

此外,還可以定義符號函數變量,如 (記得清除已定義的 f 變量)

syms x y a b
f(x,y) = sin(x) + y
f(a,b)  %將符號變量 a,b 代入 f 的表達式

符號運算

符號運算大概包括加減乘除、微積分、多項式運算、解方程和一些特殊的函數運算等等。這裏主要介紹微積分、簡單代數方程的求解以及一些特殊運算。

微積分

主要是 diff 和 int 函數。
1.diff 函數:

syms x y
f = sin(x) + cos(y)
diff(f)      %對 x 求偏導
diff(f,x)    %對 x 求偏導
diff(f,x,3)  %對 x 求三次偏導
diff(f,y)    %對 y 求偏導

2.int 函數

syms x y
f = sin(x) + cos(y) 
int(f)           %對 x 積分
int(f,x)         %對 x 積分
int(f,y)         %對 y 積分
int(f,x,[0,1])   %對 x 求定積分,上下限分別爲 0 和 1

多次求導以及多重積分就是對 diff 以及 int 函數的嵌套重複使用。
關於變分下次另開專題,先給自己立個flag。

解代數方程

求解代數方程主要就是使用 solve 函數,例子如下:

syms x
f = x^2-1 == 0
solx = solve(f)

syms x y a
[solx,soly] = solve(x^2*y^2 == 0, x-y/2 == a)

此外重要的是 assume 函數的使用,這一函數可以對符號變量進行限制假定,例如:

syms x
solve(x^7 + 2*x^6 - 59*x^5 - 106*x^4 + 478*x^3 + 284*x^2 - 1400*x + 800, x)

assume(x > 0)
solve(x^7 + 2*x^6 - 59*x^5 - 106*x^4 + 478*x^3 + 284*x^2 - 1400*x + 800, x)

兩次的結果是不一樣的,可以看到第二次的結果 x 都大於 0,滿足了對 x 的假設。清楚對 x 的假設應該使用下述代碼:

assume(x,'clear')

此外第二個方程也可用如下形式:

solve(x^7 + 2*x^6 - 59*x^5 - 106*x^4 + 478*x^3 + 284*x^2 - 1400*x + 800, x>0)
特殊的函數

一些常用的函數列舉如下:

---------------------------------------------------------------------------
syms x y
f = x^3 + 2*x^2 - x^2 + y^4
simplify(f) %化簡表達式
---------------------------------------------------------------------------
syms x
expand((x - 2)*(x - 4)) %展開表達式
---------------------------------------------------------------------------
syms x
F = factor(x^2-1)   %因式分解
---------------------------------------------------------------------------
pretty(F)   %使表達式顯示好看點,但在新版本的 matlab 中,使用 Live Scripts 可以顯示更加符合數學書寫習慣的表達式
---------------------------------------------------------------------------
syms x
taylor(exp(x))  %泰勒級數,最高階爲5,可以使用'order'選項修改
taylor(sin(x))
taylor(cos(x))
---------------------------------------------------------------------------
syms x
f = sin(x)/x
limit(f,x,0)    %求 x->0 時的極限
---------------------------------------------------------------------------
syms t
f = exp(-t^2)
ft_f = fourier(f)   %傅里葉變換
---------------------------------------------------------------------------
syms w
F = exp(-w^2/4)
ifourier(F) %傅里葉逆變換
---------------------------------------------------------------------------
syms x
f = 1/sqrt(x)
laplace(f)  %拉普拉斯變換
---------------------------------------------------------------------------
syms x y z
f(x, y, z) = 1/x + y^2 + z^3
L = laplacian(f, [x y z])   %求標量函數的拉普拉斯

最後一個是關於卷積的,只是從 Github 上覆制來的代碼,原網址在這裏

function c = symconv(a, b)
    % In short, this function takes a sym, returns a sym (usually)
    %
    % Convolve two symbolic expressions, a and b.
    %
    % Author: Edward Peguillan III
    % Date: 12 April, 2016, 21:49 UTC
    %
    %                 DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
    %                     Version 2, December 2004
    % 
    %  Copyright (C) 2016 Ed Peguillan III <[email protected]>
    % 
    %  Everyone is permitted to copy and distribute verbatim or modified
    %  copies of this license document, and changing it is allowed as long
    %  as the name is changed.
    % 
    %             DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
    %    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    % 
    %   0. You just DO WHAT THE FUCK YOU WANT TO.
    %

    % If u and v arent of class sym, then get out
    is_a_sym = isa(a, 'sym'); is_b_sym = isa(b, 'sym');

    if (isa(a, 'sym') + isa(b, 'sym')) < 2
        error('Input to symconv must be (sym, sym), not (%s, %s).', ...
            class(a), class(b));
    end

    var = symvar(a);
    if(var ~= symvar(b))
        error('Input to symconv must be functions of the same variable.');
    end

    syms tau real;

    % By the definition of convolution:
    atau = subs(a, var, var - tau); % transform all to the tau axis
    btau = subs(b, var, tau); % give one the t-tau
    c = int(atau * btau, tau, -inf, inf);

    % Preemptively repair dumb expressions:
    c = rewrite(c, 'heaviside');
    c = rewrite(c, 'exp');
end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章