• Viernes 15 de Noviembre de 2024, 09:49

Autor Tema:  Problema inversa  (Leído 2401 veces)

Checho360

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
Problema inversa
« en: Miércoles 23 de Marzo de 2011, 00:17 »
0
Hola muy buenas, estoy programando algunas cosas con C++ y en este caso el calculo de la inversa a partir de una matriz que introduce el usuario. Tengo el mismo algoritmo programado en matlab y funciona perfectamente pero en c++ no lo ejecuta como yo esperaba. En primer lugar no calcula la inversa, y ademas se cuelga si metes orden 4. Espero que alguien me diga por que no funciona. Espero vuestra respuesta un saludo y gracias de antemano!!!


Código: C++
  1. #include <iostream>
  2. using namespace std;
  3. int main ()
  4. /*Este programa pide al usuario una matriz de orden n la diagonaliza por el
  5. metodo de Gauss-Jordan sin pivote*/
  6. {
  7.     //Genero las variables, la matriz, la pido al usuario y la muestro por pantalla
  8.     int n;double long t;int w;
  9.     cout<<"Introduzca el orden de la matriz:"<<endl;
  10.     cin>>n;int q=n+1;
  11.     double A[n][2*n];double B[n][n];
  12.     for(int i=1;i<=n;i++){
  13.             for(int k=1;k<=n;k++){
  14.                     cout<<"Introduzca el elemento de la fila "<<i<<" y la columna "<<k<<endl;
  15.                     cin>>A[i][k];
  16.             }
  17.     }
  18.     cout<<endl<<endl;
  19.     for(int i=1;i<=n;i++){
  20.             for(int k=1;k<=n;k++){
  21.                     cout<<A[i][k]<<" ";
  22.                     if(k==n){cout<<endl;}
  23.             }
  24.     }
  25.     //Genero la matriz identidad
  26.     for(int i=1;i<=n;i++){
  27.             for(int j=1;j<=n;j++){
  28.                     if(j==i){B[i][j]=1;}
  29.                     else{B[i][j]=0;}
  30.                     }
  31.             }
  32.     //Acoplo la matriz identidad para trabajar con ella
  33.     for(int j=1;j<=n;j++){
  34.             int a=1;
  35.             for(int i=n+1;i<=2*n;i++){
  36.                     A[j][i]=B[j][a];
  37.                     a++;
  38.                     }
  39.             }
  40.     //Muestro la matriz con la que voy a trabajar
  41.     cout<<endl<<endl<<"La matriz introducida con la identidad acoplada es:"<<endl<<endl;
  42.     for(int i=1;i<=n;i++){
  43.             for(int k=1;k<=2*n;k++){
  44.                     cout<<A[i][k]<<" ";
  45.             }
  46.             cout<<endl;
  47.             }
  48.     cout<<endl<<endl;
  49.     //Triangulo la matriz
  50.     for(int i=1;i<=n;i++){
  51.             for(int k=i+1;k<=n;k++){
  52.                     t=A[k][i]/A[i][i];
  53.                     for(int j=1;j<=2*n;j++){
  54.                             A[k][j]=A[k][j]-t*A[i][j];
  55.                     }
  56.             }
  57.     }
  58.         cout<<endl<<endl;
  59.         //Muestro la matriz triangulada
  60.     cout<<"La matriz triangulada es:"<<endl<<endl;
  61.     for(int i=1;i<=n;i++){
  62.             for(int k=1;k<=2*n;k++){
  63.                     cout<<A[i][k]<<" ";
  64.             }
  65.             cout<<endl;
  66.             }
  67.            
  68.         cout<<endl<<endl;
  69.     //Aplico Gauss-Jordan
  70.     for(int i=1;i<=n;i++){
  71.             q--;w=q;
  72.             for(int k=i+1;k<=n;k++){
  73.                     w--;
  74.                     t=A[w][q]/A[q][q];
  75.                     for(int j=1;j<=2*n;j++){
  76.                             A[w][j]=A[w][j]-t*A[q][j];
  77.                     }
  78.             }
  79.     }
  80.     for(int i=1;i<=n;i++){
  81.             for(int j=1;j<=2*n;j++){
  82.                     A[i][j]=A[i][j]/A[i][i];
  83.             }
  84.     }
  85.     //Muestro la matriz diagonalizada y la inversa:
  86.     cout<<"La matriz diagonalizada y la inversa de A es:"<<endl<<endl;
  87.     for(int i=1;i<=n;i++){
  88.             for(int k=1;k<=2*n;k++){
  89.                     cout<<A[i][k]<<" ";
  90.             }
  91.             cout<<endl;
  92.             }
  93.    
  94.         system("pause");return 0;
  95. }        
  96.  
  97.  

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema inversa
« Respuesta #1 en: Miércoles 23 de Marzo de 2011, 20:41 »
0
Buenas.

Los rangos de las variables para los bucles estan mal.

En c/c++ los elementos de los vectores van de 0 a N-1.

Por ejemplo:

#     for(int i=1;i<=n;i++){
#             for(int k=1;k<=n;k++){
#                     cout<<"Introduzca el elemento de la fila "<<i<<" y la columna "<<k<<endl;
#                     cin>>A[k];
#             }
#     }

tendria que quedar:

#     for(int i=0;i<n;i++){
#             for(int k=0;k<n;k++){
#                     cout<<"Introduzca el elemento de la fila "<<i+1<<" y la columna "<<k+1<<endl;
#                     cin>>A[k];
#             }
#     }

La verdad que ni mire el algoritmo :P
Corregi eso y si aparece otro problema avisa.

Saludos
The sweet smell of a great sorrow lies over the land.


Checho360

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
Re: Problema inversa
« Respuesta #2 en: Miércoles 23 de Marzo de 2011, 20:51 »
0
Hola Epa; en primer lugar muchisimas gracias por contestar ya pensaba que nadie lo haría jeje. Voy a probar lo que dices. Ya sabia que las matrices se generan contando desde 0 pero simplemente me parecio mas comodo hacerlo asi, y ademas pensaba que eso no generaria errores, es decir pense: que mas da recorrer la matriz de 0 a n-1 que de 1 a n. De todas formas voy a cambiarlo todo a ver si cambia la cosa. Ahh y lo del algoritmo, creo que esta bien porque lo pense yo y lo programe primero en matlab y ahí funciona de maravilla. Lo unico que a este aun no le añadi cosas como que no tome como pivote un 0 o cosas asi (primero que funcione con esto y luego ya le añado cosas).

Un saludo y muchas gracias por contestar

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema inversa
« Respuesta #3 en: Miércoles 23 de Marzo de 2011, 22:03 »
0
Ahi revise el algoritmo.

Ademas de los de los bucles, tendrias que modificar el     q=n +1; del principio, cambiarlo por q=n;

Fijate que los valores iniciales de las variables en los bucles anidados, quedan como estaban. Por ejemplo:

for(int i=0;i<n;i++){
for(int k=i+1;k<n;k++){

k=i+1 queda asi, y no k=i

Aunque encontre un pequeño error en el algoritmo, no se si ya te habras dado cuenta.

En la parte
Código: C++
  1.  
  2.     for(int i=0;i<n;i++){
  3.             for(int j=0;j<2*n;j++){
  4.                     A[i][j]=A[i][j]/A[i][i];
  5.             }
  6.     }
  7.  
  8.  

Despues da Gauss-Jordan

Fijate que estas dividiendo primero la matriz original, por lo que vas poniendo 1's en la diagonal, y despues dividis las filas de la otra matriz por 1, o sea que queda igual.

Podrias ahcer algo como:
Código: C++
  1.  
  2.     for(int i=0;i<n;i++){
  3.             for(int j=n;j<2*n;j++){
  4.                     A[i][j]=A[i][j]/A[i][i];
  5.             }
  6.             A[i][i] = 1;
  7.     }
  8.  
  9.  

Me alegra haber sido de ayuda  :good:

Saludos
The sweet smell of a great sorrow lies over the land.


Checho360

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
Re: Problema inversa
« Respuesta #4 en: Miércoles 23 de Marzo de 2011, 22:06 »
0
Bueno pues ya he probao a cambiar eso y sigue igual. Ahora ademas tengo dos cosas que pasan que no entiendo. Adjunto una imagen para explicarlo: para empezar la primera columna de la matriz A la cambia por la columna 1 de la matriz identidad y despues todo mal claro... no encuentro el error a ver si alguien me puede decir; gracias de antemano!!

img121.imageshack.us/i/sinttuloi.gif/

El nuevo codigo es:

Código: C++
  1. #include <iostream>
  2. using namespace std;
  3. int main ()
  4. /*Este programa pide al usuario una matriz de orden n la diagonaliza por el
  5. metodo de Gauss-Jordan sin pivote y calcula su inversa*/
  6. {
  7.     //Genero las variables, la matriz, la pido al usuario y la muestro por pantalla
  8.     int n;double long t;int w;
  9.     cout<<"Introduzca el orden de la matriz:"<<endl;
  10.     cin>>n;int q=n;
  11.     double A[n-1][(2*n)-1];double B[n-1][n-1];
  12.     for(int i=0;i<n;i++){
  13.             for(int k=0;k<n;k++){
  14.                     cout<<"Introduzca el elemento de la fila "<<i<<" y la columna "<<k<<endl;
  15.                     cin>>A[i][k];
  16.             }
  17.     }
  18.     cout<<endl<<endl;
  19.     for(int i=0;i<n;i++){
  20.             for(int k=0;k<n;k++){
  21.                     cout<<A[i][k]<<" ";
  22.                     if(k==n-1){cout<<endl;}
  23.             }
  24.     }
  25.     //Genero la matriz identidad
  26.     for(int i=0;i<n;i++){
  27.             for(int j=0;j<n;j++){
  28.                     if(j==i){B[i][j]=1.0;}
  29.                     else{B[i][j]=0.0;}
  30.                     }
  31.             }
  32.     //Acoplo la matriz identidad para trabajar con ella
  33.     for(int j=0;j<n;j++){
  34.             int a=0;
  35.             for(int i=n;i<2*n;i++){
  36.                     A[j][i]=B[j][a];
  37.                     a++;
  38.                     }
  39.             }
  40.     //Muestro la matriz con la que voy a trabajar
  41.     cout<<endl<<endl<<"La matriz introducida con la identidad acoplada es:"<<endl<<endl;
  42.     for(int i=0;i<n;i++){
  43.             for(int k=0;k<2*n;k++){
  44.                     cout<<A[i][k]<<" ";
  45.             }
  46.             cout<<endl;
  47.             }
  48.     cout<<endl<<endl;
  49.     //Triangulo la matriz
  50.     for(int i=0;i<n;i++){
  51.             for(int k=i+1;k<n;k++){
  52.                     t=A[k][i]/A[i][i];
  53.                     for(int j=0;j<2*n;j++){
  54.                             A[k][j]=A[k][j]-t*A[i][j];
  55.                     }
  56.             }
  57.     }
  58.         cout<<endl<<endl;
  59.         //Muestro la matriz triangulada
  60.     cout<<"La matriz triangulada es:"<<endl<<endl;
  61.     for(int i=0;i<n;i++){
  62.             for(int k=0;k<2*n;k++){
  63.                     cout<<A[i][k]<<" ";
  64.             }
  65.             cout<<endl;
  66.             }
  67.            
  68.         cout<<endl<<endl;
  69.     //Aplico Gauss-Jordan
  70.     for(int i=0;i<n;i++){
  71.             q--;w=q;
  72.             for(int k=i+1;k<n;k++){
  73.                     w--;
  74.                     t=A[w][q]/A[q][q];
  75.                     for(int j=0;j<=2*n-1;j++){
  76.                             A[w][j]=A[w][j]-t*A[q][j];
  77.                     }
  78.             }
  79.     }
  80.     for(int i=0;i<n;i++){
  81.             for(int j=1;j<2*n;j++){
  82.                         A[i][j]=A[i][j]/A[i][i];
  83.             }
  84.             A[i][i]=1;
  85.     }
  86.     //Muestro la matriz diagonalizada y la inversa:
  87.     cout<<"La matriz diagonalizada y la inversa de A es:"<<endl<<endl;
  88.     for(int i=0;i<n;i++){
  89.             for(int k=1;k<2*n;k++){
  90.                     cout<<A[i][k]<<" ";
  91.             }
  92.             cout<<endl;
  93.             }
  94.    
  95.         system("pause");return 0;
  96. }        
  97.  
  98.  

Por cierto epa tienes toda la razon en el fallo del algoritmo en la parte de dividir por la diagonal. No lo había visto asi que un error menos jejeje.

Muchisimas gracias epa da gusto que haya gente asi ;)

EDITO: epa he modificao el primer programa que puse con este ultimo fallo que has comentao y funciona perfectamente, sin embargo cambiando los bucles por 0:n-1 no funciona (no veo el error), por esos fallos de la imagen. Aver si lo ves tu. Un saludo

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema inversa
« Respuesta #5 en: Miércoles 23 de Marzo de 2011, 22:19 »
0
En la linea 75 se te escapo un = del <= en el for.

Creo que no me explique muy bien en la otra respuesta :P

Si tenes una matriz, por ejemplo mat[N][M]

los elementos de esa matriz van desde mat[0][0] a mat[N-1][M-1]

O sea, N y M representa la cantidad de elementos e cada dimension.
Pero despues para acceder a cada elemento, se empieza desde 0.

Si tenes por ejemplo:

int A[5];

los elementos de ese vector son, A[0], A[1], A[2], A[3] y A[4]

Te dejo tu codigo con esas cositas corregidas.
Fijate que le saque la matriz B, y directamente le agrego la identidad a A.

Código: C++
  1.  
  2. #include <iostream>
  3. using namespace std;
  4. int main ()
  5. /*Este programa pide al usuario una matriz de orden n la diagonaliza por el
  6. metodo de Gauss-Jordan sin pivote*/
  7. {
  8.     //Genero las variables, la matriz, la pido al usuario y la muestro por pantalla
  9.     int n, w, q;
  10.     long double t;
  11.  
  12.     cout<<"Introduzca el orden de la matriz:"<<endl;
  13.     cin>>n;
  14.  
  15.     q=n;
  16.  
  17.     double A[n][2*n];
  18.  
  19.     for(int i=0;i<n;i++){
  20.             for(int k=0;k<n;k++){
  21.                     cout<<"Introduzca el elemento de la fila "<<i<<" y la columna "<<k<<endl;
  22.                     cin>>A[i][k];
  23.             }
  24.     }
  25.     cout<<endl<<endl;
  26.     for(int i=0;i<n;i++){
  27.             for(int k=0;k<n;k++){
  28.                     cout<<A[i][k]<<" ";
  29.                     if(k==n){cout<<endl;}
  30.             }
  31.     }
  32.  
  33.     //Acoplo la matriz identidad para trabajar con ella
  34.     for(int j = 0; j < n; j++){
  35.             for(int i = n; i < 2*n; i++)
  36.         {
  37.                   if(j == (i-n))
  38.                         A[j][i] = 1;        
  39.                   else
  40.                         A[j][i] = 0;
  41.             }
  42.     }
  43.  
  44.  
  45.     //Muestro la matriz con la que voy a trabajar
  46.     cout<<endl<<endl<<"La matriz introducida con la identidad acoplada es:"<<endl<<endl;
  47.     for(int i=0;i< n;i++){
  48.             for(int k=0;k<2*n;k++){
  49.                     cout<<A[i][k]<<" ";
  50.             }
  51.             cout<<endl;
  52.             }
  53.     cout<<endl<<endl;
  54.  
  55.     //Triangulo la matriz
  56.     for(int i=0;i<n;i++){
  57.             for(int k=i+1;k<n;k++){
  58.                     t=A[k][i]/A[i][i];
  59.                     for(int j=0;j<2*n;j++){
  60.                             A[k][j]=A[k][j]-t*A[i][j];
  61.                     }
  62.             }
  63.     }
  64.         cout<<endl<<endl;
  65.         //Muestro la matriz triangulada
  66.     cout<<"La matriz triangulada es:"<<endl<<endl;
  67.     for(int i=0;i<n;i++){
  68.             for(int k=0;k<2*n;k++){
  69.                     cout<<A[i][k]<<" ";
  70.             }
  71.             cout<<endl;
  72.             }
  73.            
  74.         cout<<endl<<endl;
  75.     //Aplico Gauss-Jordan
  76.     for(int i=0;i < n;i++){
  77.             q--;
  78.         w=q;
  79.             for(int k = i+1; k < n; k++){
  80.                     w--;
  81.                     t=A[w][q]/A[q][q];
  82.                     for(int j=0;j<2*n;j++){
  83.                             A[w][j]=A[w][j]-t*A[q][j];
  84.                     }
  85.             }
  86.     }
  87.     for(int i=0;i<n;i++){
  88.             for(int j=n;j<2*n;j++){
  89.                     A[i][j]=A[i][j]/A[i][i];
  90.             }
  91.         A[i][i] = 1;
  92.     }
  93.  
  94.     //Muestro la matriz diagonalizada y la inversa:
  95.     cout<<"La matriz diagonalizada y la inversa de A es:"<<endl<<endl;
  96.     for(int i=0;i<n;i++){
  97.             for(int k=0;k<2*n;k++){
  98.                     cout<<A[i][k]<<" ";
  99.             }
  100.             cout<<endl;
  101.             }
  102.    
  103.      return 0;
  104. }    
  105.  
  106.  

Saludos
The sweet smell of a great sorrow lies over the land.


Checho360

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
Re: Problema inversa
« Respuesta #6 en: Miércoles 23 de Marzo de 2011, 22:44 »
0
En la linea 29 creo que esta mal; deberia ser:

Código: C++
  1. if(k==n-1){cout<<endl;}
  2.  

La explicacion que das de A[5] es perfecta, ahora entiendo bien eso. Hasta ahora pensaba que era como matlab .

Bueno haciendo esos ajustes ya me funciona perfectamente, ahora le queda hacer algunos ajustes de pivoteo y esas cosas a ver que tal, si eso ya comento otra vez con el error para que me ayudes jaja.

Bueno pues lo dicho muchas gracias, y por cierto epa, que estudias??
« última modificación: Jueves 24 de Marzo de 2011, 12:29 por Checho360 »

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema inversa
« Respuesta #7 en: Miércoles 23 de Marzo de 2011, 23:13 »
0
jaja, que bueno que hayas entendido con esa "pseudo" explicacion jaja  :good:

Estudio Ingenieria en Sistemas de Informacion. O por lo menos eso intento  :P jajaja

Saludos
The sweet smell of a great sorrow lies over the land.


Checho360

  • Miembro activo
  • **
  • Mensajes: 84
    • Ver Perfil
Re: Problema inversa
« Respuesta #8 en: Lunes 28 de Marzo de 2011, 22:12 »
0
Por cierto, en su momento se me olvido... pero por si a alguien le interesa quedo:

Código: C++
  1. #include <iostream>
  2. using namespace std;
  3. int main ()
  4. /*Este programa pide al usuario una matriz de orden n la diagonaliza por el
  5. metodo de Gauss-Jordan sin pivote y calcula su inversa*/
  6. {
  7.     //Genero las variables, la matriz, la pido al usuario y la muestro por pantalla
  8.     int n;double long t;int w;
  9.     cout<<"Introduzca el orden de la matriz:"<<endl;
  10.     cin>>n;int q=n;
  11.     double A[n][(2*n)];double B[n][n];
  12.     for(int i=0;i<n;i++){
  13.             for(int k=0;k<n;k++){
  14.                     cout<<"Introduzca el elemento de la fila "<<i+1<<" y la columna "<<k+1<<endl;
  15.                     cin>>A[i][k];
  16.             }
  17.     }
  18.     cout<<endl<<endl;
  19.     for(int i=0;i<n;i++){
  20.             for(int k=0;k<n;k++){
  21.                     cout<<A[i][k]<<" ";
  22.                     if(k==n-1){cout<<endl;}
  23.             }
  24.     }
  25.     //Genero la matriz identidad
  26.     for(int i=0;i<n;i++){
  27.             for(int j=0;j<n;j++){
  28.                     if(j==i){B[i][j]=1.0;}
  29.                     else{B[i][j]=0.0;}
  30.                     }
  31.             }
  32.     //Acoplo la matriz identidad para trabajar con ella
  33.     for(int j=0;j<n;j++){
  34.             int a=0;
  35.             for(int i=n;i<2*n;i++){
  36.                     A[j][i]=B[j][a];
  37.                     a++;
  38.                     }
  39.             }
  40.     //Muestro la matriz con la que voy a trabajar
  41.     cout<<endl<<endl<<"La matriz introducida con la identidad acoplada es:"<<endl<<endl;
  42.     for(int i=0;i<n;i++){
  43.             for(int k=0;k<2*n;k++){
  44.                     cout<<A[i][k]<<" ";
  45.             }
  46.             cout<<endl;
  47.             }
  48.     cout<<endl<<endl;
  49.     //Triangulo la matriz
  50.     int u=2;
  51.     for(int i=0;i<n;i++){
  52.             for(int k=i+1;k<n;k++){
  53.                     //Activo este bucle para evitar que el programa divida por 0 (el pivote sea 0)
  54.                     if(A[i][i]==0){
  55.                                        double sum =0.0;
  56.                                        for(int x=i+1;x<n;x++){
  57.                                                if(A[x][i]!=0){sum=1;break;}
  58.                                                sum=sum+A[x][i];
  59.                                                }
  60.                                        if(sum==0){u=1;break;}
  61.                                        }
  62.                     if(u==1){break;}
  63.                     int a=i+1;
  64.                     //Permutamos las filas mientras el pivote sea 0
  65.                     while(A[i][i]==0){
  66.                                      for(int s=0;s<2*n;s++){
  67.                                              int p = A[i][s];A[i][s]=A[a][s];A[a][s]=p;  
  68.                                      }
  69.                                      a++;
  70.                                      }
  71.                     t=A[k][i]/A[i][i];
  72.                     for(int j=0;j<2*n;j++){
  73.                             if(u==1){break;}
  74.                             A[k][j]=A[k][j]-t*A[i][j];
  75.                     }
  76.             }
  77.     }
  78.         cout<<endl<<endl;
  79.         //Muestro la matriz triangulada
  80.     cout<<"La matriz triangulada es:"<<endl<<endl;
  81.     for(int i=0;i<n;i++){
  82.             for(int k=0;k<2*n;k++){
  83.                     cout<<A[i][k]<<" ";
  84.             }
  85.             cout<<endl;
  86.             }
  87.            
  88.         cout<<endl<<endl;
  89.     //Aplico Gauss-Jordan
  90.     for(int i=0;i<n;i++){
  91.             q--;w=q;
  92.             for(int k=i+1;k<n;k++){
  93.                     w--;
  94.                     t=A[w][q]/A[q][q];
  95.                     for(int j=0;j<2*n;j++){
  96.                             A[w][j]=A[w][j]-t*A[q][j];
  97.                     }
  98.             }
  99.     }
  100.     for(int i=0;i<n;i++){
  101.             for(int j=n;j<2*n;j++){
  102.                     A[i][j]=A[i][j]/A[i][i];
  103.             }
  104.             A[i][i]=1;
  105.     }
  106.     //Muestro la matriz diagonalizada y la inversa:
  107.     cout<<"La matriz diagonalizada y la inversa de A es:"<<endl<<endl;
  108.     for(int i=0;i<n;i++){
  109.             for(int k=0;k<2*n;k++){
  110.                     cout<<A[i][k]<<" ";
  111.             }
  112.             cout<<endl;
  113.             }
  114.    
  115.         system("pause");return 0;
  116. }        
  117.  
  118.