Il concetto di matrice viene definito nell’algebra lineare, che è quella branca della matematica che, fra le altre cose, si occupa dello studio delle principali regole per la manipolazione dei vettori e delle matrici. Le matrici sono fondamentali per lo studio dei sistemi di equazioni lineari e rivestono un ruolo importante non solo nella matematica, ma in un ambito molto più vasto, in quanto essenziali in molteplici applicazioni della fisica e dell’ingegneria.
In questo articolo opereremo con le matrici in C++, prima però sarà necessario introdurre alcune definizioni.
Definizioni
In matematica una matrice è un insieme di numeri disposti su righe e colonne, ad esempio:
A è una matrice formata da 2 righe e 3 colonne.
La dimensione di una matrice si esprime con il numero di righe x numero di colonne. La matrice precedente si dice essere più comunemente una matrice 2×3 o, in maniera equivalente, una matrice di tipo (2, 3). L’elemento di una matrice appartenente alla riga i-esima e alla colonna j-esima si indica con:
Nel caso della matrice precedente: a11=2, a12=3, a13=1, a21=4, a22=-7, a23=5.
Due matrici si dicono uguali se hanno ordinatamente uguali tutti i loro elementi.
I vettori sono delle matrici particolari formate da una sola riga o da una sola colonna:
V1 è un vettore riga di dimensione 1×3, V2 è un vettore colonna di dimensione 3×1.
Alcune matrici particolari sono:
- la matrice nulla: composta da elementi tutti nulli;
- la matrice quadrata: quando il n. di righe coincide con quello delle colonne;
- la matrice diagonale: è una matrice quadrata avente tutti gli elementi uguali a zero, eccetto quelli sulla diagonale principale
aij=0 per i diverso da j
- la matrice identità: caso particolare di matrice diagonale avente tutti gli elementi della diagonale principale uguali a 1
aij=0 per i diverso da j e aij=1 per i = j
- la matrice simmetrica: una matrice quadrata con aij=aji per ogni i e j, con i diverso da j
- la matrice triangolare: una matrice quadrata i cui elementi al di sopra (triangolare inferiore) o al di sotto (triangolare superiore) della diagonale sono tutti nulli. Ad esempio, la seguente matrice T è triangolare superiore:
Algebra delle matrici
- Somma di due matrici
Siano A e B due matrici m x n, ossia (attenzione) con le stesse dimensioni. La somma di A e di B è una matrice C m x n i cui elementi sono la somma degli elementi aventi la stessa posizione in A e in B:
cij=aij+bij per ogni i e j
Per la somma di due matrici valgono le seguenti proprietà:
- A+(B+C) = (A+B)+C è ASSOCIATIVA
- A+B = B+A è COMMUTATIVA
- Prodotto di un numero reale per una matrice
Sia A una matrice m x n e r un numero reale. Si dice prodotto di r per A la matrice C i cui elementi sono quelli della matrice A moltiplicati per r:
cij=raij per ogni i e j
- Trasposta di una matrice
Sia A una matrice mxn, si dice trasposta di A, e si indica con AT, la matrice nxm ottenuta da A scambiando ordinatamente le righe con le colonne:
Si fa notare che se una matrice è simmetrica allora AT=A.
- Prodotto di due matrici
Siano A una matrice mxq e B una matrice qxn, ossia tali che (attenzione) il numero delle colonne della prima matrice sia uguale al numero delle righe della seconda, si definisce matrice prodotto P la matrice i cui elementi pij sono ottenuti come somma dei prodotti degli elementi della riga i-esima di A per gli elementi della colonna j-esima di B:
Esempi
1. Prodotto matrice-matrice:
2. Prodotto matrice-vettore colonna
Per il prodotto di due matrici valgono le seguenti proprietà:
- A(BC) = (AB)C è ASSOCIATIVO
- AB != BA non è COMMUTATIVO
Operiamo in C++
In informatica una matrice è un array bidimensionale, ossia è una struttura dati che riunisce un insieme di elementi omogenei (ossia dello stesso tipo), ciascuno individuato da due indici, e che può essere rappresentata come una matrice. Per cui il primo indice è detto anche indice di riga, il secondo è detto indice di colonna.
La sintassi C/C++ per dichiarare una matrice è la seguente:
1 2 3 |
const int N = ... //n.di righe const int M = ... //n.di colonne tipo nomeMatrice [N][M]; //dichaiarazione della matrice |
Dopodiché la sintassi per operare con le matrici è quella tipica vista per i vettori, l’unica differenza è che per individuare un elemento della matrice ora non basterà più un solo indice, come avviene per i vettori, ma ne sono necessari due. Con una matrice, inoltre, per avere un accesso sequenziale a tutti i suoi elementi, diventa utilissimo, se non indispensabile, l’utilizzo della struttura di controllo con il due cicli for annidati come nel seguente codice d’esempio, che è bene tenere a mente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
const int N = 3 //n.di righe const int M = 4 //n.di colonne int m[N][M]; //SCANSIONE DEGLI ELEMENTI LUNGO LE RIGHE for(int i=0; i<N; i++){ //fissa la riga i-esima della matrice for(int j=0; j<M; j++){ //determina la colonna j-esima della matrice m[i][j] = ... //accesso in scrittura ... = m[i][j] //accesso in lettura } } //SCANSIONE DEGLI ELEMENTI LUNGO LE COLONNE for(int j=0; j<M; j++){ //fissa la colonna j-esima della matrice for(int i=0; i<N; i++){ //determina la riga i-esima della matrice m[i][j] = ... //accesso in scrittura ... = m[i][j] //accesso in lettura } } |
Scriviamo un semplice programma che dopo aver caricato una matrice, A, di dimension nxm e averla visualizza a video, calcola la trasposta AT e il prodotto P = AAT.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include <iostream> using namespace std; const int N=2, M=3; void leggiMatrice(int matrice[N][M]); void visualizzaMatrice(int matrice[N][M]); void calcolaVisualizzaTrasposta(int m[N][M], int t[M][N]); void calcolaVisualizzaProdotto(int m1[N][M],int m2[M][N], int prodotto[N][N]); int main(){ int matrice[N][M], trasposta[M][N], prodotto[N][N]; leggiMatrice(matrice); visualizzaMatrice(matrice); calcolaVisualizzaTrasposta(matrice,trasposta); calcolaVisualizzaProdotto(matrice,trasposta,prodotto); } void leggiMatrice(int matrice[N][M]){ cout << "Inserisci la matrice " << N << " x " << M << ": " <<endl; for (int i=0; i<N; i++) for(int j=0; j<M; j++) cin >> matrice[i][j]; return; } void visualizzaMatrice(int matrice[N][M]){ cout << "La matrice inserita e': " <<endl; for (int i=0; i<N; i++){ for(int j=0; j<M; j++){ cout << matrice[i][j] << "\t"; } cout <<endl; } return; } void calcolaVisualizzaTrasposta(int m[N][M], int t[M][N]){ cout << "La matrice trasposta e': " <<endl; //determina la matrice trasposta for (int i=0; i<N; i++){ for(int j=0; j<M; j++){ t[j][i]=m[i][j]; } } //visualizza la matrice trasposta for(int i=0; i<M; i++){ for(int j=0; j<N; j++){ cout << t[i][j] << "\t"; } cout <<endl; } return; } void calcolaVisualizzaProdotto(int m1[N][M],int m2[M][N], int prodotto[N][N]){ int k; //determina la matrice prodotto for(int i=0; i<N; i++){ //i: blocca la riga di m1 da moltiplicare m1[i][?] for(int j=0; j<N; j++){ //j: blocca la colonna di m2 da moltiplicare m2[?][j] prodotto[i][j] = 0; for(k=0; k<M; k++){ prodotto[i][j] += m1[i][k] * m2[k][j]; } } } //visualizza la matrice prodotto cout << "La matrice prodotto delle due e': " <<endl; for (int i=0; i<N; i++){ for(int j=0; j<N; j++){ cout << prodotto[i][j] << "\t"; } cout <<endl; } return; } |