Un "function handle" e una variabile il cui valore e una funzione. Data una funzione esistente, il suo function handle è dichiarato come handle = @nome dove nome è il nome di tale funzione esistente. Una volta dichiarato l handle, è possibile invocarlo come fosse una funzione: 1 handle_sum = @sum; 3 handle_sum([3 ]); Un function handle può essere dichiarato anche al volo, ossia su una funzione non esistente. Ad esempio: handle = @(x) x*3 è un handle di una funzione anonima che accetta in ingresso un parametro formale x e svolge su di esso una moltiplicazione. Si noti che x 3 è a tutti gli effetti il corpo della funzione anonima. 1 handle = @(x) x*3 3 handle(10) Essendo variabili, gli handle possono essere passati ad altre funzioni creando le cosiddette funzioni di ordine superiore, in quanto ricevono in ingresso altre funzioni (come argomenti). 1 handle_es = @(vett, func) func(vett) 3 handle_es([3 ], @sum) handle_es([3 ], handle_sum) 1
1.1 Esercizi Esercizio 1.1 Si definisca una funzione che riceve in ingresso un function handle e due variabili x e y contenenti numeri. Tale funzione, chiamata controlla_funzione, dovrà controllare se applicando ad x la funzione passata tramite function handle si ottiene y, e ritornare 1 o 0 a seconda che tale controllo vada a buon fine o meno. Estendere l esempio ai vettori, ovvero costruire controlla_funzione_vettori affinchè riceva in ingresso un vettore X e un vettore Y, e controlli che la condizione di cui sopra valga per tutti gli elementi corrispondenti di X e Y. Si implementi operazione affinchè controlli che y sia il doppio di x. Esercizio 1. Scrivere una funzione filtra che riceva come parametri una funzione cond (function handle) e un vettore strutturato: 1 vett(1).x vett(1).y 3 vett().x 5 vett().y 6 7... 8 9 vett(n).x 10 vett(n).y La funzione cond riceve in ingresso due parametri, a e b, e ritorna 1 (true) se a è maggiore di b, altrimenti ritorna 0 (false). La funzione di ordine superiore filtra dovrà utilizzare la funzione cond, ricevendone in ingresso un suo function handle, al fine di filtrare il vettore ricevuto in ingresso, costruendo un vettore che contenga solo quegli elementi che hanno il campo x maggiore del campo y. Sperimentare con altre funzioni al posto di cond. Ad esempio minore di, oppure uguale a, oppure uno il doppio dell altro, etc. Esercizio 1.3 Implementare la funzione di ordine superiore vrand che riceve in ingresso un function handle e un numero reale tra 0 e 1. Non si sa nulla sul function handle, se non che va A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag.
chiamato senza alcun argomento. Ad esempio: handle(). vrand dovrà chiamare la funzione passata come handle. Se il numero ritornato da tale chiamata è maggiore del numero reale ricevuto come parametro, questo viene ritornato immediatamente, se invece è inferiore, si dovrà continuare a chiamare la funzione finchè questa non restituirà un numero maggiore del reale passato. Utilizzare vrand per realizzare un dado a sei facce truccato. Chiamare 100 volte la vrand e salvare i valori così ottenuti in un vettore V. Realizzare poi altre 100 estrazioni usando la rand al posto della vrand e salvare tali valori in un vettore R. Infine, utilizzare plot() per visualizzare le estrazioni di R e V: su due grafici diversi sullo stesso grafico con colori diversi. Esercizio 1. Si considerino due dispositivi aventi le seguenti configurazioni: Configurazione A 1 Mbyte di memoria fisica e pagine di memoria da Kbyte; una memoria cache con hit rate di 0.8, hit time di 50 ns e miss penalty di 150 ns; Configurazione B indirizzo di memoria fisica a bit e pagine di memoria da 6 Kbyte; una memoria cache con hit rate di 0.9, hit time di 0 ns e miss penalty di 50 ns. 1. Quali dei due dispositivi ha il maggior numero di pagine di memoria fisica?. Si può dire quale dei due dispositivi ha maggiore memoria fisica? E quale dei due avrà maggiore memoria virtuale? 3. In quale dei due dispositivi l accesso alla memoria è più rapido?. Si consideri ora il dispositivo più lento: qual è l hit rate minimo che dovrebbe avere per essere rapido almeno quanto l altro? Giustificare tutte le risposte riportando gli opportuni calcoli. Esercizio 1.5 A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 3
Si consideri una versione semplificata della battaglia navale in cui le navi possono essere posizionate solo in orizzontale e ogni riga può contenere al massimo una nave. Il campo di gioco di un singolo giocatore può essere rappresentato tramite la matrice CampoGioco di dimensione 5 x 5 in cui ogni cella della matrice può assumere solo il valore 0 o 1. Il valore 0 rappresenta la presenza del mare e il valore 1 la presenza di un pezzo di nave. Le navi possono essere lunghe una, due, tre, quattro o cinque celle. Ad esempio la seguente istanza della matrice CampoGioco rappresenta un campo di gioco in cui sono presenti navi: una nave lunga nella prima riga, una nave lunga 1 nella terza riga, una nave lunga nella quarta riga e una nave lunga nella quinta riga. Si realizzi uno script MATLAB che: chiede all utente di inserire il contenuto della matrice CampoGioco; per ogni riga che contiene una nave visualizza a video il numero di riga e la lunghezza della nave presente al suo interno; visualizza a video inoltre le seguenti statistiche: il numero di navi presenti sul campo di gioco, la lunghezza della nave più corta presente sul campo di gioco, la lunghezza della nave più lunga presente sul campo di gioco, il numero di navi trovate per ogni lunghezza possibile. Un campo di gioco del genere: 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1 1 1 0 Darà come risultato: 1 La riga 1 contiene una nave lunga La riga 3 contiene una nave lunga 1 3 La riga contiene una nave lunga La riga 5 contiene una nave lunga 5 Sono presenti navi 6 Lunghezza nave più corta trovata: 1 7 Lunghezza nave più lunga trovata: 8 Numero di navi lunghe 1: 1 9 Numero di navi lunghe : 1 10 Numero di navi lunghe 3: 0 11 Numero di navi lunghe : 1 Numero di navi lunghe 5: 0 A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag.
Esercizio 1.6 Si implementi in MATLAB una funzione combinamatrici che svolga ricevute in ingresso due matrici A e B aventi le stesse dimensioni, produce una terza matrice C. Essa viene ottenuta da A e B secondo le seguenti regole: nelle posizioni (r, c) in cui B(r, c) è minore del minimo di A, C assume il valore di A(r, c) altrimenti assume il valore di B(r, c). Per minimo di A si intende il più piccolo di tutta la matrice A. Si scriva la funzione combinamatrici sfruttando le caratteristiche di sintesi del linguaggio MATLAB (possibilmente evitando l utilizzo di cicli). 1 A = [ ; 3] C = [3 5; 5, 3] B = [3, 5; 5,-1] Si scriva una funzione combinamatricisup simile alla precedente, ma con le seguenti differenze. La funzione combinamatricisup riceve in ingresso le due matrici A e B, e un function handle f. La funzione restituisce una matrice C così definita nelle posizioni (r, c) in cui B(r, c) è minore di f applicato al minimo di A, C assume il valore di A(r, c) altrimenti assume il valore di B(r, c). 1 A = [ ; 3]; C = [ 5; 5, 3] B = [3, 5; 5,-1]; 3 f = @(x)(x.^); Si scriva una chiamata a combinamatricisup passando come argomenti: A: la matrice identità 3x3; B: una matrice di diemensione 3x3 contentente numeri interi casuali tra -10 e 10; f: la funzione che restituisce la differenza tra seno e coseno di un numero. Esercizio 1.7 Le strade della città di Grigliopoli sono organizzate come una griglia (alcune strade attraversano la città da est a ovest e altre da nord a sud). Dati due incroci che distano X isolati lungo l asse est-ovest della città e Y isolati lungo l asse nord-sud, si vuole calcolare il numero di percorsi a distanza minima che collegano i due incroci. A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 5
Implementare una funzione ricorsiva calcola in MATLAB che ricevuti X e Y in ingresso restituisce il numero di percorsi trovati in uscita. Suggerimento: Quando X = 0 o Y = 0, c è soltanto un cammino a distanza minima che collega i due incroci. Altrimenti, esiste più di un cammino minimo dal momento che è possibile sia avvicinarsi alla destinazione lungo l asse est-ovest (riducendo quindi la distanza X) oppure avvicinarsi lungo l asse nord-sud (riducendo la distanza Y ). Esercizio 1.8 Un sistema basato su microprocessore, senza nessuna cache, ha un tempo di accesso alla memoria di 100ns. 1. Quale delle seguenti configurazioni con memoria cache può migliorare le performance del sistema? Si motivi adeguatamente la risposta. Configurazione Hit time Hit rate Miss-penality 1 10ns 0. 150ns 3ns 0. 10ns 3 1ns 0. 150ns. Si scriva una funzione MATLAB selezionacache che prende in ingresso una matrice avente 3 colonne e contenente, in ogni riga, le specifiche di una tipologia di memoria cache: hit time nella prima colonna, hit rate nella seconda e misspenality nella terza. La funzione selezionacache deve restituire l indice della riga corrispondente alla configurazione con migliori performance. Esercizio 1.9 (TdE 01) Si consideri l array definito in MATLAB e chiamato dati. Tale array contiene le informazioni riguardanti le precipitazioni atmosferiche registrate da una stazione meteorologica. In particolare, ogni elemento dell array dati è una struct che contiene un campo numerico giorno, un campo numerico mese, un campo numerico anno, e un campo numerico mm che rappresenta la quantità di pioggia (in mm) caduta nella data specificata dai precedenti campi. Ad esempio, per memorizzare nell array dati che il 3 giugno 013 sono stati registrati 15 mm di pioggia si avrà: A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 6
1 dati(i) = struct("giorno", 3, "mese", 6, "anno", 013, "mm", 15); Si risponda ai seguenti quesiti: A Scrivere l intestazione di una funzione MATLAB media che riceva in ingresso l array dati e un parametro numerico anno; la funzione deve restituire in uscita un array di 1 elementi che, sulla base del contenuto dell array dati, fornisca il valore medio dei mm di pioggia in ciascun mese dell anno solare anno. B Scrivere una funzione MATLAB di ordine superiore, mostra che riceva in ingresso l array dati, un parametro funzione f e un parametro numerico anno. Si assuma che f abbia la stessa intestazione della funzione media al punto A. La funzione mostra deve applicare f all array dati per calcolare una statistica mese per mese dell anno solare specificato dal parametro anno; inoltre, la funzione mostra deve visualizzare i valori di tale statistica mensile mediante un grafico, con il mese in ascissa e il valore della statistica per ciascun mese in ordinata. C Scrivere un esempio di chiamata della funzione mostra implementata al punto precedente, con cui si vuole mostrare il grafico delle precipitazioni medie mensili dell anno 01, i cui valori sono contenuti in un array dati che deve essere caricato con i valori memorizzati in un file in formato MATLAB di nome data. D Scrivere il corpo della funzione MATLAB media considerando il caso in cui esistano mesi degli anni considerati senza dati relativi alle precipitazioni. A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 7
Soluzioni Soluzione dell esercizio 1.1 1 clear; clc; 3 close all; 5 func = @operazione; 6 %func = @(x) x+3 7 8 x = rand(); 9 10 %Controllo singolo numero 11 controllo_funzione(func, x, *x) % vero 1 controllo_funzione(func, x, x+3) % falso 13 1 X = rand([10 1]); 15 Y = *X; 16 17 %Controllo su vettore 18 controllo_funzione_vett(func, X, Y) % vero 19 Y(3) = Y(3) - 1; 0 controllo_funzione_vett(func, X, Y) % falso 1 function ok = controlla_funzione(handle, x, y) 3 ok = (y == handle(x)); 1 function ok = controlla_funzione_vettori(func, X, Y) 3 ok = 1; for ii = 1:length(X) 5 if ~controllo_funzione(func, X(ii), Y(ii)) 6 ok = 0; 7 return; 8 end 9 end 1 function risultato = operazione(input) 3 risultato = * input; A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 8
Soluzione dell esercizio 1. 1 clc clear 3 close all 5 %Riempimento del vettore in modo casuale 6 for ii = 1:9 7 vett(ii).x = rand(); 8 vett(ii).y = rand(); 9 end 10 vett 11 1 % Filtraggio del vettore 13 %vett_modificato = filtra(@cond, vett); 1 vett_modificato = filtra(@(a,b)(a > b), vett); 15 vett_modificato 1 function V = filtra(condizione, vett) 3 jj = 1; V = []; 5 6 for ii = 1:length(vett) 7 if condizione(vett(ii).x, vett(ii).y) 8 V(jj).x = vett(ii).x; 9 V(jj).y = vett(ii).y; 10 11 jj = jj + 1; 1 end 13 end 1 function ris = cond(a, b) 3 ris = (a > b); %ris = (a < b); 5 %ris = (a == b); 6 %ris = (a == * b); 1 clear clc Soluzione dell esercizio 1.3 A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 9
3 close all; 5 %Estrazioni da dado truccato e regolare 6 for ii = 1:100 7 V(ii) = ceil(6 * vrand(@rand, 0.5)); 8 R(ii) = ceil(6 * rand()); 9 end 10 11 %Plot su due grafici diversi 1 figure(1); 13 plot(r); 1 title('dado truccato'); 15 16 figure(); 17 plot(v); 18 title('dado regolare'); 19 0 %Plot sullo stesso grafico con colori diversi 1 figure(3); plot(r); 3 hold on; plot(v, 'r'); 5 legend({'dado truccato' 'Dado regolare'}); 6 xlabel('numero estrazione'); 7 ylabel('valore estrazione'); 1 function ris = vrand(r, m) 3 ris = r(); while ris < m 5 ris = r(); 6 end Soluzione dell esercizio 1. 1. Nessuno dei due dispositivi. Entrambi hanno lo stesso numero di pagine di memoria fisica ( 8 ): La configurazione A ha 0 bit di memoria fisica indirizzabile (1 Mbyte = 0 ), di cui 1 dedicati all offset ( 1 = Kbyte), quindi A ha 8 pagine di memoria fisica. A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 10
La configurazione B ha bit di memoria fisica indirizzabile, di cui 16 dedicati all offset all interno della pagina ( 16 = 6 Kbyte), quindi ha 8 pagine di memoria fisica.. La configurazione B ha più memoria fisica perchè = 16 Mbyte > 1 Mbyte. Non è possibile invece dire nulla della memoria virtuale perchè le informazioni fornite non ci permettono di risalire al numero di pagine virtuali ne della configurazione A ne di quella B. 3. La configurazione B è più veloce: La configurazione A ha tempo medio di accesso alla memoria di 0.8 50ns + 0. 150ns = 70ns La configurazione B ha tempo medio di accesso alla memoria di 0.9 0ns + 0.1 50ns = 61ns. Se x è l hit rate, dovrà essere: x 50 + (1 x) 150 61 100 x 89 x 0.89 quindi hit rate minimo perchè la configurazione A sia veloce come la B è x = 0.89ns. Soluzione dell esercizio 1.5 1 clear clc 3 close all 5 6 %CampoGioco = [0 1 1 1 1; 0 0 0 0 0; 0 0 1 0 0; 0 1 1 0 0; 1 1 1 1 0]; 7 CampoGioco = input('inserire il campo di gioco'); 8 9 dim_gioco = size(campogioco,1); 10 nave = sum(campogioco,); 11 1 for ii = 1:dim_gioco 13 if nave(ii) > 0 1 disp(['la riga ' numstr(ii) ' contiene una nave lunga ' numstr(nave(ii))]); 15 end A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 11
16 end 17 18 nave = nave(nave> 0); 19 0 disp(['sono presenti ' numstr(length(nave)) ' navi']); 1 disp(['lunghezza nave piu'' corta trovata: ' numstr(min(nave)) ]); 3 disp(['lunghezza nave piu'' lunga trovata: ' numstr(max(nave)) ]); 5 for ii = 1:5 6 disp(['numero di navi lunghe ' numstr(ii) ': ' numstr(sum (nave == ii))]); 7 end Soluzione dell esercizio 1.6 1 clear clc 3 close all 5 A = [ ; 3]; 6 B = [3, 5; 5,-1]; 7 8 C = combinamatrici(a,b); 9 C_theor = [3 5; 5, 3]; 10 11 C == C_theor 1 13 A = [ ; 3]; 1 B = [3, 5; 5,-1]; 15 f = @(x)(x.^); 16 17 C = combinamatricisup(f,a,b); 18 C_theor = [ 5; 5, 3]; 19 0 C == C_theor 1 A = eye(3); 3 B = round((rand(3) - 0.5) * 0); f = @(x)(sin(x) - cos(x)); 5 A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 1
6 C = combinamatricisup(f,a,b); 1 function C = combinamatrici(a,b) 3 assert(all(size(a) == size(b))); 5 min_a = min(a(:)); 6 7 C = B; 8 C(C < min_a) = A(C < min_a); 1 function C = combinamatricisup(f,a,b) 3 assert(all(size(a) == size(b))); 5 min_fa = f(min(a(:))); 6 7 C = B; 8 C(C < min_fa) = A(C < min_fa); 1 clear clc 3 close all 5 X = ; 6 Y = 3; 7 8 calcola(x,y) Soluzione dell esercizio 1.7 1 function n_strade = calcola(x,y) 3 if X == 0 Y == 0 n_strade = 1; 5 else 6 n_strade = calcola(x-1,y) + calcola(x,y-1); 7 end 1 clear Soluzione dell esercizio 1.8 A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 13
clc 3 close all 5 % Formula tempo di accesso medio: 6 % hit_time * hit_rate + (1 - hit_rate) * miss_penalty 7 % Configurazione con tempo medio più basso è il migliore 8 % Quindi 9 %Conf 1: 10ns * 0. + (1-0.) * 150ns = ns + 10ns = 1ns 10 %Conf : 3ns * 0. + (1-0.) * 10ns = 0.6ns + 13ns = 13.6 ns 11 %Conf 3: 1ns * 0.6 + (1-0.) * 150ns = 7.ns + 90ns = 97.ns 1 13 Matr = [10 0. 150;... 1 3 0. 10;... 15 1 0. 150]; 16 17 18 selezionacache(matr) 1 function conf = selezionacache(matr) 3 Time = Matr(:,1).* Matr(:,) + (1 - Matr(:,)).* Matr(:,3); 5 [~, conf] = min(time); 6 %conf = find(time == min(time),1); 1 clear clc 3 close all 5 load('data.mat','dati'); 6 7 mostra(dati,@media,01); Soluzione dell esercizio 1.9 1 function medie = media(dati,anno) 3 medie = zeros(1,1); n_misurazioni = zeros(1,1); 5 6 for ii = 1:numel(dati) 7 if dati(ii).anno == anno A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 1
8 medie(dati(ii).mese) = medie(dati(ii).mese) + dati(ii). mm; 9 n_misurazioni(dati(ii).mese) = n_misurazioni(dati(ii). mese) + 1; 10 end 11 end 1 13 for ii = 1:1 1 if n_misurazioni > 0 15 medie(ii) = medie(ii) / n_misurazioni(ii); 16 end 17 end 1 function mostra(dati,f,anno) 3 resu = f(dati,anno); 5 plot(resu); 6 title(['nice plot']) 7 xlabel('mese'); 8 ylabel('mm'); 9 legend('datastream'); A.A.01 015 Informatica B (081369) - Politecnico di Milano Pag. 15