Obiettivi del Corso
Partiamo dal titolo:
Elementi di Informatica ed Applicazioni Numerica T
(Fluidodinamica e Applicazioni Numeriche T C.I.)
Il corso ha tre "anime"
- Informatica
- Calcolo numerico
- Integrazione con Fluidodinamica
- Quattro, con Matlab (dimenticavo)
Una situazione complicata (almeno dal mio punto di vista)
Obiettivi e Programma del Corso
Facciamo un po' d'ordine:
- Informatica = il tema principale del corso
- Calcolo numerico = il nostro campo di applicazione dell'Informatica
- Fluidodinamica = il nostro campo di applicazione di calcolo numerico
Matlab Octave = il nostro strumento
Obiettivi e Programma del Corso
Facciamo un po' d'ordine:
- Informatica = il tema principale del corso
- Algoritmi e strutture dati
- Linguaggi imperativi
- Programmazione strutturata
- Calcolo numerico = il nostro campo di applicazione dell'Informatica
- Fluidodinamica = il nostro campo di applicazione di calcolo numerico
Matlab Octave = il nostro strumento
Obiettivi e Programma del Corso
Facciamo un po' d'ordine:
- Informatica = il tema principale del corso
- Calcolo numerico = il nostro campo di applicazione dell'Informatica
- Equazioni non-lineari
- Integrazione
- Equazioni differenziali
- Probabilità e statistica (cenni)
- Interpolazione
- Minimizzazione non vincolata
- Fluidodinamica = il nostro campo di applicazione di calcolo numerico
Matlab Octave = il nostro strumento
Obiettivi e Programma del Corso
Facciamo un po' d'ordine:
- Informatica = il tema principale del corso
- Calcolo numerico = il nostro campo di applicazione dell'Informatica
- Fluidodinamica = il nostro campo di applicazione di calcolo numerico
- Qualche connessione verrà indicata mano a mano
- Equazioni non lineari
- Integrazione
- Interpolazione
Matlab Octave = il nostro strumento
Obiettivi e Programma del Corso
Facciamo un po' d'ordine:
- Informatica = il tema principale del corso
- Calcolo numerico = il nostro campo di applicazione dell'Informatica
- Fluidodinamica = il nostro campo di applicazione di calcolo numerico
Matlab Octave = il nostro strumento
- Funzioni predefinite
- Input/output e plot (rudimenti)
- Scrivere codice ottimizzato
Partiamo con una domanda:
Che cos'è l'Informatica?
In Inglese "Computer Science" => "scienza dei calcolatori"
- Acqua...
- Non è una definizione particolarmente buona
Vediamo un po' di informatica senza calcolatore
Un Primo Esempio
Problema: cercare un parola su un dizionario
Come risolverlo?
Un Primo Esempio
Problema: cercare un parola su un dizionario
- Sia w la parola da cercare
- Aprire il dizionario a caso
- Siano w′,w″ le parola in cima alla pagina sx/dx
- Se w < w', passiamo alle pagine precedenti e ripetiamo
- Se w > w'', passiamo alle pagine successive e ripetiamo
- Altrimenti cerchiamo w sulla pagina
Per essere pignoli dovremmo specificare anche:
- Come cercare w sulla pagina
- E come confrontare due parole!
Un Primo Esempio
Problema: trovare il massimo di un insieme di numeri casuali
Come risolverlo?
Un Secondo Esempio
Problema: trovare il massimo di un insieme di numeri casuali
- Prendiamo in mano un numero a caso (sia questo m)
- m è temporaneamente il nostro massimo
- Prendiamo in mano tutti gli altri numeri uno per volta
- Sia v il numero corrente
- Se v > m, allora v è il nuovo massimo. Mettiamo da parte m
- Altrimenti, mettiamo da parte v e passiamo al prossimo numero
Proviamo con una nuova definizione:
L'Informatica ha a che fare
con il modo in cui risolviamo i problemi
- Fuochino...
- È molto vaga, ma evidenzia un concetto fondamentale:
Algorimo: un procedimento che
in tempo finito risolve un problema
Algoritmi
Possiamo vedere un algoritmo come una "scatola nera" (black box)
- Un algoritmo si applica a dei dati di ingresso (input)
- Un algoritmo produce dei dati di uscita (output o risultati)
I dati di ingresso/uscita devono provenire da insiemi be specificati:
- L'insieme D_I dei possibili ingressi si chiama dominio di ingresso
- L'insieme D_O dei possibili risultati si chiama dominio di uscita
Algoritmi, Funzioni, Problemi
Quindi stiamo dicendo che:
- Un algoritmo mappa un elemento del dominio di ingresso...
- ...su un elemento del dominio di uscita
Ma questo non è il concetto matematico di funzione?
f: D_I \mapsto D_O
Quasi:
- Una funzione specifica quali dati di input mappare in quali output
- Quindi f è una descrizione del problema da risolvere
Algoritmi, Funzioni, Problemi
Quindi stiamo dicendo che:
- Un algoritmo mappa un elemento del dominio di ingresso...
- ...su un elemento del dominio di uscita
Ma questo non è il concetto matematico di funzione?
f: D_I \mapsto D_O
Quasi:
- Un algoritmo descrive come i dati possono essere mappati
- È ciò che permette di "dare vita" ad f, cioè di eseguirla
Algoritmi ed Elaboratori
Per eseguire un algoritmo è necessario un elaboratore
Questo è un elaboratore:
Algoritmi ed Elaboratori
Per eseguire un algoritmo è necessario un elaboratore
Questo è un elaboratore:
Algoritmi ed Elaboratori
Per eseguire un algoritmo è necessario un elaboratore
Questo è un elaboratore del 1976 (Wozniak, Apple I):
Algoritmi ed Elaboratori
Per eseguire un algoritmo è necessario un elaboratore
Questo è un elaboratore (parte) del 1837 (Babbage, Analytical Engine):
Algoritmi ed Elaboratori
Per eseguire un algoritmo è necessario un elaboratore
Questo può essere un elaboratore:
Algoritmi ed Elaboratori
Per eseguire un algoritmo è necessario un elaboratore
Dal nostro punto di vista:
Un elaboratore è una entità che può:
- Memorizzare informazioni
- Eseguire sul tali informazioni alcune operazioni elementari
- L'elaboratore determina i dati elementari che possiamo usare
- L'elaboratore determina le nostre operazioni elementari
- Es. l'operatore < nei nostri due algoritmi
"Potenza" di Un Elaboratore
Non tutti gli elaboratori hanno la stessa potenza. Per esempio:
- Questa classifica potrebbe risultare un po' strana :-)
- Tutto dipende dal nostro concetto di potenza
Potenza Espressiva di Un Elaboratore
In base alla definizione, la potenza di un elaboratore dipende da:
- Quanti e quali dati può rappresentare
- Quante e quali operazioni elementari mette a disposizione
Per essere precisi si dovrebbe parlare di potenza espressiva
Si dà il caso che (senza entrare nei dettagli):
- Per poter eseguire qualunque algoritmo eseguibile
- Sono sufficienti pochissimi tipi di dato ed operazioni elementari
È un risultato che dobbiamo ad un paio di "colossi" dell'informatica
- Alan Turing, Alonzo Church (negli anni '30)
Una Parentesi su Alan Turing & Friends
Se avete tempo, leggete questo blog post: ne vale la pena!
Why Do We Pay Pure Mathematicians?
Or, the Many Uses of Uselessness
Algoritmi Equivalenti
Due algoritmi si dicono equivalenti se:
- Hanno lo stesso dominio di ingresso D_I
- Hanno lo stesso dominio di uscita D_O
- Mappano gli stessi dati di ingresso negli stessi dati di uscita
In sintesi, se risolvono lo stesso problema
Due algoritmi equivalenti non sono necessariamente uguali:
- Possono essere più o meno efficienti
- Possono essere più o meno stabili
- Possono essere più o meno accurati
Torniamo all'Esempio #1
Consideriamo un altro algoritmo per l'esempio #1
- Sia w la parola da cercare
- Sia p la prima pagina e q l'ultima
- Aprire il dizionario alla pagina: \frac{p+q}{2}
- Siano w', w'', le parola in cima alla pagina sx/dx
- Se w < w', allora w' diventa il nostro nuovo q
- Se w > w'', allora w'' diventa il nostro nuovo p
- Altrimenti cerchiamo w sulla pagina
In pratica, apriamo sempre il dizionario a metà tra p e q
Torniamo all'Esempio #1
Se ci sono n pagine, quante ne dobbiamo aprire con i due approcci?
Algoritmo 1:
- Se siamo fortunati: una sola!
- Se siamo veramente sfortunati: n pagine
Algoritmo 2:
All'inizio abbiamo n pagine possibili
Torniamo all'Esempio #1
Se ci sono n pagine, quante ne dobbiamo aprire con i due approcci?
Algoritmo 1:
- Se siamo fortunati: una sola!
- Se siamo veramente sfortunati: n pagine
Algoritmo 2:
Dopo il primo passo (supponiamo w < w'), le pagine sono n/2
Torniamo all'Esempio #1
Se ci sono n pagine, quante ne dobbiamo aprire con i due approcci?
Algoritmo 1:
- Se siamo fortunati: una sola!
- Se siamo veramente sfortunati: n pagine
Algoritmo 2:
Dopo il secondo passo (supponiamo w > w''), le pagine sono n/4
Le pagine possibili si dimezzano ad ogni passo!
Torniamo all'Esempio #1
Se ci sono n pagine, quante ne dobbiamo aprire con i due approcci?
Algoritmo 1:
- Se siamo fortunati: una sola!
- Se siamo veramente sfortunati: n pagine
Algoritmo 2:
- Se siamo fortunati (caso migliore): una
- Se siamo veramente sfortunati (caso peggiore): \log_2 n
I due algoritmi si chiamano ricerca lineare e ricerca binaria
- Il secondo è molto più efficiente
E di Nuovo all'Esempio #2
Un nuovo algoritmo per l'esempio 2:
- Supponiamo di risolvere il problema in modo collettivo
- Sia m il numero di persone che risolve il problema
- Sia n il numero di tessere da controllare
- Possiamo dividere le n tessere in m gruppi
- E ciascuno dovrà esaminare solo n/m tessere!
Il nuovo algoritmo è di nuovo più efficiente
A differenza del caso precedente, il vantagggio dipende dall'elaboratore
- In particolare dal numero di persone m
- Il nuovo algoritmo è parallelo
Efficienza di un Algoritmo
Come si valuta l'efficienza di una algoritmo?
Di solito ci si basa sulla sua complessità asintotica
- Sia n la dimensione del problema
- Sia g(n) il #operazioni necessarie a risolverlo con il nostro algoritmo
- Si assume che n cresca indefinitamente, i.e. n \rightarrow \infty
- Si cerca una funzione h(n) che limita superiormente f(n)
A questo punto diciamo che la complessità è: O(h(n))
- È più facile di quello che sembra
- Vediamo il calcolo in atto...
Efficienza di un Algoritmo - Esempio
Consideriamo l'esempio 1, risolto con ricerca lineare
- Nel caso peggiore, dobbiamo sfogliare n pagine
- Poi dobbiamo cercare la parola sulla pagina
- Supponiamo che il numero di parole sulla pagina sia m
- E di usare (di nuovo) ricerca lineare per cercare sulla pagina
Il numero totale di operazioni sarà:
g(n,m) = n + m
- m sarà tendenzialente costante
- Quindi per n \rightarrow \infty, g(n,m) sarà limitata da h(n) = n
La complessità asintotica è quindi O(n)
Proprietà Fondamentali degli Algoritmi
Consideriamo ora un algoritmo per la funzione (i.e. il problema):
f: D_I \mapsto D_O
Perché l'algoritmo sia tale, devono valere alcune proprietà:
- Applicabilità a tutti di dati di ingresso
- Eseguibilità
- Finitezza
- Non-ambiguità
Le definizioni delle proprietà sono nelle slide seguenti...
Proprietà Fondamentali degli Algoritmi
1) Applicabilità a tutti i dati di ingresso:
L'algoritmo deve essere applicabile qualunque sia il valore dei dati di ingresso (purché ovviamente appartengano al dominio D_I)
- Se (1) non vale, l'algoritmo non calcola veramente f
- Questo non vuol dire che l'algoritmo sia inutile
- E.g. potrebbe risolvere una versione ristretta del problema
2) Eseguibilità:
Ogni azione deve essere eseguibile dall'elaboratore in un tempo finito
- Se (2) non vale, f non può essere calcolata in un tempo finito
- Di fatto è una proprietà dell'elaboratore stesso
Proprietà Fondamentali degli Algoritmi
3) Finitezza:
Per ogni possibile valore dei dati di ingresso, l'algoritmo deve terminare dopo un numero finito di passi
- Di nuovo, se (3) non vale, f non può essere calcolate in tempo finito
4) Non Ambiguità:
Ogni azione deve essere interpretabile in modo non ambiguo dall'elaboratore.
- Se (4) non vale, f non può essere calcolata
Le proprietà (3) e (4) sono collegate a due argomenti molto importanti...
Finitezza e Computabilità
Iniziamo con una definizione importante:
Una funzione f si dice computabile se è
possibile scrivere un algoritmo che la calcola
Può esistere una funzione ben definita e non computabile?
- Sì! Il risultato è del matematico Kurt Gödel
- Vediamo degli esempi...
Finitezza e Computabilità
Un primo esempio:
f(a, b) = \{v \in \mathbb{Q} \ |\ a < v < b \}
f associa a due numeri a e b l'insieme dei razionali compresi tra di essi
- Ci sono infiniti numeri razionali tra a e b!
- Ci vuole un tempo infinito per costruire questo insieme
In questo caso, non è possibile soddisfare la finitezza
Finitezza e Computabilità
Un secondo esempio:
f(\text{affermazione}) = \left\{\begin{aligned}
&1 && \text{se l'affermazione è vera}\\
&0 && \text{altrimenti}
\end{aligned}\right.
f è un dimostratore: stabilisce se una certa affermazione è vera o falsa
- Cosa succede se usiamo come input "Questa affermazione è falsa?"
- Per verificare l'affermazione dobbiamo stabilire se essa sia vera
- Il che richiede di verificare se l'affermazione sia vera
- E così via, all'infinito!
Quindi non è possibile calcolare f in un numero finito di passi
Consideriamo ora la non-ambiguità:
- Più che essere una proprietà dell'algoritmo...
- ...È una proprità del modo in cui lo descriviamo
Per descrivere in modo non ambiguo un algoritmo:
- Ci serve un linguaggio (per esempio testuale)
- Il linguaggio deve avere una sintassi non-ambigua
- Cioè: delle regole sintattiche formalmente definite
- Il linguaggio deve avere una semantica non-ambigua
- Cioè: ogni componente del testo ha un solo significato
Un linguaggio di questo tipo si chiama linguaggio formale
Linguaggi di Programmazione
Si chiama linguaggio di programmazione un linguaggio formale:
- La cui semantica è definita in base ad operazioni elementari...
- ...Che possono essere eseguite su un elaboratore
Un testo scritto in un linguaggio di programmazione:
- Può essere eseguito!
- Si chiama programma
Un algoritmo può essere definito usando un programma
- Spesso si usa il termine "codificare" o "implementare"
Linguaggi di Programmazione - Un Esempio
Questo è un programma per l'esempio 2 (max di una serie di numeri)
V = [1, 7, 16, 33, 41, ...]
m = V[0]
for v in V[1:]:
if m < v:
m = v
- Il programma è scritto in Python
- Python è un linguaggio di programmazione piuttosto "di moda" :-)
- Non sarà argomento del corso
Programmi ed Algoritmi
Non tutti i programmi sono algoritmi
- Ci sono programmi che eseguono indefinitamente
- Programmi che non "calcolano un risultato"
Anche se in verità ambedue queste due osservazioni sono opinabili...
Ma in sostanza cosa fa un programma?
- Rappresenta informazioni
- Elabora informazioni
Il che ci porta alla definizione di Informatica che adotteremo!
L'Informatica è la scienza della rappresentazione e dell'elaborazione dell'informazione
Cos'è Octave
Octave è un sistema software per calcolo numerico
Sistema = collezione di componenti SW (pensiamoli come "programmi")
- Ideato nel 1988 per un corso di progettazione di reattori chimici
- Si interagisce con il SW mediante un linguaggio di programmazione
Di seguito con "Octave" ci riferimento sia al SW che al linguaggio
Perché Octave e non Matlab?
- Octave è pesantemente ispirato a Matlab
- I linguaggi utilizzati sono quasi 100% compatibili
- Octave però è completamente gratuito
Interfaccia Utente di Octave
Octave ha due tipi di interfaccia
Interfaccia a riga di comando ("no GUI" - Graphical User Interface)
Interfaccia Utente di Octave
Octave ha due tipi di interfaccia
Interfaccia a finestre ("GUI", dalla versione 4.0)
Octave in Laboratorio & a Casa
Octave è pre-installato in laboratorio
Potete già avviare la versione con l'interfaccia grafica!
Utilizzare Octave a casa
Installare Octave a casa è:
- Facile se usate Linux
- Facile se usate Windows
- Non proprio banale se usate OSX (come me)
Potete trovare delle istruzioni dettagliate sul sito del corso
Installare Octave è importantissimo per potervi esercitare!
Componenti della GUI di Octave
L'elemento più importante della GUI è la finestra dei comandi
Il simbolo ">>" si chiama prompt ed indica dove potete scrivere
Componenti della GUI di Octave
Nella colonna di SX trovate un file browser
Ogni programma quando esegue è associato ad una cartella
- Il file browser ci permette di conoscere quale sia...
- ...E di esplorarla
Torneremo su questo punto in futuro
Componenti della GUI di Octave
Sempre nella colonna di SX trovate una finestra di workspace e la storia dei comandi
- La finestra di workspace mostra le variabili attualmente definite
- La storia dei comandi mostra le istruzioni eseguite
Quando comincerete ad eseguire, fate attenzione al loro contenuto
Il "Linguaggio Octave"
Il linguaggio Octave si basa su pochi concetto fondamentali
- Tipi di dato elementari
- Tipi di dato composti
- Variabili
- Espressioni e funzioni
- Istruzioni di controllo del flusso
E diversi concetti più complessi, ma meno essenziali:
- Range, Function handler, ...
Oggi cominciamo a vederli insieme
Tipi di Dato Elementari: Numeri Reali
Il tipo di dato più importante in Octave sono i numeri reali
Sintassi:
3.14159
1000
314159e-5
1e3
Semantica: beh, un numero reale!
Tipi di dato composto: Vettori
Octave permette di comporre dati elementari in vettori (o array)
Sintassi:
[<dato a>, <dato b>, ...]
[<dato a> <dato b> ...]
Qualche esempio:
[1, 5, 3, 9]
[1 5 3 9]
La notazione #2 è sconsigliata (in alcuni casi causa confusione)
Semantica: un vettore, proprio come vi aspettereste
Vettori e Range
Se gli elementi sono consecutivi possiamo usare un range
Sintassi:
<primo>:<ultimo>
<primo>:<incremento>:<ultimo>
Qualche esempio:
1:6
equivale a: [1, 2, 3, 4, 5, 6]
1:2:6
equivale a: [1, 3, 5]
1:2.5:6
equivale a: [1, 3.5, 6]
Tipi di dato composto: matrici
Octave permette di comporre dati elementari in matrici
Sintassi (una sequenza di vettori, separati da ";"):
[<dato a>, <dato b>, ...; <dato c>, <dato d>, ...; ...]
Un esempio:
[1, 5; 3, 9]
Semantica (i vettori rappresentano le righe):
\left(\begin{array}{cc}
a & b & \ldots\\
c & d & \ldots\\
\ldots & \ldots & \ldots
\end{array}\right)
Tipi di dato composto: stringhe
Octave permette di rappresentare stringhe di testo
Sintassi:
'ciao mondo!'
"ciao mondo!"
Semantica (qui le cose si fanno un filo complicate):
- Una stringa corrisponde in realtà ad un vettore di caratteri
- Una carattere è un simbolo di testo
Un carattere corrisponde però internamente ad un numero
Tipi di dato composto: stringhe
Si usa la seguente tabella di conversione carattere <-> numero:
Si chiama tabella ASCII (dal nome dello standard)
Tipi di dato composto: stringhe
Octave permette di rappresentare stringhe di testo
Sintassi:
'ciao mondo!'
"ciao mondo!"
Semantica (qui le cose si fanno un filo complicate):
- Una stringa corrisponde in realtà ad un vettore di caratteri
Quindi 'ciao mondo!'
corrisponde a:
[99, 105, 97, 111, 32, 109, 111, 110, 100, 111, 33]
Variabili ed Assegnamento
Per memorizzare dati, Octave utilizza il concetto di variabile:
Una variabile è una astrazione per un dato in memoria
Potete pensarla come un contenitore con un nome
- Una variabile viene definita assegnandovi un valore
- Per farlo si utilizza l'operatore di assegnamento
Sintassi:
<variabile> = <dato>
Variabili ed Assegnamento
Vediamo un esempio:
a = 5
- Quando premete [invio], viene definita la variabile
a
con valore 5
Il contenuto di una variabile può essere cambiato:
a = 5
a = 3
- Viene definita la variabile
a
con valore 5
- Al passo successivo ad
a
viene assegnato il valore 3
Una variabile è un contenitore, ricordate?
Variabili ed Assegnamento
Una variabile può contenere qualunque tipo di dato:
x = 1
x = [1, 2, 3]
x
viene definita con il valore 1
- Dopo il secondo passo,
x
contiene il vettore [1, 2, 3]
Il nome di una variabile:
- Deve iniziare con una lettera o con "
_
"
- I caratteri successivi possono essere lettere, "
_
", o numeri
r2d2 = 'un droide'
c_3po = 'un altro droide'
Variabili Speciali
Alcune variabili sono automaticamente disponibili:
- Pi-greco "
pi
"
- Numero di Eulero "
e
"
- Unità immaginaria "
i
"
L'unità immaginaria può essere utilizzata per definire numeri complessi:
2 + 3i
- Non li useremo gran che in questo corso...
Variabili Speciali
- Quando scriviamo un dato sul prompt e premiamo [invio]:
- Il dato viene inserito in una variabile speciale che si chiama
ans
Questo è il motivo per cui scrivendo per esempio:
10
Octave risponde con:
ans = 10
Espressioni (o "cosa fare con i dati")
Una espressione è una notazione che denota un valore. Il processo per cui questo avviene si chiama valutazione
- Quando scrivete una espressione e premete [invio]...
- ...Octave la valuta e denota (o restituisce) un valore
Un modo per pensarla: il valore restituito "rimpiazza" l'espressione
Si può usare una espressione ovunque sia richiesto un dato
Espressioni Semplici
Una espressione può essere semplice o composta
La notazione per un dato è un esempio di espressione semplice:
10
- quello che avete fatto è scrivere del testo
- Nel momento in cui premete [invio]
- Octave valuta l'espressione ed ottiene il valore
10
Il risultato dell'espressione viene memorizzato nella variabile ans
Espressioni Semplici
Il nome di una variabile è una espressione semplice
x = 10
x
- Quando premete [invio] dopo il secondo passo...
- ...Octave controlla se la variabile
x
sia definita...
- ...Se lo è, restituisce il valore corrente
Se la variabile non è definita viene riportato un errore
Eccezione: Il nome di una variabile non è una espressione se compare a sinistra dell'operatore di assegnamento =
x = 10
Espressioni Composte: Vettori (e Matrici)
La definizione di un vettore è una espressione composta
Quando scrivete...
[1, 3, 4]
...e battete "invio", Octave lo interpreta come:
[<exp1>, <exp2>, <exp3>]
- Le espressioni "
<exp1>
", "<exp2>
", "<exp3>
" vengono valutate...
- ...E restituiscono i valori
1
, 3
e 4
- A questo punto viene valutata
[<dato>, <dato>, ...]
Ed otteniamo il nostro vettore!
Espressioni Composte: Funzioni
Octave fornisce un costrutto fondamentale per comporre espressioni:
Si chiama chiamata a funzione una notazione che permette di eseguire un sotto-programma precedentemente definito
Qualche esempio:
plus(2, 5)
minus(10, 3)
times(2, 3)
Chiamando una funzione si esegue il sotto-programma corrispondente
Sintassi di una Chiamata a Funzione
La sintassi per una chiamata a funzione è:
<nome della funzione>(<dato>, <dato>, ...)
I dati tra parentesi rappresentano l'input del sotto-programma
Tipicamente un funzione incapsula un algoritmo
- Conseguenza: la funzione restituisce un risultato
Si chiama "funzione" per analogia con le funzioni matematiche:
- Accetta dati di ingresso e restituisce un risultato
- Ha addirittura la stessa notazione di una funzione matematica
Semantica di una Chiamata a Funzione
Una chiamata a funzione viene valutata come segue:
- Innanzitutto vengono valutati i parametri
- Otteniamo così i dati di ingresso del sotto-programma
- Quindi viene eseguito il sotto-programma corrispondente
- Quando il sotto-programma termina, viene restituito il risultato
Non si tratta di un meccanismo molto complesso:
- È quello che fareste voi se doveste fare i conti a mano
Vediamo un esempio...
Semantica di una Chiamata a Funzione
La nostra espressione di partenza:
plus(5, times(2, minus(7, 5)))
Per valutare plus
dobbiamo valutare i parametri:
- Il primo parametro è
5
(immediato da valutare)
- Il secondo parametro è una invocazione di
times
- Per valutare
times
dobbiamo valutare i parametri:
- Il primo parametro è
2
- Il secondo parametro è una invocazione di
minus
- Per valutare
minus
dobbiamo valutare i parametri:
- Il primo parametro è
7
- Il secondo parametro è
5
Semantica di una Chiamata a Funzione
La nostra espressione di partenza:
plus(5, times(2, minus(7, 5)))
Per valutare plus
dobbiamo valutare i parametri:
- Il primo parametro è
5
(immediato da valutare)
- Il secondo parametro è una invocazione di
times
- Per valutare
times
dobbiamo valutare i parametri:
- Il primo parametro è
2
- Il secondo parametro è quindi
2
plus(5, times(2, 2))
Semantica di una Chiamata a Funzione
La nostra espressione di partenza:
plus(5, times(2, minus(7, 5)))
Per valutare plus
dobbiamo valutare i parametri:
- Il primo parametro è
5
(immediato da valutare)
- Il secondo parametro è quindi
4
plus(5, 4)
Semantica di una Chiamata a Funzione
La nostra espressione di partenza:
plus(5, times(2, minus(7, 5)))
L'intera espressione denota il valore 9
9
Ottenere Aiuto
Octave mette a disposizione una enormità di funzioni
Ognuna ha la sua definizione!
- Il suo nome
- I suoi parametri
- La sua specifica (sotto-programma)
- Il numero di parametri può essere variabile
Come fare ad orientarsi?
- Prima soluzione: imparare a memoria
- Seconda soluzione: Google o il manuale di octave
- Terza soluzione: usare una funzione!
Ottenere Aiuto
Per conoscere la specifica di una funzione con nome noto
Potere usare la funzione help
o la funzione doc
help(<nome funzione>)
doc(<nome funzione>)
help
visualizza un messaggio sulla finestra dei comandi
doc
apre una finestra del document browser
- Il document browser è un altro elemento della GUI
Provate con:
help('plus')
doc('plus')
Ottenere Aiuto
Se conoscete solo parte del nome di una funzione
Potete iniziare a scrivere a poi premere [tab]:
- Octave mostrerà i possibili completamenti
- I completamenti sono nomi di funzioni o di variabili
Provate con:
pl<e poi premete [tab]>
È una funzionalità molto utile
Funzioni con Sintassi Speciale: Comandi
Alcune funzioni hanno una sintassi speciale. Per esempio:
- Se tutti i parametri di una funzione sono stringhe...
- ...In Octave la funzione viene chiamata un comando
I comandi si possono invocare:
- Senza riportare le parentesi
- Senza riportare i simboli
'
o "
intorno alle stringhe
Per esempio, le seguenti invocazioni sono equivalenti:
help('plus')
help plus
Funzioni con Sintassi Speciale: Operatori
Tutti gli operatori aritmetici hanno una sintassi speciale in Octave
Operatore di somma: "+
":
Sintassi:
<dato> + <dato>
- Calcola la somma di scalari o vettori/matrici
- I vettori/matrici vengono sommati elemento per elemento
- Quindi, i due operandi devono avere le stesse dimensioni
2 + 3
[1, 2] + [3, 4]
Esiste anche un operatore di somma +
unario, che non fa nulla
Funzioni con Sintassi Speciale: Operatori
Operatore di sottrazione: "-
":
Sintassi:
<dato> - <dato>
- Calcola la differenza di scalari o vettori/matrici
- I vettori/matrici vengono sottratti elemento per elemento
a = 5
a - 3
[3, 3] - [a, a]
Esiste anche l'operatore -
unario
- <dato>
Funzioni con Sintassi Speciale: Operatori
Operatore di prodotto: "*
"
Sintassi:
<dato> * <dato>
- Se gli operandi sono scalari, calcola il prodotto
- Per vettori o matrici, calcola il prodotto matriciale
- Ossia il prodotto riga per colonna
- Valgono le classiche restrizioni studiate in Algebra
2 * 3
[1, 2; 2, 1] * [2, 1; 1, 2]
[1, 2] * 2
[1, 2] * [2; 1]
[1; 2] * [2, 1]
Funzioni con Sintassi Speciale: Operatori
Operatore di prodotto elemento per elemento: ".*
"
Sintassi:
<dato> .* <dato>
- Se gli operandi sono scalari, è identico a
*
2 .* 3
- Per vettori o matrici con dimensioni identiche...
- ...Moltiplica gli elementi in posizioni analoghe
[1, 2; 2, 1] .* [2, 1; 1, 2]
[1, 2] .* [2, 1]
Funzioni con Sintassi Speciale: Operatori
Operatore di prodotto elemento per elemento: ".*
"
Sintassi:
<dato> .* <dato>
- Vettore * scalare = prodotto per scalare
[1, 2] .* 3
- Se moltiplichiamo un vettore riga per un vettore colonna...
- ...La colonna viene moltiplicata per ciascuno scalare nella riga...
- ...ed otteniamo una matrice
[1; 2] .* [1, 3]
Broadcasting
Per alcuni operatori (e.g. ".*
"):
- Se gli operandi hanno una dimensione "sbagliata"...
- ...Octave cerca di risolvere il problema "espandendo" gli operandi
Per esempio:
[1; 2] .* [1, 3]
Viene espanso come (replica di righe/colonne):
\left(\begin{array}{cc}
1 & 1\\
2 & 2
\end{array}\right) .*
\left(\begin{array}{cc}
1 & 3\\
1 & 3
\end{array}\right)
Broadcasting
Per alcuni operatori (e.g. ".*
"):
- Se gli operandi hanno una dimensione "sbagliata"...
- ...Octave cerca di risolvere il problema "espandendo" gli operandi
Un altro esempio:
[1, 2] .* 2
Viene espanso come (replica dello scalare):
\left(\begin{array}{cc}
1 & 2
\end{array}\right) .*
\left(\begin{array}{cc}
2 & 2
\end{array}\right)
Questo meccanismo di espansione si chiama broadcasting
- Non lo useremo spesso, ma qualche volta sì
Funzioni con Sintassi Speciale: Operatori
Operatore di divisione elemento per elemento: "./
"
Sintassi:
<dato> ./ <dato>
- Calcola il quoziente elemento per elemento
- Per vettori/matrici: stesse regole di "
.*
" (incluso il broadcasting)
Esiste anche un vero e proprio operatore di divisione "/
"
- Se applicato a scalari, è identico a "
./
"
- Se applicato a matrici, ha un comportamento più complesso
Lo vedremo più avanti
Funzioni con Sintassi Speciale: Operatori
Operatore di trasposizione (unario): ".'
"
Sintassi:
[a, b; c, d].'
- Calcola la trasposizione del vettore/matrice cui è applicato
Operatore di trasposizione e coniugazione: "'
"
- Stesso effetto del precedente, se i numeri sono reali
- Se i numeri sono complessi, trasposizione + coniugazione
[a+i, b+i; c+i, d+i]'
Ricordate: i numeri complessi non li useremo gran che
Funzioni con Sintassi Speciale: Operatori
Elevamento a potenza elemento per elemento: ".^
" o ".**
"
Sintassi:
<dato> .^ <dato>
<dato> .** <dato>
- Dato a sx = base, dato a dx = esponente
- Eleva la base all'esponente, elemento per elemento
- Per vettori e matrici: stesse regole di "
.*
" (incluso il broadcasting)
Esiste anche un operatore di elevamento a potenza "^
" (o "**
")
- Se applicato a scalari, è identico a "
.^
" (o ".**
")
- Su matrici & vettori, calcola l'esponenziale di matrice
Funzioni con Sintassi Speciale: Operatori
Anche l'assegnamento "=
" è considerato un operatore
In particolare, esso denota il valore assegnato:
x = 10
- Assegna
10
alla variabile x
e denota il valore 10
(x = 10) * 2
- Assegna
10
alla variabile x
e denota il valore 20
y = x = 10
- Assegna
10
ad x, poi ad y
, quindi denota il valore 10
Si dice che =
è un operatore con effetti collaterali
Associatività e Priorità
Consideriamo l'espressione:
2 * a + b + 5
Sappiamo (per regole di matematica) che va interpreta come:
((2 * a) + b) + 5
Questa interpretazione si basa su due proprietà degli operatori:
- Priorità, che determina quali operatori debbano essere risolti prima
- Associatività, per risolvere applicazioni multiple di un operatore
Octave utilizza le stesse proprietà per interpretare gli operatori
Associatività e Priorità
Operatori, per priorità decrescente |
chiamata a funzione |
trasposizione ed elevamento a potenza |
operatori + e - unari |
moltiplicazione e divisione |
somma e sottrazione |
operatore : (costruzione di range) |
assegnamento |
Tutti gli operatori che abbiamo visto sono associativi da sx a dx
Associatività e Priorità
Qualche esempio:
2 * 3 + 4
2**3 * 2
a = 10 + 2
1:5+5*2
plus(2,3)*2
Per forzare un ordine diverso, si possono usare le parentesi
2 * (3 + 4)
Plotting
Octave permette anche di disegnare facilmente dei grafici
- Si utilizzano delle funzioni apposite
- Le vedremo più avanti nel corso
Oggi, come esempio, stampiamo un sombrero :-)
sombrero()
La funzione sombrero()
:
- Serve a verificare il funzionamento del back-end grafico
- Calcola il valore di una funzione in due variabili per un range di valori
- Costruisce una figura ed un grafico 3D