Articoli tecnici

Insight di MathWorks

Indicizzazione di matrici in MATLAB


Autori:

  • Steve Eddins, MathWorks
  • Loren Shure, MathWorks

8 minuti di lettura

Riepilogo

  • L’indicizzazione di matrici consente di selezionare e modificare i dati in modo efficiente, costituendo la base per la manipolazione degli array e gli algoritmi basati su matrici.
  • MATLAB supporta più stili di indicizzazione, tra cui l’indicizzazione tramite indici e tramite vettori, nonché l’operatore due punti e la parola chiave end per accedere a intervalli ed elementi limite.
  • L’indicizzazione supporta sia l’estrazione che l’assegnazione, consentendo trasformazioni concise come il riordinamento degli elementi, la sostituzione di valori e le operazioni sui subarray.
  • Un’indicizzazione efficace è alla base della vettorializzazione, riducendo la necessità di ricorrere a loop e producendo codice generalmente più breve, più chiaro e più rapido.

L’indicizzazione in una matrice è un modo di selezionare o modificare un sottoinsieme di elementi della matrice. MATLAB® dispone di diversi stili di indicizzazione che non sono solo potenti e flessibili, ma anche leggibili ed espressivi. Le matrici sono una componente fondamentale di MATLAB per l’organizzazione e l’analisi dei dati, e l’indicizzazione è essenziale per manipolare le matrici in modo efficace e comprensibile.

L’indicizzazione è strettamente correlata a un altro termine che gli utenti MATLAB sentono spesso: vettorializzazione. Per vettorializzazione si intende l’utilizzo di operazioni di matrici e vettori MATLAB anziché operazioni scalari, il che solitamente produce codice più breve, più espressivo e leggibile dal punto di vista matematico e talvolta più rapido.

Indicizzazione di vettori

Partiamo dal semplice caso di un vettore con i suoi indici.

 v = [16 5 9 4 2 11 7 14];

L’indice può essere un unico valore:

 v(3) % Extract the third element
 ans =
 9

Oppure un indice può a sua volta essere un altro vettore.

 v([1 5 6]) % Extract the first, fifth, and sixth elements
 ans =
 16 2 11

La notazione con i due punti in MATLAB offre un modo semplice per estrarre un intervallo di elementi da v.

 v(3:7) % Extract the third through the seventh elements
 ans =
 9 4 2 11 7

Invertendo le due metà di v è possibile creare un nuovo vettore.

 v2 = v([5:8 1:4]) % Extract and swap the halves of v
 v2 =
 2 11 7 14 16 5 9 4

L’operatore speciale end è un modo rapido e semplice per riferirsi all’ultimo elemento di v.

 v(end) % Extract the last element
 ans =
 14

È possibile usare l’operatore end in un intervallo.

 v(5:end) % Extract the fifth through the last elements
 ans =
 2 11 7 14

È anche possibile eseguire operazioni aritmetiche utilizzando end.

 v(2:end-1) % Extract the second through the next-to-last elements
 ans =
 5 9 4 2 11 7

Combinando l’operatore due punti ed end si possono ottenere molteplici effetti, come ad esempio estrarre ogni k-esimo elemento o capovolgere l’intero vettore.

 v(1:2:end) % Extract all the odd elements
 ans =
 16 9 2 7
 v(end:-1:1) % Reverse the order of elements
 ans =
 14 7 11 2 4 9 5 16

Utilizzando un’espressione di indicizzazione a sinistra del segno di uguale, è possibile sostituire determinati elementi del vettore.

 v([2 3 4]) = [10 15 20] % Replace some elements of v
 v =
 16 10 15 20 2 11 7 14

In genere, il numero di elementi a destra deve essere lo stesso del numero di elementi a cui fa riferimento l’espressione di indicizzazione a sinistra. Tuttavia, è sempre possibile utilizzare uno scalare a destra. Questo processo si chiama espansione scalare.

 v([2 3]) = 30 % Replace second and third elements by 30
 v =
 16 30 30 20 2 11 7 14

Ricorda: MATLAB utilizza l’indicizzazione su base 1. Quando si eseguono indicizzazioni in una matrice, alcuni linguaggi partono da zero. Altri linguaggi, come MATLAB, partono da 1. MATLAB segue la stessa notazione che probabilmente incontrerai nei libri di testo di matematica. Perché MATLAB parte da 1? Secondo Cleve Moler, fondatore di MATLAB, “è così che funziona la matematica”.

Indicizzazione di matrici con due indici

Ora considera l’indicizzazione in una matrice. Utilizzeremo un quadrato magico per i nostri esempi.

 A = magic(4)
 A =
 16 2 3 13
 5 11 10 8
 9 7 6 12
 4 14 15 1

Nella maggior parte dei casi, l’indicizzazione nelle matrici è eseguita utilizzando due indici: il primo indice per le righe e il secondo per le colonne.

La forma più semplice sceglie un unico elemento.

 A(2,4) % Extract the element in row 2, column 4
 ans =
 8

Più in generale, uno o entrambi gli indici possono essere vettori.

 A(2:4,1:2)
 ans =
 5 11
 9 7
 4 14

Un unico “:” nella posizione di un indice è una notazione abbreviata per 1:end ed è spesso utilizzato per selezionare intere righe o colonne.

 A(3,:) % Extract third row
 ans =
 9 7 6 12
 A(:,end) % Extract last column
 ans =
 13
 8
 12
 1

Talvolta può risultare poco chiaro come selezionare elementi sparsi di una matrice. Ad esempio, immaginiamo di voler estrarre da A gli elementi (2,1), (3,2) e (4,4).

Matrice 4x4 con tre valori evidenziati sparsi in diverse posizioni all’interno della matrice. Si trovano rispettivamente in riga 2, colonna 1; riga 3, colonna 2; e riga 4, colonna 4.

Elementi sparsi in una matrice.
Quale notazione occorre utilizzare per ottenere l’output desiderato?

L’espressione A([2 3 4], [1 2 4]) non produrrà il risultato che si desidera. Questo diagramma illustra il funzionamento dell’indicizzazione con due indici.

L’estrazione di elementi sparsi da una matrice richiede un diverso stile di indicizzazione, il che ci porta al nostro prossimo argomento.

Indicizzazione lineare

Che cosa fa l’espressione A(14)?

Quando si indicizza nella matrice A utilizzando un solo indice, MATLAB considera A come se i suoi elementi fossero disposti in fila in un lungo vettore colonna, scorrendo consecutivamente le colonne dall’alto verso il basso, come in:

16
5
9
...
8
12
1

Suggerimento: MATLAB segue l’ordine per colonne: l’indicizzazione lineare inizia scorrendo consecutivamente le colonne dall’alto verso il basso.

L’espressione A(14) estrae semplicemente il 14° elemento del vettore colonna implicito. L’indicizzazione in una matrice con un solo indice con questo metodo viene spesso chiamata indicizzazione lineare.

Dal diagramma, che mostra gli indici lineari nell’angolo in alto a destra di ciascun elemento della matrice, si può osservare che A(14) corrisponde a A(2,4).

L’unico indice può essere un vettore contenente più di un indice lineare, come di seguito:

 A([6 12 15])
 ans =
 11 15 12

Consideriamo nuovamente il problema di estrarre solo gli elementi (2,1), (3,2) e (4,4) di A. È possibile utilizzare l’indicizzazione lineare per estrarre tali elementi.

 A([2 7 16])
 ans =
 5 7 1

In questo esempio è facile vedere come funziona, ma come si calcolano gli indici lineari in generale? MATLAB offre una funzione chiamata sub2ind che converte gli indici di righe e colonne in indici lineari. È possibile utilizzarla per estrarre gli elementi desiderati in questo modo:

 idx = sub2ind(size(A), [2 3 4], [1 2 4])
 idx =
 2 7 16
 A(idx)
 ans =
 5 7 1

Indicizzazione logica

Un’altra variante di indicizzazione, l’indicizzazione logica, è una notazione compatta ed espressiva utile in molte applicazioni, tra cui l’elaborazione di immagini. Nell’indicizzazione logica, si usa un solo array logico per l’indice della matrice.

Ecco un esempio di array logico che è possibile utilizzare:

A > 12 

ans =
4×4 logical array

1  0  0  1
0  0  0  0
0  0  0  0
0  1  1  0

Queste sono le posizioni nella matrice in cui l’espressione logica è vera, in questo caso, ogni posizione maggiore di 12.

Ora l’espressione A(A > 12) estrae gli elementi della matrice che corrispondono ai valori diversi da zero dell’array logico. L’output è sempre sotto forma di vettore colonna.

A(A > 12) 

ans =

 16
 14
 15
 13

Molte funzioni di MATLAB che iniziano per is restituiscono array logici e sono molto utili per l’indicizzazione logica. Ad esempio, è possibile sostituire tutti gli elementi NaN di un array con un altro valore utilizzando una combinazione di isnan, indicizzazione logica ed espansione scalare con una riga di codice.

 B(isnan(B)) = 0

MATLAB ha molte funzioni per gli array di stringhe che restituiscono array logici, come contains, startsWith e matches. Possono essere utilizzate per operare sul testo utilizzando l’indicizzazione logica. Ad esempio, è possibile estrarre tutti i nomi dei programmi spaziali che contengono “Skylab.”

>> names

names =

  6×1 string array

    "Mercury"
    "Gemini"
    "Apollo"
    "Skylab"
    "Skylab B"
    "ISS"

>> names(contains(names,"Skylab"))

ans =

  2×1 string array

    "Skylab"
    "Skylab B"

L’indicizzazione logica è strettamente correlata alla funzione find. L’espressione A(A > 5) equivale a A(find(A > 5)). L’espressione di indicizzazione logica è più rapida per i casi semplici, ma si potrebbe utilizzare find se si ha bisogno dei valori degli indici per qualche altro scopo all’interno del calcolo. Per esempio, immaginiamo di voler temporaneamente sostituire i valori NaN con degli zeri, eseguire un calcolo e quindi reinserire i valori NaN nelle loro posizioni originali. In questo esempio, il calcolo è un filtraggio bidimensionale con filter2. Si procede così:

 nan_locations = find(isnan(A)); 

 A(nan_locations) = 0; 

 A = filter2(ones(3,3), A); 

 A(nan_locations) = NaN; 

Ci auguriamo che questi esempi nell’articolo ti aiutino a comprendere come esprimere gli algoritmi in modo compatto ed efficiente. Integrare queste tecniche e le relative funzioni nel tuo repertorio di programmazione MATLAB ti consente di scrivere codice più conciso, leggibile e vettorializzato.

Pubblicato nel 2024


Prodotti utilizzati: MATLAB

Per saperne di più