Sunteți pe pagina 1din 13

Programare în MATLAB

Se descrie limbajul propriu MATLAB şi modul de a scrie programe (script-uri)


şi subrutine, proceduri (funcţii).

Cuprins
Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Utilizarea efectivă a script-urilor . . . . . . . . . . . . . . . . . . . . . 2
Funcţii şi spaţiul de lucru . . . . . . . . . . . . . . . . . . . . . . . . . 3
Condiţionale: if şi switch . . . . . . . . . . . . . . . . . . . . . . . . . 4
Cicluri for şi while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Debugging şi profiling . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Function handles şi funcţii anonime . . . . . . . . . . . . . . . . . . . . 8
Subfuncţii şi funcţii imbricate . . . . . . . . . . . . . . . . . . . . . . . 10
Erori şi avertismente . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Argumente de intrare şi iesire, precizări suplimentare . . . . . . . . . . 12

Introducere
Un fişier M este un fişier text ce conţine comenzi MATLAB şi care are tipul .m .
Există două tipuri, script şi function. MATLAB are încorporat un foarte bun
editor, el se poate lansa din meniu sau tastând edit . Totuşi, utilizatorul poate
utiliza orice editor de texte. Pentru a putea fi executat, un fişier M trebuie salvat
pe calea curentă (path). Calea este o listă de directori (foldere) în care MATLAB
caută fişiere. Utilizaţi addpath sau meniuri pentru a vizualiza sau modifica
calea. Nu este nevoie să compilăm un fişier M. Pentru execuţie este suficient să
tastăm numele fişierului (fără extensie). Modificările care sunt salvate pe disc
vor fi luate în considerare la urmatorul apel al funcţiei sau script-ului. Un tip
important de instrucţiune într-un fişier M este comentariul, indicat printr-un
semn procent %. Orice text din linia curentă situat după semnul procent este
ignorat, exceptând situaţia când el este parte a unui şir de caractere. Mai mult,
primul bloc contiguu de comentarii dintr-un fişier M serveşte ca documentaţie
pentru fişier şi va fi afişat în fereastra de comandă dacă se dă help pe fişier. De
exemplu, să presupunem că textul de mai jos este salvat în fişierul cu numele
myscript.m pe calea curentă:

%Un exemplu aiurit


%de fişier .m
x = rand(1); % oare ce face?
%

Apoi, la prompter se obţine

1
help myscript

Un exemplu aiurit
de fisier .m

Este firesc şi recomandabil să se includă o scurtă descriere şi informaţii de


sintaxă in documentaţia propriilor dumneavoastră funcţii.

Utilizarea efectivă a script-urilor


Conţinutul unui script este interpretat ca şi cum ar fi introdus după prompter.
De fapt este de preferat să se utilizeze MATLAB exclusiv prin introducerea
comenzilor în fişiere script şi apoi execuţia lor. Această tehnică face mai uşor
de creat şi revizuit o secvenţa care are mai mult de câteva linii şi vă ajută să
documentaţi şi să urmariţi paşii mai târziu. De asemenea, se pot crea script-
uri din liniile pe care deja le-aţi introdus selectându-le din fereastra Command
History de pe desktop şi dând click dreapta pe ele.
O altă utilizare interesantă a script-urilor este publicarea lor ca fişiere HTML
(pagini Web) sau în alte formate disponibile. Acesta este un mod comod de
a crea rapoarte şi documentaţii pe baza rezultatelor MATLAB, deşi suportul
pentru formule şi expresii matematice este limitat. La publicarea unui script,
blocurile de linii de comentariu apar ca text obişnuit, iar codul şi rezultatele
de ieşire sunt formatate. Pentru a obţine cele mai bune rezultate utilizaţi doua
semne procent (%%) la începutul unei linii pentru a crea margini de celule.
Aceste margini cauzează crearea ieşirilor inainte ca urmatorul bloc de comen-
tarii, cod şi ieşiri să înceapa. Ca exemplu, vezi script-ul hilbpub.m

%%
% A Hilbert matrix has entries that are reciprocals of
% integers.
%%
%
% $$H=(h_{ij}), h_{ij}=\frac{1}{i+j-1}$$
%
format rat
H = hilb(4)
%%
% Although the inverse of a Hilbert matrix is difficult
% to find numerically by Gaussian elimination, an explicit
% formula is known.
invhilb(4)
%%
format short e
H*ans

se va publica aproximativ în modul urmator: Hilbert publish

2
În plus, celulele vă permit să creaţi secţiuni cu titluri şi cu cuprinsuri (table
of contents) cu hyperlink-uri. Editorul propriu al MATLAB este cel mai bun
mod de a publica script-uri. El va ajută să creaţi celule, să lucraţi cu ele,
să evidentiati cu claritate marginile de celule şi titlurile şi să publicaţi şi să
vizualizaţi rezultatele cu bătaie de cap minimă. Ca regulă utilă, apelati script-
urile doar din linia de comandă şi nu apelaţi alte script-uri dintr-un script.
Pentru a scrie programe mai mari şi a rezolva subproblemele într-un cadru mai
larg, funcţiile sunt o alegere mai bună.

Funcţii şi spaţiul de lucru


Funcţiile şi script-urile grupează instrucţiuni MATLAB pentru a realiza sarcini
complexe. Caracteristica distinctivă cea mai importantă a unei funcţii este
spaţiul ei de lucru local (local workspace) . Orice variabile create în timpul
execuţiei funcţiei sunt disponibile numai acelui apel de funcţie (sunt câteva
excepţii, vezi variabile globale). Reciproc, variabilele disponibile la nivelul linie
de comandă – adică cele din spaţiul de lucru de bază ( base workspace ) nu
sunt în mod normal vizibile în interiorul funcţiei. Dacă funcţia mai apelează şi
alte funcţii, fiecare astfel de apel secundar va avea spaţiul său de lucru privat.
Aceste restricţii de acces se numesc restricţii de domeniu ( scoping ) şi ele ne
permit scrierea de programe complexe cu multe componente, fără a fi preocupaţi
de conflictele dintre numele de variabile. Variabilele din spaţiul de lucru curent
se pot vizualiza cu comanda whos, sau în fereastra Workspace de pe desktop. La
nivelul liniei de comandă spaţiul de bază este cel vizibil, dar în timpul depanării
funcţiilor se pot inspecta şi alte spaţii de lucru locale.
Orice funcţie începe cu o linie de forma

function [out1,out2] = myfun(in1,in2,in3)

Numele myfun trebuie să coincidă cu numele fişierului de pe disc. Variabilele


in1, etc. sunt argumente de intrare , iar out1 , etc. sunt argumente de
ieşire. Putem avea oricâte argumente de fiecare tip dorim (inclusiv niciunul) şi
să le denumim cum dorim. Teoretic, singurul mod de comunicare între spat, iul
de lucru al unei funcţii şi cel al apelantului este prin intermediul argumentelor
de intrare şi iesire, dar sunt şi excepţii. Valorile argumentelor de intrare ale unei
funcţii sunt copii ale datelor originale şi astfel orice modificare vom face asupra
lor nu se va modifica nimic din afara domeniului de vizibilitate al funcţiei. De
fapt, interpretorul MATLAB evită copierea argumentelor de funcţii, realizând
transmiterea prin referinţă, dacă funcţia nu alterează valoarea unui argument.
Mai mult, începând cu MATLAB 7.6, se poate forţa transmiterea prin referinţă
chiar şi pentru valori modificate, vezi help pe handle pentru detalii.
Iată un exemplu de funcţie didactică ce implementează formula de rezolvare
a ecuaţiei de gradul al doilea ax2 + bx + c:

function [x1,x2] = quadform(a,b,c)


d = sqrt(b^2 - 4*a*c);
x1 = (-b + d) / (2*a);

3
x2 = (-b - d) / (2*a);

(Trebuie menţionat că din punct de vedere numeric nu este un algoritm bun).


După salvarea acestui text în fişierul quadform.m de pe calea MATLAB pentru
apel se poate tasta

[r1,r2] = quadform(1,1,1)

r1 =
-5.0000e-01 + 8.6603e-01i

r2 =
-5.0000e-01 - 8.6603e-01i

Principala utilizare a funcţiilor este de a compartimenta o sarcină specifică.


Orice problemă complexă se poate descompune într-o serie de subprobleme mai
mici, iar regulile de domeniu de vizibilitate pentru funcţii ne permit să abordăm
fiecare subproblemă independent. Ele ne permit de asemenea să exploatăm
soluţii ale problemelor fundamentale care deja au aparut în diverse probleme.
La fel ca o teoremă bună, o funcţie bună ne invită să-i inspectăm detaliile de
construcţie şi să tragem maxim de învăţăminte din ele.
Un alt aspect important al fişierelor M de tip funcţie este acela că multe
funcţii MATLAB sunt ele însele fişiere M pe care le puteţi citi, modifica şi din
care vă puteţi inspira. Acesta este un mod excelent de a învaţa practici bune
de programare, dar şi trucuri.

Condiţionale: if şi switch
Adesea, o funcţie trebuie să se ramifice pe baza unei condiţii întâlnite la execuţie.
MATLAB oferă facilităţi de acest tip similare celor din multe alte limbaje de
programare.
Iată un exemplu ce ilustrează cele mai multe facilităţi ale instrucţiunii if.

if isinf(x) || ~isreal(x)
disp('Bad input!')
y = NaN;
elseif (x == round(x)) && (x > 0)
y = prod(1:x-1);
else
y = gamma(x);
end

Condiţiile pentru instrucţiunea if pot implica operatorii relaţionali din


tabela ?2.3?, pag. ??? sau funcţii care returnează valori logice, ca isinf.
Se pot utiliza valori numerice, cu nenul însemnând true, dar “ if x~=0 ” este

4
mai sugestiv decât “ if x ” când x este numeric. O atenţie specială necesită
utilizarea tablourilor la construcţia condiţiilor dintr-o instrucţiune if. Dacă
condiţia nu este scalară, se consideră adevarată numai dacă toate elementele ei
sunt adevarate/nenule. Pentru a evita confuziile, este cel mai bine să se utilizeze
any ori all pentru a reduce tablourile logice la valori scalare.
Condiţiile scalare compuse se pot crea utilizând operatorii && (şi logic) şi ||
(SAU logic) în locul operatorilor tablou & şi | . (Operatorul NOT ~ este identic
în ambele cazuri.) Operatorii dublu-simbol pot fi scurt-circuitaţi: dacă, pe
masură ce o condiţie este evaluată de la stânga la dreapta, devine clar înainte
de terminarea evaluării ce valoare finală se va obţine, atunci evaluarea condiţiei
este oprită. Aceasta facilitate face convenabilă scrierea unor construcţii ca

if (length(x) > 2) && (x(3)==0), disp('xy plane'), end

care altfel ar conduce la erori sau ar fi dificil de scris. În unele situaţii, funcţia
isequal este mai robustă decât operatorul relaţional ==. De exemplu, con-
strucţia isequal(s,’foo’) returnează false dacă s nu este identic cu şirul ’foo’
, pe când s==’foo’ va da o eroare dacă s nu are dimensiunea 1×3. De obicei,
prima comportare este mai de dorit. Construcţia if/elseif este de preferat
numai când avem un număr mic de alternative. Dacă avem un număr mare de
opţiuni se preferă switch. De exemplu:

switch units
case 'length'
disp('meters')
case 'volume'
disp('liters')
case 'time'
disp('seconds')
otherwise
disp('I give up')
end

Expresia din switch poate fi un şir sau un număr. Expresia din case poate fi
un scalar, un şir, un tablou de celule. Se execută secvenţa de comenzi din primul
case care se potriveşte cu expresia din switch. Execuţia nu curge mai departe
ca în C. Dacă otherwise este prezent, secvenţa de comenzi corespunzătoare se
execută dacă nu avem nici o potrivire.

Cicluri for şi while


Mult, i algoritmi necesită iteraţii, adică execuţia repetitivă a unui bloc de in-
strucţiuni. Din nou, MATLAB este similar cu alte limbaje din acest domeniu.
Merită reamintit aici că, deoarece i şi j sunt foarte folosiţi ca indici de ciclare,
să se utilizeze 1i sau 1j pentru unitatea imaginară. Ca o ilustrare a unui ci-
clu simplu for, să considerăm secvent, a de cod de mai jos pentru calculul a 10
elemente din şirul lui Fibonacci:

5
f = [1 1];
for n = 3:10
f(n) = f(n-1) + f(n-2);
end

Se pot pune oricâte instrucţiuni în corpul ciclului. În exemplul anterior,


valoarea indicelui n variază de la 3 la 10, odată cu execuţia corpului, după
fiecare atribuire. Reamintim că 3:10 este un vector linie. De fapt, se poate
utiliza orice vector linie într-un ciclu for, nu doar unul creat cu :. De exemplu,

x = 1:100; s = 0;
for j = find(isprime(x))
s = s + x(j);
end

calculează suma numerelor prime mai mici decât 100. O versiune mai bună:

isprm = isprime(1:100); % which are prime?


sum( isprm ) % how many primes

ans =
25

sum( find(isprm) ) % sum the primes

ans =
1060

Uneori este necesar să repetăm o secvenţă de instrucţiuni în funcţie de sat-


isfacerea unei condiţii, nu de un număr fixat de ori. Aceasta se realizează cu
while :

while abs(x) > 1


x = x/2;
end

Condiţia este evaluată înainte de execuţia corpului, deci este posibil să avem
zero iteraţii. Uneori este o idee bună să limităm numărul de iteraţii pentru a
evita ciclurile infinite (cum s-ar putea întâmpla mai sus dacă x este infinit).
Aceasta se poate face în mai multe feluri, dar cel mai comun este utilizarea lui
break.

6
n = 0;
while abs(x) > 1
x = x/2;
n = n+1;
if n > 50, break, end
end

break întrerupe imediat execuţia şi sare la prima instrucţiune de după ciclu.


Este o practică bună să includem anumite ieşiri de diagnostic sau alte indicaţii
că a avut loc o ieşire anormală din ciclu.

Debugging şi profiling

Figura 1. Editorul-debugger-ul MATLAB

Editorul MATLAB are încorporat un debugger care vă permite să opriţi


execuţia oriunde într-un fişier M. Este foarte util pentru a corecta cod cu erori
sau a întelege cum funcţionează acesta. În figura 1 se arată o captură de ecran.
Pentru a intra în modul de depanare, trebuie setate breakpoints (puncte de
repriză) în locuri convenabil alese. În editor, se dă click pe liniuţa care urmează
după numărul de linie, sau se utilizează meniul corespunzător din editor pentru a
crea puncte de repriză condiţionale. Când MATLAB se opreşte la un breakpoint,
se pot inspecta şi modifica variabilele din spaţiul de lucru curent —de fapt, se
poate executa orice din linia de comandă. Se poate continua cu execuţie pas cu
pas sau până la un nou breakpoint sau până la sfârşit. Pentru detalii vezi help
debug sau doc debug .
O nevoie curentă este de a face codul mai rapid. Cel mai eficient mod este
de a vedea care părţi iau cel mai mult timp la execuţie. Aceste linii de cod
sunt candidaţii evidenţi pentru optimizare. Se pot determina astfel de linii prin

7
profiling , care ţine evidenţa timpului petrecut cu execuţia fiecărei linii dintr-
o funcţie. Profiling este de asemenea un mod de a vedea dependenţele dintre
funcţii (cine pe cine apelează). Se începe prin a tasta profile viewer .

Function handles şi funcţii anonime


Un mod de a privi o funcţie este acela de algoritm sau proces. Uneori, dorim
să privim o funcţie ca o dată. De exemplu, problema matematică a integrarii
definite poate fi privită ca o aplicat, ie de la intrări de forma un interval [a, b] şi
Rb
o funcţie f (x) la valori de forma a f (x)dx. Aceasta este o problemă clasică in
calculul numeric şi există mult, i algoritmi pentru aproximarea aceste aplicat, ii.
Astfel, putem fi pus, i in situat, ia de a scrie şi utiliza funcţii care aceptă alte
funcţii ca date. MATLAB le numes, te function functions, (funcţii de funcţii)
iar lista lor se poate obt, ine cu comanda help funfun. Alte probleme care
presupun operat, ii asupra funcţiilor privite ca date sunt determinarea rădăcinilor,
optimizare şi rezolvarea ecuat, iilor diferent, iale.
Pentru a face distinct, ie intre apelul unei funcţii şi utilizarea ei ca dată,
MATLAB utilizează o construct, ie specială, numită function handle . De
exemplu, funcţia predefinită fzero caută o rădăcină a funcţiei furnizate ca prim
argument, pornind de la o valoare init, ială dată în al doilea argument. Nu putem
să o apelăm pentru a determina o rădăcină a lui sin(x) sub forma

>> fzero(sin,3) % error!

deoarece interpretorul MATLAB va încerca să apeleze funcţia predefinită sin


fără nici un argument, ceea ce dă eroare. În loc de aceasta se va crea un function
handle, utilizând @ ca prefix, ca în

fzero(@sin,3)

ans =
3.1416e+00

Orice funcţie apelabilă din domeniul de vizibilitate curent poate fi convertită


într-un handle, inclusiv funcţiile predefinite şi propriile dumneavoastră funcţii
din fişiere M.
Adesea, este nevoie de definit, ii de funcţii care combină operat, iile predefinite
într-un mod elementar. Cel mai bun instrument pentru astfel de situat, ii este
funcţia anonimă . O funcţie anonimă ne permite simultan să definim o funcţie
şi să cream un handle pentru ea. De exemplu, pentru a crea o reprezentare a
funcţiei sin(x) + cos(x), se introduce

sincos = @(x) sin(x) + cos(x);

8
Acum sincos este o funcţie de o variabilă, iar apelurile sincos(pi/4) şi
sincos(rand(2)) sunt perfect acceptabile. La fel, se pot crea şi funcţii anonime
de mai multe variabile, ca în exemplul

w = @(x,t,c) cos(x-c*t);

Nu este nevoie să atribuim funcţia anonimă unei variabile, putem folosi şi


construct, ii de forma

fzero( @(x) sin(x)+cos(x), 0 )

ans =
-7.8540e-01

Când definim o funcţie anonimă, numele de variabile care urmează după


@ sunt argumente de intrare ale funcţiei (parametrii formali). Dacă aceleas, i
nume sunt definite în spat, iul de lucru curent, acele valori nu sunt disponibile
în interiorul definit, iei funcţiei anonime. Totus, i, alte valori definite în spat, iul de
lucru curent în momentul definit, iei sunt disponibile în definit, ia funcţiei anonime.
Mai mult, aceste valori sunt înghet, ate în definit, ia funcţiei anonime: ele rămân
fixe, chiar dacă valorile lor sunt schimbate ulterior sau variabilele din spat, iul de
definit, ie nu mai sunt în domeniul de vizibilitate.
Această facilitate poate fi extrem de convenabilă. O situat, ie tipică este aceea
în care avem o funcţie definită într-un fişier M bigfun(a,x,b) care acceptă
parametrii a şi b în plus fat, ă de variabila de interes x. Sintactic, multe funcţii
de funcţii acceptă ca date numai funcţii de o variabilă. Deci, vet, i defini o funcţie
anonimă de forma

f = @(x) bigfun(0.5,x,b_value);

care blocheaza valorile parametrilor şi accepta numai o variabilă de intrare. Ca


exemplu, să considerăm din nou funcţia fzero, care determină rădăcinile unei
funcţii de o variabilă. Presupunem că dorim să determinăm o solut, ie a ecuat, iei
e−ax = x pentru mai multe valori ale parametrului a. O funcţie anonimă ne
simplifică mult sarcina:

for a = 1:0.25:2, fzero( @(x) exp(-a*x)-x, 0 ), end

ans =
5.6714e-01

ans =
5.2124e-01

9
ans =
4.8391e-01

ans =
4.5278e-01

ans =
4.2630e-01

În corpul ciclului, variabilei a i se atribuie fiecare din valorile 1, 1.25, 1.5,


1.75, 2. La fiecare execut, ie a ciclului se crează o funcţie anonimă în variabila x
şi cu valoarea curentă a lui a, care este transmisă lui fzero .

Subfuncţii şi funcţii imbricate


Un fişier M poate cont, ine mai mult de o definitie de funcţie. Linia de antet de
funcţie de la inceput defines, te funct, ia primară a fişierului. În acelas, i fişier
mai pot apare înca două tipuri de funcţii: subfuncţii şi funcţii imbricate.
Subfuncţia este un mod convenabil de a evita dezordinile de nume şi direc-
tor. Subfuncţia începe după sfârs, itul funcţiei primare, cu un nouă linie antet
de funcţie. Fiecare subfuncţie din fişier poate fi apelată din funcţia primara sau
din alte subfuncţii. Din toate celelalte puncte de vedere, ea se comportă ca o
funcţie primară dintr-un fişier separat, inclusiv utilizarea unui spat, iu de lucru
privat. Ca exemplu ultrasimplificat de funcţie care utilizează o subfuncţie să
consideram o nouă versiune a lui quadform.m :

function [x1,x2] = quadform(a,b,c)


d = discrim(a,b,c);
x1 = (-b + d) / (2*a);
x2 = (-b - d) / (2*a);
end % quadform()
function D = discrim(A,B,C)
D = sqrt(B^2 - 4*A*C);
end % discrim()

Linia cu end este opt, ională în fişierele care cont, in o singură funcţie, dar este
o idee bună cand apar mai multe funcţii şi este obligatorie la utilizarea funcţiilor
imbricate. Schimbările făcute asupra lui a , b , sau c in interiorul lui discrim
nu se vor propaga în restul quadform , nici o altă variabilă din funcţia primară
nu va fi disponibilă în discrim . Subfuncţiile nu sunt vizibile înafara fişierului
de definit, ie —doar funcţia primară poate fi apelată. Totus, i există o except, ie
majoră şi utilă la această regulă. Presupunem că dorim să investigăm valorile
proprii ale unei anumite matrice A(x) —concret, dorim să găsim cel mai mic x
astfel încât partea reală maximă a valorilor proprii să fie egală cu 1. O abordare
simplă este sa utilizăm fzero pentru a atinge valoarea dorită:

10
function x0 = findx
x0 = fzero(@objective,[0 10]);
end
function r = objective(x)
B = diag(ones(499,1),1); A = B-B';
A(1,1) = x;
e = eig(A); r = max(real(e)) - 1;
end

Subfuncţia objective este transmisă ca un handle lui fzero, care este capabilă
să acceseze şi să apeleze subfuncţia, chiar dacă fzero ar putea să nu o recunoască
dacă ar fi apelată direct prin nume.
O funcţie imbricata (nested function) este similara cu o subfuncţie, dar
este definita în interiorul domeniului de vizibilitate al funcţiei părinte. Ea se
comporta diferit de o subfuncţie dintr-un punct de vedere foarte important:
spat, iul de lucru se poate suprapune peste cel al părintelui. Orice variabilă
utilizată atât în funcţia imbricată, cât şi în funcţia părinte este partajată.
Unul din motivele utilizării funcţiilor imbricate este crearea de efecte colat-
erale persistente. Să consideram din nou exemplul de mai sus cu valorile pro-
prii. Deoarece fzero este o “cutie neagra” cu sintaxa standardizată, ea poate
returna doar valoarea x pe care o căutăm. Nu ne poate spune, de exemplu,
partea imaginară a valorii proprii a cărei parte reală este 1, nici nu ne poate
da altă informat, ie despre valorile proprii. Pentru a obt, ine acele funcţii, trebuie
sa repetăm mult din funcţia objective, ceea ce face codul confuz şi necesită
timp de calcul suplimentar. Reorganizând calculele prin utilizarea unei funcţii
imbricate, se pot transmite informat, ii suplimentare înafara objective :

function x0 = findx
function r = objective(x)
A(1,1) = x;
e = eig(A); r = max(real(e)) - 1;
end
B = diag(ones(499,1),1); A = B-B';
e = []; % create a shared variable for side effect
x0 = fzero(@objective,[0 10]);
plot(e,'x')
end

Linia e = []; este critică. Dând variabilei e o definit, ie în spatiul părinte i


se permite să fie partajată între funcţia objective imbricată şi parintele său,
astfel că la terminarea lui fzero, valoarea lui e este aceeas, i ca la sfârsitul celui
mai recent calcul de valoare proprie. De notat că transmitem de asemenea
informat, ii statice despre variabila A în funcţia imbricată, economisind timpul
pierdut în versiunea precedenta.
Partajarea variabilelor cu funcţii imbricate este o tehnică care trebuie uti-
lizată cu precaut, ie. Experient, a arată ca bazarea încrederii pe spat, iul comun

11
poate conduce la cod care es, ueaza us, or şi este dificil de citit şi înteles. Există,
totus, i, situat, ii în care astfel de tehnici sunt efectiv avantajoase.

Erori şi avertismente
Funcţiile MATLAB pot întâlni instruct, iuni imposibil de executat, într-un mod
care nu poate fi anticipat până la execut, ia efectivă. De exemplu, instruct, iunea
A*B este sintactic validă, dar nu are sens dacă matricele au dimensiuni incom-
patibile. Într-o astfel de situat, ie se declans, ează o eroare: execut, ia se opres, te,
se afis, eaza un mesaj, iar controlul se dă în fereastra de comandă (la prompter),
argumentele de ies, ire fiind ignorate. Se pot declans, a erori în funcţiile scrise de
dumneavoastră cu instructiunea error, apelata cu un s, ir de caractere pe post de
mesaj. Asemanător se comporta warning , care afis, ează mesajul, dar permite
continuarea execut, iei.
Uneori este de dorit să putem recupera dupa o eroare şi sa continuăm cu
un plan pentru situat, ii neprevăzute. Aceasta se poate realiza cu construct, ia
try/catch. De exemplu, secvent, a de cod de mai jos continuă să ceară o
instruct, iune validă până când d-voastră dat, i una care să se execute cu succes:

done = false;
while ~done
state = input('Enter a valid statement: ','s');
try
eval(state);
done = true;
catch me
disp('That was not a valid statement! Look:')
disp(me.message)
end
end

Într-un bloc catch se poate obt, ine cel mai recent mesaj de eroare cu
instruct, iunea lasterr, sau în versiunile mai recente MATLAB, inspectând
obiectul special de except, ie me, as, a cum s-a aratat mai sus şi cum se explică în
pagina de help pentru MException .

Argumente de intrare şi iesire, precizări suplimentare


Buna practică de programare dictează să se verifice validitatea argumentelor
de intrare ale unei funcţii. Aceasta este o idee bună, în special pentru limbaje
slab tipizate, cum este MATLAB, unde o sintaxă validă poate conduce la rezul-
tate fără sens. Există mai multe funcţii ajutătoare pentru verificarea intrărilor,
ilustrate în fragmentul de cod de mai jos:

function [x,y] = myfun(a,b,c)


assert(isnumeric(a), 'First input must be a number.')
assert(numel(a)==1, 'First input must be a scalar.')

12
assert(~any(isinf(b)), 'Second input must be finite.')
assert(~any(isnan(b)), 'No NaNs allowed in second input.')
assert(ischar(c), 'Third input must be a string.')

Dacă prima expresie furnizată lui assert este falsă, se declanşează o eroare
cu mesajul care apare ca al doilea argument.
Deşi un header de funcţie explică numărul şi numele argumentelor de intrare
şi de ieşire, acestea nu sunt forţate la apel. În loc de aceasta, execuţia continuă
cât mai mult posibil, până se întamplă ceva nedefinit sau ilegal. Acest fapt ne
permite să acceptăm diferite numere de argumente de intrare în situaţii diferite.
O utilizare comună a listelor de argumente de lungime variabilă este să se dea
valori implicite unor valori lipsă, ca în fragmentul următor:

function shirt(neck,sleeve,color,cuff)
if nargin < 4
cuff = 'button';
if nargin < 3
color = 'blue';
end
end

Valoarea lui nargin este setată la execuţie pe numărul de argumente de


intrare cu care funcţia a fost efectiv apelată. Cu sintaxa de mai sus, valorile
implicite sunt asignate celui de-al treilea şi al patrulea argument dacă ele lipsesc.
Intrările depind de poziţie (în engleză place-sensitive), deci nu este posibil să se
specifice o valoare a lui cuff fără a se da o valoare pentru color. Dacă funcţia
este apelată cu zero argumente sau cu un argument, execuţia va continua pâna
când se face o referire la neck ori sleeve , care nu au date valori implicite. Pen-
tru o abordare diferită a numărului de argumente variabil, a se vedea secţiunea
referitoare la tablouri de celule.

13

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