Problema con invcertitore matrici

di il
2 risposte

Problema con invcertitore matrici

Ciao a tutti,
devo consegnare a breve un programma che si occupi di invertire una qualsiasi matrice. Vi posto quello che ho scritto, il programma in generale funziona, ma quando ci sono alcuni zeri durante la riduzione della matrice mi da dei problemi. Potete darmi una mano senza sconvolgere il programma???

#include <iostream>



using namespace std;





      // ci sono ancora problemi con gli zeri







char p;

int main()

{



do 

{

                                                              // Allocazione della memoria

 double **A;                                                   

 int n;

 cout<< "Creazione matrice n x n \n Inserire il valore di n: "; 

 cin>>n; cout<<endl;

 A=new double*[n];

 for(int i=0;i<n;i++) 

   A[i]=new double[n];





  

    double **I;                 // Matrice identità

    I=new double*[n];

    for(int i=0;i<n;i++) 

      I[i]=new double[n];

                                        

         for(int i=0;i<n;i++)

            for(int j=0;j<n;j++)

              if(i==j) I[i][j] = 1;

              else I[i][j]=0;







// Ricordarsi di aggiungere un controllo sul determinante: se è = 0, la matrice non si può invertire.





                                           // Riempimento matrice

  cout<<endl<<"Riempi la matrice"<<endl;

  for(int i=0;i<n;i++) 

    for(int j=0;j<n;j++)

    {

      cout<<"Elem " << i+1 << ", " << j+1 << ": "; 

      cin>>A[i][j];

    } cout<<endl;







                                           // Verifica riempimento

      cout<< "Questa è la matrice che hai inserito: "<<endl;

      for(int i=0;i<n;i++)

      {

       for(int j=0;j<n;j++)

       cout<<A[i][j] << "\t";

       cout<<endl;  

      } cout<<endl;







 //Costruzione della matrice [A|I] come metodo di riduzione

 double **B;

 B=new double*[n];

 for(int i=0;i<n;i++) 

  B[i]=new double[2*n];



 for(int i=0;i<n;i++)         // Copio la matrice A in B (che è larga il doppio, quindi 2n)

   for(int j=0;j<n;j++)

     B[i][j]=A[i][j];



 int k=0;                     // Copio la matrice I nella seconda parte di B

 for(int i=0;i<n;i++) 

 {

   for(int j=n;j<2*n;j++,k++)

     B[i][j]=I[i][k];

   k=0;

 }



//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------

 //Eliminazione sotto la diagonale principale

 double *tmp; tmp=new double[2*n];

 for(int j=0;j<n-1;j++)

   for(int i=j+1;i<n;i++)

     if(B[i][j]!=0) {

       double mol=B[i][j]/B[j][j];

       for(int k=0;k<2*n;k++) tmp[k]=mol*B[j][k];

       for(int k=0;k<2*n;k++) B[i][k]-=tmp[k];

     }





 //Eliminazione sopra la diagonale principale

 for(int j=n-1;j>0;j--)

   for(int i=j-1;i>=0;i--)

     if(B[i][j]!=0) {

       double mol=B[i][j]/B[j][j];

       for(int k=0;k<2*n;k++) tmp[k]=mol*B[j][k];

       for(int k=0;k<2*n;k++) B[i][k]-=tmp[k];

     }







//_________________________________________________________________________________________________

//Calcolo determinante

 int Det,d;

 Det=1;

 for(int s=0; s<n-1; s++)

  {

     if (s==0)

     {

      d=B[s][s]*B[s+1][s+1]; 

      Det=d;      

     }

         else

         {

           d=Det*B[s+1][s+1];

           Det=d;

         }

  }

 cout<<"Determinante: "<<Det<<endl;



 if(Det!=0)   //Controllo che il determinante sia !=0

 {

//_________________________________________________________________________________________________

        

//Stampa della matrice ridotta

 cout<< "Questa è la matrice ridotta: "<<endl;

      for(int i=0;i<n;i++)

      {

       for(int j=0;j<n;j++)

       cout<<B[i][j] << "\t";

       cout<<endl;  

      } cout<<endl;



 //Ultimo step per ottenere la matrice [I|A]

 for(int i=0;i<n;i++) 

   if(B[i][i]!=1) {

     double mol=B[i][i];

     for(int k=0;k<2*n;k++) 

       B[i][k]=B[i][k]/mol;

   }



//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------

 

 //Copia dell'inversa ottenuta

 double** Inv;

 Inv=new double*[n];

 for(int i=0;i<n;i++) 

  Inv[i]=new double[n];

 k=0;

 for(int i=0;i<n;i++) 

 {

   for(int j=n;j<2*n;j++,k++)

     Inv[i][k]=B[i][j];

   k=0;

 }





 //Scrittura della matrice Inversa

 cout<< "Matrice inversa: "<<endl;

 for(int i=0;i<n;i++)

 {

   for(int j=0;j<n;j++)

     cout<<Inv[i][j]<< "\t";

   cout<<endl;  

 } cout<<endl;

                                          }

                                          else

                                            cout<<"La matrice non si può invertire!!! "<<endl;









//Deallocazione della memoria

for(int i=0;i<n;i++) {delete I[i];delete A[i];}

delete I;

delete A;

for(int i=0;i<n;i++) delete B[i]; 

delete B;

delete tmp;





                                        

                                        cout<<"Vuoi invertire un'altra matrice? (y/n) "<<endl;

                                        cin>>p; 

                                        cout<<endl<<endl;

                                        cout<<"-----------------------------------------------------"<<endl<<endl;

                                        } //chiusura do iniziale

                                        while (p=='y');

                                        



}

2 Risposte

  • Re: Problema con invcertitore matrici

    Intanto il tuo programma lo devono leggere gli altri e stai faccendo il tutto per non farlo leggere. La formattazione del codice è una cosa importante se vuoi che qualcuno ti aiuti. Ho perso mezz'ora solo per mettere il codice a posto.
    
    #include <iostream>
    
    using namespace std;
    
    // ci sono ancora problemi con gli zeri
    
    char p;
    
    int main()
    {
    	do
    	{
    		// Allocazione della memoria
    		double **A;                                                   
    		int n;
    		cout<< "Creazione matrice n x n \n Inserire il valore di n: ";
    		cin>>n;
    		cout<<endl;
    		A = new double*[n];
    		for(int i=0;i<n;i++)
    		   A[i]=new double[n];
    	
    		double **I;                 // Matrice identità
    	    I=new double*[n];
    	
    		for(int i=0;i<n;i++)
    			I[i]=new double[n];
    
    		for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                  if(i==j) 
    				  I[i][j] = 1;
                  else 
    				  I[i][j]=0;
    
    		// Ricordarsi di aggiungere un controllo sul determinante: se è = 0, la matrice non si può invertire.
    	    // Riempimento matrice
    
    		cout<<endl<<"Riempi la matrice"<<endl;
    
    		for(int i=0;i<n;i++)
    		    for(int j=0;j<n;j++)
    			{
    				cout<<"Elem " << i+1 << ", " << j+1 << ": ";
    				cin>>A[i][j];
    			} 
    		cout<<endl;
    
    		// Verifica riempimento
    		cout<< "Questa è la matrice che hai inserito: "<<endl;
    
    		for(int i=0;i<n;i++)
    		{
    			for(int j=0;j<n;j++)
    				cout<<A[i][j] << "\t";
    			cout<<endl; 
    		} 
    		cout<<endl;
    
    		//Costruzione della matrice [A|I] come metodo di riduzione
    
    		double **B;
    		B = new double*[n];
    
    		for(int i=0;i<n;i++)
    			B[i]=new double[2*n];
    
    		for(int i=0;i<n;i++)         // Copio la matrice A in B (che è larga il doppio, quindi 2n)
    			for(int j=0;j<n;j++)
    				B[i][j] = A[i][j];
    		
    		int k=0;                     // Copio la matrice I nella seconda parte di B
    		for(int i=0;i<n;i++)
    		{
    			for(int j=n;j<2*n;j++,k++)
    				B[i][j]=I[i][k];
    			k=0;
    		}
    
    
    		//-------------------------------------------------------------------------------------------------
    
    		//-------------------------------------------------------------------------------------------------
    
    		//Eliminazione sotto la diagonale principale
    
    		double *tmp; 
    		tmp=new double[2*n];
    
    		for(int j=0;j<n-1;j++)
    			for(int i=j+1;i<n;i++)
    				if(B[i][j]!=0) 
    				{
    					double mol = B[i][j] / B[j][j];
    					for(int k=0;k<2*n;k++) 
    						tmp[k] = mol * B[j][k];
    					for(int k=0;k<2*n;k++) 
    						B[i][k]-= tmp[k];
    				}
    		
    		//Eliminazione sopra la diagonale principale
    
    		for(int j=n-1;j>0;j--)
    			for(int i=j-1;i>=0;i--)
    				if(B[i][j]!=0) 
    				{
    					double mol = B[i][j] / B[j][j];
    					for(int k=0;k<2*n;k++) 
    						tmp[k] = mol * B[j][k];
    					for(int k=0;k<2*n;k++) 
    						B[i][k]-= tmp[k];
    				}
    
    		//_________________________________________________________________________________________________
    
    		//Calcolo determinante
    
    		int Det,d;
    		Det=1;
    
    		for(int s=0; s<n-1; s++)
    		{
    			if(s==0)
    			{
    				d=B[s][s]*B[s+1][s+1];
    				Det=d;     
    			}
    			else
    			{
    				d=Det*B[s+1][s+1];
    				Det=d;
    			}
    		}
    
    		cout<<"Determinante: "<<Det<<endl;
    		if(Det!=0)   //Controllo che il determinante sia !=0
    		{
    			//_________________________________________________________________________________________________
    			//Stampa della matrice ridotta
    
    			cout<< "Questa è la matrice ridotta: "<<endl;
    			for(int i=0;i<n;i++)
    			{
    				for(int j=0;j<n;j++)
    					cout<<B[i][j] << "\t";
    				cout<<endl; 
    			} 
    			cout<<endl;
    
    			//Ultimo step per ottenere la matrice [I|A]
    			for(int i=0;i<n;i++)
    			if(B[i][i]!=1) 
    			{
    				double mol=B[i][i];
    				for(int k=0;k<2*n;k++)
    			       B[i][k]=B[i][k]/mol;
    			}
    
    			//-------------------------------------------------------------------------------------------------
    
    			//-------------------------------------------------------------------------------------------------
    
    			//Copia dell'inversa ottenuta
    
    			double** Inv;
    			Inv=new double*[n];
    
    			for(int i=0;i<n;i++)
    				Inv[i]=new double[n];
    
    			k=0;
    			for(int i=0;i<n;i++)
    			{
    			   for(int j=n;j<2*n;j++,k++)
    			     Inv[i][k]=B[i][j];
    			   k=0;
    			}
    
    			//Scrittura della matrice Inversa
    			cout<< "Matrice inversa: "<<endl;
    
    			for(int i=0;i<n;i++)
    			{
    			   for(int j=0;j<n;j++)
    			     cout<<Inv[i][j]<< "\t";
    			   cout<<endl; 
    			} 
    			cout<<endl;
    		}
    		else
    			cout<<"La matrice non si può invertire!!! "<<endl;
    
    		//Deallocazione della memoria
    		for(int i=0;i<n;i++) 
    		{
    			delete I[i];
    			delete A[i];
    		}
    		
    		delete I;
    		delete A;
    		
    		for(int i=0;i<n;i++) 
    			delete B[i];
    		delete B;
    		delete tmp;
    		
    		cout << "Vuoi invertire un'altra matrice? (y/n) " << endl;
    		cin >> p;
    		cout << endl << endl;
    
    		cout<<"-----------------------------------------------------" << endl << endl;
    	}while (p=='y');//chiusura do iniziale
    }
    
    Controlla adesso il tuo codice e vedi se trovi dei errori
  • Re: Problema con invcertitore matrici

    Ma guarda, il codice l'ho messo così perchè si capisca meglio... E in ogni caso se l'ho postato significa che l'errore che commetto non mi è evidente, altrimenti lo avrei corretto.
Devi accedere o registrarti per scrivere nel forum
2 risposte