Accedere agli elementi di una matrice in MATLAB

Nella lezione precedente abbiamo visto come utilizzare gli indici e i vettori indice per accedere agli elementi di un vettore in MATLAB. In questa lezione vedremo come accedere, invece, agli elementi di una matrice in MATLAB e come modificarne gli elementi.

Accedere agli elementi di una Matrice

Il modo per accedere agli elementi di una matrice è molto simile a quello impiegato per i vettori. La differenza è che bisogna specificare due indici per le matrici: il primo per la riga e il secondo per la colonna. Questi indici vanno racchiusi tra parentesi tonde e separati da virgole. Vediamo un esempio:

>> A = [1:3;4:6]

A =

     1     2     3
     4     5     6

>> A(2,3)

ans =

     6

Sotto-matrici

Anche per le matrici, così come per i vettori, è possibile selezionare sotto-matrici usando vettori indice. In questo caso, tuttavia, vanno specificati due vettori indici: il primo per le righe e il secondo per le colonne. Prendiamo un esempio:

>> A = [11:15;16:20;21:25]

A =

    11    12    13    14    15
    16    17    18    19    20
    21    22    23    24    25

>> A([2 3], [4 5])

ans =

    19    20
    24    25

In questo caso abbiamo selezionato la sotto-matrice composta dalle righe 2 e 3 e dalle colonne 4 e 5. Anche per le matrici, così come per i vettori, possiamo specificare i vettori indice usando l'operatore di iterazione:

>> A(2:3,4:5)

ans =

    19    20
    24    25

Esiste anche la possibilità di utilizzare l'operatore di iterazione senza specificare i limiti, ossia usando soltanto i due punti: :. Quando usato in questo modo, l'operatore indica la selezione di tutte le righe o tutte le colonne a seconda di dove viene posto. Ad esempio, se volessimo selezionare solo le colonne 3 e 4 e selezionare tutte le righe, potremmo scrivere così:

>> A(:,[3 4])

ans =

    13    14
    18    19
    23    24

In questo esempio, inserendo solo i due punti : al posto del vettore indice per le righe indichiamo a MATLAB di selezionare tutte le righe. Analogamente, può essere usato per le colonne:

>> A([1 2],:)

ans =

    11    12    13    14    15
    16    17    18    19    20

Ovviamente, anche per le matrici gli indici contenuti nei vettori indice possono essere ripetuti o messi in ordine non sequenziale. Ad esempio:

>> A([3 3 1], [5 2])

ans =

    25    22
    25    22
    15    12

In questo caso, abbiamo ripetuto la riga 3 due volte, mentre per le colonne abbiamo invertito l'ordine tra 5 e 2.

Utilizzare l'espressione end

Anche per le matrici possiamo usare la parola chiave end. La differenza rispetto ai vettori è che essa indica l'ultima riga o l'ultima colonna a seconda di dove viene posta.

Infatti, se usata come indice per la riga o all'interno di un vettore indice per le righe, end indicherà l'ultima riga. Viceversa, se usata per l'indice di colonna o all'interno di un vettore indice per le colonne, indicherà l'ultima colonna.

Vediamo un esempio:

>> A([2 end], [1 end])

ans =

    16    20
    21    25

>> A([2 end], [1 2])

ans =

    16    17
    21    22

>> A([2 3], [4 end])

ans =

    19    20
    24    25

Modificare gli elementi di una Matrice

Modificare gli elementi di una matrice in MATLAB è simile al caso dei vettori. Bisogna, semplicemente, porre l'espressione di accesso agli elementi a sinistra dell'operatore di assegnamento.

Tornando alla matrice A di prima, possiamo modificare, ad esempio, l'elemento posto sulla riga 3 e sulla colonna 2 in questo modo:

>> A = [11:15;16:20;21:25]

A =

    11    12    13    14    15
    16    17    18    19    20
    21    22    23    24    25

>> A(3, 2) = 100

A =

    11    12    13    14    15
    16    17    18    19    20
    21   100    23    24    25

Possiamo anche modificare più elementi insieme utilizzando i vettori indice e assegnando una matrice di valori. Bisogna, però, prestare attenzione affinché la matrice di valori da assegnare abbia lo stesso numero di righe e di colonne specificate dai vettori indice. Proviamo, ad esempio, a modificare gli elementi nelle righe 2 e 3 e nelle colonne 3 e 4. Per far questo, la matrice dei valori da assegnare deve essere una matrice di 2 righe e due colonne:

>> A = [11:15;16:20;21:25]

A =

    11    12    13    14    15
    16    17    18    19    20
    21    22    23    24    25

>> A([2 3], [3 4]) = [100 200; 300 400]

A =

    11    12    13    14    15
    16    17   100   200    20
    21    22   300   400    25

Inoltre, se usiamo i vettori indice possiamo assegnare anche un semplice scalare. In questo caso lo scalare viene replicato in tutte le posizioni indicate dai vettori indice. Ad esempio:

>> A = [11:15;16:20;21:25]

A =

    11    12    13    14    15
    16    17    18    19    20
    21    22    23    24    25

>> A([2 3], [3 4]) = 100

A =

    11    12    13    14    15
    16    17   100   100    20
    21    22   100   100    25

In questo caso, lo scalare 100 è stato replicato in quattro posizioni.

Aggiungere elementi ad una matrice

Usando gli indici possiamo anche aggiungere nuovi elementi ad una matrice estendendola. Tuttavia, rispetto ai vettori, estendere una matrice comporta sempre l'aggiunta di una nuova riga o colonna.

Ad esempio, prendiamo la matrice A che segue:

>> A = [11:15;16:20;21:25]

A =

    11    12    13    14    15
    16    17    18    19    20
    21    22    23    24    25

Questa è una matrice di 3 righe e 5 colonne. Se proviamo ad aggiungere un elemento in posizione (4, 1), necessariamente MATLAB deve aggiungere dapprima una riga di zeri per poi inserire l'elemento nella posizione richiesta. Infatti, se osserviamo il risultato:

>> A(4, 1) = 200

A =

    11    12    13    14    15
    16    17    18    19    20
    21    22    23    24    25
   200     0     0     0     0

MATLAB ha effettivamente aggiunto l'elemento di valore 200 nella posizione (4, 1) ma ha dovuto comunque estendere la matrice con un'intera riga di zeri. Allo stesso modo, se proviamo ad assegnare un valore in una colonna inesistente:

>> A(2, 6) = 300

A =

    11    12    13    14    15     0
    16    17    18    19    20   300
    21    22    23    24    25     0
   200     0     0     0     0     0

Aggiungere elementi ad una matrice, anche se risulta molto semplice, a volte non è efficiente specialmente se si pensa a matrici di grandi dimensioni. Si provi a pensare ad una matrice di 1000 righe e 1000 colonne. Aggiungere un nuovo elemento significherebbe aggiungere una riga o una colonna di 999 zeri più l'elemento nuovo. Questo procedimento potrebbe richiedere tempo aggiuntivo per l'allocazione della memoria e, pertanto, è poco efficiente. Più avanti vedremo tecniche più sofisticate per estendere e modificare la dimensione delle matrici.

Indicizzazione lineare

In MATLAB, quando accediamo agli elementi di una matrice possiamo usare anche un solo indice. Tuttavia, in questo caso, il significato dell'indice cambia: si parla di indicizzazione lineare.

In pratica, quando usiamo un solo indice, MATLAB srotola linearmente la matrice (in inglese unwind), ossia la appiattisce accedendovi come se fosse un vettore. Tuttavia, in memoria le matrici vengono memorizzate per colonne (column-wise).

Infatti, Supponiamo di avere una matrice m \times n, ossia di m righe e n colonne. In memoria essa sarà memorizzata linearmente, dato che la memoria di un computer è un grande array lineare di locazioni di memoria, per colonne. Questo significa che viene prima memorizzata la colonna 1, poi la 2 fino ad arrivare alla colonna n. Le singole colonne sono memorizzate come vettori di m elementi. Per cui la disposizione in memoria di una matrice è la seguente:

\left[ a_{1,1},\; a_{2,1},\; a_{3,1},\; \dots, a_{m,1},\; a_{1,2},\; \dots, a_{m,2},\; \dots, a_{1,n},\; \dots, a_{m,n} \right]

Quando usiamo un indice lineare i, MATLAB applicherà le formule seguenti per ricavare riga e colonna:

riga=mod(i, m)

Ossia, la riga sarà uguale ad i modulo m.

colonna = \left \lfloor{ \frac{i}{m} }\right \rfloor + 1

La colonna sarà invece la parte intera di i fratto m più uno.

Proviamo ad applicare l'indicizzazione lineare alla matrice degli esempi visti sopra: A.

>> A = [11:15;16:20;21:25]

A =

    11    12    13    14    15
    16    17    18    19    20
    21    22    23    24    25

Proviamo ad accedere con indicizzazione lineare all'elemento 8. Applicando le formule otteniamo che:

riga=mod(i, m)=mod(8, 3)=2

Quindi dobbiamo selezionare la seconda riga. Per la colonna invece:

colonna = \left \lfloor{ \frac{i}{m} }\right \rfloor + 1 = \left \lfloor{ \frac{8}{3} }\right \rfloor + 1 = 2 + 1 = 3

Dobbiamo, quindi, scegliere la terza colonna. L'elemento selezionato sarà quello con indici (2, 3). Ciò viene confermato dal fatto che le seguenti espressioni danno lo stesso risultato:

>> A(8)

ans =

    18

>> A(2, 3)

ans =

    18

Riassumendo

In questa lezione abbiamo visto come accedere agli elementi di una matrice in vari modi:

  • Usando in ordine un indice per la riga e un indice per la colonna
  • Usando in ordine un vettore indice per le righe ed uno per le colonne

Abbiamo visto, poi, come modificare gli elementi di una matrice o aggiungerne di nuovi sia usando gli indici che i vettori indice. Nel secondo caso abbiamo visto che bisogna passare una matrice con lo stesso numero di righe e colonne indicate dai due vettori oppure passare uno scalare che verrà replicato nelle posizioni indicate.

Infine, abbiamo visto come usare l'indicizzazione lineare per accedere agli elementi.

Nella prossima lezione vedremo come lavorare con le dimensioni di vettori e matrici, come modificarle e come concatenare vettori e matrici fra loro.