O functie simpla pentru plot: Sintaxa: ezplot(‘functia(x)’,[limita_inf,limita_sup]) Daca nu se specifica limitele, se folosesc limite implicite [0,2*pi] Exemple: Ezplot(‘sin(x)’) Ezplot(‘x^2+y^2-1’,[-2,2]) ezplot ('x^2+y^2-1',[-2,2]); axis equal Important – e necesar sa se specifice axis equal, precedat de ; daca dorim ca unitatile de masura sa fie egale pe cele doua axe (adica sa iasa chiar cerc) – altfel cercul arata ca o elipsa!! Alt mod de a scrie: Se poate folosi functia inline g=Inline(‘x^2’) ezplot(g) // fara ghilimele!!! g=inline('x^2+y^2-9'); ezplot(g,[-5,5]);axis equal De retinut si comanda SOLVE – care intoarce solutia unei ecuatii sau a unui sistem. solve('x^2-5*x+6=0') O chestie foarte importanta, care distinge MATLAB de alte limbaje de programare – se accepta variabile simbolice. De exemplu: syms x y //fara virgula!!! asta iti permite sa le folosesti ulterior fara sa le asignezi neaparat niste valori numerice!! deci se poate scrie: syms x y y=x^2+3 ezplot(y) //y nu e in ghilimele!! alt exemplu: syms y y z y=10*(1-cos(x)) z=sin(x) ezplot(y*z,[0,10]) Vectori si matrici Vectorii se pot defini asa: X=[1,2,3,4,5] sau: X=[1 2 3 4 5]
Virgula si spatiul sunt echivalente in acest caz. Sau asa: X=1:5 Variante: X=[5,4,3,2,1] X=5:-1:1 La modul general X=limita_inf : cuanta : limita_sup Cuanta poate fi fractionala sau negativa! X’ este vectorul transpus lui X Y=X' Y = 5 4 3 2 1 Se poate aplica un vector ca argument al unei functii: De exemplu, sin(X) este un vector de aceeasi dimensiune cu X, care are ca elemente sinusul elementelor lui X. Se poate scrie si direct: sin(1:5) sin(1:2:20) Matricile se pot defini asa: A = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12]
Raspunsul este: A 1 5 9
= 2 3 4 6 7 8 10 11 12
Se observa ca delimitarea intre linii se face cu ‘;’ Suma a doua matrici A+B este o matrice care are ca elemente suma elementelor i,j din cele doua matrici. Matricile adunate trebuie sa aiba aceleasi dimensiuni. Doua matrici se pot inmulti daca A[nxm] B[mxl] atunci C[mxl]=A*B
m
( A * B ) ij = ∑ Aik * Bkj k =1
Exemplu: Daca A= 1 2 3 4 5 6 7 8 9 B=[10, 20,30] A*B’= 1*10+2*20+3*30 4*10+5*20+6*30 7*10+8*20+9*30 Nota: B’ este transpusa lui B Vom reveni asupra matricilor. De retinut comanda whos, care listeaza variabilele definite in cursul programului sau a sesiunii de lcuru curente. Poti sa verifici daca o variabila este definita, tastandu-i numele. De exemplu: % definire variabilei x=2 %.... x Si obtii raspunsul:
x= 2 Nota: Comentariile se delimiteaza cu simbolul ‘%’
Comanda LENGTH – intoarce dimensiunea unui vector. Exemplu: A=[1 2 3 4] length(A) ans 4 Daca este aplicata unei matrici, length intoarce numarul de elemente de pe o linie.\
A=[1 2 3 4] B=[4 5 6 7] C=[A;B] length(C) – intoarce 4. Pentru a afla dimensiunea unei matrici, se foloseste comanda SIZE SIZE(C) ans 2 4 Elementele individuale ale unui vector Acestea pot fi adresate astfel: A=[1 2 3 6 8 10] A(1) 1 A(4) 6 A(5) 8 Observatie: Nu se incepe numerotarea de la zero ci de la 1!! In cazul unei matrici, se poate adresa un element oarecare cu: C(i,,j) % i este numarul liniei j este numarul coloanei Array multiplication Este produsul element cu element a doi vectori. Se simbolizeaza cu ‘.*’ Exemplu: >> A=[1:2:10] A = 1 3 5 >> B=[3:2:11] B = 3 5 7 >> P=A.*B P = 3 15 35
7
9
9
11
63
99
Functia SUM Pentru un vector, intoarce suma elementelor. Exemplu: A=[1 2 3 4] sum(A)=1+2+3+4 Daca argumentul sum este o matrice, sum() intoarce un vector linie care are ca elemente suma elementelor de pe fiecare coloana a matricii argument. Exemplu:
>> A=[1 2 3 4] >> B=[3 4 5 6] >> C=[A;B] C = 1 3 >> sum(C) ans = 4 6
2 4
3 5
8
4 6
10
Adresarea unui grup de elemente dintr-un vector A=[1 2 3 4 5] X=A(2:4) X=[2 3 4]
Izolarea unei coloane dintr-o matrice Sintaxa:
C(:,i) – izoleaza coloana i Exemplu: C = 1 3
2 4
3 5
4 6
C(:,2) ans = 2 4
Selectarea unei linii C(1,:) ans = 1 C(2,:) ans =
2
3
4
3
4
5
6
Stergerea unei coloane intr-o matrice D(:,2)=[ ] D = 1 3
3 5
4 6
Stergerea unei linii D(1,:)=[ ]
D = 3
4
5
6
Selectarea unei sub-matrici C(1:2,2:3) 1:2 se refera la liniile selectate 2:3 se refera la coloanele selectate
Note despre rezolvarea ecuatiilor 1. Ecuatii polinomiale de tipul P(x)=0 Comanda ROOTS(A) A este un vector al coeficientilor polinomului. Exemplu A=[1 –5 6] % x^2-5*x+6=0 roots(A) ans = 3.0000 2.0000
1. Rezolvarea unor ecuatii generale Comanda SOLVE(‘expresia1=0’,’expresia2=0’) Exemplu: [x, y] = solve('x^2 - y = 2', 'y - 2*x = 5') Asta intoarce: x = [ 1+2*2^(1/2)] [ 1-2*2^(1/2)]
y = [ 7+4*2^(1/2)] [ 7-4*2^(1/2)] double ([x,y]) ans = 3.8284 12.6569 -1.8284 1.3431 Exemplu de mai sus este un sistem de ecuatii cu doua solutii. Se pot izola valorile individuale ale solutiilor cu x(1)
Care intoarce: ans = 1+2*2^(1/2) si y(1) ans = 7+4*2^(1/2) x(2) ans = 1-2*2^(1/2) y(2) ans = 7-4*2^(1/2) Mai sunt si alte moduri/comenzi pentru rezolvarea unor ecuatii, dar nu ma intereseaza deocamdata. Mai multe despre plotting 1. Comanda AXIS AXIS([XMIN XMAX YMIN YMAX]) Defineste limitele plot-ului Atentie – vectorul de intrare pentru axis() se refera intai la limitele pentru axa x si apoi la limitele pentru axa y – NU la perechi (x,y) cum ar parea logic!! 2. Comanda PLOT(x,y,’S’) Daca x, y sunt scalari – atunci se ploteaza un punct in plan cu ccoordonatele (x,y) Parametrul ‘S’ indica ce simbol sa se foloseasca pentru reprezentarea punctului. - omiterea parametrului – se pune un punct Cateva optiuni posibile pentru S - S=x - S=o - S=* - S=p ; pentagram - S=h – hexagram Daca sunt mai multe puncte de plotat, se poate scrie: plot(x1,y1,’S’,x2,y2,’S’,x3,y3,’S’.....) De regula, parametrii x si y ai plot sunt vectori. Daca se omite parametrul ‘S’ punctele plot-ului se unesc cu linie continua.
Exemplu: X = -1:0.01:2; plot(X, X.^2)
Asta are ca efect plotarea unei parabole. Exemplu: f=exp(-x); g=exp(-2*x); plot(x,f,'-',x,g,':') % ‘:’ linie punctata ‘-‘ line continua plot(x,f,'-',x,g,'--') % dashed line plot(x,f,'--',x,g,':')
Selectia culorilor pentru plot Sunt posibile 8 culori (din care una e alb!) pentru plot-uri. Ele sunt codate astfel: Color White Black Blue Red Cyan Green Magenta Yellow
Specifier w k b r c g m y
Daca vrem sa specificam simultan ca e vorba de linie intrerupta de culoare verde, atunci includem in aceleasi ghilimele ambii specificatori: plot(x,f,'-',x,g,'g--') % dashed line
Comanda FPLOT Exemplu: fplot('exp(–2*t)*sin(t)',[0,4]), xlabel('t'), ylabel('f(t)'), title('Damped Spring Forcing') Parametrii xlabel, ylabel sunt facultativi. Comanda fplot este mai putin pretentioasa decat ‘plot: Seamana mai mult cu ezplot decat cu plot – parametrii sunt string-uri, delinitate de ghilimele simple. Observatie importanta!!! Secventa de comenzi: t = [0:0.01:4]; f = exp(-2*t)*sin(t); plot(t, f) Desi pare corecta, genereaza o eroare. Eroarea provine de la faptul ca exp(-2*t) si sin(t) sunt VECTORI (matrici).
Corect, trebuie sa folosim array multiplication (.*), care are ca efect inmultirea element cu element a celor doi vectori!!! Deci corect este: t = [0:0.01:4]; f = exp(-2*t).*sin(t); plot(t, f) Crearea unor grafice cu plot-uri multiple Comanda HOLD ON/OFF Mentine deschisa fereastra unde se genereaza plot-ul si pentru urmatoarele comenzi plot/ezplot. Exemplu: ezplot('exp(-x)', [0 10]) hold on ezplot('sin(x)', [0 10]) Asta are ca efect figura urmatoare:
Comanda LEGEND Adauga o legenda la un plot multiplu: Ex: plot(x,y,'g-',x,z,'--b'); legend('sin(x)','cos(x)')
Comanda LINSPACE LINSPACE(X1, X2) generates a row vector of 100 linearly equally spaced points between X1 and X2. LINSPACE(X1, X2, N) generates N points between X1 and X2. Este cumva similara cu: X=[a1:q:a2] Care genereaza un vector cu valori intre a1 si a2, distantata cu cuanta q. Comanda polar(x,y) Este similara cu plot() dar traseaza graficul in coordonate polare Comanda loglog(x,y) Simlara cu plot, dar foloseste scara logaritmica pe ambele axe Comanda semilog(x,y) Similara cu plot – cu axa logaritmica pe axa x.
Comanda bar(x,y) Genereaza un plot de tip bargraf. Exemplu: x = [1:5]; y = [50,98,75,80,98]; bar(x,y), xlabel('Student'),ylabel('Score'), title('Final Exam')
Asta produce un grafic ca in figura: 100
90
80
70
60 Sco re
50
40
30
20
10
0
1
2
3 Student
4
Comenzile load si save Salveaza si restaureaza valorile variabilelor curente Exemplu: Y=load('test.txt') Atentie – single quotes !
5
Incarca matricea Y dintr-un fisier text Observatie: Am incarcat cu comanda load fisierul MAP0.TXT pe care l-am folosit in programul cu feromonii, dar mi-a generat o matrice 21x21. Ca sa obtin o singura linie ar fi trebuit sa elimin CR-urile din fisier. Oricum e interesanta observatia. Comanda de salvare: save -ascii test.txt Y Despre functii Functiile sunt fisiere m, plasate in directorul curent sau in alta parte pe calea de cautare, care contin definitia UNEI functii. Exemplu – functia urmatoare calculeaza distanta intre doua puncte, date prin coordonatele lor (x1, y1, x2, y2) dist.m function y=dist(x1,y1,x2,y2); y=(x1-x2)^2+(y1-y2)^2; y=sqrt(y); Odata definita, o functie poate fi apelata de programul principal, iar valoarea intoarsa de aceasta poate fi asignata unor variabile. De exemplu: d=dist(1,2,3,4) Observatie, variabila locala y folosita in functie, nu o gasesc cu WHOS in programul principal! Nota: Nu se pot defini functii care sunt deja predefinite in MATLAB. De exemplu nu poti redefini functia sin(x) – obtii o eroare. Important ! Variabilele definite intr-o functie sunt LOCALE ! Despre buclele de program 1. while(conditie) Exemplu: x=1; while(x<=10) x=x+1; end While trebuie marcat de un end. Nu se folosesc acoladele in MATLAB (sau se folosesc in alt scop). 2. for
Exemplu: for (x=1:0.1:10) if(x>=4.5) break; end end x x = 4.50000000000000 Nota: In exemplul de mai sus sunt doua statement-uri “end” – unul pentru for si unul pentru if !! Se poate si asa: N=10; for (x=1:0.1:N) if(x>=4.5) break; end end 3. SWITCH Exemplu: N=3; switch(N) case 3 disp(' end Got it
Got it')
Exercitiu: Sa se rezolve sistemul de ecuatii liniare: 3x + 4y + 5z = 2 2x − 3y + 7z = −1 x − 6y + z = 3. Solutie: [x, y, z] = solve(’3*x + 4*y + 5*z = 2’, ’2*x - 3*y + 7*z = -1’, ’x - 6*y + z = 3’, ’x’, ’y’, ’z’) Verificarea rezultatului: A = [3, 4, 5; 2, -3, 7; 1, -6, 1]; A*[x; y; z] ans = [ 2] [ -1] [ 3]
Mai multe despre expresii simbolice Niste functii folositoare expand(expresie) Exemple: syms x, y expand(sin(x+y))
%!!!
ans = sin(x)*cos(y)+cos(x)*sin(y)
factor(expresie) – produce descompunerea in factori Exemplu: factor(x^2-y^2) ans = (x-y)*(x+y)
Functia simplify Exemplu: simplify(cos(x)^2+sin(x)^2) ans = 1 Note despre debugging Daca dorim putem plasa breakpoints in programe, ca sa putem inspecta variabilele. asta se face din menu sau cu comanda dbstop Daca dorim sa continuam executia se foloseste dbcont In final dbclear – pentru stergerea breakpoint-urilor sau dbquit, ca sa terminam programul. DBSTOP poate fi conditionat, de exemplu: DBSTOP IF WARNING Note despre dialogul cu operatorul Functia disp(‘mesaj’) Functia input(‘mesaj’) exemplu: x=input(‘Introduceti un numar: ‘) Functia fprintf() este foarte asemanatoare cu printf() din C
Un exemplu de functie care citeste date dintr-un fisier text in care datele sunt scrise cate o valoarea pe fiecare linie; File: read.m function A=read(file_name) fp=fopen(file_name,'r'); A=fscanf(fp, '%d', [1,8]); VL=fscanf(fp, '%d', 1); % dummy data VR=fscanf(fp, '%d', 1); % dummy data while 1 A=[A;fscanf(fp, '%d', [1,8])]; VL=[VL;fscanf(fp, '%d', 1)]; VR=[VR;fscanf(fp, '%d', 1)]; if feof(fp) break end %end if end %end while fclose(fp); end %end file Apelarea acestei functii se face sub forma: A=read(‘record.dat’); Sunt cateva - modul de - modul de - modul de - modul de
lucruri demne de atentie in functia asta: folosire a fopen/fclose. lipire a doua matrici A=[A:B] citire formatata direct cu fscanf [1,8] testare pentru end of file
Note despre ezplot Ca sa deschid mai multe figuri simultan, inainte de fiecare comanda ezplot se da comanda: figure(1) figure(2) etc. Ca sa controlez culoarea in ezplot, e nevoie de un script: setcurve.m (salvata pe cale sau in directorul curent) %change properties of last curve in current figure %Examples: % setcurve('color','red') % setcurve('color','green','linestyle','--') %Type help plot to see available colors and line styles function setcurve(varargin) h=get(gca,'children'); set(h(1),varargin{:})
O problema uzuala Se da o matrice X=[-1:0.01:1] Se cere graficul plot(X,Y) unde Y este o matrice de forma Y=[1,f(x(1,i))] Fiecare element al matricii Y este o functie de elementul corespunzator al matricii X. Una din solutii este, de exemplu: ezplot('(1/(1+exp(-2.2*x)))', [-1,1]) Daca vrem sa folosim plot(X,Y), atunci Y trebuie sa fie o matrice de aceeasi dimensiune cu X. Pentru asta ne trebuie o functie File:sigmoid.m % presupunem ca X este o matrice linie (1,i) function Y=sigmoid(X) sigma=2.2; for (i=1:1:length(X)) Y(1,i)=1+exp(-1*sigma*X(1,i)); Y(1,i)=1/Y(1,i); end Sigma poate fi si el pasat ca parametru: % presupunem ca X este o matrice linie (1,i) function Y=sigmoid(X,sigma) for (i=1:1:length(X)) Y(1,i)=1+exp(-1*sigma*X(1,i)); Y(1,i)=1/Y(1,i); end Cazul cand Y contine niste date experimentale care se citesc dintr-un fisier dintr-un fisier: Y=load('record.dat'); % le citeste ca o coloana Y=Y'; %Y’ este transpusa lui Y X=[1:1:length(Y)]; hold on plot(X,Y); Nota Dimensiunile unei matrici se pot afla cu comanda size E util de exemplu cand citim matricea dintr-un fisier. sa=size(A) ans= 215 8
Recapitulare
a. Comenzi de file management PWD – print working directory. Afiseaza directorul curent DIR – listeaza fisierele din directorul curent LS – echivalent cu DIR (pentru utilizatori invatati cu Linux) CD change directory Merge si CD .. MKDIR – make directory RMDIR – remove directory COPYFILE – copiere fisier DELETE - sterge fisier Adaugarea unor directoare la calea (PATH) curenta se face fin meniul principal File -> Set path b. Numere complexe 5+4i – este un numar complex 5+4*i – i este interpretat ca o variabila!! c. Sintaxa generala a comenzilor O comanda lunga poate fi continuata pe linia urmatoare, de exemplu: a=1+2+3+4; % este echivalent cu: a=1+2+... % trei puncte 3+4; De asemenea, pe aceeasi linie se pot introduce mai multe comenzi separate prin virgula sau ‘;’ De exemplu: a=5, b=7, c=6 sau a=5; b=7; c=6; %fara afisare Comanda diary(‘filename’) creaza un fisier text in care se pastreaza tot dialogul din fereastra de comenzi, pana la comanda ‘diary off’. E utila pentru incepatori, daca vrei sa reicitesti secvente de exercitii. MATRICI 1. Modalitati de definire a variabilelor de tip matrice si vector a. Comenzile zeros si ones A=zeros(3) are ca efect crearea unei matrici (3x3) cu toate elementele egale cu zero. A =
0 0 0 0 0 0 >> A=zeros(1,4)
0 0 0
A = 0
0
0
0
0 0
0 0
>> A=zeros(2,4) A = 0 0
0 0
>> B=ones(4,2) B = 1 1 1 1
1 1 1 1
Nota: Dimensiunea unei matrici se poate afla cu functia size() >> size(B) ans = 4
2
b. Comanda eye Creaza matrici diagonale Exemplu: >> eye(4) ans = 1 0 0 0 Merge si: >> eye(3,4)
0 1 0 0
0 0 1 0
0 0 0 1
ans = 1 0 0
0 1 0
0 0 1
0 0 0
c. Comenzile rand si randn creaza matrici ale caror elemente sunt numere aleatoare >> rand(3) ans = 0.4741 0.2572 0.3252
0.0845 0.6618 0.5165
0.2126 0.4850 0.4113
1.4151 -0.8051 0.5287
0.2193 -0.9219 -2.1707
>> randn(3) ans = -1.6041 0.2573 -1.0565
d. Comanda linspace Genereaza un vector. Se poate folosi in doua moduri: i.
x=linspace(lim1, lim2)
Genereaza un vector cu fix 100 de elemente, echidistante in intervalul definit de valorile lim1, lim2. De exemplu: x=linspace(1,100) genereaza x=[1 2 3 4 .... 100] Obs. Nu este necesar ca lim1 < lim2 Se poate si asa: x=linspace(100,1) x=[100 99 98 ... 2 1] ii. x=linspace(lim1, lim2, N) Se poate specifica direct numarul de elemente al vectorului generat. Doar daca nu se specifica, se foloseste valoarea implicita N=100. E utila pentru plot-uri rapide. e. Definirea matricilor prin asignare directa
Definirea unor vectori: A=[1 2 3 4] echivalent cu A=[1,2,3,4] >> A=[1 2 3 4] A = 1
2
3
4
3
4
>> B=[1,2,3,4] B = 1
2
Observatie: Asignarea directa REDEFINESTE matricea, daca ea era deja definita!! De exemplu, secventa: >> A=zeros(4) A = 0 0 0 0
0 0 0 0
>> A=[1 2 3 4]
0 0 0 0
0 0 0 0
%reduce A la un vector (1,4)
A = 1
2
3
4
Separarea liniilor in comanda de asignare pentru matrici se face cu ‘;’ Exemplu: >> A=[1,2,3,4;5,6,7,8] A = 1 5
2 6
3 7
4 8
Sau asa: >> A=[1 2 3 4 ; 5 6 7 8]
>> B=[1;2;3;4] B = 1 2 3 4 f. Definirea vectorilor folosind operatorul colon ‘:’ Exemple de sintaxa: >> A=[1:3:8] A = 1
4
7
Merge si fara paranteza patrate!! >> A=1:3:8 A = 1
4
7
Primul termen al expresiei A=1:3:8 este marginea inferioara a intervalului, al doilea este cuanta, iar al treilea este marginea superioara. Accesul la elementele unei matrici Elementele individuale ale unei matrici pot fi adresate indicand numarul liniei si al coloanei De exemplu A(i,j) este elementul de pe linia i si coloana j. >> A=zeros(3) A = 0 0 0
0 0 0
0 0 0
0 1 0 0 0 0 >> A(1,3)=2
0 0 0
>> A(1,2)=1 A =
Obs. Aici e obligatoriu ca argumentele sa fie separate de virgula. Nu merge cu spatiu! A(1 3)=2 da eroare. Atentie: numerotarea liniilor si coloanelor incepe de la 1, NU de la zero! A = 0 0 0
1 0 0
2 0 0
Izolarea unei linii sau coloane dintr-o matrice >> B=A(1,:) B = 0
1
2
>> C=A(:,3) C = 2 0 0 Observatie: Aici trebuie evitata confuzia intre paranteze patrate si rotunde! Se pot izola si linii sau coloane incomplete >> X=A(1, [2 3]) X = 2
2
>> Z=A([1 2], 3) Z = 2 0 >> A=[1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16] A = 1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
>> B=A(1, 2:end) % linia 1 de la coloana 2 la end B = 2
3
4
>> C=A(1:end, 2) C = 2 6 10 14 >> D=A(1:3, 2:3) D = 2 6 10
3 7 11
Evident, merge si cu variabile simbolice: >> k=3 k = 3 >> D=A(1:k, 2:k) D = 2 6 10
3 7 11
Se poate folosi asta si pentru asignarea unor valori in submatrici: >> A(1, 1:end)=5 A = 5 5 9 13
5 6 10 14
5 7 11 15
5 8 12 16
Combinarea elementelor din mai multe matrici pentru a obtine o noua matrice >> A = [1 1 1; 1 1 1], B = [2 2 2; 2 2 2], C =... [3 3 3; 3 3 3] A = 1 1
1 1
1 1
2 2
2 2
2 2
3 3
3 3
3 3
1 1
1 1
1 1 2 2
1 1 2 2
B =
C =
>> X=[A, B] X = 1 1
2 2
2 2
2 2
>> Y=[A;B] Y = 1 1 2 2
>> Z=[A,B C] virgula
% am combinat intentionat separatori spatiu si
Z = 1 1
1 1
Se poate si asa: >> W=[A B; B C]
1 1
2 2
2 2
2 2
3 3
3 3
3 3
W = 1 1 2 2
1 1 2 2
1 1 2 2
2 2 3 3
2 2 3 3
2 2 3 3
Operatii cu matrici a. Adunarea si scaderea De exemplu, daca X si Y au aceleasi dimensiuni, atunci Z=X+Y are elementele Z(m,n) = X(m,n) + Y(m,n)
De exemplu, daca A = 1 1
1 1
1 1
2 2
2 2
2 2
3 3
3 3
B =
Atunci A+B ans = 3 3
Se poate face si adunarea cu un scalar: >> A+3 ans = 4 4
4 4
4 4
b. Inmultirea matricilor E de doua feluri: -
Array multiplication. Z=X.*Y Se foloseste cand avem doua matrici X si Y de aceleasi dimensiuni iar Z=X.*Y are elementele Z(m,n) = X(m,n) * Y(m,n) - Matrix multiplication Z=X*Y
Asta este imultirea propriu-zisa de matrici din algebra
Z (m, n) = ∑ X (m, k ) * Y (k , n) k
c. Impartirea matricilor (division) Sunt patru feluri de impartire: doua array division si doua matrix division Array division ./ sau .\ Z = X./Y means that for each m and n, Z(m,n) = X(m,n)/Y(m,n) Z = X.\Y means that for each m and n, Z(m,n) = Y(m,n)/X(m,n) Matrix division Cele doua forme de matrix division implica folosirea conceptului de matrice inversa, sau pseudo-inversa, care vor fi analizate mai tarziu FUNCTII Sintaxa generala: variabila=function_name(arg1, arg2,...argN) Exista totusi si in MATLAB functii void (care nu intorc nici o valoare, dar altereaza niste avriabile globale) si functii de argument void. Apelarea lor se face prin simpla invocare a numelui – fara paranteze. Exemplu functia rand – intoarce un numar pseudoaleator O particularitate importanta a functiilor MATLAB (multe din ele) este polimorfismul: adica pot fi apelate cu un numar variabil de parametri, sau pot intoarce mai mult de o variabila! (asta nu e posibil in alte limbaje). Exemplu: A = 1 1 >> size(A)
1 1
1 1
ans = 2
3
>> [m,n]=size(A) %se asigneaza cele doua valori intoarse de size variabilelor m si n!! m = 2 n = 3
Functii predefinite in MATLAB
INPUT & OUTPUT FUNCTIONS Keyboard input Functia input(‘prompt_string’) Exemplu: a=input(‘Introduceti ceva:’); Acel ‘ceva’ introdus este asignat variabilei a si poate fi orice: numeric, caracter, string, vector etc. Exemple de folosire: >> a=input('Introduceti ceva:') Introduceti ceva:1234 a = 1234 >> a=input('Introduceti ceva:') Introduceti ceva:[1 2 3 4] a = 1 2 3 4 >> a=input('Introduceti ceva:') Introduceti ceva:[1 2 3 4; 5 6 7 8]
a = 1 5
2 6
3 7
4 8
>> a=input('Introduceti ceva:') Introduceti ceva:asgfasdf ??? Undefined function or variable 'asgfasdf'. %sirul trebuie inclus in ghilimele simple!! Introduceti ceva:'assder' assder
a =
Observatie: Am incercat sa folosesc functia input dintr-o functie definita de mine: File: kbin.m function kbin a=input('Introduceti ceva:') end Cand o apelez: >> kbin Introduceti ceva:123 a = 123 In schimb, daca incerc sa asignez valoarea intoarsa catre o variabila, obtin o eroare: >> x=kbin ??? Error using ==> kbin Too many output arguments. Geseala e urmatoarea: File: kbin.m function a=kbin a=input('Introduceti ceva:') end >> x=kbin Introduceti ceva:123 a = 123 x = 123 Observatie: >> whos
Name
Size
x
1x1
Bytes 8
Class double array
a este variabila locala pentru functia kbin!! Ramane locala chiar daca o definesc ca globala in functie: File: kbin.m function a=kbin global a; a=input('Introduceti ceva:') end In schimb, daca o definesc ca globala inainte de a apela functia, in programul principal >> clear >> global a; >> x=kbin Introduceti ceva:123 a = 123 x = 123 >> whos Name Size Bytes Class a 1x1 (global) x 1x1 FUNCTII DE IESIRE
8
double array
8
double array
Functia disp(var); Afiseaza variabila, fara a indica si numele: >> x=[1 2 3 4]; >> x x = 1 2 3 4 >> disp(x) 1 2 3 4 Functia fprintf Seamana cu printf din C/C++. Exemple de utilizare: >> fprintf('Avem un numar oarecare, %d\n', 3.0); Avem un numar oarecare, 3 >> fprintf('Avem un numar oarecare, %d\n', 3.05); Avem un numar oarecare, 3.050000e+000 >> fprintf('Fie un string: %s\n', 'Asta e string-ul');
Fie un string: Asta e string-ul >> fprintf('Fie un caracter: %c\n', 'C'); Fie un caracter: C >> fprintf('Fie un numar zecimal: %f\n', 234.556); Fie un numar zecimal: 234.556000 >> fprintf('Fie un numar zecimal: %5.2f\n', 234.556); Fie un numar zecimal: 234.56 >> fprintf('Fie un numar zecimal: %2.2f\n', 234.556); Fie un numar zecimal: 234.56 >> fprintf('Fie un numar zecimal: %2.0f\n', 234.556); Fie un numar zecimal: 235 Se observa ca face rotunjire automat, daca nu_i dam voie sa afiseze toate zecimalele. >> fprintf('Fie un numar intreg afisat hex: %2X\n', 234); Fie un numar intreg afisat hex: EA >> fprintf('Fie un numar zecimal afisat hex: %2X\n', (234.3)); Fie un numar zecimal afisat hex: 2.30e+002 Nu vrea cu numere negative !! >> fprintf('Fie un numar negativ zecimal exprimat hex: %16X\n', -1); Fie un numar negativ zecimal exprimat hex: -1.000000e+000 Observatii in legatura cu fprintf -
Nu stie sa tipareasca numere complexe : pur si simplu ignora partea imaginara In principiu, fprintf merge si pentru scrierea intr-un fisier, caz in care trebuie specificat FID – ul (File ID-ul, obtinut cu fopen)
Exemple de apel fopen: >> FID1=fopen('test.txt','r+') FID1 = -1 % daca fisierul nu exista, intoarce -1!!! >> FID1=fopen('test.txt','w+') FID1 = 3 % a creat fisierul >> fprintf(FID1, 'Sa scriem un sir: %s\n\r', 'Asta e sirul'); Rezumatul specificatorilor de format la fprintf:
FUNCTIA plot Cel mai simplu mod de a o apela este: plot(x,y) Unde x si y sunt doi vectori Exemplu: x = 0:0.1:2*pi; y1 = sin(x); y2=cos(x); Dupa ce am definit vectorii, se poate scrie: plot(x,y1); Dar merge sa folosim doua sau mai multe seturi de vectori: plot(x,y1, x,y2); si iese ceva de genul asta:
Observatie. Este posibil ceva de genul urmator: x1=linspace(0, 2*pi); x2=linspace(-pi/2, 2*pi); y1=sin(x1); y2=cos(x2); plot(x1,y1,x2,y2) si se obtine:
Parametri suplimentari pentru functia plot plot(x,y,’s’); Parametrul suplimentar s defineste culoarea si tipul de linie folosit pentru plot si poate lua urmatoarele valori:
Se pot combina, de exemplu: plot(x1,y1,'r.',x2,y2,'b'); Genereaza figura:
iar: plot(x1,y1,'g--',x2,y2,'bd'); rezulta in:
Comenzi auxiliare pentru plot axis axis equal modifica figura in felul urmator:
>> >> >> >> >>
axis equal grid on xlabel('angle in radians'); ylabel('amplitude in Volts'); title('Some diagram');
PROGRAM LOOPS Bucle de tip for. Au structura generala: for variable = expression statements end Exemplu: for ii = 1:10 fprintf(‘\n Loop Count: %d\n’, ii); end Expresia care defineste bucla for are forma generala for ii=limit1:quantum:limit2 Exemplu: >> for ii=1:2:10 fprintf('Loop count= %d\n', ii); end Loop count= 1 Loop count= 3 Loop count= 5 Loop count= 7 Loop count= 9 Merge si asa: (indexul definit de un sir de valori) for ii = [-2 4 6 -7 3 5 -45 1 -0.5 2.6] if ii > 0 fprintf(‘%f \n’, ii); end end Mult mai interesant, se poate face acelasi lucru si asa:
x=[-2 4 6 -7 3 5 -45 1 -0.5 2.6]; for ii = 1:length(x) if x(ii) > 0 fprintf('%f \n', x(ii)); end end In bucle for se poate folosi break pentru iesirea prematura. Bucle de tip while Exemplu: % test pentru bucle de tip while n = 1; total = 0; while n <= 10 total = total + n; fprintf('n=%d, Total=%d\n', n, total); if(total>=30) break; end n = n + 1; %incrementarea indexului e treaba utilizatorului end Observatii: 1. 2. 3.
Ca si la for conditia de la while NU se pune obligatoriu in pranateze Spre deosebire de for, incrementarea indexului ramane in grija programatorului. E nevoie de cate un end pentru while for si if!
USER DEFINED FUNCTIONS Structura generala a definitiei unei functii este: function [output_argument1, output_argument2, …] = function_name(input_argument1, input_argument2, …) -
-
Functiile se definesc in fisiere m de sine statatoare – cate un fisier pentru fiecare functie. Numele fisierului trebuie sa coincida cu numele functiei Definitia functiei trebuie sa fie prima linie necomentata din fisier. Daca incercam sa definim o variabila inainte de a defini functia, obtinem o eroare (Attempt to use a script as a function) Cuvantul function apare primul in expresia de definitie a functiei; Spre deosebire de C o functie poate intoarce mai multe valori. Sunt obligatorii parantezele patrate in definitia liste de valori de iesire
O functie desteapta (Sita lui Eratostene) pentru gasirea numerelor prime mai mici decat numarul specificat in argument. File:myprimes.m function list_of_primes = myprimes(N) % MYPRIMES Returns a 1xN vector of all the primes from 1 to N % Method: Sieve of Eratosthenes (ca 240 BC)
% Variables: % prime 1xN, prime(n) = 1 if n is prime, 0 if n is not prime. % (1) Assume that all the integers from 2 to N are prime. all_numbers=1:N; prime = ones(1,N); prime(1) = 0; % (2) Mark all the numbers that are multiples of a number: for n = 2:sqrt(N) % No factor can be larger than sqrt(N) if prime(n) % Multiples of primes include all multiples prime(n+n:n:N) = 0; end end % (3) Put the survivors on a list: prime = logical(prime); list_of_primes = all_numbers(prime); Ce e demn de retinut de aici este smecheria numita “logical indexing”. Se construieste vectorul prime de aceeasi lungime cu all_numbers, initial cu toate valorile 1. Apoi se pune in prime cate un zero in pozitiile in care numarul e multiplu al unui numar mai mic. Se obtine o structura pentru prime ca mai jos: prime = 0
1
1
0
1
0
1
0
0
0
Asta e “sita”. Apoi se fac doua operatii importante: prime=logical(prime) Asta converteste valorile numerice 0 si 1 din vectorul prime in valori logice. Apoi se foloseste indexarea logica – list_of_primes = all_numbers(prime); prin care se extrag in variabila list_of_primes doar elementele din all_numbers indicate de 1 (logic) din prime. Alta tehnica demna de retinut este linia de cod: prime(n+n:n:N) = 0; care indica mai multe operatii executate asupra vectrului prime. Asta se facea relativ greu in C/C++. Exemplu step by step de functionare: >> prime=ones(1,10) prime = 1 1 1 1 >> n=2 >> prime(n+n:n:10) = 0
1
1
1
1
1
1
prime = 1
1
1
0
1
0
1
0
1
0
Se vede ca a scris 0 la pozitiile corespunzatoare multiplilor numarului n=2. Variabile globale Variabilele globale trebuie definite ca atare atat in programul principal, cat si in TOATE functiile care le folosesc! Variabile persistente Se folosesc in functii care se apeleaza de mai multe ori si isi pastreaza valorile inte apleuri. Conceptul e cumva similar cu variabilele statice din C. Definitia trebuie sa apara inainte de orice folosire Exemplu de folosire a variabilelor persistente: function count = running_total(x) %running_total Maintains a running total of all values passed to the function % Function running_total will print the sum total of all values passed to it. persistent total; % % % % %
Declares the variable total to be persistent. Note: the local variable count defined in the function declaration can not be persistent! That’s because any variable that is going to be persistent must be declared that way before appearing anywhere else in the function. That restriction includes the function declaration.
if isempty(total) total = 0; end % % % %
The first time this function is run, total exists as a persistent variable, but it's an empty matrix. This conditional checks to see if the matrix is empty. If it is, that means it's the first time the function has been run and the value of total is set to zero.
total = total + x; count = total;
O alta functie interesanta: function out = iscomplex(input) % ISCOMPLEX Determines whether the input argument is complex % The function will return 1 if the input is a complex number and % will return 0 if the input is not complex. if imag(input) > eps out = 1; else out = 0; end % un singur end pentru if si else
Asta poate fi folosita, de exemplu, asa:
function test_real(n) if iscomplex(n) fprintf('E numar complex\n'); else fprintf('E numar real\n'); end
TIPURI DE DATE (DATA TYPES) Se poate afla de ce tip este o anumita variabila folosind functia class Exemplu: >> class(10) ans = double 1. Date numerice
Sunt posibile conversii de forma: x=10; class(x) ans= double x=int8(x) class(x) ans= int8 Conversiile astea merg bine daca nu se depaseste domeniul. de exemplu:
uint8(300) ans= 255 sau: uint8(-10) ans= 0
%uint nu poate reprezenta decat numere pozitive
Totusi sunt aiureli majore aici, de exemplu: >> x=10 x = 10 >> x=uint8(x) x = 10 >> x=x*30 ??? Error using ==> * Function '*' is not defined for values of class 'uint8'. Functii in legatura cu sirurile
Exemple: >> x=num2str(pi) x =
3.1416 >> class(x) ans = char >> x=num2str(pi) x= 3.1416 >> a=str2num(x) a= 3.1416 Uite cum merge isspace: >> mmm='what a day!' mmm = what a day! >> isspace(mmm) ans = 0
0
0
0
1
0
1
0
0
0
0
Intoarce un vector cu 1 in pozitiile unde era spatiu in stringul indicat ca input! GRAPHICAL USER INTERFACES (GUI) Conceptul de « obiect » Din perspectiva programarii, un obiect este un set de date si totalitatea functiilor care opereaza asupra lor. Un obiect este descris de un set de « proprietati ». Definirea unei proprietati Object_Name.Property_Name = Property_Value Se observa ca obiectul este o structura de date. E bine de retinut ca elementele unui GUI avem astfel de obiecte. Crearea unui GUI se face folosind GUIDE Secventa de tratare a unui event 1. The user causes an event with the mouse or keyboard. 2. Matlab’s GUI system detects the event and calls the primary function, which is in our current case MyVeryOwnGUI, passing as an argument the name of the callback function 3. The primary function calls gui_mainfnc, 4. gui_mainfnc calls the callback function. 5. The callback function executes.
Pentru obiecte de tip buton, in lista de proprietati gasim una numita “String” – care este textul de pe buton si una numita “Tag” . E bine sa modificam tag-ul pentru ca functia apelata la apasarea butonului va avea un nume compus din tag+_Callback Proiectul learn/GUI1 Am o functie care ploteaza traiectoria unui proiectil File:throw.m function throw(viteza) % Flight trajectory computation % % Initial values g = 9.81; % gravity, ft/s^2 theta = 80 * pi/180; % launch angle, radians % Compute and display results disp('time of flight (s):') % label for time of flight tg = 2 * viteza * sin(theta)/g % time to return to ground, s disp('distance traveled (ft):') % label for distance xg = viteza * cos(theta) * tg % distance traveled % Compute and plot flight trajectory t = linspace(0,tg,256); x = viteza * cos(theta) * t; y = viteza * sin(theta) * t - g/2 * t.^2; plot(x,y), axis equal, axis([ 0 1100 0 600 ]), grid, ... xlabel('Distance (m)'), ylabel('Height (m)'), title('Flight Trajectory') end Imi propun sa construiesc un GUI cu graficul si un buton care declanseaza aruncarea. OK e banal – pur si simplu in functia callback asociata cu butonul se invoca functia throw cu viteza fixa. In pasul urmator GUI2 imi propun sa adaug un slider cu care sa ajustez viteza initiala. Problema e mult mai complicata si se bazeaza pe doua functii: GUIDATA GUIHANDLES Comanda GUIDATA Store or retrieve application data. Mod de utilizare:
•
Get a copy of the data with the command data = guidata(object_handle).
•
Make the desired changes to data.
•
Save the changed version of data with the command guidata(object_handle,data).
GUIDE defineste automat un handle (hObject ) al figurii si o structura de date (handles) in _Opening_Fcn: % hObject % handles
handle to figure structure with handles and user data (see GUIDATA)
Recapitulare Luam ca referinta programul /learn/GUI3 care simuleaza aruncarea unor corpuri in camp gravitational si traseaza traiectoria rezultanta. Exista un buton “Aruncare” si doua slider-e unul care ajusteaza viteza initiala si celalalt unghiul de aruncare. - definirea variabilelor suplimentare se face in functia gui_OpeningFcn handles=guidata(hObject); %citim structura %aici definim noile variabile!!!!!! handles.speed=100; handles.unghi=45; handles.intensity_factor=0.5; handles.angle_factor=0.5; % Update handles structure guidata(hObject, handles) %salvam noua structura -
In functiile (callback) asociate cu fiecare slider: % --- Executes on slider movement. function slider1_Callback(hObject, eventdata, handles) intensity_factor = get(hObject,'Value'); handles=guidata(hObject); handles.intensity_factor=intensity_factor; guidata(hObject,handles);
-
%read user data %write it back
Iar in functia callback asociata cu butonul, scriem: % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) handles=guidata(hObject);
%citim structura
speed=handles.speed; intensity_factor=handles.intensity_factor; angle_factor=handles.angle_factor; speed=speed*intensity_factor; unghi=90*angle_factor; % guidata(hObject, handles); %n-am nevoie sa salvez nimic aici throw(speed,unghi); %executia efectiva
Despre debugging
dbstop - Set breakpoints for debugging Syntax dbstop in file dbstop in file at location dbstop in file if expression
dbstop in file at location if expression dbstop if condition dbstop(s)
dbcont – continua executia de la beakpoint (pana la urmatorul) dbstep – executa un pas Ctrl+C iese din mod debug dbquit – iese Cate ceva despre dialogul cu utilizatorul in GUI Comentarii la programul “/learn/dialog1” Contine un “Edit box”, un camp “Static text” si doua butoane “Afiseaza” si “Sterge” Folosind GUIDE ,am modificat proprietatile “String’ si ‘Tag’ ale obiectelor din GUI ca sa arate asa:
Am modificat codul generat automat in functiile callback asociate cu butoanele, in felul urmator: % --- Executes on button press in Clear_Button. function Clear_Button_Callback(hObject, eventdata, handles) % hObject handle to Clear_Button (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) m=get(handles.edit1,'String'); set(handles.edit1,'String',''); % --- Executes on button press in Message_Button. function Message_Button_Callback(hObject, eventdata, handles) % hObject handle to Message_Button (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) m=get(handles.edit1,'String'); set(handles.msg_disp,'String',m);
Variatiune, proiectul dialog2 care muta cu doua butoane mesajul intre doua Edit-box-uri.
Pasul urmator: Proiectul /Learn/sumator Are urmatoarele obiecte:
Se incepe prin a defini doua variabile suplimentare num1 si num2 care reprezinta valorile numerice asociate cu sirurile introduse in cele doua Edit-box-uri. Asta se face intotdeauna in functia sumator_OpeningFcn % --- Executes just before sumator is made visible. function sumator_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to sumator (see VARARGIN) % Choose default command line output for sumator handles.output = hObject;
% Aici cream noile variabile!!!!!! % cream doua variabile NUMERICE asociate cu SIRURILE din edit-box-uri % si le initializam cu zero handles.num1=0; handles.num2=0; % Update handles structure guidata(hObject, handles);
Mai departe se editeaza callback-functions pentru cele doua edit-box-uri. In esenta, rolul functiilor este urmatorul: - se verifica faptul ca datele introduse sunt numerice, se afiseaza un mesaj de eroare in caz contrar - se preiau datele introduse si se salveaza in variabilele adaugate num1 si num2 - de notat folosirea functiei str2double - de notat faptul ca hObject este handle pentru obiectul curent!
function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit1 as text % str2double(get(hObject,'String')) returns contents of edit1 as a double
num = str2double(get(hObject,'String')); if isnan(num) num = 0; set(hObject,'String',num); errordlg('Input must be a number', 'Error') end handles.num1 = num; guidata(hObject,handles) function edit2_Callback(hObject, eventdata, handles) % hObject handle to edit2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit2 as text % str2double(get(hObject,'String')) returns contents of edit2 as a double num = str2double(get(hObject,'String')); if isnan(num) num = 0; set(hObject,'String',num); errordlg('Input must be a number', 'Error') end handles.num2 = num; guidata(hObject,handles)
Si pentru butoane: Butonul de adunare (Tag = ‘Add_Button’ % --- Executes on button press in Add_Button. function Add_Button_Callback(hObject, eventdata, handles) % hObject handle to Add_Button (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) addition = handles.num1 + handles.num2; set(handles.result, 'String', addition); % result este Static text-ul unde se afiseaza rezultatul Butonul Clear (Tag=’Clear_button’) sterge atat campurile de tip edit-box cat si rezultatul
% --- Executes on button press in Clear_button. function Clear_button_Callback(hObject, eventdata, handles) % hObject handle to Clear_button (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) handles=guidata(hObject);
set(handles.edit1,'String','0'); set(handles.edit2,'String','0'); handles.num1=0; handles.num2=0; set(handles.result, 'String', 0); guidata(hObject,handles)
Proiectul /Learn/GUI4 – Aruncare in camp gravitational Revenim la proiectul cu aruncarea in camp gravitational, dar de data asta valorile vitezei si ale unghiului se introduc manual in doua Edit-box-uri.
Incepem prin a defini doua variabile suplimentare speed si angle, pe care le salvam in structura handles. function GUI4_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to GUI4 (see VARARGIN) % Choose default command line output for GUI4 handles.output = hObject; % Aici cream noile variabile!!!!!! % cream doua variabile NUMERICE handles.speed=50; handles.angle=45; % Update handles structure guidata(hObject, handles);
Modificam codul generat automat pentru cele doua edit-box-uri: function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit1 as text % str2double(get(hObject,'String')) returns contents of edit1 as a double handles=guidata(hObject); %citim structura num = str2double(get(hObject,'String')); if isnan(num) num = 0; set(hObject,'String',num); errordlg('Input must be a number', 'Error') end if (num>100) || (num<0) num = 0; set(hObject,'String',num); errordlg('Speed out of range', 'Error') end handles.speed = num; guidata(hObject,handles) function edit2_Callback(hObject, eventdata, handles) % hObject handle to edit2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit2 as text % str2double(get(hObject,'String')) returns contents of edit2 as a double handles=guidata(hObject); %citim structura num = str2double(get(hObject,'String')); if isnan(num) num = 0; set(hObject,'String',num); errordlg('Input must be a number', 'Error') end if (num>90) || (num<0) num = 0; set(hObject,'String',num); errordlg('Angle out of range', 'Error') end handles.angle = num; guidata(hObject,handles)
Si pentru pushbutton function Throw_Button_Callback(hObject, eventdata, handles) % hObject handle to Throw_Button (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) handles=guidata(hObject); %citim structura speed=handles.speed; angle=handles.angle; throw(speed,angle);
Functii cu numar variabil de argumente de intrare. Folosirea varargin Reluam exemplul cu functia care traseaza traiectoria unui proiectil aruncat in camp gravitational function throw2(varargin) % Flight trajectory computation % if nargin<2 disp('Too few arguments'); return; end % Initial values g = 9.81; % gravity, ft/s^2 viteza=varargin{1}; theta = varargin{2} * pi/180; % launch angle, radians % Compute and display results disp('time of flight (s):') % label for time of flight tg = 2 * viteza * sin(theta)/g % time to return to ground, s disp('distance traveled (ft):') % label for distance xg = viteza * cos(theta) * tg % distance traveled % Compute and plot flight trajectory t = linspace(0,tg,256); x = viteza * cos(theta) * t; y = viteza * sin(theta) * t - g/2 * t.^2; if nargin==2 hold on; plot(x,y), axis equal, axis([ 0 1100 0 450 ]), grid on, ... xlabel('Distance (m)'), ylabel('Height (m)'), title('Flight Trajectory') else hold off; plot(0,0), axis equal, axis([ 0 1100 0 450 ]), grid on, ... xlabel('Distance (m)'), ylabel('Height (m)'), title('Flight Trajectory') end
Se observa ca se poate testa numarul de argumente al functiei (nargin) si se pot extrage argumentele din varargin{} . Folosirea RADIO BUTTONS Proiect /Learn/GUI5 E un upgrade la GUI4 in care introducem in pluis un radio button care controleaza HOLD ON/OFF pentru plot. Definim o variabila suplimentara: function GUI5_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. handles.output = hObject; % Aici cream noile variabile!!!!!! handles.speed=50; handles.angle=45; handles.rbstatus=0; %radio button status % Update handles structure guidata(hObject, handles);
Modificam codul pentru Radio button: % --- Executes on button press in radiobutton1. function radiobutton1_Callback(hObject, eventdata, handles) % hObject handle to radiobutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of radiobutton1 handles=guidata(hObject); %citim structura mm=get(hObject, 'Value'); handles.rbstatus=mm; guidata(hObject, handles); Si pentru pushbutton % --- Executes on button press in Throw_button. function Throw_button_Callback(hObject, eventdata, handles) % hObject handle to Throw_button (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) handles=guidata(hObject); speed=handles.speed; angle=handles.angle; mm=handles.rbstatus; if(mm==1) throw2(speed,angle); else throw2(speed,angle,1); end
Folosirea check-box-urilor Proiect: /Learn/Beat
%citim structura
Ilustreaza grafic si sonor compunerea a doua oscilatii cu frecvente apropiate care dau fenomenul de batai. GUI-ul arata asa:
Detalii function beats_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to beats (see VARARGIN) % Choose default command line output for beats handles.output = hObject; %%%ADDED%%% % initialise global variable cf global cf; cf=1000; %%%%%%%%%%% % Update handles structure guidata(hObject, handles);
O noutate aici: folosirea uei variabile globale cf. Variabile globale trebuie redeclarate ca globale in toate functiile care le folosesc! Functia asociata cu butonul “Play” % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% reference global variable global cf; % get beat frequency from text box bf=45; % make beats by combining two sinewaves %t=0:1/11025:1; t=0:1/44000:1; y=0.5*sin(2*pi*(cf-bf/2)*t)-0.5*sin(2*pi*(cf+bf/2)*t); soundsc(y,44000); % set default axes to figure and plot axes(handles.axes1); plot(t,y), axis([ 0 0.1 -1 1 ]), grid on return;
O noutate aici: folosirea functiei SOUNDSC soundsc(y,Fs) sends audio signal y to the speaker at sample rate Fs. If you do not specify a sample rate, soundsc plays at 8192 Hz. Like the sound function, soundsc assumes that y contains floating-point numbers. However, before playing the signal, soundsc scales the
values to fit in the range from -1.0 to 1.0, so that the audio is played as loudly as possible without clipping. specifies the bit depth (that is, the precision) of the sample values. The possible values for bit depth depend on the audio hardware available on your system. Most platforms support depths of 8 bits or 16 bits. If you do not specify bits, the soundsc function plays at an 8-bit depth.
soundsc(y,Fs,bits)
soundsc(y,Fs,bits,range), where range is of the form [low high], maps the values between low and high to the full sound range. The default range is [min(y) max(y)]. Specifying Fs and bits is optional.
Tips •
The soundsc function supports sound devices on all Windows and most UNIX platforms.
•
Most sound cards support sample rates between 5 kHz and 48 kHz. Specifying a sample rate outside this range produces unexpected results.
Functiile asociate cu check-box-urile % --- Executes on button press in checkbox1. function checkbox1_Callback(hObject, eventdata, handles) % hObject handle to checkbox1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of checkbox1 global cf; cf=1000; set(handles.checkbox1,'Value',1); set(handles.checkbox2,'Value',0); set(handles.text1,'String','Beats Demonstration (1000Hz)'); return; % --------------------------------------------------------------------
in y
% --- Executes on button press in checkbox2. function checkbox2_Callback(hObject, eventdata, handles) % hObject handle to checkbox2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of checkbox2 global cf; cf=2000; set(handles.checkbox2,'Value',1); set(handles.checkbox1,'Value',0); set(handles.text1,'String','Beats Demonstration (2000Hz)'); return; % --------------------------------------------------------------------
Variatiuni: /Learn/beats2
Observati1: Din GUIDE, daca salvam cu Save as si schimbam numele figurii, se creaza automat fisierul m asociat cu noul nume, care pastreaza toate modificarile facute de user!! Se poate modifica proprietatea “Style” a check-box-urilor, sa arate ca un Toggle Button, sau Pushbutton, sau Radio button, fara sa modificam deloc codul. Cea ma semnificativa variatiune pe tema asta este sa definim un edit box unde sa introducem valoarea frecventei de batai bf. Pentru asta, avem nevoie de inca o variabila globala: function beats3_OpeningFcn(hObject, eventdata, handles, varargin) handles.output = hObject; % initialise global variables global cf; global bf; cf=1000; bf=100;
% Update handles structure guidata(hObject, handles);
Iar codul pentru edit-box arata asa: function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit1 as text % str2double(get(hObject,'String')) returns contents of edit1 as a double global bf; handles=guidata(hObject); %citim structura num = str2double(get(hObject,'String')); if isnan(num) num = 100; set(hObject,'String',num); errordlg('Input must be a number', 'Error') end if (num>1000) || (num<1) num = 100; set(hObject,'String',num); errordlg('Bf out of range', 'Error') bf=num; end bf=num; guidata(hObject,handles)
Cate ceva despre File I/O 1. Exercitiu: Sa se scrie o matrice A[m,n] intr-un fisier text in asa fel incat fiecare element al matricii sa fie pe cate o linie a fisierului. File: fcreate.m % asta e un script nu o functie! % definim o matrice A si o scriem intr-un fisier text, in asa fel incat s-o % putem reconstitui usor. A=rand(4,8); [m n]=size(A); % m contine numarul de linii, n numarul de coloane fid=fopen('mdata1.txt','w'); if fid<0 disp('Cannot open file'); return end for i=1:m for j=1:n fprintf(fid, '%f\r\n', A(i,j)); end end fclose(fid);
Variatiune: Sa scriem matricea in fisier, cate o linie a matricii pe o linie a fisierului de iesire. File: fcreate2.m % asta e un script nu o functie! % definim o matrice A si o scriem intr-un fisier text, in asa fel incat s-o % putem reconstitui usor. A=rand(4,8); [m n]=size(A); % m contine numarul de linii, n numarul de coloane al A fid=fopen('mdata2.txt','w'); if fid<0 disp('Cannot open file'); return end for i=1:m for j=1:n fprintf(fid, '%4.0f ', 1000*A(i,j)); end fprintf(fid, '\r\n'); end fclose(fid);
Totul se poate scrie mai simplu: File: fcreate3.m % asta e un script nu o functie! % definim o matrice A si o scriem intr-un fisier text, in asa fel incat s-o % putem reconstitui usor. A=rand(4,8); [m n]=size(A); % m contine numarul de linii, n numarul de coloane al A fid=fopen('mdata3.txt','wt'); if fid<0 disp('Cannot open file'); return end fprintf(fid, ‘%3.0f’, 1000*A); fclose(fid);
OK. Acum sa le citim. Secventa de comenzi: fid=fopen(‘mdata1.txt’, ‘rt’); x=fscanf(fid, ‘%d’); intoarce in vectorul x TOATE valorile din fisier, indiferent cum sunt organizate. x este un vector cu N linii si o coloana (N- numarul total de valori din fisier) Ne propunem sa scriem un script – si ulterior o functie refolosibila – care sa citeasca datele dintr-un fisier text (se presupune ca sunt valori numerice acolo) si sa le organizeze in diverse configuratii de matrici specificate. File: fread1.m % citim fisierul specificat intr-o matrice % organizam matricea initiala copiind campurile intr-o alta matrice % de dimenziunea dorita [m,n] fid=fopen('mdata1.txt','rt'); if fid<0 disp('Cannot open input file') return end A=fscanf(fid, '%d'); A=A'; fclose(fid); m=4; %numarul de linii n=8; %numarul de coloane k=1; B=zeros(m,n); for i=1:m for j=1:n B(i,j)=A(k); k=k+1; end end
Variatiune. Sa se scrie o functie care primeste ca argumente numele fisierului si numarul de linii si coloane al matricii de iesire. Citeste datele din fisier si intoarce o matrice de dimensiunea specificata cu datele citite din fisier. File: fread2.m function B=read(file_name, m, n) % m si n sunt dimensiunile matricii de iesire care contine datele din % fisier fid=fopen(file_name,'rt'); if fid<0 disp('Cannot open input file') return end A=fscanf(fid, '%d'); A=A'; fclose(fid); k=1; B=zeros(m,n); for i=1:m for j=1:n B(i,j)=A(k); k=k+1; end end
%A is a local variable
Exemple de apel a acestei functii: B=read2(‘mdata1.txt’,4,8) Se pot citi si bucati mai mici din fisierul initial: B=read2(‘mdata1.txt’,2,8) sau se pot reorganiza altfel datele: B=read2(‘mdata1.txt’,3,7) OK – ce urmeaza? 1. Comunicatie seriala. Primirea unor pachete de date pe linia seriala, interpretarea lor, salvarea in fisiere, plotarea. Transmisia unor pachete de raspuns, conditionate de primirea pachetelor de intrare. 2. Timere, cum se folosesc 3. Fuzzy logic 4. Neural networks 5. Automate celulare Cam asta ar fi si ordinea de abordare Pentru inceput, e bine sa citesc help-ul pentru urmatoarele demo-uri: Serial port demos. demos_ascii - Introduction to serial port ASCII read and write operations. demos_async - Introduction to serial port asynchronous operations. demos_binary - Introduction to serial port binary read and write operations.
Pentru teste, pot genera cu terminalul Br@y aproape orice pachete repetitive de date. Un prim test cu linia seriala:
% % % %
FILE: serial_hello.m Creaza un nou obiect de tip serial port (COM1) il deschide trimite un string pe linia seriala inchide portul si sterge variabilele asociate
%Verificam daca portul exista deja existing_ports=instrfind('Port', 'COM1'); if length(existing_ports) > 0 disp('Port already in use!'); delete(existing_ports); clear existing_porta; end
;
% cream noul obiect newport = serial('COM1', 'baudrate', 9600, 'terminator', 'CR'); fopen(newport) fwrite(newport, 'Hello World! - cu fwrite'); fprintf(newport, 'Alt mesaj emis cu cu fprintf'); fprintf(newport, '%3.0f', 123); A=1:5; fprintf(newport, A); % se emite 0x01, 0x02, 0x03, 0x04, 0x05!!! fclose(newport); delete(newport) clear newport; Se pot schimba individual parametrii portului, de exemplu: set(newport, 'BaudRate', 4800) set(newport, 'InputBufferSize', set(newport, 'TimeOut', .1);
300 )
Un interludiu Functia fill deseneaza un poligon plin cu o culoare specificata Exemple: fill (X, Y, c) X si Y sunt matrici care contin coordonatele colturilor poligonului c este culoarea c este o matrice de forma [R G B] unde R, G, B sunt numere intre 0 si 1. De exemplu: [1 1 1] inseamna alb [0 0 0] inseamna negru, [1 0 0] inseamna rosu pur Exemplu de utilizare: file: corners.m % % % % % %
o functie care primeste ca argumente coordonatele (x,y) ale unui punct din plan si o constanta a - cell size si creaza DOI vectori X, Y care contin coordonatele colturilor unui patrat cu centrul in punctul (x,y) Numerotarea colturilor incepe cu cel din dreapta-jos si se continua in sens trigonometric
% defineste colturile unui patrat de latura a in jurul punctului specificat function [X,Y]=corners(x,y,a) x1=x+a/2; x2=x+a/2; x3=x-a/2; x4=x-a/2; y1=y-a/2; y2=y+a/2; y3=y+a/2; y4=y-a/2; X=[x1 x2 x3 x4]; Y=[y1 y2 y3 y4];
Exemplu de utilizare a acestei functii %un test de folosire a functiei corners cu fill figure(1); hold on axis equal; k=[1 1 1]; % k este culoarea de fill R G B % daca R=G=B se obtin nuante de gri!! for i=10:20:500 for j=10:20:500 [X,Y]=corners(i,j,20); fill(X,Y,k); end end Si efectul este:
Se poate reorganiza mai general asa: File: draw_map.m % o functie care primeste ca input doi parametri
% number_of_cells si cell_size % deseneaza o harta grid patrata cu latura data de % number_of_cells*cell_size % harta este simetrica in jurul originii % de exemplu draw_map(50, 20) deseneaza un teritoriu patrat (50x50 celule) intins intre % -500 si +500 function draw_map(number_of_cells, cell_size) size=number_of_cells*cell_size; color=[1 1 1]; for ii=-size/2:cell_size:size/2 for jj=-size/2:cell_size:size/2 [X,Y]=corners(ii,jj,cell_size); fill(X,Y,color); end end
Nota: In main, inainte de a apela draw_map() e necesar sa scriem: figure(1); hold on; axis equal; In continuare, avem nevoie de o functie paint_cell(x,y,color_shade) care sa coloreze celula hartii, corespunzatoare coordonatelor(x,y) specificate. Se presupune ca cell_size este globala. De exemplu, varianta asta, care afiseaza nuante de gri:
% % % % %
paint_cell e o functie care primeste ca input coordonatele unui punct in plan (x,y) si inca un parametru care indica nuanta de culoare folosita pentru fill. color_shade ia valori intre 0 si 1. se identifica celula hartii corespunzator coordonatelor specificate, apoi se determina colturile patratului si in final se face fill
function paint_cell(x,y,color_shade,cell_size) color_shade=1-color_shade; if x>=0 center_x=cell_size*floor(x/cell_size)+cell_size/2; else center_x=cell_size*floor(x/cell_size)-cell_size/2; end if y>=0 center_y=cell_size*floor(y/cell_size)+cell_size/2; else center_y=cell_size*floor(y/cell_size)-cell_size/2; end [X,Y]=corners(center_x,center_y,cell_size); color=[color_shade, color_shade, color_shade]; fill(X,Y,color);
Iata si functia main care deseneaza o diagonala: figure(1) hold on axis equal global cell_size;
cell_size=20; draw_map(51,cell_size); X=0:10:500; Y=0:10:500; for i=1:length(X) paint_cell(X(i),Y(i),0.8,cell_size); end
Generarea unor sunete cu frecventa/forma controlata si salvarea intr-un fisier wav. Functia MATLAB care scrie efectiv datele in fisier este: WAVWRITE Write Microsoft WAVE (".wav") sound file. WAVWRITE(Y,FS,NBITS,WAVEFILE) writes data Y to a Windows WAVE file specified by the file name WAVEFILE, with a sample rate of FS Hz and with NBITS number of bits. NBITS must be 8, 16, 24, or 32. Stereo data should be specified as a matrix with two columns. For NBITS < 32, amplitude values outside the range [-1,+1] are clipped. WAVWRITE(Y,FS,WAVEFILE) assumes NBITS=16 bits. WAVWRITE(Y,WAVEFILE) assumes NBITS=16 bits and FS=8000 Hz. Daca folosim valorile implicite de mai sus, matricea Y care trebuie pregatita pentru o secunda de ton ar trebui sa aiba 8000 de elemente. (in intervalul [-1,1]) Exemplu: x=linspace(0,1,8000) y=sin(2*pi*x) plot(x,y)
% creaza o matrice cu 8000 de elemente liniar crescatoare intre 0 si 1
file: snd1.m total_time=3; %in secunde Fs=20000; % sample frequency. Numarul de esantioane pe secunda total_samples=Fs*total_time; % numarul total de esantioane f0=7.6; % frecventa sunetului generat in Hz x=linspace(0,total_time,total_samples); y=sin(2*pi*f0*x); plot(x,y); %sound(y,Fs); wavwrite(y,Fs,'rada.wav'); file: snd2.m total_time=3; %in secunde Fs=40000; % sample frequency. Numarul de esantioane pe secunda total_samples=Fs*total_time; % numarul total de esantioane f0=7.6; % frecventa sunetului generat in Hz f1=16000; x=linspace(0,total_time,total_samples); y=(sin(2*pi*f0*x)).*(sin(2*pi*f1*x)); plot(x,y); sound(y,Fs); wavwrite(y,Fs,'rada2.wav'); Varianta cu modulatie de frecventa %Modulatie de frecventa total_time=2; %in secunde Fs=40000; % sample frequency. Numarul de esantioane pe secunda total_samples=Fs*total_time; % numarul total de esantioane f0=8; % frecventa sunetului generat in Hz f1=15000;
t=linspace(0,total_time,total_samples); fm=f1+1000*sin(2*pi*f0*t); y=0.9*sin(2*pi*t.*fm); plot(t,y); axis ([0 0.01 -1 1]); %sound(y,Fs); wavwrite(y,Fs,'rada2.wav'); De notat aici si modul de plot cu specificarea axelor.