Le matrici sparse su Octave
In questa lezione online ti spiego come fare una matrice sparsa su Octave.
Cos'è una matrice sparsa? A cosa serve? Quando crei una matrice molto grande con molti valori costanti (es. zero) occupi inutilmente una gran parte della memoria del computer. Ad esempio, una matrice diagonale ha valori diversi da zero solo sulla diagonale principali e zero altrove. $$ M = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ \end{pmatrix} $$ Puoi ottenere lo stesso risultato creando una matrice sparsa (sparse matrix) dove gli zeri sono compressi. In questo modo occupi una minore quantità di memoria.
Puoi usare le matrici sparse per creare matrici identità e matrici diagonali compresse.
La matrice identità sparsa
Ti faccio un esempio pratico
Crea una matrice identità tramite il comando eye(4)
>> eye(4)
ans =
Diagonal Matrix
0 1 0 0
0 0 1 0
0 0 0 1
Nella matrice ci sono 12 zeri e 4 uno. Gran parte dello spazio è occupato inutilmente dai valori nulli.
Puoi realizzare la stessa matrice identità usando la tecnica delle matrici sparse tramite il comando speye(4)
>> speye(4)
ans =
Compressed Column Sparse (rows = 4, cols = 4, nnz = 4 [25%])
(1, 1) -> 1
(2, 2) -> 1
(3, 3) -> 1
(4, 4) -> 1
In questo caso la matrice memorizza solo le posizioni (riga, colonna) in cui ci sono i valori diversi da zero, occupando meno spazio di memoria.
Per questa ragione si chiama matrice "sparsa".
Nota. Nella matrice sparsa sono memorizzate solo le informazioni utili. In una matrice identità i valori nulli sono ininfluenti nel calcolo. Pertanto sono eliminati. Questo riduce lo spazio di memoria occupato (complessità spaziale) e rende più veloce il calcolo matriciale (complessità temporale) su Octave. Il vantaggio delle matrici sparse è tanto maggiore quanto più è grande la matrice.
Puoi usare la matrice sparsa che hai appena creato anche nei calcoli come se fosse una matrice 4x4
Ad esempio, crea una matrice con 4 colonne
>> M=[1 2 3 4;5 6 7 8; 9 0 1 2; 3 4 5 6]
M =
1 2 3 4
5 6 7 8
9 0 1 2
3 4 5 6
Ora moltiplica la matrice M per la matrice identità
>> M*eye(4)
ans =
1 2 3 4
5 6 7 8
9 0 1 2
3 4 5 6
Poi moltiplica la matrice M per la matrice identità sparsa
>> M*speye(4)
ans =
1 2 3 4
5 6 7 8
9 0 1 2
3 4 5 6
Il risultato è sempre lo stesso.
Nel secondo caso però hai occupato meno memoria e il tempo di calcolo è minore.
La matrice diagonale sparsa
Per creare una matrice diagonale sparsa con valori diversi da 1 usa il comando spdiags()
>> spdiags([1;2;3],0,3,3)
ans =
Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%])
(1, 1) -> 1
(2, 2) -> 2
(3, 3) -> 3
- Il primo parametro è un vettore colonna [1;2;3] contenente gli elementi da inserire sulla diagonale
- il secondo parametro è la diagonale dove inserire gli elementi (0 indica la diagonale principale)
- il terzo e il quarto parametro sono il numero di righe (3) e colonne (3) della matrice sparsa da creare
Il risultato in output è la sparse matrix di una matrice diagonale 3x3
$$ M = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 3 \\ \end{pmatrix} $$
Come definire una matrice sparsa con appositi valori non nulli
Su Octave puoi anche creare una matrice sparsa specificando soltanto i valori non nulli e la loro posizione nella matrice.
Ad esempio, crea una sparse matrix con questi valori
$$ M = \begin{pmatrix} 3 & 0 & 1 \\ 0 & 1 & 2 \\ 4 & 0 & 0 \end{pmatrix} $$
Definisci un array con tante righe quanti sono i valori non nulli della matrice.
In ciascuna riga scrivi il numero della riga, della colonna e il valore dell'elemento non nullo.
>> v = [1 1 3; 1 3 1; 2 2 1; 2 3 2; 3 1 4]
v =
1 1 3
1 3 1
2 2 1
2 3 2
3 1 4
Spiegazione. Il primo elemento non nullo (3) si trova nella prima riga e colonna (1,1). Pertanto, la prima riga del vettore è 1 1 3. Il secondo elemento non nullo (1) si trova nella prima riga alla terza colonna. Quindi, la seconda riga del vettore è 1 3 1. Il terzo elemento non nullo (2) si trova nella seconda riga alla seconda colonna. Quindi, la terza riga del vettore è 2 2 2. E via dicendo.
Ora per creare la matrice sparsa usa la funzione spconvert()
>> spconvert(v)
Il risultato è una matrice sparsa con i valori nelle posizioni che hai indicato.
ans =
Compressed Column Sparse (rows = 3, cols = 3, nnz = 5 [56%])
(1, 1) -> 3
(3, 1) -> 4
(2, 2) -> 1
(1, 3) -> 1
(2, 3) -> 2
Nell'array usato per costruire la matrice sparsa puoi definire i valori non nulli seguendo qualsiasi ordine.
Nota. Puoi anche indicare più valori per una stessa posizione della matrice. Quando una posizione della matrice è presente più volte nell'array, Octave somma i valori tra loro senza andare in errore. Ad esempio, definisci una matrice sparsa indicando nella posizione (1,1) il valore 2 e il valore 3. Nella posizione (1,1) Octave somma i due valori tra loro 2+3=5
Con questo metodo puoi anche creare una matrice sparsa con i numeri complessi.
Se questa lezione di StemKB sulle matrici tramite Octave ti piace, continua a seguirci.