Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Renault Twingo E-Tech Electric: che prezzo!
Renault Twingo E-Tech Electric: che prezzo!
Renault annuncia la nuova vettura compatta del segmento A, che strizza l'occhio alla tradizione del modello abbinandovi una motorizzazione completamente elettrica e caratteristiche ideali per i tragitti urbani. Renault Twingo E-Tech Electric punta su abitabilità, per una lunghezza di meno di 3,8 metri, abbinata a un prezzo di lancio senza incentivi di 20.000€
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media
Nel Formula 1 Technology and Media Centre di Biggin Hill, la velocità delle monoposto si trasforma in dati, immagini e decisioni in tempo reale grazie all’infrastruttura Lenovo che gestisce centinaia di terabyte ogni weekend di gara e collega 820 milioni di spettatori nel mondo
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica
Il nuovo gimbal mobile DJI evolve il concetto di tracciamento automatico con tre modalità diverse, un modulo multifunzionale con illuminazione integrata e controlli gestuali avanzati. Nel gimbal è anche presente un'asta telescopica da 215 mm con treppiede integrato, per un prodotto completo per content creator di ogni livello
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 28-04-2005, 16:51   #1
Keethra
Junior Member
 
Iscritto dal: Apr 2005
Messaggi: 6
Inversione matrice in c++

Salve a tutti!
E' da giorni che cerco disperatamente di implementare un codice che faccia l'inversione di una matrice. Io ho scritto alcune funzioni, messe in un file sorgente a parte, che vengono richiamate nel main. Una calcola la sottomatrice ottenuta eliminando colonna e riga dell'elemento di cui si vuole calcolare il complemento algebrico. Questa funzione viene richiamata per ricorsione dalla funzione determinante. La funzione inversa richiama a sua volta determinante e sottomatrice. Purtroppo questo codice non funziona. Sapete dirmi dove sta l'errore?

Questo è ciò che ho scritto io nel file sorgente dove contengono le funzioni che avete implementato:

double** sottomatrice(double** A, int i, int j, int dim){
// Allocazione della matrice
double** Aij = new double*[dim - 1];
for(int n = 0; n < dim - 1; n++)
{
Aij[n] = new double[dim - 1];
}
int h = 0;
int k;
for(int r = 0; r < dim; r++)
{
k=0;
//indice delle colonne della matrice Aij
if(r != i)
{
for(int c = 0; c < dim; c++)
if(c != j)
{
Aij[h][k] = A[r][c];
k++;
}
h++;
}
}
return Aij;
}


double determinante(double** A, int dim)
{
if(dim==1)
return A[0][0]; // Ritorna l'unico elemento della matrice
else
{
double ris=0.0;
for(int col=0, row=0; col<dim; col++)
{ // esegue la somma sugli elementi della prima riga.
// Chiama ricorsivamente la funzione determinante sulla matrice Aij
ris += pow(-1.0,(row+col)) * A[row][col] * determinante(sottomatrice(A, row, col, dim), dim-1);
}
return ris;
}
}


double** inversa(double** A, int dim)
{
// Allocazione della matrice inversa
double** invA;
invA = new double*[dim];
for(int i=0; i<dim; i++)
{
invA=new double[dim];
}
// Calcolo dell'inversa
if(dim == 1)
invA[0][0] = A[0][0];
else
{
double detA = determinante(A, dim);
for(int i=0; i < dim; i++)
{
for(int j=0; j < dim; j++)
{
invA[j]=(1/detA) * pow(-1.0,(i+j)) * determinante(sottomatrice(A,i,j,dim),(dim-1));
}
}
}
return invA;
}


questo è cio che ho scritto nel main:

double **a; //dichiarazione della matrice che contiene la copia della matrice da invertire

a = new double*[dim_ridotta];
if (a == NULL)
{
cout << "Non è stata allocata memoria per pt.\n";
exit(EXIT_FAILURE);
} ;
for (int i = 0; i < dim_ridotta; i++)
{
a= new double[dim_ridotta]; //copio kr e affianco la matrice identita'
if (a == NULL)
{
cout << "Non è stata allocata memoria per a.\n";
exit(EXIT_FAILURE);
}
}



for (int i = 0; i < dim_ridotta; i++)
{
for (int j = 0; j < dim_ridotta; j++)
{
a[j]=k_r[j];
}
}





double **inv; //dichiarazione la matrice che contiene l'inversa di k_rl
inv = new double*[dim_ridotta];
if (inv == NULL)
{
cout << "Non è stata allocata memoria per pt.\n";
exit(EXIT_FAILURE);
}
for (int i = 0; i < dim_ridotta; i++)
{
inv= new double[dim_ridotta]; //copio kr e affianco la matrice identita'
if (inv == NULL)
{
cout << "Non è stata allocata memoria per a.\n";
exit(EXIT_FAILURE);
}
}

double detA = determinante(a, dim_ridotta);
cout << "\nDeterminante: " << detA << "\n";

// Se la matrice non é singolare é possibile calcolare la sua inversa

if(detA != 0.0){
double** inva = inversa(a,dim_ridotta);
cout << "\nInversa:\n";
for (int a = 0; a < dim_ridotta; a++) {
for (int b = 0; b < dim_ridotta; b++)
cout << "[" << inva[a] <<"]";
cout << "\n";
}
for (int i = 0; i < dim_ridotta; i++)
{
for (int i = 0; i < dim_ridotta; i++)
{
inv[j]=inva[j];
}
}
}
else
cout << "\n Matrice singolare, impossibile invertirla!";

inserendo i seguenti dati questi sono i risultati:

2.1213 0.7071 -0.7071
0.7071 2.1213 -0.7071
-0.7071 -0.7071 0.7071

ottengo un determanante pari a 1.4142 (giusto)
e questa matrice inversa:

1.7247*e^-350 0 0
1.7247*e^-350 0 0
1.7247*e^-350 0 0

che ovviamente non è giusto.

Aiutatemi, son disperata!!!!!
Keethra è offline   Rispondi citando il messaggio o parte di esso
Old 28-04-2005, 17:37   #2
Ziosilvio
Moderatore
 
L'Avatar di Ziosilvio
 
Iscritto dal: Nov 2003
Messaggi: 16211
Prendi un libro di Algebra Lineare, studia l'algoritmo di inversione di Gauss, e implementa quello.
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" Chi scherza col fuoco si brucia.
Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici
REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu
Ziosilvio è offline   Rispondi citando il messaggio o parte di esso
Old 28-04-2005, 17:56   #3
Keethra
Junior Member
 
Iscritto dal: Apr 2005
Messaggi: 6
Con Gauss ci avevo già provato ma senza grossi risultati...
__________________
Nulla si raffina, tranne l'intelletto

Visita la comunity di Spade Degli Angeli... Spade degli Angeli
Keethra è offline   Rispondi citando il messaggio o parte di esso
Old 29-04-2005, 10:52   #4
Ziosilvio
Moderatore
 
L'Avatar di Ziosilvio
 
Iscritto dal: Nov 2003
Messaggi: 16211
Si vede che non ci hai provato abbastanza

Scherzi a parte, implementare l'inversione di matrici usando l'algoritmo di Cramer è un suicidio in termini di tempo di esecuzione, e probabilmente anche di complessità della struttura dati necessaria per rappresentare "bene" le matrici.
Forse a questo punto un libro di Analisi Numerica può essere di aiuto più di uno di Algebra Lineare.
Puoi provare con le Numerical Recipes, che esistono in versione C, C++, Fortran 77 e Fortran 90.
Leeggi bene la licenza d'uso, che è piuttosto limitativa: in particolare, non puoi includere parti del libro sotto forma di codice sorgente.
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" Chi scherza col fuoco si brucia.
Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici
REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu
Ziosilvio è offline   Rispondi citando il messaggio o parte di esso
Old 29-04-2005, 17:37   #5
Keethra
Junior Member
 
Iscritto dal: Apr 2005
Messaggi: 6
Facendo le giuste correzioni ora funziona quello che vi ho scritto qui
__________________
Nulla si raffina, tranne l'intelletto

Visita la comunity di Spade Degli Angeli... Spade degli Angeli
Keethra è offline   Rispondi citando il messaggio o parte di esso
Old 30-04-2005, 13:54   #6
Keethra
Junior Member
 
Iscritto dal: Apr 2005
Messaggi: 6
Ecco con l'altro metodo, ma funziona fino ad un certo punto. Perchè?

int main()
{

int dim_ridotta;
cout << "Inserisci la dimensione della matrice: ";
cin >> dim_ridotta;


double s;
double inversa[dim_ridotta][dim_ridotta];
double k_r[dim_ridotta][dim_ridotta];
double a[dim_ridotta][2*dim_ridotta];


cout << "\n\nInserisci la matrice da invertire:\n";
for (int i = 0; i < dim_ridotta; i++) //scorro le righe
{ //inizio for i
for (int j = 0; j < dim_ridotta; j++)
{ //inizio for j
cout <<"["<< i + 1 <<"]"<<"["<< j + 1<<"]"<< ": ";
cin >> k_r[i][j]; //copio kr nella parte sinistra della matrice
} //fine for j
} //fine for i
cout <<endl;

//copio kr
for (int i = 0; i < dim_ridotta; i++) //scorro le righe
{ //inizio for i
for (int j = 0; j < dim_ridotta; j++)
{ //inizio for j
a[i][j] = k_r[i][j]; //copio kr nella parte sinistra della matrice
} //fine for j
} //fine for i


//affianco l'identita'
for (int l = 0; l < dim_ridotta; l++) //scorro le righe
{ //inizio for l
for (int k = dim_ridotta; k < 2*(dim_ridotta); k++)
{ //inizio for k
if(l == k - dim_ridotta)
a[l][k] = 1; //assegno valore 1 lungo la diagonale
else a[l][k] = 0; //assegno valore 0 a tutti gli altri elementi
} //fine for k
} //fine for l


//inversione della matrice di rigidezza ridotta
//inizio dell'applicazione del teorema di Jordan
for (int i = 0; i < dim_ridotta; i++)
{ //inizio for i
if(a[i][i]==0) //inizio scambio_righe
{
double u[2*dim_ridotta];
for (int j = i+1; j < dim_ridotta; j++)
{ //inizio for m
if (a[j][i] != 0)
{ //inizio if
for (int k = i; k < 2*dim_ridotta; k++)
{ //inizio for k
u[k] = a[i][j];
a[i][k] = a[j][k];
a[j][k] = u[k];
}
j = dim_ridotta+1;
} //fine if
if (j != dim_ridotta+1)
{ //inizio if
printf(" MATRICE NON INVERTIBILE!! ");
printf(" Premere un tasto per continuare ");
scanf("%c");
} //fine if
} //fine for j
} //fine scambio_righe
s=a[i][i];
for (int j = i; j < 2*dim_ridotta; j++)
{//inizio for j
a[i][j]=a[i][j]/s;
} //fine for j
for (int k = i+1; k < dim_ridotta; k++)
{ //inizio for k
s=a[k][i];
for (int j = i; j < 2*dim_ridotta; j++)
{//inizio for j
a[k][j] = a[k][j]-a[i][j]*s;
} //fine for j
} //fine for k
}//fine for i

if (a[(dim_ridotta - 1)][(dim_ridotta - 1)] == 0)
{ //inizio if
printf(" MATRICE NON INVERTIBILE!! ");
printf(" Premere un tasto per continuare ");
scanf("%c");

} //fine if
for (int k = dim_ridotta; k < 2*dim_ridotta; k++)
{//inizio for k
a[(dim_ridotta-1)][k] = a[(dim_ridotta-1)][k]/a[(dim_ridotta-1)][(dim_ridotta-1)] ;
a[(dim_ridotta-1)][(dim_ridotta-1)] = 1;
}//fine for k

for (int i = 1; i < dim_ridotta; i++)
{ //inizio for i
for (int k = 0; k < i; k++)
{ //inizio for k
s=a[k][i];
for (int j = i; j < (2*dim_ridotta); j++)
{ //inizio for j
a[k][j] = a[k][j]-a[i][j]*s;
} //fine for j
} //fine for k
} //fine for i
//fine applicazione della jordan_form



//creazione della matrice inversa
for (int i = 0; i < dim_ridotta; i++)
{ //inizio for i
for(int j = dim_ridotta; j < 2*dim_ridotta; j++)
{
inversa[i][(j - dim_ridotta)]= a[i][j];
}
}//fine for i




printf( "\n\nLa matrice inversa e' \n\n");
for (int i = 0; i < dim_ridotta; i++)
{ //inizio for i
for(int j = 0; j < dim_ridotta; j++)
{
cout << inversa[i][j] << "\t ";
} //fine for j
cout <<"\n";
}//fine for i



system("PAUSE");
return 0;
}
__________________
Nulla si raffina, tranne l'intelletto

Visita la comunity di Spade Degli Angeli... Spade degli Angeli
Keethra è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Renault Twingo E-Tech Electric: che prezzo! Renault Twingo E-Tech Electric: che prezzo!
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media Il cuore digitale di F1 a Biggin Hill: l'infrast...
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica DJI Osmo Mobile 8: lo stabilizzatore per smartph...
Recensione Pura 80 Pro: HUAWEI torna a stupire con foto spettacolari e ricarica superveloce Recensione Pura 80 Pro: HUAWEI torna a stupire c...
Opera Neon: il browser AI agentico di nuova generazione Opera Neon: il browser AI agentico di nuova gene...
Crolla a 89€ una scopa elettrica low cos...
Anche Huawei segue il trend del mercato:...
Un portatile un tuttofare definitivo a 5...
PosteMobile passerà alla rete TIM...
I 6 migliori smartphone da acquistare su...
iPhone Air 2 è già in cant...
OnePlus 15, in Europa sarà uguale...
Portal X, un nuovo modo per controllare ...
Con Satispay ora si può pagare in...
Sora sbarca anche su Android: una nuova ...
Vibes sbarca in Europa: Meta sfida TikTo...
Tesla, approvato il pacchetto da 1.000 m...
Rockstar posticipa GTA 6 a novembre 2026...
Snap e Perplexity unite: dal prossimo an...
La Cina dice addio a NVIDIA? Il governo ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 08:57.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v