Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Gigabyte MO32U24 OLED: il 4K a 240Hz su un pannello OLED ideale per il gaming
Gigabyte MO32U24 OLED: il 4K a 240Hz su un pannello OLED ideale per il gaming
Pannello QD-OLED da 32 pollici con risoluzione 4K, frequenza di aggiornamento a 240Hz e tempi di risposta rapidissimi: il Gigabyte MO32U24 evolve il progetto del suo predecessore MO32U e alza ulteriormente l'asticella delle prestazioni. È ancora una volta un monitor indirizzato ai giocatori più esigenti
Recensione realme 16 5G: lo smartphone con Selfie Mirror ha una batteria da 6550mAh
Recensione realme 16 5G: lo smartphone con Selfie Mirror ha una batteria da 6550mAh
realme 16 5G è un nuovo smartphone con sensore Sony IMX 852 da 50MP sul retro e uno specchio selfie fisico integrato nella camera bar, una prima nel segmento di mercato. Batteria da 6550mAh in un corpo da 8,1mm e 183g, certificazione IP69K e ricarica da 45W completano un pacchetto aggressivo per la fascia media, per uno dei prodotti più interessanti del produttore sul piano commerciale
Come rispettare tutte le nuove regole per i monopattini elettrici? La guida per non rischiare sanzioni
Come rispettare tutte le nuove regole per i monopattini elettrici? La guida per non rischiare sanzioni
Sono ormai definitive le nuove norme del Codice della Strada per i monopattini elettrici. Non solo targa e assicurazione, le regole sono tante e riguardano diversi aspetti, vi spieghiamo come evitare sanzioni che possono essere salate
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 28-04-2005, 15: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, 16:37   #2
Ziosilvio
Moderatore
 
L'Avatar di Ziosilvio
 
Iscritto dal: Nov 2003
Messaggi: 16214
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, 16: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, 09:52   #4
Ziosilvio
Moderatore
 
L'Avatar di Ziosilvio
 
Iscritto dal: Nov 2003
Messaggi: 16214
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, 16: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, 12: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


Gigabyte MO32U24 OLED: il 4K a 240Hz su un pannello OLED ideale per il gaming Gigabyte MO32U24 OLED: il 4K a 240Hz su un panne...
Recensione realme 16 5G: lo smartphone con Selfie Mirror ha una batteria da 6550mAh Recensione realme 16 5G: lo smartphone con Selfi...
Come rispettare tutte le nuove regole per i monopattini elettrici? La guida per non rischiare sanzioni Come rispettare tutte le nuove regole per i mono...
DLSS 4.5: con Dynamic Frame Generation e MFG 6X NVIDIA alza la posta DLSS 4.5: con Dynamic Frame Generation e MFG 6X ...
Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere) Plaud NotePin S, il registratore IA si fa indoss...
Grazie a GLIMPSE-17775 il telescopio spa...
Samsung Galaxy A27 5G è ufficiale...
TCL aggiorna la sua gamma di monitor per...
Anche OPPO avrà uno smartphone co...
La Radeon RX 9070 XT appare su Steam e m...
L'America si ribella ai datacenter: bloc...
'Artificial General Engineer': l'IA di J...
Il drone NASA Dragonfly, che voler&agrav...
Stop immediato a Fable 5 e Mythos 5: il ...
"Prime Day Amazon il 23-26 giugno": sì e...
Oggi 2 super MacBook Pro M5 e M5 Pro, 24...
Tineco Floor One Station S9 Artist: il s...
Raggiunte nuove altitudine e velocit&agr...
Apple Watch Series 11 GPS a 339€ su Amaz...
Come un MacBook, ma con la RTX 5070: MSI...
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: 04:15.


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