Comments
Transcript
Lezioni del 25 settembre 2007/02 ottobre 2007
a a 3 -4 lezione di laboratorio Laurea Ingegneria CIVILE Lauree Specialistiche in Ingegneria CHIMICA, ELETTRONICA, AMBIENTE a.a. 2007-2008 m-file File di testo contenente codici MATLAB. Consente di memorizzare ed organizzare istruzioni e comandi MATLAB script m-file function m-file script • Standard ASCII file di testo • Esegue una serie di comandi MATLAB sul workspace base % eps1.m - m-file per % calcolare la precisione di % macchina num=0; EPS=1; while (1+EPS)>1 EPS=EPS/2; num=num+1; tab(num,:)=[num EPS]; fprintf('%3d %30.16e\n',... tab(num,:)); end EPS=tab(end-1,2) N.B. Lo script non Il carattere “ % “ è usato per: accetta argomenti • scrivere commenti all’interno di di input e di output M-file •definire il formato di stampa Salvare e richiamare un m-script Salvare un m-script: Dopo avere digitato le istruzioni nella finestra dell’editor di testo, si salva selezionando sulla barra la voce file e scegliendo nel menu : Save as. Assegnare un nome: eps1 Richiamare: Si richiama digitando solo il nome con cui è stato memorizzato il file eps1 N.B. Lo script opera sul Workspace base. Risultati del file eps1.m % eps1.m - m-file per % calcolare la precisione di % macchina num=0; EPS=1; while (1+EPS)>1 EPS=EPS/2; num=num+1; tab(num,:)=[num EPS]; fprintf('%3d %30.16e \n',... tab(num,:)); end EPS=tab(end-1,2) » eps1 1 5.0000000000000000e-001 2 2.5000000000000000e-001 3 1.2500000000000000e-001 ………………… 52 2.2204460492503131e-016 53 1.1102230246251565e-016 » La variabile EPS è stata scelta con lettere maiuscole per differenziarla dalla variabile eps del Matlab . m-file function Argomento di output Nome della funzione Argom. di input Help Online Codice function s = fatt(c) % %fatt calcola il fattoriale di c. % s=1; if c>=1 for i=1:c s=s*i; end end Caso generale function [out1,out2,out3] = nome_fun(in1,in2) Salvare e Richiamare una m-function – Si salva in modo analogo ad un m-script: nome_fun – Si richiama digitando un’uguaglianza del tipo:[out1,out2,out3] = nome_fun(in1,in2) – out1,out2,out3 sono i parametri in uscita, – in1,in2 sono i parametri in input valore=fatt(5) N.B. La function • accetta argomenti di input e di output • opera su un’area di memoria distinta dal Workspace base (variabili locali) Risultati della function fatt.m » numero =5; » valore=fatt(numero) function s = fatt(c) valore = % 120 % fatt calcola il fattoriale » del numero c usando la definizione. % s=1; if c>=1 for i=1:c s=s*i; Usando la function prod del Matlab, end si può anche calcolare il fattoriale end di un numero: » valore=prod(1:5) Osservazione: Esiste inoltre la valore = 120 function factorial di Matlab » che restituisce il fattoriale di un numero (si faccia l’help). Un secondo esempio di file function function m = media(v) » v =[-3 0 4 5 6]; % » media_ar=media(v) % MEDIA calcola la media media_ar = % aritmetica di n numeri 2.4000 % memorizzati nel vettore v. » % n=length(v); m=0; for i=1:n m=m+v(i); end Usando la function sum m=m/n; di Matlab si ottiene anche la Osservazione: Esiste la function mean di Matlab che restituisce la media di n Numeri (si faccia l’help). media : » v =[-3 0 4 5 6]; » media_ar=sum(v)/length(v) media_ar = 2.4000 » Per utilizzare i file function sui PC del laboratorio Sul PC o sul floppy sono presenti le cartelle: Sis_lin, Eq_non_lin, Approx, ecc. che non devono essere modificate per alcun motivo. 2. Copiare perciò dalla cartella relativa al problema, la function che si vuole utilizzare nella directory di lavoro ad esempio: C:\Documents and Settings\studente\Documenti 3. Scegliere, in Current Directory del Matlab, il percorso: C:\Documents and Settings\studente\Documenti Il file che si sta creando nell’ editor e che talvolta contiene i dati per l’input della function che si vuole utilizzare, dovrà essere salvato nella directory C:\Documents and Settings\studente\Documenti Buon lavoro!!!! 1. Funzioni matematiche elementari round(x) Arrotonda all’intero più vicino fix(x) Arrotonda all’intero più vicino verso 0 » x=[-1.9 -0.2 3.4 5.6 7.0] floor(x) Arrotonda all’intero più vicino verso - ceil(x) Arrotonda all’intero più vicino verso sign(x) -1 se x è negativo, 1 se positivo rem(x,y) Resto della divisione x/y abs(x) Modulo o valore assoluto sqrt(x) Radice quadrata exp(x) Esponenziale log(x) Logaritmo naturale log10(x) Logaritmo in base 10 log2(x) Logaritmo in base 2 » round(x) ans = -2 0 » fix(x) ans = -1 0 » floor(x) ans = -2 -1 » ceil(x) ans = -1 0 3 6 7 3 5 7 3 5 7 4 6 7 Funzioni trigonometriche sin(x) Seno cos(x) Coseno tan(x) Tangente cot(x) Cotangente asin(x) Arcseno acos(x) Arccoseno atan(x) Arctangente acot(x) Arccotangente sinh(x) Seno iperbolico cosh(x) Coseno iperbolico » x=[0:0.2:1]'; » y=sin(x); » [x y] ans = 0 0 0.2000 0.1987 0.4000 0.3894 0.6000 0.5646 0.8000 0.7174 1.0000 0.8415 tanh(x) Tangente iperbolica L’angolo x deve essere espresso in radianti!!! Esistono anche funzioni trigonometriche che agiscono su angoli misurati in gradi. ciclo for % ESEMPIO N = 4; for I = 1:N for J = 1:N A(I,J) = 1/(I+J-1); end end for espressione istruzioni end • È simile a quello di altri linguaggi di programmazione • Ripete le istruzioni molte volte • Può essere annidato Osservazione: le istruzioni del ciclo su scritto consentono di costruire la matrice di Hilbert 4x4 che si può ottenere chiamando la function Risultati >> format rat >> A A = 1 1/2 1/3 1/4 >> 1/2 1/3 1/4 1/5 1/3 1/4 1/5 1/6 1/4 1/5 1/6 1/7 Esercizio 1: applicazione del ciclo for Scrivere un file script tale che, assegnate due matrici A e B R nm con n=3 e m=3, A=[1:3; 4:6; 7:9], B=[5 -6 -9; 1 1 0; 24 1 0], determini la matrice C delle stesse dimensioni, che ha l’elemento C(i,j) pari a: C(i,j)=A(i,j)+cos((i+j)*pi/(n+m))*B(i,j). N.B. Si salvi lo script col nome prova File prova.m A=[1:3; 4:6; 7:9]; B=[5 -6 -9; 1 1 0; 24 1 0]; [n,m]=size(A); for i =1:n for j=1:m C(i,j)=A(i,j)+cos((i+j)*pi/(n+m))*B(i,j); end end disp('Il risultato è') disp(C) Risultati file prova.m >>prova Il risultato è 3.5000 2.0000 4.0000 4.5000 -5.0000 7.1340 >> 7.5000 6.0000 9.0000 Operatori relazionali e logici Relazionali Logici < Minore <= Minore o uguale > Maggiore >= Maggiore o uguale == Uguale ~= Diverso & and | or ~ not Gli operatori relazionali precedono nell’ordine gli operatori logici. ciclo while while condizione_logica istruzioni end Consente di ripetere le istruzioni sotto il controllo di una condizione logica % ESEMPIO I=1; N=4; while I <= N J = 1; while J <= N A(I,J) =(I+J); J=J+1; end I=I+1; end Risultati >> A A = 2 3 4 5 3 4 5 6 4 5 6 7 5 6 7 8 >> Costruire con cicli while la matrice di Hilbert 4x4. Costrutto if - else • È una struttura condizionale • Se una condizione è verificata esegue le istruzioni associate if condizione_logica istruzioni end if condizione_logica_1 istruzioni elseif condizione_logica_2 istruzioni … elseif condizione_logica_n N.B. La parola chiave elseif, nel costrutto qui presentato, istruzioni va scritta senza spazio tra else ‘else’ e ‘if ‘. istruzioni end Esempio Questo script consente di N=4; for I=1:N costruire una matrice for J=1:N simmetrica 4che ha tutti if I == J A(I,J) = N^2; elseif I<J A(I,J) = J; else A(I,J) = I; end 4 ^2 sulla diagonale principale, il vettore [2 3 4] sulla prima codiagonale (inferiore e superiore), il vettore [3 4] sulla seconda codiagonale (inferiore e superiore) e gli elementi A(1,4) e A(4,1) uguali a 4. end end Risultati >> A A = 16 2 3 4 2 16 3 4 3 3 16 4 4 4 4 16 >> Lo studente verifichi che lo script precedente, per N generico, costruisce una matrice simmetrica che ha N^2 su ogni elemento della diagonale principale e il vettore v=k+1: N sulla codiagonale k-esima (inferiore e superiore), k=1,…,N-1. Comando di input input: inserimento di variabili numeriche da tastiera Sintassi: nome_var=input(str) str: stringa che si vuole compaia sul prompt » z=input(' Introduci il valore di z ') Introduci il valore di z -12 z = -12 » a=input(' Introduci la matrice a ') Introduci la matrice a [0 -1 0; 3:5; -2*ones(1,3)] a = 0 -1 0 3 4 5 -2 -2 -2 Comando di input input: inserimento di stringhe da tastiera Sintassi: var_str=input(str) oppure var_str=input(str, 's') str: stringa che compare sul prompt » flag=input('Vuoi continuare? ') Vuoi continuare? 'Si' flag = Si » flag=input('Vuoi continuare? ', 's') Vuoi continuare? Si flag = Si Comandi di output disp consente di stampare linee di testo e valori di variabili. Sintassi: disp(str) str stringa o nome di una variabile numerica che si vuole far comparire sul prompt. » disp('valore della funzione') valore della funzione num2str(x) converte lo scalare x in una »x=sqrt(2); » disp(['Il valore di x stringa di Il valore di x è 1.4142 caratteri »x=sqrt(2); »disp(x) 1.4142 è ',num2str(x)]) Comandi di output fprintf consente di stampare linee di testo, valori numerici e matrici (tabelle) specificandone il formato. Sintassi: fprintf(' formato \n', tab' ) formato è una stringa contenente i formati scelti con la specifica f oppure e, per i formati virgola fissa o virgola mobile con la regola: %campo_totale.num_cifre_decimalitipo_formato I formati devono essere in numero pari alle colonne della matrice tab; %campod è la scrittura per i numeri interi \n serve per andare a capo » temp=31; » fprintf('La temperatura è di %4.1f gradi C°\n',temp) La temperatura è di 31.0 gradi C° %f consente la stampa dei numeri in fixed point, %e consente la stampa in floating point Nei formati f ed e il numero alla sinistra del punto è il campo totale, quello alla destra indica quante cifre decimali devono essere stampate » fprintf(' %f\n',pi) 3.141593 » fprintf(’ %13.10f\n ',pi) 3.1415926536 » fprintf(’ %18.10e\n ',pi) 3.1415926536e+000 Come visualizzare una tabella • Quesito: Perché è stato scritto tab'? • Risposta: Per stampare nel formato scelto, la matrice tab, che è stata costruita per colonne, così come si visualizza sul Command quando si digita tab. • N.B. Se la matrice tab fosse stata costruita per righe in fprintf sarebbe bastato porre semplicemente tab Esercizio 2 • Calcolare la funzione f = e-xsin(x) nei punti appartenenti all’intervallo [0,1] equispaziati con passo 0.2. • Costruire una tabella contenente i valori di x e di f e stamparla utilizzando: • 3 cifre decimali in formato virgola fissa per x • 8 cifre decimali in virgola fissa per f. • N.B. Si memorizzi il file col nome funzione File funzione.m e risultati x=[0:.2:1]; % vettore riga f=exp(-x).*sin(x); tab=[x; f];%tab costruita per righe fprintf(' x f\n') fprintf('%6.3f %12.8f\n',tab) Numero di formati pari alle righe della matrice tab; Risultati x 0.000 0.200 0.400 0.600 0.800 1.000 f 0.00000000 0.16265669 0.26103492 0.30988236 0.32232887 0.30955988 Esercizio 3 • Costruire una stringa che mostri il valore di • con 6 cifre decimali; utilizzare poi un comando di output per farlo stampare sul prompt. • Creare la stringa di input che consente di assegnare alla variabile A una matrice generica. • Creare la stringa di input che consente di assegnare alla variabile f la stringa 4ln(x)-7e-x. Soluzioni esercizio 3 1. » str=[‘Il valore di pi greco è ‘, num2str(pi,7)]; % il secondo numero in % parentesi rappresenta il numero massimo di % cifre significative con cui si vuole % rappresentare pi » disp(str) Il valore di pi greco è 3.141593 2. » A=input('inserisci la matrice A = '); inserisci la matrice A = -3*ones(2,3) » 3. » f=input('inserisci la funzione ') inserisci la funzione '4*log(x)-7*exp(-x)' » f = 4*log(x)-7*exp(-x) Presenza di un parametro in una stringa La presenza di un parametro in una stringa può talvolta essere causa di errore. k = 4.5051 fs = x.^2+k*x-3 clc clear all x=(-4:0.5:0)'; k=4.50511 fs='x.^2+k*x-3' fplot(fs,[-4 0]) ??? Error using ==> inline.feval Not enough inputs to inline function. Error in ==> fplot at 102 x = xmin; y = feval(fun,x,args{4:end}); Error in ==> concatenaz_strin at 26 fplot(fs,[-4 0]) La presenza di un parametro nella stringa fs produce errore nel comando fplot. Occorre trasformare il valore numerico di k in stringa e, di conseguenza, modificare la scrittura di fs. Espressione corretta della stringa fs da utilizzare nel comando fplot ks=num2str(k) % ks è la stringa '4.5051' (il valore di k è % arrotondato con 4 decimali) fs=['x.^2+',ks,'*x-3'] % fs è ottenuta come concatenazione di stringhe fplot(fs,[-4 0]) Nota Bene: Il comando num2str(k) trasforma k in una stringa di cifre (le stesse cifre di k) con 4 cifre decimali. Valutazione di stringa Programma stringhe: clc clear all In questo caso la stringa x=(-4:0.5:0)';format long è valutata correttamente k=4.50511 fs='x.^2+k*x-3' f=eval(fs); format short [x f] ks=num2str(k); fs=['x.^2+',ks,'*x-3'];f=eval(fs);[x f] ks=num2str(k, '%10.5f')% così prende tutte le cifre di k fs=['x.^2+',ks,'*x-3']; f=eval(fs); [x f] Output del file stringhe k = 4.50511000000000 fs = x.^2+k*x-3 ks = 4.50511 fs = x.^2+4.50511*x-3 ans = ans = -4.0000 -3.5000 -3.0000 -2.5000 -2.0000 -1.5000 -1.0000 -0.5000 0 -5.0204 -6.5179 -7.5153 -8.0128 -8.0102 -7.5077 -6.5051 -5.0026 -3.0000 -4.0000 -3.5000 -3.0000 -2.5000 -2.0000 -1.5000 -1.0000 -0.5000 0 -5.0204 -6.5179 -7.5153 -8.0128 -8.0102 -7.5077 -6.5051 -5.0026 -3.0000 Presenza di un parametro in una stringa: un altro caso di errore function tab=tabella(x,fs) f=eval(fs); tab=[x f]; clc clear all x=(-4:0.5:0)'; k=4.50511; fs='x.^2+k*x-3'; tab=tabella(x,fs) La funzione tabella non ha visibilità sul parametro k. ??? Error using ==> eval Undefined function or variable 'k'. Error in ==> tabella at 2 f=eval(fs) Error in ==> concatenaz_strin at 26 tab=tabella(x,fs) Un modo per eliminare il problema è ancora ricorrere all’utilizzo del comando num2str: Con l’uso di num2str, la function tab=tabella(x,fs) function non ha problemi f=eval(fs); di visibilità su k perché k non tab=[x f]; è più un parametro numerico. clc clear all x=(-4:0.5:0)'; k= 4.50511; ks=num2str(k, '%10.5f'); fs=['x.^2+',ks,'*x-3']; tab=tabella(x,fs) tab = -4.0000 -3.5000 -3.0000 -2.5000 -2.0000 -1.5000 -1.0000 -0.5000 0 -5.0204 -6.5179 -7.5153 -8.0128 -8.0102 -7.5077 -6.5051 -5.0026 -3.0000 Altro modo di risolvere il problema function tab=tabella(x,fs) global k f=eval(fs); tab=[x f]; clc clear all global k x=(-4:0.5:0)'; k= 4.50511; fs=['x.^2+k*x-3']; tab=tabella(x,fs) tab = -4.0000 -3.5000 -3.0000 -2.5000 -2.0000 -1.5000 -1.0000 -0.5000 0 -5.0204 -6.5179 -7.5153 -8.0128 -8.0102 -7.5077 -6.5051 -5.0026 -3.0000