Sunteți pe pagina 1din 40

ELEMENTE DE SIMULARE NUMERICA

IN MATLAB
Curs 1
1
1. NOTIUNI DE BAZA
1.1. Numere reale si complexe.
Intrucat multimea R a numerelor reale este innita, iar orice cal-
culator are resurse nite, multimea R este reprezentata printr-o
submultime nita F de numere reale. Aceste numere, elemente
ale submultimii F se numesc numere in virgula mobila. Orice nu-
mar real x este in principiu trunchiat de calculator, dand nastere
unui nou numar (numit numar cu virgula mobila) care aprox-
imeaza pe x in engleza: oating point number.
In Matlab reprezentarea interna a numerelor este realizata cu
16 cifre zecimale. Modalitatea de asare a numerelor poate
schimbata cu ajutorul comenzii format. De exemplu:
2
1/7
ans = 0.1429
format long
1/7
ans = 0.14285714285714
format short; 1/7
ans = 0.1429
format short e; 1/7
3
ans = 1.4286e-001
format long e; 1/7
ans = 1.428571428571429e-001
Folosirea numerelor cu virgula mobila duce in unele cazuri la acu-
mularea unor erori de rotunjire semnicative si de aceea rezul-
tatele oferite de calculator trebuie, pe cat este posibil, supuse
analizei si vericarii.
4
Multimea numerelor complexe C cuprinde numerele de forma
z = x+iy. In Matlab variabilele i si j noteaza unitatea imaginara
(daca nu se atribuie lui i sau j alte valori).
Pentru a introduce un numar complex se scrie simplu z = x+iy,
sau se da comanda complex(x,y). In reprezentarea trigonomet-
rica a unui numar complex
z = e
i
= (cos +i sin)
avem ca este modulul lui z care se scrie abs(z), iar este
unghiul care se noteaza angle(z). Reprezentarea graca a unui
numar complex poate facuta cu comanda graca compass(z).
De exemplu
z=3+i*3; compass(z)
5
1
2
3
4
5
30
210
60
240
90
270
120
300
150
330
180 0
6
Partea reala, partea imaginara si conjugatul unui numar complex
z se obtin prin comenzile: real(z) , imag(z) , conj(z).
In Matlab toate operatiile se fac considerandu-se implicit ca nu-
merele sunt complexe. De aceea, daca vom calcula radacina
cubica a numarului -5, vom obtine rezultatul:
(-5)(1/3)
ans = 0.8550 + 1.4809i
Se ia radacina complexa pentru care unghiul este cel mai mic,
adica punctul z
2
din gura.
7
1.3 Matrices 9
Re(z)
Im(z)
z
1
z
2
z
3

8
1.2. Matrice si vectori
In Matlab se lucreaza foarte usor cu matrice. Ele se introduc
astfel
A=[1,2,3 ; 4,5,6] sau
A=[1 2 3 ; 4 5 6]
Matrice speciale: ones(m,n) , zeros(m,n), eye(m,n).
Operatii: A+B , A*B , A, A.*B , A.3 , ....
Alte comenzi: size(A), inv(A) , det(A) .
9
Vectorii sunt matrice care au o singura linie sau o singura coloana.
Daca se da un vector v, atunci comanda diag(v) produce o
matrice diagonala cu elementele lui v pe diagonala principala.
Mai general, prin comanda diag(v,m) se creaza matricea cu el-
ementele lui v pe supra-diagonala sau sub-diagonala numerotata
cu m.
Prin comenzile tril(A) si triu(A) se pot extrage matricea tri-
unghiulara inferioara, respectiv superioara, din matricea A de
dimensiune n. Mai general, putem folosi tril(A,m) si triu(A,m)
unde m este un numar intreg intre -n si n.
Daca w si v sunt doi vectori coloana, produsul lor scalar se poate
calcula prin expresia w*v.
Norma vectorului este data de comanda norm(v).
10
1.3. Functii reale
Consideram o functie reala oarecare f denita pe intervalul (a, b).
Sa vedem cum putem sa-i determinam comportarea, sa gasim
zerourile sale si sa calculam derivata si integrala ei.
Comanda fplot( fun, lims) traseaza gracul functiei fun (care
este data ca un sir de caractere) pe intervalul (lims(1), lims(2)).
De exemplu, pentru a trasa gracul functiei f(x) = 1/(1 + x
2
)
pe intervalul (5, 5), putem scrie:
fun=1/(1+x2); lims=[-5,5]; fplot(fun, lims);
sau mai scurt
fplot(1/(1+x2), [-5,5]);
11
5 4 3 2 1 0 1 2 3 4 5
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
12
Gracul este obtinut prin calcularea functiei intr-un numar de
abscise x (ne-echidistante) si reproduce gracul adevarat al lui f
cu o toleranta de 0.2% .
Pentru a imbunatati acuratetea gracului, putem folosi comanda
fplot(fun, lims, tol, n, LineSpec, P1, P2,...)
unde tol indica toleranta dorita, parametrul n stabileste ca gra-
cul va trasat prin cel putin n+1 puncte exacte (x, f(x)), iar
LineSpec indica tipul de linie folosita pentru trasare (intrerupta
- -, punctata : etc.). Parametrii P1, P2,... pot trecuti di-
rect functiei fun. Daca in locul variabilelor tol, n, LineSpec se
pune matricea vida ([ ]), atunci sunt utilizate valorile standard
predenite in Matlab.
13
Pentru a calcula valoarea unei functii fun intr-un punct x, putem
folosi comanda y=eval(fun), dupa ce am initializat in prealabil
variabila x.
Observatii: 1. Atat x cat si y pot vectori !
2. Cand folosim comanda eval , argumentul functiei fun trebuie
sa aiba neaparat numele x. Daca argumentul functiei are un alt
nume decat x, se poate folosi o alta comanda si anume feval.
fun=1./(1+x.2); x=[2,5,6]; y=eval(fun)
y = 0.2000 0.0385 0.0270
Uneori este util sa denim functii care sa poata avea un numar
variabil de argumente. In aceste situatii se foloseste variabila
varargin , care contine argumentele optionale ale functiei.
14
1.3.1. Zerourile unei functii
Ne intereseaza zerourile unei functii reale f , adica solutiile ale
ecuatiei f() = 0.
Daca f

() = 0, atunci solutia se numeste simpla, iar in caz


contrar ea este multipla.
Din gracul unei functii ne putem da seama (cu o anumita pre-
cizie) care sunt zerourile sale reale. In general, problema calcu-
larii zerourilor functiilor reale este dicila. Nu se poate preciza a
priori nici macar numarul zerourilor unei functii. Chiar si in cazul
polinoamelor de grad 5, nu se cunoaste o formula explicita
pentru determinarea radacinilor sale.
Pentru a calcula un zero al functiei fun , in vecinatatea unei val-
ori date x0 (reala sau complexa), Matlab ne pune la dispozitie
15
comanda fzero(fun, x0) . Ca rezultat obtinem o valoare aprox-
imativa a solutiei cautate si, de asemenea, intervalul in care s-a
efectuat cautarea.
Alternativ, putem folosi forma fzero(fun, [x0 x1]), prin care se
cauta solutia in intervalul [x0, x1], cu conditia ca functia sa isi
schimbe semnul intre x0 si x1.
Luam ca exemplu functia f(x) = x
2
1 +e
x
. Din grac ne dam
seama ca are 2 zerouri in (-1,1). Pentru a le calcula putem scrie
fun=x2-1+exp(x); lims=[-2,2]; fplot(fun, lims); grid on
fzero(fun, 1)
Zero found in the interval: [-0.28, 1.9051].
ans = 5.4422e-018 %Aproximare a lui 0
16
2 1.5 1 0.5 0 0.5 1 1.5 2
2
0
2
4
6
8
10
12
17
fzero(fun, -1)
Zero found in the interval: [-0.68, -1.2263].
ans = -0.7146
sau, alternativ,
fzero(fun, [-0.5 1])
Zero found in the interval: [-0.5, 1].
ans = 5.5265e-017 %Aproximare a lui 0
fzero(fun, [-1 -0.5])
Zero found in the interval: [-1, -0.5].
ans = -0.7146
18
1.3.2. Functii polinomiale
Functiile polinomiale sunt de forma
p(x) = a
n
x
n
+a
n1
x
n1
+... +a
1
x +a
0
, a
k
R, a
n
= 0.
Pentru lucrul cu functiile polinomiale exista un toolbox special in
Matlab, numit polyfun.
Comanda polyval se poate utiliza pentru a calcula valoarea unei
functii polinomiale intr-unul sau mai multe puncte.
y=polyval(p,x)
unde vectorul p contine coecientii polinomului in ordinea [a
n
, ..., a
1
, a
0
],
iar x este un vector de abscise.
Exemplu. Calculam valorile lui p(x) = x
7
+3x
2
1 in punctele
echidistante x
k
= 1 +k 0.25 pentru k = 0, 1, ...8.
19
p=[1 0 0 0 0 3 0 -1]; x=-1:0.25:1;
y=polyval(p,x)
y = 1.0000 0.5540 -0.2578 -0.8126 -1.0000 -0.8124 -0.2422
0.8210 3.0000
Amintim ca zerourile unei functii polinomiale se mai numesc si
radacinile polinomului. Pentru a calcula radacinile unui polinom
putem folosi comanda roots(p).
Exemplu. Radacinile polinomului p(x) = x
3
6x
2
+11x6 sunt
p=[1 -6 11 -6]; roots(p)
ans = 3.0000 2.0000 1.0000
Pentru a calcula produsul a doua polinoame P
1
si P
2
se foloseste
comanda p=conv(p1,p2), iar pentru a imparti polinomul P
1
20
la polinomul P
2
se scrie [q,r]=deconv(p1,p2). Aici p1 si p2
sunt vectorii coecientilor polinoamelor P
1
si P
2
, iar p reprezinta
produsul polinoamelor, q si r reprezinta polinomele cat si rest.
Exemplu. Fie polinoamele P
1
(x) = x
4
1 , P
2
(x) = x
3
1.
p1=[1 0 0 0 -1]; p2=[1 0 0 -1]; p=conv(p1,p2)
p = 1 0 0 -1 -1 0 0 1
[q,r]=deconv(p1,p2)
q = 1 0
r = 0 0 0 1 -1
Deci produsul este P(x) = x
7
x
4
x
3
+1, catul este Q(x) = x
si restul R(x) = x 1.
Prin integrarea sau derivarea unui polinom se obtin tot poli-
noame. Coecientii acestor polinoame se obtin prin comenzile
polyint(p) (calculeaza primitiva care se anuleaza in x = 0) si
respectiv polyder(p).
21
1.3.3. Derivarea si integrarea functiilor
Ne intereseaza calcularea derivatei si a integralei nedenite (prim-
itiva) ale functiilor reale.
Amintim ca orice functie f(x) de clasa C
n+1
intr-o vecinatate
a unui punct x
0
poate aproximata pe aceasta vecinatate cu
polinomul Taylor de grad n in punctul x
0
, care este denit de:
T
n
(x) = f(x
0
) +(x x
0
)f

(x
0
) +... +
1
n!
(x x
0
)
n
f
(n)
(x
0
).
Toolbox-ul symbolic din Matlab ne pune la dispozitie comenzile
di , int si taylor pentru a obtine expresia analitica a derivatei, a
primitivei si respectiv a polinomului Taylor pentru o functie data.
Astfel, dupa ce am denit sirul de caractere f pentru functia
asupra careia vrem sa operam, atunci di(f,n) ne da derivata de
22
ordin n . Comanda int(f) returneaza integrala nedenita,
iar taylor(f,x,n+1) ne da polinomul Taylor de grad n intr-o
vecinatate a lui x
0
= 0.
Variabila x trebuie declarata ca variabila simbolica prin comanda
syms x. Putem face calcule fara a preciza valoarea lui x.
Exemplu. Fie functia f(x) = (x
2
+2x +2)/(x
2
1).
f=(x2+2*x+2)/(x2-1);
syms x
di(f)
(2*x+2)/(x2-1)-2*(x2+2*x+2)/(x2-1)2*x
int(f)
x+5/2*log(x-1)-1/2*log(x+1)
taylor(f,x,6)
-2-2*x-3*x2-2*x3-3*x4-2*x5
23
Comanda funtool prezinta o interfata deosebit de utila pentru
manevrarea cu usurinta a functiilor simbolice arbitrare (v. g.).
funtool
Functiile pot introduse si prin comanda inline, cu sintaxa:
g=inline(expr, arg1,arg2,...,argn)
unde expr este un sir de caractere care contine expresia functiei
g, ce depinde de arg1, arg2,..., argn. Calculul valorilor functiei
intr-o multime de puncte se face folosind comanda feval.
Exemplu:
g=inline(sin(r), r); z=[0 1 pi/2];
y=feval(g,z)
y = 0 0.8415 1.0000
24
25
1.4. Tipuri de erori
In simularea numerica si calculul stiintic erorile sunt inevitabile.
Ele apar inca de la modul de reprezentare a numerelor reale in
calculator. Nu trebuie incercat sa eliminam erorile, ci sa m
capabili sa controlam efectul lor.
Erorile apar la mai multe niveluri atunci cand incercam sa re-
zolvam o problema concreta, zica (PP). Mai intai, putem vorbi
despre o eroare care apare atunci cand incercam sa descriem o re-
alitate zica printr-un anumit model matematic. Daca notam
cu x
ph
solutia problemei zice si cu x solutia problemei matem-
atice, atunci eroarea de modelare e
m
este data de diferenta
dintre x
ph
si x. Existenta si marimea unor astfel de erori va
restrange aria de aplicabilitate a diferitelor modele matematice.
26
Astfel, pentru a mentine eroarea e
m
mica trebuie sa alegem un
model matematic cat mai adecvat.
In al doilea rand, atunci cand incercam sa rezolvam problema
matematica (MP), observam ca in general solutia nu poate
gasita in forma explicita. De aceea se apeleaza la metode
numerice de rezolvare, prin care se obtin solutii aproximative.
Astfel, se introduce o problema numerica (NP) a carei solutie
x
n
difera de solutia x a problemei matematice printr-o eroare e
t
,
numita si eroare de trunchiere.
Rezolvarea problemelor numerice cu ajutorul calculatorului folosind
diversi algoritmi va introduce erori suplimentare (erorile de ro-
tunjire, de exemplu), pe care le vom nota e
a
. In urma intregului
proces numeric se obtine solutia aproximativa x.
Suma dintre erorile e
t
si e
a
reprezinta eroarea computationala
e
c
, pe care dorim sa o estimam (v. gura).
27
x
n
=

k
(t
k
)
k
x =
T

0
(t)dt
x
MP
PP
NP
x
ph
e
m
e
t
e
a
e
c
28
Eroarea computationala absoluta este diferenta dintre solutia
exacta x si solutia numerica aproximativa x, adica:
e
abs
c
= |x x| ,
iar eroarea computationala relativa este (pentru x = 0)
e
rel
c
= |x x|/|x| ,
unde | | noteaza modulul sau o alta masura a marimii, depinzand
de semnicatia lui x.
Procesul numeric este in general o aproximare a modelului matem-
atic obtinut ca o functie de un parametru de discretizare, care va
notat cu h (h > 0). Daca, atunci cand h 0, solutia numerica
tinde la solutia matematica exacta, procesul numeric se numeste
convergent.
29
De exemplu, atunci cand aproximam o integrala prin sumele Dar-
boux, parametrul de discretizare h este lungimea subintervalelor
de divizare.
Daca eroarea computationala (absoluta sau relativa) se exprima
ca o functie de h in forma
e
c
= C h
p
,
unde C este independent de h, iar p > 0, atunci spunem ca
metoda numerica este convergenta de ordin p.
Pentru a pune in evidenta ordinul de convergenta al unei metode
numerice, de multe ori se folosesc grace care reprezinta eroarea
computationala ca o functie de h, pe o scala logaritmica. Aceasta
inseamna ca pe axa absciselor se masoara log(h), iar pe axa
30
ordonatelor log(e
c
). Motivul acestei reprezentari logaritmice este
simplu:
e
c
= C h
p
log(e
c
) = log(C) +p log(h)
si deci ordinul de convergenta h va dat de panta dreptei log(e
c
).
In Matlab se obtin foarte usor gracele in scala logaritmica,
folosind comanda loglog(x,y) , unde x si y sunt vectorii ce contin
abscisele si ordonatele punctelor (v. gura).
De fapt, eroarea computationala nu este o marime care sa poata
calculata, intrucat ea insasi depinde de solutia problemei, care
este necunoscuta. Din acest motiv, este necesar sa se introduca
marimi calculabile ce pot folosite la estimarea erorii computa-
tionale, asa-numitii estimatori de eroare.
31
10
6
10
5
10
4
10
3
10
2
10
12
10
10
10
8
10
6
10
4
10
2
1
1
1
2
32
1.5. Costuri computationale
In general, o problema este rezolvata de calculator printr-un al-
goritm, care implica un numar nit de pasi.
Costul computational al unui algoritm este dat de numarul de
operatii in virgula mobila (oatingpoint operations) care sunt
necesare pentru executia algoritmului.
Cunoasterea exacta a numarului de operatii necesare pentru un
anumit algoritm nu este insa esentiala. Este important sa se
stie ordinul de marime al numarului de operatii, ca functie de un
parametru d ce este legat de dimensiunea problemei.
Se spune ca un algoritm are o complexitate constanta daca el
necesita un numar de operatii ce nu depinde de d, adica O(1) op-
eratii. Algoritmul are o complexitate liniara daca necesita O(d)
33
operatii, si mai general are o complexitate polinomiala daca
necesita O(d
m
) operatii, unde m este un intreg pozitiv.
Unii algoritmi pot avea complexitate exponentiala (O(c
d
) oper-
atii), sau chiar complexitate factoriala (O(d !) operatii).
(Reamintim ca n = O(d
m
) inseamna: n se comporta ca C d
m
,
pentru d sucient de mare).
Exemple. Algoritmul de calcul al produsului a doua matrice
patratice de ordin n (folosind denitia produsului) are o com-
plexitate de ordin O(n
3
) operatii.
Calcului determinantului unei matrice patratice de ordin n dupa
un algoritm ce foloseste formula recursiva a lui Laplace (dez-
voltarea dupa o linie) are o complexitate de O(n!).
34
Numarul de operatii nu este singurul parametru important in
analizarea unui algoritm. Un alt factor important este dat de
timpul necesar de accesare a memoriei calculatorului. Acest fac-
tor depinde de maniera in care a fost scris algoritmul pentru
calculator.
Astfel, un indicator al performantei unui algoritm este timpul
CPU (central processing unit), care poate obtinut prin co-
manda Matlab cputime.
t=cputime; ...(operatii algoritm)... ; cputime-t
Timpul total care s-a scurs pentru rularea unui program poate
obtinut prin comanda etime. Exemplu:
t0 = clock; ... operatii...; etime(clock,t0)
35
1.6. Programare in Matlab
Matlab pune la dispozitie si un limbaj special, in care utilizatorul
poate scrie noi programe. Acest limbaj contine instructiuni stan-
dard, cum ar instructiunile conditionale sau ciclurile (loops).
Instructiunea conditionala ifelseifelse are forma generala:
if conditie(1)
operatie(1)
elseif conditie(2)
operatie(2)
......
else
operatie(n)
end
36
In Matlab exista doua tipuri de cicluri repetitive (loops): cel care
utilizeaza for si cel care utilizeaza while.
Exemplu. Sa calculam primii 6 termeni ai sirului lui Fibonacci
denit recursiv prin: f
1
= 0, f
2
= 1, f
i
= f
i1
+f
i2
.
f(1)=0; f(2)=1;
for i=[3 4 5 6] %sau: for i=3:6
f(i)=f(i-1)+f(i-2);
end
Aternativ, putem scrie:
f(1)=0; f(2)=1; k=3;
while k<=6 (1)
f(k)=f(k-1)+f(k-2); k=k+1;
end
37
Programele scrise in Matlab trebuie salvate in siere cu extensia
.m, care se numesc siereM (Mle). Trebuie sa distingem
intre sierele script si sierele function.
Fisierele script contin o secventa de comenzi Matlab, care pot
utilizate interactiv. De exemplu, secventa (1) poate salvata
intr-un sier script, sub numele de bonacci6.m . Pentru a
lansa in executie, se da comanda
bonacci6
Fisierele de tip function sunt mult mai exibile. Pentru a deni
un sier de tip function, salvat cu numele generic nume.m, prima
linie a programului trebuie sa aiba forma
function [out1,out2,...,outn]=nume(in1,in2,...,inm)
unde in1,...,inm sunt variabilele de intrare, iar out1,...,outn
sunt variabilele de iesire.
38
Exemplu de program Matlab:
function det=det23(A)
%Calculeaza det. unei matrice patratice de dimensiune 2 sau 3
[n,m]=size(A);
if n==m
if n==2
det=A(1,1)*A(2,2)-A(1,2)*A(2,1);
elseif n==3
det=A(1,1)*det23(A([2,3],[2,3]))-A(1,2)*det(A([2,3],[1,3]))+...
A(1,3)*det23(A([2,3],[1,2]));
else
disp(Numai matrice 2x2 sau 3x3);
end
else
disp(Numai matrice patratice);
end
return
39
Comanda return se foloseste pentru a iesi din executia unui
program.
Prin comanda nargin se poate obtine numarul variabilelor de
intrare ale unui program. De exemplu,
nargin(det23)
ans = 1
Cu ajutorul comenzii help se pot obtine informatii despre toate
functiile predenite in Matlab.
40

S-ar putea să vă placă și