%% MATLAB
% MATLAB è un linguaggio di programmazione di alto livello:
% MATLAB sta per “MATrix LABoratory”, quindi si basa sulla gestione di matrici;
% é simile all’inglese: se non vi viene in mente un comando, pensate a come lo direste in inglese e tendenzialmente lo trovate.
% Caratteristica di MATLAB è avere a una quantità esorbitante di toolbox, che sono librerie utilizzate per approcciare problemi di natura diversa.
% MATLAB un ambiente di programmazione che viene utilizzato in ambito ingegneristico (meccanica, telecomunicazioni, elettronica), scientifico (neuroscienze), economico.
% Lo studiamo perché potreste trovarlo nella ricarca scientifica e nelle aziende; o comunque potreste trovarvi a lavorare con ingegneri che lo usano.
%% Ambiente base
% Aprendo l'ambiente MATLAB, notiamo vari elementi.
% Al centro, un riquadro chiamato “command window”, che è una sorta di terminale di matlab.

a = 1

% A destra (o comunque lateralmente), una finestra chiamata “workspace”, che mostra le variabili create nella command window.
% Compare la variabile a appena creata nella command window.
% Questa finestra è utile se fate una pausa e al ritoro volete vedere di cosa stavate trattando; oppure in fase di debugging per vedere come evolvono le variabili nel vostro codice.
% Sulla sinistra, una finestra che indica le cartelle in uso.
% In alto nella barra, una serie di opzioni che facilitano la scrittura del codice: perché nelle fasi di scrittura anzichè digitare ogni carattere, si possono utilizzare degli script già pre-impostati.
% Si possono creare due tipi di script: normal e live script.
% Script normale. Clicchiamo l’icona più a sinistra e si apre una finestra vuota in cui scriviamo:

a = 1
b = 2

% poi salviamo, dando un nome, e lanciamo lo script digitando icona “Run”. Vediamo che nella command window principale compaiono il titolo dello script e le due variabili a e b.
% Live script: sono script in cui possiamo aggiungere immagini e testo al fianco delle linee di codice. E’ un tipo di scripting didattico oppure adatto a una presentazione di un lavoro.
%% Commenti
% I commenti per escludere parte del codice dall'esecuzione si ottengono con

%

% CTRL T per commentare
% CTRL R per decommentare
%% Aritmetica di base
% MATLAB implementa le classiche operazioni aritmetiche +, -, x, :, ^ lavorando direttamente nella command window oppure tramite script.
% Se in uno script scrivete

18 * 4

% e lanciate “Run”, nella command window compare ANS=72: questo perché MATLAB crea una variabile provvisoria e la assegna al risultato.
% Ora nello script scriviamo:

15 * 3
10 * 10

% se diamo “Run”, allora vediamo ANS=45 e ANS=100.
% Dunque, andiamo nel/nella workspace e vediamo che c’è una sola variabile ANS a cui è associato valore 100, cioè l’ultimo valore: quindi l’informazione dell’operazione precedente è persa.
% Per non perdere informazioni è bene fare una assegnazione: che vuol dire apporre un uguale tra il nome della variabile e il suo valore.
% Scriviamo quindi nello script le precedenti come:

d = 15 * 3
e = 10 * 10

% dando “Run”, vediamo che nella command window compaiono le due variabili e nella workspace compare una nuova variabile, e, con valore 100, mentre la vecchia variabile d è aggiornata a 45.
% MATLAB usa il “.” come virgola:
% se per sbaglio scrivo

f = 3,5

% MATLAB mi crea due variabili: f=3 e ANS=5.
%% Variabili e funzioni
%% Definizione variabili
% Regola - Le varibili non possono avere un nome che cominci con un numero:
% se nella command window, scrivo (senza commento iniziale%)

%1a = 1

% MATLAB dice che è una formula invalida.
% MATLAB è case sensitive,
% g e G sono due variabili diverse:

g = 10
G = 11

% Equazioni complesse richiedono di innestare i calcoli tra parentesi tonde.
% Se ci dimentichiamo un valore di una variabile, basta digitare quella variabile nella command window:

h = (36 - 4 ) + 4

% nella command window, digitando h ci viene restituito 36.
% Oppure possiamo andare nella workspace è cliccare due volte sulla variabile: si apre un foglio excel in cui compare il valore. In questo caso, cliccando due volte sue h, c’è solo un valore, 36, perché è uno scalare; ma se avessimo una quantità vettoriale, avremo elencate tutte le componenti.
%% Calcoli sulle variabili
% Possiamo combinare variabili esistenti in nuove variabili.
% Scriviamo

l = h + a

% risultato l=37.
% Oppure possiamo aggiornare in modo ricorsivo una variabile già esistente: nello script

h = h + 1

% risultato h=37.
% Se ora nello script diamo

l

% vediamo che il suo valore è 37, cioè quello assegnato in precedenza senza l’aggiornamento di g nell’ultima riga: l’incremento di h non implica un ricalcolo di l.
% Quando si definisce una variabile, non è sempre necessario che la stessa venga pubblicata nella command window, anzi può essere fastidioso. Perciò basta apporre un “;” dopo la definizione e l’output verrà soppresso, cioè nulla verrà mostrato nella command window:
% nello script scrivere

m = l + 10;

% dare Run e guardare la command window.
%% Salvare le variabili
% Si può salvare il workspace in un file .mat, che poi si può ricaricare a piacimento. Possiamo salvare anche solo una specifica variabile, scrivendo:

save my_first_workspace m

% save è il comando
% my_first_workspace è il nome del file, che ritroviamo nella finestra a sinistra
% m è la variabile.
% Per ricaricare la nostra variabile precedentemente salvata, il comando da lanciare dallo script è:

load my_first_workspace.mat m
m

%% Pulizia
% Per pulire workspace, nella command window dare

clear d e

% scompaiono le variabili d e e.
% Se vogliamo cancellare proprio tutto, dare solo

clear

% oppure

clear all

% Per pulire command window, nella command window dare

clc

% verranno cancellati tutti i comandi: rimangono però le variabili nella workspace !
%% Costanti
% MATLAB presenta una serie di costanti built-in, cioè costanti caratteristiche che non ci ricordiamo o che preferiamo richiamare per avere una maggiore precisione dopo la virgola:
% basta richiamarle

c = physconst('Lightspeed') % [m/s]
k = physconst('Boltzmann') % [J/K]

% Può essere che il comando physconst sia compreso in un toolbox che non abbiamo ancora installato: MATLAB segnala quale toolbox è richiesto per quel comando e vi porta a scaricarlo (attenzione che nello scarice il toolbox potrebbe chiudersi l'ambiente MATLAB).
% Le variabili che non hanno bisogno di toolbox:
% pigreco: vengono stampate solo alcune cifre significative, ma MATLAB ne considera di più;

pi

% numero immaginario:

i

%% Funzioni built-in
% Analogamente alle costanti built-in, ci sono le funzioni built-in:

o = sqrt(-9)
p = cos(pi/2)
q = round(atan2d(0.5736, 0.8192))

% Può succedere che non ricordi una funzione come "round" (una funzione che approssima) o "atan2d", allora posso cercarne il significato, solo e soltanto nella command window, dando per esempio

help atand2d

% vengono illustrate ulteriori informazioni sulla funzione (cosa indica quindi atand2D?) e suggerite altre ricerche correlate (quali in questo caso? [atand per esempio]).
% Oppure si può aprire la documentazione online di matlab, che contiene ancora più informazioni.
% Attenzione: MATLAB non è ottimale nella circostanza in cui volessi nominare una variabile proprio come una funzione built-in:
% nella command window diamo

%sqrt = 1 

% se poi diamo

sqrt(10) 

% compare errore: fintantoché esiste la variabile sqrt, non si può utilizzare la funzione built-in sqrt() !
% Se magari per sbaglio a un certo momento denominate una variabile sqrt, ecco che basta cancellarla con

clear sqrt

% e la funzione built-in "sqrt" torna ripristinata.
%% Precisione variabili
% Le variabili possono essere distinte in base alla precisione dopo la virgola:
% precisione singola: 8 cifre dopo la virgola,
% precisione doppia: 16 cifre dopo la virgola,
% int: solo numeri interi.
% Casi d'utilizzo:
% solitamente le variabili sono in double precision;
% se ho bisogno di rapidità di calcolo e ho hardware limitato andrò sul double? NO, per non sprecare velocità di calcolo e memoria.
% Esempi. Nella command window, digitando:

r = pi

% nella workspace, facciamo double click sulla variabile r e vediamo che si apre un foglio di calcolo: andando nella cella con la variabile, vediamo che nella barra sopra compare 1x1 double.
% Se riproponiamo una stringa, nella command window scriviamo:

s = "Hello world"

% nella workspace, facciamo double click sulla variabile s e si apre un foglio di calcolo: andando nella cella corrispondente alla variabile vediamo che nella barra sopra compare 1x1 string.
% Se vogliamo cambiare la precisione:

t = single(pi)
j = int8(pi)

% e controlliamo come sopra.
% Possiamo controllare le proprietà delle varie variabili,
% o andando a mano nella workspace come già visto;
% oppure digitando il comando whos.
%%
%% Precisione di macchina
% Matlab presenta una precisione di macchina definita con un valore detto eps, che è il valore più piccolo che matlab riesce a gestire. Vediamo che succede coi seguenti comandi:

eps %valore della quantità più piccola
PlusEPS = 1 + eps %compaiono delle cifre dopo la virgola
PlusHalfEPS = 1 + eps/2 %non compaiono più delle cifre dopo la virgola perché è un valore troppo piccolo

% Per accertarci di questo, trasformiamo in stringa i valori numerici appena calcolati, tramite comando "num2str" (esiste pure il comando inverso "str2num"):
% il secondo termine tra parentesi indica il numero di cifre significative da mostrare dopo la virgola:

num2str(PlusEPS,100) %svariate cifre dopo la virgola
num2str(PlusHalfEPS,100) %no cifre: non si sente solo alcunché sotto eps

% Il numero di cifre dopo la virgola viste digitando pi è 4 (provare).
% Però posso cambiare questo formato e vederne gli effetti coi seguenti due comandi:

format long
pi

% Se voglio formato breve:

format short

%% Matrici
% Esistono vari tipi di matrici
% logiche: 0 o 1
% char: caratteri
% numeriche: che si distinguono in base alla precisione
% table, celle, strutture
% function handle sono scalari.
%
%% Vettori o array
% Anche un singolo scalare è considerato un array 1x1:
%  infatti, se ricordate, quando facciamo doppio click su una variabile ci compare 1x1.
% Gli array numerici si definiscono come righe x colonne: primo numero x secondo numero.
% Definire un vettore riga:

u = [2 4 6] %row vector

% oppure equivalentemente (spazio e virgola sono uguali):

v = [2, 4, 6] %row vector

% Invece per una vettore colonna, si usa punto e virgola:

w = [2; 4; 6] %column vector

% Attenzione che gli elementi del vettore devono essere della stessa precisione;
% così non fosse, matlab adotta il livello di precisione più bassa:

z = [1, pi, int8(4)]

% si adegua al int8, il che non cambia per il primo elemento, ma per pigreco sì !
% Possiamo aver bisogno di creare vettori equispaziati, per esempio x = [1 2 3 4 eccetera fino a 20].
% Possiamo semplificare scrivendo (da 1 a 20 a passo di 1)

x1 = 1:1:20

% In formato ancora più breve, posso lasciare lo spacing di default

x2 = 1:20

% Oppure se voglio uno spacing particolare di 0.4:

x3 = 1:0.4:20

% Anche a ritroso

x4 = -10:2:-6

%  oppure

x5 = 10:-2:6

% Se conosciamo il numero di elementi ma non i loro valori, e vogliamo equispaziarli:
% esempio: 13 elementi tra 1 e 3

y1 = linspace(1,3,13)

% se non si indica i terzo termine, il valore di spacing di default è 100:

y2 = linspace(1,3)

%% Matrici
% Per definire una matrice:
% mettere virgole o spazi è equivalente per separare elementi della stessa riga:

m1 = [1 2 ; 3 4 ; 5,6] 

% si possono inserire operazioni

m2 = [3*3 -2^2 ; 65+3 -5+90]

% oppurre anche costanti o funzioni built in

angles = [pi pi/2; pi/3 pi/4]
cos(angles)

%% Allocazione di memoria
% MATLAB non richiede di pre-allocare memoria indicando le dimensioni di una matrice/vettore:
% per esempio, scrivendo le prossime due righe, vediamo che MATLAB riconosce automaticamente l’intenzione di creare una matrice

k=1
k(2)=3

% tuttavia con grandi numeri può essere utile fare una assegnazione iniziale;
% però è anche vero che non sempre si possono conoscere in anticipo le dimensioni di una matrice.
%% Grafici
% Ci sono infiniti grafici disponibili su MATLAB.
% Plot 2D
% 2 vettori con lo stesso numero di elementi possono esseri graficati tramite

clear
x = linspace(0,4*pi,15);
y = cos(x);
plot(x,y)

% MATLAB associa a ogni punto x un punto y e poi connette i punti tra loro;
% il risultato non è granché perché ci sono solo 15 punti;
% allora dobbiamo aumentare il numero di punti, per esempio sostituendo 15 con 100;
% ma se zoomiamo ritroviamo il problema di una discretizzazione non perfetta.
% Possiamo personalizzare i grafici:
% la linea (spessore/tratteggio, il marker (come è rappresentato il punto), i colori;

plot(x,y,':*r') % linea a puntini (:), rossa (r), con punti segnati in asterisco (*)

% possiamo aumentare il dettaglio richiesto:

plot(x,y,'Marker','*', 'MarkerSize', 8, 'MarkerEdgeColor', 'k', 'LineWidth',3, 'Color', '#FFB240')

% label:

title('Grafico \alpha')
xlabel('angolo')
ylabel('valore funzione')

% Si possono inserire formule e cambiare gli stili così da poter integrare il grafico in latex.
% cambiare i limiti/estremi degli assi:

xlim([-1,15])
ylim([-2,2])

% ticks (valori sugli assi) in x, da 0 a 15 con passo di 3:

xticks(0:3:15)
yticks([-1 0 1])

% Si possono sovrapporre due curve nel grafico, usando il comando "hold on":

z = sin(x)
plot(x,y)
hold on
plot(x,z)
hold off

% A questo punto, con 2 curve, non sappiamo quale sia quale: perciò occorre inserire una legenda: automatica

legend % legenda automatica

% oppure con maggior dettaglio (con "Location" "best" si sposta la legenda nella posizione migliore):

legend({'cos(x)', 'sin(x)'},'Location','best') 

% per ottenere una griglia:

grid on

% Il comando "subplot" permette di dividere le figure in una griglia/tabella di figure:

ya = cos(2*x);
yb = sin(2*x);
yc = ya-yb;
yd = log(abs(x));
subplot(2,2,1)
plot(x,ya)
title('a')
subplot(2,2,2)
plot(x,yb)
title('b')
subplot(2,2,3)
plot(x,yc)
title('c')
subplot(2,2,4)
plot(x,yd)
title('d')

% Per plottare più grafici nello stesso momento, ma non nella stessa figura bensì in finestre separate si usa "figure":

figure
plot(x,ya)
title('a')
figure
plot(x,yb)
title('b')
grid on

% Modificare un grafico è possibile dall’interfaccia grafica (barra in alto) in figure, oppure:

figure
mygraph = plot(x,yd)
mygraph.LineWidth = 5;
mygraph.Color = 'red';

% qui si è chiamata una struttura di dati che si è denominata mygraph
% Plot 3D:

x = 0:0.01:30;
senx = sin(x);
cosx = cos(x);
plot3(senx,cosx,x);
title('Spiral')
xlabel('x')
ylabel('y')
zlabel('z')

% Grafici di superfici in 3D:

figure
x = linspace(-2,2,20);
y = x;
[X, Y] = meshgrid(x,y);

% meshgrid crea due dataset X (una matrice in cui ogni riga è una copia di x) e Y (una matrice in cui ogni colonna è una copia di y)

Z = exp(-X.^2.*cos(X/3)).*sin(Y);
mesh(X,Y,Z);

% in alternativa, un comando simile a mesh, ma capace di riempie gli spazi vuoti è:

surf(X,Y,Z)

%% Programmazione
% Le espressioni logiche >, <, <=, >=, ==, ~=
% (attenzione che = è segno di assegnazione e non operatore logico)
% danno un risultato:
% Vero : 1
% Falso: 0
% Esempi

3 < 4

5 <= 2

a = 8;
b = 4*2;
a == b

% Le espressioni logiche & (AND), | (OR), ~ (NOT) si possono applicare anche a vettori/matrici

D = [1 2 3 4 ; 5 6 7 8]
D (D>=1 & D<=3) = 5

%
% risulta 5 5 5 4 5 6 7 8
%% Costrutti built-in
% if, elseif, else
% esempio:
% switch: smile a if, ma con un set finito di opzioni
% esempio
% for (loops)
% esempio:
% while (loops): analogo al for, ma senza sapere in anticipo il numero di iterazioni: continuo a iterare finché vale una condizione
% esempio:
%% Funzioni esterne custom
% function output = something(input)
% per esempio, n uno script scriviamo e salviamo il file (rimuovendo il commento)

%function n = by4(x)
%n= x*4;
%end

% poi nella finestra di comando:

%clear
%by4(5)
%20

% risultato 20.
% Continuando con altra prova, vediamo che non compaiono mai “n” o “x” dati in definizione:

%a=3
%b=by4(a)

% risultato 12.
% Le funzioni possono avere più input e più output, l’importante è essere coerenti nell’utilizzarli
% esempio di script:
%