Tartalomjegyzék

Rövid Matlab segédlet

Anoním függvények (function handle)

Ha egy matematikai függvényt akarok deklarálni pl. $f(x,y) = x^2y + \sin(3x)\cos(y) + \frac{x}{x^2 + y^2}$, akkor azt megtehetem így:
function ret = csunya_nagy_fuggveny(x,y)
    ret = x.^2 .* y + sin(3*x).*cos(y) + x ./ (x.^2 + y.^2)
end
Majd egy scriptben meghívhatom ezt, valahogy így:
[x_num,y_num] = meshgrid(-1:0.01:1);
z_num = csunya_nagy_fuggveny(x_num,y_num);
surf(x_num,y_num,z_num)
Azt is megtehetem, hogy a függvényt átkeresztelem:
f = @csunya_nagy_fuggveny;
% ettől fogva `f` is meghívható (úgy viselkedik mint egy függvény handle)

[x_num,y_num] = meshgrid(-1:0.01:1);
surf(x_num,y_num,f(x_num,y_num))
De ha nem szeretnénk minden egyes ilyen aprócska matematikai függvény esetén külön file-ba irkálni, akkor az anoním függvények is nagyszerű szolgálatot tudnak biztosítani:
% Szintaxisa:
% [függvény neve] = @([változók]) [függvény definíciója]
f = @(x,y) x.^2 .* y + sin(3*x).*cos(y) + x ./ (x.^2 + y.^2);

[x_num,y_num] = meshgrid(-1:0.01:1);
surf(x_num,y_num,f(x_num,y_num))
Fontos, hogy elemenkénti műveleteket alkalmazzunk, mert az anoním függvények hívása esetén az x és y változók helyére lesznek majd behelyettesítve az esetünkben 2 dimenziós tömb típusú x_num és y_num változók értékei.

Szimboliks vs. numerikus számítás

Szimbolikus számításnak nevezzül pl. egy polinóm négyzetének kifejtését, egy $f(x,y,z)$ függvény gradiensének képletszerű kiszámítását, kb. azt, amit papíron ceruzával képesek vagyunk (néha azért nem) elvégezni. Numerikus számítás alatt azt értem, ha pl. egy $x(t)$ függvénynek az $[a,b]$ intervallumon vett integrálját az $x(t_k)$, $k\in\{0,...,n\}$ behelyettesítési értékei alapján közelítem, ahol $t_0 = a, t_n = b$, továbbá $n < \infty$. A Matlabban többnyire ezt tesszük:
% Az [a,b] intervallumot `n` egyenlő részre osztjuk.
n = 1000;

% Egy ilyen intervallum-szeletecske hossza (sampling time):
Ts = (b-a) / n;

% Ezen időpillanatokban mérjük $x(t) = x^2$ értékét:
t_num = linspace(a,b,n+1); % ez egy n+1 hosszú tömb lesz

% Így is megoldhatnám:
% x_num = t_num.^2;

% De inkább gyakoroljuk az anoním függvényeket:
x = @(t) t.^2;
x_num = x(t_num);

% Numerikus integrálás (legegyszerűbb módon, demonstrációs céllal csupán)
Int_ab_x = sum(x_num(1:n)) / Ts;

Szimbolikus objektumok

A beépített syms paranccsal lehet szimbolikus változókat létrehozni. Az expand, simplify, collect, stb... függvények segítségével lehet kedvünkre alakítani egy szimbolikus kifejezést.
>> syms x y a b real
>> r = [x,y];

% Legyen p(x,y) egy polinom (a,b paraméterek)
>> p = (x + a)^5 + (x + b + y)^3

% p =
%
% (b + x + y)^3 + (a + x)^5

% Fejtsük ki a ezt a zárt alakot
>> p = expand(p)

% p =
%
% a^5 + 5*a^4*x + 10*a^3*x^2 + 10*a^2*x^3 + 5*a*x^4 + b^3 + 3*b^2*x + 3*b^2*y + 3*b*x^2 + 6*b*x*y + 3*b*y^2 + x^5 + x^3 + 3*x^2*y + 3*x*y^2 + y^3

% Csoportosítsuk monomok szerint
>> p = collect(p)

% SAJNOS CSAK x-ek szerint csoportosította
% p =
%
% x^5 + (5*a)*x^4 + (10*a^2 + 1)*x^3 + (10*a^3 + 3*b + 3*y)*x^2 + (5*a^4 + 3*b^2 + 6*b*y + 3*y^2)*x + a^5 + b^3 + 3*b^2*y + 3*b*y^2 + y^3

% Csoportosítsuk az x és y-ban monomok szerint
>> p = collect(p,r)

% NO, ÍGY MÁR JÓ
% p =
%
% x^5 + (5*a)*x^4 + (10*a^2 + 1)*x^3 + 3*x^2*y + (10*a^3 + 3*b)*x^2 + 3*x*y^2 + (6*b)*x*y + (5*a^4 + 3*b^2)*x + y^3 + (3*b)*y^2 + (3*b^2)*y + a^5 + b^3
Legyen $f(r), r = \begin{bmatrix} x \\ y \end{bmatrix}$ egy vektormező, ami $a$, $b$ paraméterektől függ. Számoljuk ki a Jacobi mátrixát.
>> f = [ a*x^2 + b*a*x*y + a ; x*y + a*x ]

% f =
%
%  a*x^2 + a*b*y*x + a
%            a*x + x*y

>> Df = jacobian(f)

% SAJNOS a,b,x,y szerint számolta a Jacobi mátrixot
% Df =
%
% [ x^2 + b*y*x + 1, a*x*y, 2*a*x + a*b*y, a*b*x]
% [               x,     0,         a + y,     x]

>> Df = jacobian(f,r)

% NO, ÍGY MÁR JÓ
% Df =
%
% [ 2*a*x + a*b*y, a*b*x]
% [         a + y,     x]

>> pretty(Df)

% / 2 a x + a b y, a b x \
% |                      |
% \     a + y,       x   /

Szimbolikus változó behelyettesítése subs paranccsal

Adott egy $f(x,y)$ függvény, és $x = x(t)$. Fejezzük ki a $g(t,y) = \big[f(x,y)\big]_{x = x(t)}$ függvény alakját.

syms x y t real

f_xy = (sin(x) + cos(y) * x^2) / (x^2 + y^2 + 1);
x_t = (t+2) / (t^2 + 1);

pretty(f_xy)

%           2
% sin(x) + x  cos(y)
% ------------------
%      2    2
%     x  + y  + 1

pretty(x_t)

%  t + 2
% ------
%  2
% t  + 1

% Itt történik a mágia:
g_ty = subs(f_xy, x, x_t);

pretty(g_ty)

%                               2
%    /  t + 2 \   cos(y) (t + 2)
% sin| ------ | + ---------------
%    |  2     |        2     2
%    \ t  + 1 /      (t  + 1)
% -------------------------------
%                2
%         (t + 2)     2
%        --------- + y  + 1
%          2     2
%        (t  + 1)matlab_segedlet#

A matlabFunction parancs (kedvencem)

Ennek segítségével egy szimbolikus objektumot anoním függvénnyé tudunk alakítani:
>> f = x^2 + y^2 + sin(x)

% f =
%
% sin(x) + x^2 + y^2

>> f_fh = matlabFunction(f)

% f_fh =
%
%     @(x,y)sin(x)+x.^2+y.^2

>> [x,y] = meshgrid(1:3)

% x =
%
%      1     2     3
%      1     2     3
%      1     2     3
%
%
% y =
%
%      1     1     1
%      2     2     2
%      3     3     3

>> f_fh(x,y)

% ans =
%
%     2.8415    5.9093   10.1411
%     5.8415    8.9093   13.1411
%    10.8415   13.9093   18.1411
De ezzel a matlabFunction-al óvatosan kell bánni ám, mert ha nem specifikáljuk, hogy milyen változók szerint alakítsa anoním függvénnyé, akkor ezt saját tetszése szerint fogja majd tenni. Hozzunk létre egy $f(t,r,\theta)$ függvényt, ahol $r = \begin{bmatrix} x & y & z \end{bmatrix}^T$ és $\theta = \begin{bmatrix} a & b \end{bmatrix}^T$
>> syms x y z t a b real
>> f = x + y + z + t + a + b;
>> f_fh = matlabFunction(f)

% NEM KIFEJEZETTEN EZT SZERETTUK VOLNA ELERNI
% f_fh =
%
%     @(a,b,t,x,y,z)a+b+t+x+y+z

>> f_fh = matlabFunction(f, 'vars', {t,[x;y;z],[a;b]})

% NO, ÍGY MÁR MINDJÁ' MÁS!
% f_fh =
%
%     @(t,in2,in3)in3(1,:)+in3(2,:)+t+in2(1,:)+in2(2,:)+in2(3,:)

Szimbolikus függvények, vektoranalízis

A Matlab szimbólikus toolboxának segítségével ellenőrizni tudjuk a szorzásra vonatkozó deriválási szabályokat.

% Először deklaráljuk a szimbólikus objektumokat
syms x y z
f = sym('f(x,y,z)');
g = sym('g(x,y,z)');

F = [
    sym('F1(x,y,z)')
    sym('F2(x,y,z)')
    sym('F3(x,y,z)')
    ];

G = [
    sym('G1(x,y,z)')
    sym('G2(x,y,z)')
    sym('G3(x,y,z)')
    ];

r = [x;y;z];

% Feltételezzük, hogy minden szimbólikus objektum valós (nem komplex)
assume([F,G,f,g,r],'real')

% Gradiens, divergencia, rotáció, vektoriális szorzat műveletek
grad = @jacobian;
div = @(F) diff(F(1),x) + diff(F(2),y) + diff(F(3),z);
rot = @(F) -[
    diff(F(2),z) - diff(F(3),y)
    diff(F(3),x) - diff(F(1),z)
    diff(F(1),y) - diff(F(2),x)
    ];
cross = @(F,G) [
     F(2)*G(3) - F(3)*G(2)
     F(3)*G(1) - F(1)*G(3)
     F(1)*G(2) - F(2)*G(1)
     ];

% Végül a szabályok ellenőrzése, nullát kell kapjunk minden esetben
simplify(grad(f*g) - (f*grad(g) + g*grad(f)))
simplify(div(f*F) - (grad(f)*F + f*div(F)))
simplify(rot(f*F) - (cross(grad(f),F) + f*rot(F)))
simplify(div(cross(F,G)) - (G'*rot(F) - F'*rot(G)))

Egy megadott vektormező divergenciájának és rotációjának kiszámítása

F = [
    x^2*y
    y*z
    x*y*z^2
    ];

disp('div(F) = '), pretty(div(F))
disp('rot(F) = '), pretty(rot(F))

Output:

div(F) =
z + 2 x y + 2 x y z

rot(F) =
/    2     \
| x z  - y |
|          |
|       2  |
|   -y z   |
|          |
|      2   |
\   - x    /