[Prévia] [Próxima] [Prévia por assunto] [Próxima por assunto]
[Índice cronológico] [Índice de assunto]

Re: Gauss-Jordan



/* Novo programa, com poucas (pouquíssimas) novidades
Deu alguns resultados estranhos...


 */

#include <stdio.h>
#include <time.h>

#define NULO (-1)
#define TRUE 1
#define FALSE 0
#define M 10
#define N 10

main()
{

float E[M][N], D[M][N], F[M][N], G[M][N], C[M][N], ah, ai;
int p, q, h, k, i, j, limiteN, limiteM, P[M];
time_t start,end;

printf("Multiplicação de Matrizes.\n");
printf("M x N = ");
scanf("%d %d", &limiteM, &limiteN);

if (limiteM > M) limiteM = M;
if (limiteN > N) limiteN = N;

/* Preencher F e G com identidade */
identidade(F, limiteM); identidade(G, limiteM);

inclui_dados(D,"D",limiteM, limiteN);
copia_matriz(D, E, limiteM, limiteN);

start = time(NULL);

/* Inicializar P[] */
for (i = 0; i < limiteM; i++) P[i] = (NULO);

while (escalonada(E, P, limiteM, limiteN) == FALSE)
{
    h = escolhe_h(E, limiteM, limiteN, P);
    k = escolhe_k(E, h, limiteN);

    printf("h= %d, k= %d\n",h+1,k+1);
    mostra_matriz(E,"E",limiteM,limiteN);

    /*  P I V O T A C A O  */
    for (i = 0; i < limiteM; i++)
        F[i][h] = D[i][k];

    ah = 1/E[h][k];

    printf(", ah= %f, ai= { ",ah);

    for (i=0; i < limiteM; i++)
    {
        ai = E[i][k] / E[h][k];

        if (i != h)
            printf("%f ",ai);

        for (j = 0; j < limiteN; j++)
        {
            if (i == h)
            {
                G[i][j] = ah * G[i][j];
                E[i][j] = ah * E[i][j];
            }
            else
            {
                  G[i][j] = G[i][j] - ai*G[h][j];
                  E[i][j] = E[i][j] - ai*E[h][j];
            }
        }
    }

    printf(" }\n");

    /* Inclui h e k na base */
    P[h] = k;
}
end=time(NULL);

printf("\n----------%f segundos-----------------\n", difftime(end, start));

mostra_matriz(F, "F", limiteM, limiteM); mostra_matriz(G, "G", limiteM,
limiteM);
multiplica(F, G, C, limiteM, limiteM); mostra_matriz(C, "FG", limiteM,
limiteM);

multiplica(G, D, C, limiteM, limiteN); mostra_matriz(C, "GD", limiteM,
limiteN);
mostra_matriz(E, "E", limiteM, limiteN);

printf("\n----------%f segundos-----------------\n", difftime(end, start));
}



/* Multiplica duas matrizes: C = AB */

multiplica(float MTA[M][M], float MTB[M][N], float MTC[M][N], int nc, int
nl)
{

int i, j, k;
for (i = 0; i < nl; i++)
    for (j = 0; j < nc; j++)
    {
        MTC[i][j] = 0;
        for (k = 0; k < nc; k++)
            MTC[i][j] = MTC[i][j] + (MTA[i][k] * MTB[k][j]);
    }
}



/* Retorna a linha h, tal que E[h,] <> zero para algum h em M - P */

int escolhe_h(float E[M][N], int limM, int limN, int P[M])
{
    int h, i, j;

    for (i = 0; i < limM; i++)
        if ( P[i] == (NULO) )
            if (linha_nula(E, i, limN) == FALSE)
            {
                h = i;
                break;
            };
    return h;
}


/* Retorna TRUE se E[M - P,] = 0 (está escalonada) */

int escalonada(float E[M][N], int P[M], int limM, int limN)
{
    int i, j, escal = TRUE;
    for (i = 0; i < limM; i++)
        if (P[i] == (NULO) ) /* i nao esta na base P */
            if (linha_nula(E, i, limN) == FALSE)
            {
                escal = FALSE;
                break;
            }
    return escal;
}


/* Devolve k em N, tal que E[h,k] <> zero */

int escolhe_k(float E[M][N], int h, int limN)
{
    int j, k;
    for (j = 0; j < limN; j++)
        if (E[h][j] != 0)
        {
            k = j;
            break;
        }
    return k;
}


/* Preenche MT com a Matriz Identidade */

identidade (float MT[M][M], int lim)
{
    int i, j;

    if (lim > M) lim = M;

    for (i = 0; i < lim; i++)
    {
        for (j = 0; j < lim; j++)
        {
            if (i == j)
                MT[i][j] = 1;
            else
                MT[i][j] = 0;
        }
    }
}


mostra_matriz (float MT[M][N], char name[], int lim, int lim2)
{
  int i, j;

  if (lim > M) lim = M;
  if (lim2 > N) lim2 = N;
  for (i = 0; i < lim; i++)
  {
      printf("%s[%2d, ] = ", name, i+1);
      for (j = 0; j < lim2; j++) printf("%8.1f ", MT[i][j]);
      printf("\n");
  }
  printf("\n");
}


/* Recebe os valores da matriz */

inclui_dados(float MT[M][N], char nome[], int limiteM, int limiteN)
{
int i, j;
for (i = 0; i < limiteM; i++)
{
    for (j = 0; j < limiteN; j++)
    {
        printf("%s[%d,%d] = ",nome,i,j);
        scanf("%f", &MT[i][j]);
    }
    printf("\n");
}
}


/* Copia Matriz A em Matriz B */

copia_matriz(float MTA[M][N], float MTB[M][N], int limiteM, int limiteN)
{
int i, j;
for (i = 0; i < limiteM; i++)
    for (j = 0; j < limiteN; j++)
        MTB[i][j] = MTA[i][j];
}


/* retorna TRUE se todos os elementos da linha são iguais a zero */

int linha_nula(float E[M][N], int linha, int limN)
{
    int j, flag = TRUE;
    for(j = 0; j < limN; j++)
        if (E[linha, j] != 0)
        {
            flag = FALSE;
            break;
        }
    return flag;
}