Sunteți pe pagina 1din 19

1

LUCRAREA 12

Depanarea i optimizarea programelor MATLAB.

Pe parcursul conceperii i implementrii unui program MATLAB
se pot face o serie de erori. Primul tip de erori cu care ne ntlnim este cel
al erorilor sintactice, adic nu respectm regulile stabilite n MATLAB
pentru expresii,funcii i celelalte componente ale limbajului. Prezentm
trei dintre cele mai des ntlnite:
- Punerea greit a paranteze;or n expresii. E exemplu:

>> 3/(2+3))
??? 3/(2+3))
|
Error: Unbalanced or misused parentheses or brackets.

La sfritul expresiei a fost pus o parantez n plus. De remarcat modul
cum semnaleaz MATLAB erorile sintactice prin scrierea
atenionrilor cu culoare roie.
- Nescrierea,omiterea unui operator:

>> x=2;
>> 5*(4+2x)
??? 5*(4+2x)
|
Error: Missing MATLAB operator.

n exemplul de mai sus apare eroarea cea mai des ntlnit omiterea
operatorului nmulire *.
- Scrierea incorect a numelui variabilelor, a funciilor, etc.

>> 1+2*sinx
??? Undefined function or variable 'sinx'.
Eroarea const n scrierea incorect a funciei sin x. n MATLAB toate
funciile au argumentul scris ntre paranteze rotunde. Deci corect este
sin(x).
2
Erorile sintactice sunt uor de depistat pentru c ni le semnaleaz
MATLAB. Un program nu este executat de MATLAB pn cnd nu mai
are nici o eroare sintactic.
Odat lansat n execuie un program MATLAB poate depista o
alt clas de erori numit erori de execuie. Exemplul tipic este
mprirea cu 0. i alte tipuri de funcii i operaii pot duce la rezultate
nedorite: NaN, Inf sau empty matrix:

>> x=-2:0.1:2;
>> y=x;
>> [x,y]=meshgrid(x,y);
>> z=x.*sin(y)./(x.^2-y.^2);
Warning: Divide by zero.

Eroare provine din faptul c atunci cnd x=y n calculul lui z
apare o mprire cu 0. n Ex.5 de la Lucrarea 9 am artat cum se rezolv
astfel de erori: In acest caz definim variabila aayy=x
@
- y
2
i apoi dm
comanda:
>> xxyy=xxyy+(xxyy==0)*eps
ce va introduce valoarea foarte mic eps n locul elementelor nule. Deci
secvena corect este:

>> x=-2:0.1:2;
>> y=x;
>> [x,y]=meshgrid(x,y);
>> xxyy=x.^2-y.^2;
>> xxyy=xxyy+(xxyy==0)*eps;
>> z=x.*sin(y)./xxyy;

n sfrit programul funcioneaz fr erori. Dar dac totui nu
obinem rezultatul dorit?!! Cauza este c am dat peste cea de-a treia
categorie de erori , i anume erorile logice. Sunt cele mai greu de depistat
erori pentru c MATLAB nu se ocup de logica programului. Logica
programului este un lucru ce ine numai de cel ce programeaz. Erorile
logice pot fi prevenite i depistate mai uor dac respectai cteva reguli
nescrise ale programrii. n primul rnd programul trebuie conceput
modularizat. Aceasta nseamn s descompunei programul n module ce
vor deveni funcii sau scripturi. Trebuie testat fiecare modul n sensul
verificrii faptului c la nite date de intrare modulul livreaz napoi date
de ieire corecte. Alte reguli ar fi urmtoarele:
3
1. F un test cu un set de date iniiale pentru care rezultatele finale i
unele rezultate intermediare sunt cunoscute i compar cu ce ai
obinut.
2. Pentru a vedea unele rezultate intermediare care ar fi utile n
depanare anuleaz ; de la sfritul liniei comenzii pentru a vedea
imediat rezultatul comenzii. (Lucru nerecomandabil n mod
obinuit).
3. Adaug comenzi care s listeze unele variabile cheie dar i locul n
program unde au fost listate (poate ulterior au fost modificate).
4. Utilizeaz comanda keyboard care oprete execuia programului i
d controlul tastaturii ceea ce permite s dm o comand de
vizualizarea a oricrei variabile dorite.
5. Utilizeaz pentru programele mari utilizai comenzile funciei
debugger din fereastra edit. Acest mod presupune o oarecare
experien n programarea n MATLAB
Observaie. Toate recomandrile de mai sus duc la ncetinirea
substanial a execuiei programului i trebuie nlturate dup depanare.
Am corectat erorile sintactice, i cele de execuie, i cele logice i n
sfrit programul face ce trebuie s fac. Totui nu suntem mulumii.
Timpul de rulare este neateptat de mare. Trebuie s mbuntim
performana programului, s-l optimizm. Pentru msurarea timpului de
execuie avem comenzile tic i toc. Definii scriptul rxtictoc dat de:
tic
t=1;
for i=1:10000000
t=(t+i)/t;
end
t
toc
Dac-l punem n execuie obinem (pentru un P4 cu 1GB DDR400):
>> rxtictoc
t =
3.162777778741289e+003
Elapsed time is 0.297000 seconds.
Vom prezenta cteva tehnici de reducere a timpului de execuie a
programelor MATLAB.
A. Vectorizarea. Sub acest nume sunt cunoscute metodele prin care
anumite operaii se execut asupra ntregii matrici i nu element cu
element. De exemplu nmulirea element cu element a unei matrici se
poate face individual sau printr-o singur comand: Definim scriptul inm
de mai jos:
4


Lansm in execuie scriptul inm:

>> A=ones(1000,1000);
>> B=A;
>> inm
Elapsed time is 0.031000 seconds.
Elapsed time is 0.063000 seconds.

Se observ c timpul de execuie vectorizat este mult mai mic. Este util
s utilizm vectorizarea i n cazul funciilor. Scriptul vecsin este un
exemplu simplu cu rezultatele:

>> t=0:0.01:100000;
>> i=0;
>> vecsin
Elapsed time is 4.453000 seconds.
Elapsed time is 4.719000 seconds.

Iar scriptul este:
5


n afara execuiei mai rapide vectorizarea are i avantajul scrierii unui
numr mai mic de comenzi (anse mai mici de eroare) i al creterii
claritii programului.
Observaie. Performanele codrii nevectorizate au crescut mult la
versiunea MATLAB6.5(r13) i mai ales la versiunea MATLAB7(r14).
De aceea n exemplele de mai sus diferenele de timp sunt mult mai mici
dect la versiunile anterioare. Totui diferena n favoarea vectorizrii
exist plus celelalte avantaje.
B. Funcii build-in. Este bine s utilizm funcii built-in, adic deja
existente dect s definim noi o funcie. Am mai vorbit n Lucrarea 9
despre calculul factorialului. S vedem acum ct dureaz calculul lui 70!.
Scriptul de execuie este:

>> n=70;
>> testfb
Elapsed time is 0.000000 seconds.
Elapsed time is 0.016000 seconds.
Elapsed time is 0.016000 seconds.

Scriptul testfb i funcia fact:
6




7
Se remarc primul timp pentru gamma(71) foarte mic. Timpul pentru
prod(1:70) este egal cu cel pentru funcia noastr fact dar mcar nu am
scris dect comanda de apel.
C. Prealocarea. Este esenial pentru performan s prealocm
matricile (mai ales cele mari). Astfel dac ele for fi create element cu
element MATLAB va mri dimensiunile noii matrici la fiecare calcul. n
plus exist riscul ca matricea creat sa nu ocupe un spaiu continuu n
memorie ceea ce duce evident la scderea vitezei de acces. Vom msura
timpii pentru ambele situaii. Matricea B este creat n scriptul preal1:



Testul n MATLAB este:
>>k=10000;
>>n=1000;
>> A=floor(k*rand(n,n));
>> [r,c]=size(A);
>> preal1
Elapsed time is 14.234000 seconds.
>> B=zeros(r,c); % Aici prealocm B
>> preal1
Elapsed time is 0.297000 seconds.
8
Se observ timpul substanial mai mic n cazul prealocrii. Primele trei
comenzi arat cum se creeaz o matrice de ordin n cu numere ntregi
aleatoare pe intervalul [0, k].
D. Accesarea indexat. Dei este considerat de unii drept principala
component a vectorizrii, considerm c merit o prezentare special. n
esen accesarea indexat nlocuiete cutarea elementelor matricii A ce
verific o anumit condiie cu expresia A(condiie) ce livreaz un vector
ce conine toate elementele ce verific aceast condiie.. Dup cum am
mai exemplificat i n lucrrile anterioare A(A>0) va livra un vector ce
are ca elemente elementele pozitive ale lui A. n exemplul urmtor ne
propunem s calculm suma elementelor mai mari dect 5 ale unei
matrici A. Scriptul suma5 va face acest lucru cu i fr indexare i
compar timpii de calcul:



Executm scriptul suma5:
>> A=floor(10*rand(10000,1000));
>> [r,c]=size(A);
>> suma5
ans =
29986704
9
Elapsed time is 0.578000 seconds.
s =
29986704
Elapsed time is 0.922000 seconds.
Se observ faptul c timpul de calcul este substanial redus prin
accesarea indexat.

Aplicaii

1.Scriei exact aa cum este scris scriptul supr1, apoi depanai-l :

x=-2:0,2:2;
y=(6-x)./(3-x;
(x,y)=meshgraid(x,y);
z=(x.^2+y.^2)/(x*y);
Surf(x,y,z)

2.S se determine matricea alab ale crui elemente sunt obinute din
elementele a doi vectori a i b astfel: fiecare element al lui a este ridicat
la puterea fiecare element al lui b. De exemplu dac a=[1,2] i b= [2,3],
atunci alab va fi
1 1
3 3
1 2
1 2
alab

=


, adic:
1 4
1 8
alab

=



3. Tips and tricks. Sub acest nume n informatic se nelege mecheria,
trucul cu care obinem mai rapid o soluie. In acest punct de vedere
vectorizarea pare c face parte din aceast categorie.
a) Cum definim o matrice a crui elemente sunt egale cu un numr dat.
Da-ti cel puin dou soluii.
b) Cum obinem un vector a crui elemente sunt n ordine invers cu cele
ale unui vector dat? Da-i o soluie cu bucl i una vectorizat.
c) Cum definim o matrice de tip mXn cu coloane identice cu un vector
dat? Dai cel puin dou soluii.

4.Vectorizarea buclei for cu if. Deseori prelucrarea elementelor unei
matrici conduce l dou bucle for mbricate (pentru a accesa elementul) i
un if pentru prelucrare:
for i=1:r
for j=1:c
if cond
prelucrare1 a(i,j);
10
else
prelucrare2 a(i,j);
end
end
end
De exemplu pentru condiie avem a(i,j)>5, iar prelecrare 1 poate fi
a(i,j)=a(i,j)=5, iar prelucrare 2 : a(i,j)=-a(i,j).
Cum se scrie aceast secven fr nici un for i fr if?

5. S se scrie o funcie indlinie care are ca parametru de intrare o matrice
Iar ca parametru de ieire o matrice cu acelai numr de linii i cu dou
coloane ce va conine indicii primului element nenul al fiecrei linii din
matricea iniial. Matricea de ieire va avea mai puine linii dac n
matricea de intrare exist linii numai cu 0. ncercai s determinai i o
form vectorizat a funciei.

6. S se creeze o funcie vectz care are ca parametru de intrare un vector,
x, iar ca parametru de ieire un vector y de aceiai lungime ca i x, a;e
crui elemente nenule sunt aceleai ca elementele corespunztoare din x,
iar n locul elementelor nule se pune valoarea elementului nenul anterior.
Astfel dac x=[1 3 0 0 0 4 5 0 0 6 0 7] atunci y=[ 1 3 3 3 3 4 5 5 5 6 6 7].
Se va presupune c x are ntotdeauna primul element nenul.


Indicaii

1.Erori sintactice:
Linia 1 col. 7 se pune punct n loc de virgula zecimal (notaia
american);
Linia 2 col .14 parantez nchis;
Linia 3 col. 3 paranteze ptrate pentru parametrii de ieire;
Linia 3 col. 7 funcia meshgraid inexistent (este meshgrid);
Linia 4 col. 14 operaia de mprire cu punct;
Linia 4 col. 18 operaia de mprire cu punct;
Linia 5 col. 1 - funcia surf cu litera s mic;
Erori de execuie:
Linia 4 - mprire cu 0;

2. Este clar c alab va fi o matrice cu numrul de linii egal cu lungimea
lui b iar numrul de coloane egal cu lungimea lui a. se pot face dou
11
bucle for imbricate pentru determinarea elementelor lui alab. Aceasta
este forma clasic a programrii. MATLAB are funcia meshgrid ce
transform vectorii n matrici i care poate fi utilizat.

3. a) O soluie ar fi utilizarea lui ones(n,m). O alt soluie ar fi utilizarea
funciei repmat(A,n,m) care repet o matrice A de n ori pe linie i de m
ori pe coloan.
b) Definim o bucl n care primul element al noului vector s fie egal cu
ultimul element al celui dat, al doilea element al noului vector s fie egal
cu penultimul element al celui dat, . a. m. d. pentru vectorizare putem
utiliza adresarea cu operatorul :.
c) Fiind vorba de o matrice o vom crea cu dou bucle for mbricate.
Exist i forme vectorizate ale scriptului bazate pe concatenare i
operatorul : sau repmat.


4. Se va utiliza accesarea indexat.

5. Prelucrarea obinuit a elementelor unei matrici cu dou bucle for i
un if ca la Ex. 4 anterior se complic prin faptul c apare o condiie n
plus (aceasta este prelucrarea doar a primului element din linie). Cum
MATLAB memoreaz matricile pe coloan vectorizarea acestei
probleme trebuie altfel gndit (dac este posibil)..Pentru prelucrarea cu
for-if este necesar un semnal care s ne spun c pentru linia n execuie
am gsit deja primul element. Pentru matricea y de ieire este necesar un
indice de lucru special ce trebuie incrementat cu 1 la fiecare memorare de
indici.

6. Este necesar o variabil n care s memorm pe parcursul unei
prelucrri cu o bucl for ultimul element nenul. Aceast variabil trebuie
iniializat cu valoarea primului element din x (presupus nenul).
Varianta vectorizat se bazeaz pe urmtoarele observaii. S
presupunem c avem vectorul x=[x1,x2,0,0,x3,0,x4] i putem obine
vectorul diferenelor elementelor nenule consecutive
xdcons=[x1,x2-x1,0,0,x3-x2,0,x4-x3],
atunci vectorul soluie
vsol=[x1,x2,x2,x2,x3,x3,x4]
se obine prin aplicarea funciei cumsum asupra lui xdcons. Funcia
cumsum(x) creeaz un vector ce are pe poziia k suma elementelor lui x
de la 1 la k, adic pentru vdcons de mai sus
x1 deci x1
12
x1+(x2-x1) deci x2
x1+(x2-x1)+0 deci x2
x1+(x2-x1)+0+0 deci x2
x1+(x2-x1)+0+0(x3-x2) deci x3
x1+(x2-x1)+0+0(x3-x2)+0 deci x3
x1+(x2-x1)+0+0(x3-x2)+0+(x4-x3) deci x4.


Soluii

1.


13


2.

14


Execuia:
>> a=1:10000;
>> b=1:20;
>> alab1
Elapsed time is 2.516000 seconds.
>> alab2
Elapsed time is 0.250000 seconds.
Se remarc timpul mult mai mic al scriptului vectorizat.

3. a) Presupunem c t este constanta egal cu toate elementele i n i m
dimensiunile matricii. Putem da oricare din comenzile:
>> A=k*ones(n,m);
Sau
>>A=k; A=repmat(A,n,m);
b) O bucl for rezolv problema:
for i=1:length(v)
w(i)=v(length(x)-i+1);
end
Vectorul w va conine elementele lui v n ordine invers. Vectorial:
W=v(end:-1:1)
15
Iat o utilizare interesant a lui end.
c)Presupunem c avem vectorul coloan v de dimensiune m. Atunci
putem creaa matricea M astfel:
for i=1:m
for j=1:n
M(i,j)=v(i);
end
end
Variantele vectorizate sunt:
N=v(:,ones(n,1))
Sau
O=repmat(v,1,n)

4. Scriptul iniial este forcuif :



Scriptul cu indexare fararor:
16


Funcia indlinie nevectorizat este:

17
Iar funcia vectorizat indliniv este:


Punerea n execuie:
>> A=[ 0 0 1 ;0 1 0 ;0 0 1 ;1 1 2 ;0 2 1 ; 0 0 0 ;0 0 2 ];
A =
0 0 1
0 1 0
0 0 1
1 1 2
0 2 1
0 0 0
0 0 2
>> y=indlinie(A)
y =
1 3
2 2
3 3
4 1
5 2
7 3
>> y=indliniv(A)
18
y =
1 3
2 2
3 3
4 1
5 2
7 3
Pe fiecare linie a lui y prima valoare este linia , iar a doua valoare este
coloana elementelor cutate

6. Funcia vectz (cu bucla for cu if) este:




Funcia vectorizat (cu funciile fiind, diff i cumsum) este:
19


Punerea n execuie:
>> x=[1 3 0 0 0 4 5 0 0 6 0 7] ;
>> vectz(x)
ans =
1 3 3 3 3 4 5 5 5 6 6 7
>> vectzo(x)
ans =
1 3 3 3 3 4 5 5 5 6 6 7
Aceast problem 6 este un exemplu c uneori vectorizarea este complex
i nu aduce avantaje deosebite.