miércoles, 30 de noviembre de 2016

GaussJordan en C



Cuando estudias programación, posiblemente uno de los programas básicos que te pedirán es el de GaussJordan, o tal vez no, pero como sea, aquí les comparto uno que desarrollé cuando lo necesité.

Es bastante simple, utiliza memoria dinámica para todo el cálculo y además si no encuentra solución pues envía un mensaje que no lo hay.

Hay muchas cosas que se necesitan pulir, por ejemplo, si ingresan más 20 ecuaciones, a veces se cicla. Claro, hay programas mucho más complejos que ya resuelven este problema, pero cuando a uno se lo piden, pues no es tan simple desarrollarlo.

El código es el siguiente, el cual solo se copia, se pega a un documento de texto y se compila con c, en mi caso utilizo geany para eso:

/* Autor: Fernando Merino
 * Programa: Método de Gauss-Jordan
 * Descripción: El método de Gauss-Jordan soluciona sistemas de ecuaciones
 * simultáneas.
 * */

#include <stdio.h>
#include <stdlib.h>

void gausJordan(float **matriz,int n,float *raices);
void imprimirMatriz(float *raices,int n);
void leerValores(float **matriz,int n);

int main(){
 int n;
 float **matriz,*raices;
 printf("Ingrese el número de ecuaciones (n): ");
 scanf("%d",&n);
 getchar();
 matriz=(float**) malloc (sizeof (float*)*n);
 raices=(float*) malloc (sizeof (float*)*n);
 leerValores(matriz,n);
 gausJordan(matriz,n,raices);
 printf("Solución \n\n");
 imprimirMatriz(raices,n);
 getchar();
 return 0;
}
void imprimirMatriz(float *raices,int n){
 int i;
 for(i=0;i<n;i++){
  printf("X%d = %f\n",i+1,raices[i]);
 }
}
void gausJordan(float **matriz,int n,float *raices){
 int i,j,k;
 float termino;
 for(i=0;i<n;i++){
  if(matriz[i][i]==0.0){
   fprintf(stderr,"Error: División entre 0:: No hay solución!!!\n\n");
   system("pause");
   return ;
  }
  for(k=0;k<n;k++){
   if(k!=i){
    termino=matriz[k][i]/matriz[i][i];
    for(j=0;j<=n;j++){
     matriz[k][j]-=termino*matriz[i][j];
    }
   }
  }
 }
 for(i=0;i<n;i++){
  termino=matriz[i][n]/matriz[i][i];
  raices[i]=termino;
 } 
}
void leerValores(float **matriz,int n){
 int i,j;
 for(i=0;i<n;i++){
  matriz[i]=(float*) malloc (sizeof(float)*(n+1));
  for(j=0;j<n;j++){
   printf("Ingrese coeficiente de 'X%d' de la ecuación %d: ",j+1,i+1);
   scanf("%f",&matriz[i][j]);
  }
  printf("Ingrese el resultado de la ecuación %d ",i+1);
  scanf("%f",&matriz[i][n]);
 }
}


Ahora, lo que le trato de implementar, es muestre los resultados en fracciones, todo el proceso, es decir, que se le ingrese algo así 1/4, y que así se lo lleve en todo el proceso, y que al final de un resultado en fracciones. Si alguien ya lo tiene por ahí y que sea en C, y quiera compartirlo, me parecería perfecto, esto más por hobbie. Gracias y espero que les sirva.


3 comentarios:

  1. Hola. Para leer los datos en fracciones, puedes programar un intérprete. Te doy el ejemplo incompleto en C#:

    if ((m_iIdTokensEspera & ID_TOKEN_NUMERADOR) > 0 && EsNumero(m_sSiguienteToken))
    {
    m_dNumerador = m_sSiguienteToken;
    m_iIdTokensEspera = ID_TOKEN_DIVISION + ID_TOKEN_ENTER;
    } // if ((m_iIdTokensEspera & ID_TOKEN_NUMERADOR) > 0 && ...

    ...

    else if ((m_iIdTokensEspera & ID_TOKEN_DENOMINADOR) > 0 && EsNumero(m_sSiguienteToken))
    {
    m_dDenominador = m_sSiguienteToken;
    m_iIdTokensEspera = ID_TOKEN_ENTER;
    } // else if ((m_iIdTokensEspera & ID_TOKEN_DENOMINADOR) ...

    ...

    else if ((m_iIdTokensEspera & ID_TOKEN_ENTER) > 0 && EsEnter(m_sSiguienteToken))
    {
    m_bPuedeSalir = true;
    } // else if ((m_iIdTokensEspera & ID_TOKEN_ENTER) > 0 && ...

    ResponderEliminar
  2. Hola. Para llevar todo el proceso en fracciones, puedes programar algo como lo siguiente:

    for(int i = 2; i <= min(m_iNumerador, m_iDenominador); i++)
    {
    if (EsFactorComun(i, m_iNumerador, m_iDenominador))
    {
    m_iNumerador = m_iNumerador / i;
    m_iDenominador = m_iDenominador / i;
    i--; // para que vuelva a probar el mismo factor común
    } // if (EsFactorComun(i, m_iNumerador, m_iDenominador))
    } // for(int i = 2; i <= min(m_iNumerador, m_iDenominador); i++)

    ResponderEliminar
    Respuestas
    1. Muchas gracias.

      no se me había ocurrido la idea de utilizar un interprete, pero es muy acertado.


      tu no tienes gauss jordan ya en modo fracciones?

      Eliminar