Teorema di Laplace in C++
In questo articolo spiegherò come scrivere un programma in C++ che calcoli il determinante di una matrice utilizzando il Teorema di Laplace.
Il Teorema di Laplace afferma: “Data una matrice quadrata di ordine n, il suo determinante è uguale alla somma dei prodotti degli elementi di una qualsiasi riga (o colonna) per i rispettivi complementi algebrici“.
Il complemento algebrico dell’elemento aij appartenente alla matrice M, è il determinante della matrice che si ottiene cancellando la i-esima riga e la j-esima colonna dalla matrice M, preso con il segno + se i+j è pari, segno – se i+j è dispari.
Il determinante di una matrice di ordine 2, è semplicemente:
Il Teorema di Laplace ci permette di calcolare il determinante di una matrice di ordine n tramite un determinante di ordine n-1. Applicando ricorsivamente Laplace, possiamo quindi ridurre il calcolo di qualsiasi determinante a quello di una matrice di ordine 2, che è facilmente calcolabile.
Testualmente, ciò che faremo è questo:
Funzione determinante(matrice, ordine)
L’ordine è 2? Allora calcolalo con la semplice formula.
L’ordine è superiore a 2? Richiama questa funzione applicando il Teorema di Laplace…
Così facendo, verrà applicato il Teorema di Laplace finché il programma non si troverà a calcolare un determinante di ordine 2.
Vediamo ora il codice. Queste prime righe servono soltanto a generare la matrice:
#include <iostream>
#include <stdlib>
#define MAX 30
int det(int m[MAX][MAX], int car); //Prototipo
int main()
{
int m[MAX][MAX], c;
cout<<"Ordine della matrice: ";
cin>>c;
//Genera matrice
for (int i=0; i<c; i++) {
cout<<"Riga "<<i<<": ";
for (int j=0; j<c; j++) cin>>m[i][j];
}
//Determinante
cout<<"Determinante: "<<det(m, c)<<endl<<endl;
system("pause");
return 0;
}
Spostiamo ora l’attenzione sulla funzione che genera il determinante: det(). Come abbiamo già visto dal prototipo, questa funzione richiede un array bidimensionale che è la nostra matrice, e un valore intero car, che rappresenta la cardinalità (numero di righe/colonne).
int det(int m[MAX][MAX], int car) {
int determinante = 0;
//Cardinalità uno
if (car == 1) determinante = m[0][0];
//Cardinalità due
if (car == 2)
determinante = m[1][1]*m[0][0]-m[0][1]*m[1][0];
//Cardinalità > 2
else {
for (int row = 0; row < car; row++) {
int sub_m[MAX][MAX];
//Sottomatrice di ordine car-1
for (int i = 0; i < car-1; i++) {
for (int j = 0; j < car-1; j++) {
int sub_row = (i < row ? i : i+1);
int sub_col = j+1;
sub_m[i][j] = m[sub_row][sub_col];
}
}
//Segno sottomatrice + per pari, - per dispari
if (row % 2 == 0)
determinante += m[row][0]*det(sub_m, car-1);
else
determinante -= m[row][0]*det(sub_m, car-1);
}
}
return determinante;
}
Se la cardinalità della matrice è 1, il determinante è l’elemento stesso; se è 2 utilizziamo la formula vista prima.
In caso contrario, applichiamo il Teorema di Laplace alla prima colonna. Utilizziamo un for che cicla tutti gli elementi della prima colonna: per ognuno di questi ne determina il complemento algebrico, il cui segno sarà positivo se la riga è pari, negativo altrimenti. Sommando tutti i complementi algebrici ottengo il determinante.
Per determinare il complemento algebrico ho bisogno della matrice che ottengo cancellando la j-esima colonna e i-esima riga: utilizzo quindi altri due for (i, j) che ciclano la matrice iniziale car-1 volte. Avendo scelto di applicare il Teorema alla prima colonna, mi basta selezionare le rimanenti “j+1” colonne; per le righe devo invece utilizzare la i-esima, finché non raggiungo la riga da eliminare e seleziono quindi “i+1“.
Infine, ecco il file già compilato del programma appena visto:
Download – Laplace.zip
Uno screenshot per una matrice diagonale, il cui determinante è dato dal prodotto degli elementi della diagonale:
