Facoltà di Ingegneria Industriale
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Laurea in Ingegneria Energetica, Meccanica e dei Trasporti
Matlab/Octave - Esercitazione 3
‣ funzioni
‣ definizione
ed invocazione delle funzioni
‣ semantica dell’invocazione
‣ ambiente locale e globale
‣ grafici 3D
‣ variabili di tipo funzione
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
1
Richiami teorici
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
In Matlab/Octave, una funzione è una sequenza di comandi che:
‣ ha un nome
‣ può essere invocata
‣ è influenzata da parametri definiti dal chiamante
‣ produce un risultato
Questo consente di:
‣ scrivere un codice modulare organizzato
‣ riutilizzare una porzione di codice più volte senza riscrivere il codice
stesso
‣ Suddividere operazioni complesse in un insieme di operazioni semplici
Definizione di una funzione
La prima riga del file deve essere del tipo:
function [output1 output2 ...] = nome_funzione(input1, input2, ...)
Invocazione di una funzione
[output1 output2 ...] = nome_funzione(input1, input2, ...)
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
2
Richiami teorici
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Ogni funzione ha associato un record di attivazione che contiene:
‣ tutti i dati relativi all’ambiente locale della funzione
‣ l’indirizzo di ritorno del programma chiamante
‣ altri dati
I record di attivazione delle funzioni sono memorizzati in una porzione della memoria di
lavoro chiamata stack.
Stack
Script
principale
...
Workspace
chiama f1
record di attivazione di f1 - 3
record di attivazione di f2 - 2
record di attivazione di f1 - 2
f1
f2
chiama f2
chiama f1
record di attivazione di f2
record di attivazione di f1
workspace
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
3
Esercizio 1
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Scrivere un programma che chiede all'utente di inserire un
numero positivo (nel caso in cui il numero non sia positivo
ripetere inserimento).
-Verifica se il numero è perfetto;
-in caso contrario dice se è abbondante o difettivo.
Un numero è perfetto se corrisponde alla somma dei suoi
divisori, escluso se stesso; abbondante se è maggiore della
somma dei suoi divisori; altrimenti difettivo.
-Richiede
un altro numero e controlla se i due numeri sono
amici.
a,b sono amici se (somma dei divisori di a) = b e viceversa.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
4
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Script principale
Script principale - Parte 1
n1 = inserisciNumero();
[p,a] = controllaSePerfetto(n1);
if(p)
disp([num2str(n1), ' è perfetto'])
else
disp([num2str(n1), ' non è perfetto'])
if(a)
disp([num2str(n1), ' è abbondante'])
else
disp([num2str(n1), ' non è abbondante'])
end
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
5
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Script principale
Chiedo in input un numero e contemporaneamente controllo se è positivo. Nel caso non
lo sia, ripeto l’operazione.
n1 = inserisciNumero();
Tutte le specifiche riguardanti l’immissione di un numero positivo da parte dell’utente,
possono essere soddisfatte con una sola istruzione.
Questo è possibile se l’istruzione è una funzione.
Di seguito la definizione della funzione inserisciNumero che analizzaremo
successivamente nel dettaglio.
function numero = inserisciNumero()
Controllo se il numero inserito è perfetto, abbondante o difettivo.
Anche queste operazioni possono essere racchiuse nella funzione:
[p,a] = controllaSePerfetto(n1);
function [perfetto,abbondante] = controllaSePerfetto(numero)
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
6
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Script principale
La funzione controllaSePerfetto analizza numero e pone p=1 se numero è perfetto,
a=1 se abbondante e a=0 se difettivo.
In base al risultato fornito dalla funzione visualizzo sulla command window la stringa
corrispondente.
if(p)
disp([num2str(n1), ' è perfetto'])
else
disp([num2str(n1), ' non è perfetto'])
if(a)
disp([num2str(n1), ' è abbondante'])
else
disp([num2str(n1), ' non è abbondante'])
end
end
L’esecuzione dello script principale è terminata. Vediamo ora nel dettaglio tutte le funzioni
che sono state invocate, iniziando da inserisciNumero.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
7
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
MATLAB/Octave - Esercitazione 3
inserisciNumero
Definisco la funzione specificandone il nome, i parametri di input ed i parametri di
output.
function numero = inserisciNumero()
Nel nostro caso la funzione insericiNumero non ha parametri di input.
Quest’ultimi le vengono passati da tastiera tramite il comando input.
%
%
%
%
%
%
numero = inserisciNumero()
controlla che il numero inserito sia effettivamente
positivo
intero
uno scalare
I commenti che seguono (o precedono) la definizione della funzione costituiscono
l’help della funzione stessa.
Provare a digitare sulla commad window >>help inserisciNumero.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
8
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
MATLAB/Octave - Esercitazione 3
inserisciNumero
Per essere sicuri che la funzione venga individuata ed
eseguita da Matlab/Octave è necessario:
‣ porla nella stessa cartella dello script principale
(consigliato)
o
‣ aggiungere la cartella di lavoro nei percorsi in cui Matlab/
Octave cerca le funzioni:
‣ usare il comando addpath
‣ specificare il percorso tramite il menu a tendina: File/
Set Path (solo Matlab)
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
9
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
MATLAB/Octave - Esercitazione 3
inserisciNumero
Chiedo in input il numero
controllando che tale numero:
‣ non sia negativo: numero<0
‣ non sia decimale: round(numero)~=numero
‣ non sia un vettore: max(size(numero))>1
numero = input(' inserisci un intero positivo ');
while(numero<0|round(numero)~=numero|max(size(numero))>1)
numero = input(' inserisci un intero positivo ');
end
A questo punto l’esecuzione della funzione inserisciNumero è terminata.
Lo stack riporta l’esecuzione allo script principale.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
10
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
MATLAB/Octave - Esercitazione 3
controllaSePerfetto
Vediamo nel dettaglio la seconda funzione chiamata dallo script principale.
function [perfetto,abbondante] = controllaSePerfetto(numero)
% function [perfetto,abbondante]=controllaSePerfetto(numero)
%
% perfetto= 1 numero perfetto
% perfetto= 0 altrimenti
Si noti che i nomi delle variabili differiscono dalla chiamata della funzione alla definizione
della funzione stessa.
Questo è possibile perchè n1, p ed a sono variabili globali mentre perfetto,
abbondante e numero sono variabili locali, definite unicamente all’interno della
funzione.
Quando l’esecuzione passa dallo script principale alla funzione, viene automaticamente
operata l’assegnazione:
numero = n1
Quando l’esecuzione ritorna allo script principale, invece, le assegnazioni sono:
p = perfetto
a = abbondante
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
11
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
MATLAB/Octave - Esercitazione 3
controllaSePerfetto
La funzione controllaSePerrfetto chiama immediatamente un’altra funzione:
sommaDivisori.
somma = sommaDivisori(numero);
Questa funzione prende in input il numero specificato dall’utente e ne calcola la somma
dei divisori.
Inizializzo le due variabili d’uscita e controllo se il numero è perfetto. In tal caso pongo
ad 1 la variabile perfetto.
perfetto=0;
abbondante=[];
if (somma==numero)
perfetto=1;
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
12
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
MATLAB/Octave - Esercitazione 3
controllaSePerfetto
Controllo se il numero è abbondante o difettivo ed assegno il relativo valore ad
abbondante.
if(somma>numero)
abbondante=1;
else
abbondante=0;
end
Vediamo ora nel dettaglio come opera la funzione sommaDivisori, chiamata da
controllaSePerfetto.
function somma = sommaDivisori(numero)
% function somma=sommaDivisori(numero)
%
% restituisce la somma dei divisori di numero
%
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
13
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
controllaSePerfetto
MATLAB/Octave - Esercitazione 3
sommaDivisori
Il numero di divisori di numero dev'essere necessariamente minore o uguale alla (metà
di numero) + 1. I numeri maggiori di numero/2 non possono dividere il numero
stesso.
somma = 0;
ii = 1;
while(ii<numero/2+1)
if(mod(numero,ii)==0)
somma = somma + ii;
end
ii = ii+1;
end
La funzione mod(x, y) restutuisce il resto della divisione x./y.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
14
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Script principale
Script principale - Parte 2
La seconda parte dell’esercizio ci chiede nuovamente di prendere in ingresso un
numero inserito da utente.
Per farlo non occorre scrivere nuovo codice, sarà sufficiente richiamare la funzione già
invocata nella prima parte.
n2=inserisciNumero();
Controllo se n1 e n2 sono amici attraverso l’invocazione della funzione
amici=controllaSeAmici(n1,n2);
Visualizzo i risultati sulla command window
if(amici)
disp([num2str(n1), ' e ', num2str(n2),' sono amici'])
else
disp([num2str(n1), ' e ', num2str(n2),' non sono amici'])
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
15
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
Script principale
MATLAB/Octave - Esercitazione 3
controllaSeAmici
La funzione controllaSeAmici richiama la funzione sommaDivisori per due volte al
suo interno.
Ricordiamo che, per ogni invocazione di funzione, ne viene creata un’istanza (una
copia). L’esecuzione delle due istanze sono tra loro indipendenti.
function amici=controllaSeAmici(numero1,numero2)
%
% controlla se i due numeri sono amici
%
amici=0;
if (numero1==sommaDivisori(numero2)& numero2==sommaDivisori(numero1))
amici=1;
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
16
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Esercizio 1 - Codice completo
% Script principale
n1 = inserisciNumero();
[p,a] = controllaSePerfetto(n1);
if(p)
disp([num2str(n1), ' è perfetto'])
else
disp([num2str(n1), ' non è perfetto'])
if(a)
disp([num2str(n1), ' è abbondante'])
else
disp([num2str(n1), ' è difettivo'])
end
end
n2=inserisciNumero();
amici=controllaSeAmici(n1,n2);
if(amici)
disp([num2str(n1), ' e ', num2str(n2),' sono amici'])
else
disp([num2str(n1), ' e ', num2str(n2),' non sono amici'])
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
17
Esercizio 1 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Esercizio 1 - Codice completo
function numero=inserisciNumero()
% numero=inserisciNumero()
%
% controlla che il numero inserito sia effettivamente
% positivo
% intero
% uno scalare
numero=input(' inserisci un intero positivo ');
% controllo che il numero sia intero positivo
while(numero<0|round(numero)~=numero|max(size(numero))>1)
numero=input(' inserisci un intero positivo ');
end
function [perfetto,abbondante] = controllaSePerfetto(numero)
% perfetto= 1 numero perfetto
% perfetto= 0 altrimenti
somma = sommaDivisori(numero);
perfetto = 0;
abbondante = [];
if (somma==numero)
perfetto = 1;
end
if(somma>numero)
abbondante = 1;
else
abbondante = 0;
end
function amici=controllaSeAmici(numero1,numero2)
%
% controlla se i due numeri sono amici
%
amici=0;
if (numero1==sommaDivisori(numero2)& numero2==sommaDivisori(numero1))
amici=1;
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
function somma = sommaDivisori(numero)
% restituisce la somma dei divisori di numero
somma = 0;
ii = 1;
while(ii<numero/2+1)
if(mod(numero,ii)==0)
somma = somma + ii;
end
ii = ii+1;
end
Informatica B - Esercitazione 10 del 10/12/2010
18
Esercizio 2
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Si considerino due matrici di interi A e B, di uguali
dimensioni. Diciamo che A domina B se, confrontando i valori
in posizioni corrispondenti, risulta che il numero dei valori
in A maggiori dei corrispondenti valori in B è più grande del
numero di quelli di B maggiori dei corrispondenti in A ed
inoltre gli elementi corrispondenti non sono mai uguali (se
due elementi corrispondenti sono uguali la dominanza non è
definita).
Si codifichi la funzione domina() che riceve le matrici come
parametri e restituisce 1 se la prima domina la seconda, -1 se
la seconda domina la prima, 0 altrimenti.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
19
Esercizio 2 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Script principale
Creo le due matrici casuali in modo che abbiano la stessa dimensione.
A = round(20*rand(10, 10));
B = round(20*rand(size(A)));
Definisco la funzione domina per confrontare A con B.
risultato = domina(A, B);
Analizzo il risultato fornito e stampo sulla command window il risultato corrispondente.
switch(risultato)
case 1
disp('A domina B');
case -1
disp('B domina A');
case 0
disp('dominanza non definita')
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
20
Esercizio 2 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Funzione domina
Definisco la funzione secondo lo standard di Matlab/Octave
function esito = domina(M1, M2)
Confronto le due matrici tramite l’operatore logico >. Per entrambi i confronti, il risultato
sarà una matrice logica di dimensioni uguali ad M1 ed M2.
X = (M1 > M2);
Y = (M2 > M1);
Controllo quanti elementi di A sono maggiori di B e genero il risultato corrispondente.
if(sum(X(:)) > sum(Y(:)))
esito = 1;
elseif (sum(X(:)) < sum(Y(:)))
esito = -1;
else
esito = 0;
end
L’istruzione X(:) srotola la matrice X in un vettore nel senso delle colonne.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
21
Esercizio 2 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Esercizio 2 - Codice completo
% Script principale
A = rand(10, 10);
B = rand(size(A));
risultato = domina(A, B);
switch(risultato)
case 1
disp('A domina B');
case -1
disp('B domina A');
case 0
disp('dominanza non definita')
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
function esito = domina(M1, M2)
X = (M1 > M2);
Y = (M2 > M1);
if(sum(X(:)) > sum(Y(:)))
esito = 1;
elseif (sum(X(:)) < sum(Y(:)))
esito = -1;
else
esito = 0;
end
Informatica B - Esercitazione 10 del 10/12/2010
22
Esercizio 3
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Dato un array quotaX di 365 valori interi, che rappresentano le
quotazioni nell’anno solare corrente del titolo azionario X, si
vuole realizzare un programma in grado di:
-inizializzare il contenuto dell’array quotaX con valori letti
da standard input che devono essere compresi tra 1 e 100
(estremi inclusi), scartando eventuali valori fuori
dall’intervallo (i valori esterni all’intervallo saranno posti
uguali all’estremo più prossimo).
-Salvare in un’ opportuna variabile di tipo struttura la
quotazione massima e il primo giorno (espresso come posizione
nell’array) in cui tale quotazione è stata memorizzata.
-Determinare e stampare a video il numero di periodi dell’anno
in cui il titolo si è mantenuto costante (ossia, quante volte
la medesima quotazione si è presentata in giorni successivi).
Ad esempio, se le quotazioni fossero 10 10 15 14 12 12 1 8 9 9
12 12…, il titolo avrebbe avuto 4 periodi di quotazione
costante.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
23
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Script principale
Chiedo all’utente di inserire in input le quote del titolo tramite la funzione
inizializzaQuotazioni().
quotaX = inizializzaQuotazioni();
La funzione non ha nessun parametro di ingresso perchè non ne necessita. I suoi
parametri di ingresso saranno quelli inseriti dall’utente.
Individuo la quotazione massima del titolo ed il giorno in cui si è verificata.
[quotaXmax.valore quotaXmax.giorno] = max(quotaX);
disp(' ')
disp(['Quota massima raggiunta: ' num2str(quotaXmax.valore)]);
disp(['nel giorno: ' num2str(quotaXmax.giorno)]);
Utilizzo la funzione predefinita di Matlab/Octave [y, i] = max(x).
Il suo help ci dice che, nel caso in cui x sia un vettore, la funzione pone in y il valore
massimo di x e in i la sua posizione.
Nel caso in cui y si presenti più volte, i riporterà la posizione della prima occorrenza.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
24
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Script principale
Individuo i periodi in cui il titolo ha avuto quotazione costante e quanto sono durati,
tramite la funzione quotaCostante().
[valore giorni] = quotaCostante(quotaX);
disp(' ')
disp(['Quote periodiche: ' num2str(valore)]);
disp(['di giorni: ' num2str(giorni)]);
Qui termina lo script principale.
Vediamo nel dettaglio le funzioni che si sono utilizzate.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
25
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Funzione inizializzaQuotazioni()
Definisco la funzione e chiedo in input i le quotazioni del titolo.
function quota = inizializzaQuotazioni()
quota = input('inserire il vettore delle quotazioni: ');
Controllo che nel vettore inserito ci siano effettivamente 365 valori.
Finché la sua lunghezza non è pari a 365, continuo a chiederne l’inserimento.
while(length(quota) ~= 365)
disp(['Sono stati inseriti' num2str(length(quota)) ' valori....
Inserire 365 valori'])
disp(' ')
quota = input('inserire il vettore delle quotazioni: ');
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
26
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Funzione inizializzaQuotazioni()
Controllo che i valori siano compresi nell’intervallo [1 100]. I valori esterni all’intervallo
saranno posti uguali all’estremo più prossimo.
quota(quota > 100) = 100;
quota(quota < 1) = 1;
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
27
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Funzione quotaCostante()
Questa funzione ha il compito di ricercare all’interno del vettore i periodi in cui il titolo si
è mantenuto costante e la lunghezza di tali periodi.
Definisco la funzione ed inizializzo le variabili che utilizzerò nella funzione.
function [valori periodo] = quotaCostante(quota)
valori = 0;
periodo = 0;
giorni = 0;
k = 1;
costante = 0;
L’inizializzazione di valori e periodo serve nel caso in cui il titolo non si sia mai
mantenuto costante nel corso dell’anno.
Le altre inizializzazioni riguardano variabili utilizzare all’interno della funzione.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
28
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Funzione quotaCostante()
for i = 1:length(quota)-1
Analizzo tutti i valori all’interno del vettore
if(quota(i+1)==quota(i)) Se due valori consecutivi sono uguali
costante = 1;
segnalo la presenza di una zona costante,
giorni = giorni + 1; incremento il contatore dei giorni.
valori(k) = quota(i);
Assegno alle variabili di uscita il valore della quota che si
periodo(k) = giorni + 1;
sta mantenendo costante ed il suo periodo di permanenza
elseif(costante == 1)
Se non mi trovo in una zona costante ma l’ho appena superata
resetto i giorni di permanenza e
giorni = 0;
costante = 0; segnalo l’assenza di una zona costante
k = k + 1;
incremento il contatore che tiene traccia delle quote costanti per
end
prepararmi alla memorizzazione della prossima quota costante.
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
29
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Esercizio 3 - Codice completo
% Script principale
quotaX = inizializzaQuotazioni();
[quotaXmax.valore quotaXmax.giorno] = max(quotaX);
disp(' ')
disp(['Quota massima raggiunta: ' num2str(quotaXmax.valore)]);
disp(['nel giorno: ' num2str(quotaXmax.giorno)]);
[valore giorni] = quotaCostante(quotaX);
disp(' ')
disp(['Quote periodiche: ' num2str(valore)]);
disp(['di giorni: ' num2str(giorni)]);
function quota = inizializzaQuotazioni()
quota = input('inserire il vettore delle quotazioni: ');
while(length(quota) ~= 365)
disp(['Sono stati inseriti' num2str(length(quota)) ' valori. Inserire 365 valori'])
disp(' ')
quota = input('inserire il vettore delle quotazioni: ');
end
quota(quota > 100) = 100;
quota(quota < 1) = 1;
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
30
Esercizio 3 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Esercizio 3 - Codice completo
function [valori periodo] = quotaCostante(quota)
valori = 0;
periodo = 0;
giorni = 0;
k = 1;
costante = 0;
for i = 1:length(quota)-1
if(quota(i+1)==quota(i))
costante = 1;
giorni = giorni + 1;
valori(k) = quota(i);
periodo(k) = giorni + 1;
elseif(costante == 1)
giorni = 0;
costante = 0;
k = k + 1;
end
end
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
31
Esercizio 4
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Definire le seguenti funzioni usando due variabili funzionali:
f1 = x2 − y 2
!√
"
sin
x2 +y 2
- f2 =
√ 2 2
-
x +y
-Rappresentare
ogni singola funzione con un grafico
tridimensionale valutandola per valori di x ed y
rispettivamente pari a: x = [-7:0.1:7] e y = [-7:0.1:7].
-Disegnare la porzione di f1 valutata su y = [0:0.1:7] in
bianco e quella valutata su y = [0:-0.1:-7] in blu.
-Evidenziare nel grafico di f2 i valori ‘discreti’ di cui è
composta la funzione per x = [-7:7] e y = [-7:7]
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
32
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Definisco la variabile f1 come variabile funzionale, assegnandole la funzione specificata
nella traccia.
f1=@(x,y)(x.^2-y.^2);
Le variabili funzionali sono funzioni vere e proprie che hanno il vantaggio di poter essere
passate ad altre funzioni come parametro.
Per definire una variabile f come variabile funzionale, la sintassi è la seguente:
f = @(lista_argomenti) funzione
Con le variabili funzionali, la definizione di funzione si avvicina ancora di più alla sua
accezione matematica rispetto alle funzioni viste fino ad ora.
La nostra funzione f1, infatti, può essere valutata per qualsiasi valore di x e y nello
stesso modo in cui lo si fa per le funzioni matematiche.
f1 valutata in x=3 e y=4:
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
f1(3, 4)
Informatica B - Esercitazione 10 del 10/12/2010
33
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Creo l’insieme di valori in cui voglio valutare la parte ‘bianca’ della funzione.
x = [0:0.1:7];
y = [0:0.1:7];
[xx,yy]=meshgrid(x,y);
I vettori x ed y specificati nella traccia indicano l’intervallo di valori in cui valutare la
funzione ma non forniscono tutti i valori necessari a farlo.
zz
Se valutassimo f1 in x ed y semplicemente
con l’istruzione: zz = f1(x, y),
otterremmo tutti i valori che essa assume
solamente lungo gli assi coordinati.
Quello che si vuole ottenere, invece, è
valutare la funzione in tutti i punti del piano
compresi tra i due assi.
Per farlo abbiamo bisogno di generare una
‘griglia’ di valori su cui valutare la funzione.
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
x
y
Informatica B - Esercitazione 10 del 10/12/2010
34
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
La funzione meshgrid(x,y) genera due matrici. La prima contiene il vettore x replicato
tante volte quanti sono i valori in y. La seconda opera analogamente su y. L’insieme delle
due matrici è la griglia desiderata.
Esempio
zz
x= [1:5];
y = [5:8];
[xx, yy] = meshgrid(x, y)
meshgrid(x,y)
x
y
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
xx = 1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
4
5
5
5
5
yy = 5
6
7
8
5
6
7
8
5
6
7
8
5
6
7
8
5
6
7
8
Informatica B - Esercitazione 10 del 10/12/2010
35
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Valuto f1 in ogni punto della griglia e disegno il risultato.
zz=f1(xx,yy);
figure(1)
mesh(xx,yy,zz);
Per disegnare superfici tridimensionali utilizzo la funzione mesh a cui passo le due
matrici ottenute da meshgrid ed i relativi valori della funzione.
L’istruzione figure(1) crea una nuova finestra d’immagine e le assegna l’identificativo
1.
Proseguo il disegno di f1 per i valori della parte in blu, rivaluto la funzione ed
aggiungo la nuova porzione alla precedente (senza sovrascrivere).
[xx1,yy1]=meshgrid(x,[0:-0.1:-7]);
zz1=f(xx1,yy1);
figure(1),
hold on
mesh(xx1,yy1,zz1,'FaceColor','b');
hold off
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
36
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Definisco la funzione f2 e la valuto nel range di valori desiderato disegnandola
su di una nuova figura che identifico con il numero 2.
f2=@(x,y)(sin(sqrt(x.^2+y.^2))./(sqrt(x.^2+y.^2)))
[xx,yy]=meshgrid([-7:0.1:7],[-7:0.1:7]);
zz=f2(xx,yy);
figure(2)
surf(xx,yy,zz);
Rivaluto la griglia per rappresentare i valori discreti di f2.
Ricalcolo la funzione per i valori scelti e sovrappongo il nuovo grafico a quello
esistente.
[xx,yy]=meshgrid([-7:7],[-7:7]);
zz=f2(xx,yy);
figure(2)
hold on
plot3(xx,yy,zz,'ro', 'Linewidth', 2)
hold off
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
37
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
La funzione plot3() funziona analogamente a plot() ma è in grado di rappresentare
punti e curve nello spazio tridimensionale.
Come plot(), anche plot3() accetta informazioni di visualizzazione come: larghezza
del tratto (Linewidth), color e forma del marker (ro), etc.
plot3(xx,yy,zz,'ro', 'Linewidth', 2)
f1
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
f2
Informatica B - Esercitazione 10 del 10/12/2010
38
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
In Octave i risultati grafici sono leggermente differenti dato che:
‣mesh() valuta come parametri in ingresso solamente xx, yy, zz ma non
'FaceColor','b'.
‣in plot3() al carattere ‘o’ corrispondono dei triangoli e non dei cerchi.
f1
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
f2
Informatica B - Esercitazione 10 del 10/12/2010
39
Esercizio 4 - Soluzione
Salvo Daniele Valente
Dipartimento di Elettronica e Informazione
MATLAB/Octave - Esercitazione 3
Esercizio 4 - Codice completo
f1=@(x,y)(x.^2-y.^2);
[xx,yy]=meshgrid([0:0.1:7],[0:0.1:7]);
zz=f1(xx,yy);
figure(1)
mesh(xx,yy,zz);
[xx1,yy1]=meshgrid([0:0.1:7],[0:-0.1:-7]);
zz1=f1(xx1,yy1);
figure(1)
hold on
mesh(xx1,yy1,zz1,'FaceColor','b');
hold off
f2=@(x,y)(sin(sqrt(x.^2+y.^2))./(sqrt(x.^2+y.^2)))
[xx,yy]=meshgrid([-7:0.1:7],[-7:0.1:7]);
zz=f2(xx,yy);
figure(2)
surf(xx,yy,zz);
[xx,yy]=meshgrid([-7:7],[-7:7]);
zz=f2(xx,yy);
figure(2)
hold on
plot3(xx,yy,zz,'ro', 'Linewidth', 2)
hold off
Politecnico di Milano - DEI Dipartimento di Elettronica e Informazione
Informatica B - Esercitazione 10 del 10/12/2010
40
Scarica

Slides - Informatica B - Politecnico di Milano