Método de Power para calcular o autovelor dominante de uma matriz

Publicado por David Lorente 18/12/2005

[ Hits: 8.308 ]

Homepage: .

Download power.cpp




Esse é um programa que que fiz para a disciplina de análise numérica. Ele utiliza o algoritmo de power para calcular o autovalor dominante (em módulo) de uma matriz real e seu autovetor associado. O programa usa alocação dinâmica de memória e também um ponteiro para funções (isso não era necessário, mas eu quis enfeitar um pouco :D ). Bom, é isso, espero que ajude a alguém.

  



Esconder código-fonte

/*******************************************************************
*       Metodo de power para calcular o autovalor                  *
*       dominante (em modulo) e seu autovetor associado,           *
*       de uma matriz de numeros reais                             *
* ---------------------------------------------------------------- *
*Autor: David Oliveira Lorente                                     *
* ---------------------------------------------------------------- *
* Exemplo:                                                         *
* Dimensao da matriz: 3                                            *
* Numero de iteracoes: 3                                           *
*                                                                  *
* Matriz de entrada                                                *
*     2.000000 1.000000 1.000000                                   *
*     1.000000 2.000000 1.000000                                   *
*     1.000000 1.000000 2.000000                                   *
*                                                                  *
* n     lambda(n)              X(n)'                                       *
* --------------------------------------------------------         *
* 1       2.000000      [ 0.750000 0.250000 1.000000 ]'                *
* 2       3.000000      [ 0.916667 0.750000 1.000000 ]'                *
* 3     3.666667      [ 0.977273 0.931818 1.000000 ]'                *
*                                                                  *
*******************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define MAX(a,b) c = (absval(a) >= absval(b)) ? a : b // usado  no calculo da norma infinita.

FILE *fp; // arquivo texto com o autovetor e seu autovalor associado

double *cria_vetor(int tam) { /* rotina para alocar vetores dinamicamente */
  double *vetor;

  vetor = (double *) calloc(tam, sizeof(double));
  if (!vetor) {
     printf("Falta memoria para alocar o vetor de ponteiros");
    exit(1);
  }
  return vetor;
}

double absval(double val) // valor absoluto com precisao dupla
{
   if (val >= 0) return val;
   else return -val;
}

void dados(int dim, int *N, double *TOL, double **A, double *x) {  /* recebe os dados da
                                                                     matriz de entrada */
  for (int i = 0; i < dim; i++)
    for (int j = 0; j < dim; j++)
      A[i][j] = 0.0;

/* entrada da matriz */
  for (int i = 0; i < dim; i++) {
    printf("\n Linha #%d: \n", i+1);
     for (int j = 0; j < dim; j++) {
       printf("\n    Coluna #%d: ", j+1);
       scanf("%lf", &A[i][j]);
     }
  }
  printf("\n Entre com o vetor X inicial:"); /* vetor inicial X(0) */
  for(int i = 0; i < dim; i++) {
    printf("\n x#%d: ", i+1);
    scanf("%lf", &x[i]);
  }
  printf("\n Entre com a Tolerancia: ");
  scanf("%lf", TOL);
  printf("\n Entre com o numero maximo de iteracoes: ");
  scanf("%d", N);
  system("clear");
  fprintf(fp, "Matriz de entrada\n");
  for(int i = 0; i < dim; i++) {
    for(int j = 0; j < dim; j++)
      fprintf(fp, "%lf ", A[i][j]);
    fprintf(fp, "\n");
  }
  fprintf(fp, "\n");
} // fim dados

double norma_inf(double *x, int dim) {
  int i;
  double c;                        // norma infinita do vetor
  i = 0;
  c = x[0];
  for(i = 1; i < dim; i++)
    c = MAX(c, x[i]);
  if(c == 0) {
    printf("\n A matriz \"A\" possui um autovalor 0, selecione um novo vetor \"x\" e reinicie!");
    fprintf(fp,"\nA matriz \"A\" possui um autovalor 0, selecione um novo vetor \"x\" e reinicie!");
    exit(1);
  }
  return c;
} // fim norma_inf

void exibe(double *x, double lambda, int dim, int k) { // exibe os dados computados
  int i;

  if(k == 0) {
    printf("n\t lambda(n)\t\t\t X(n)' \n");
    printf("-----------------------------------------------------------------\n");
    fprintf(fp, "n\t lambda(n)\t\t\t X(n)' \n");
    fprintf(fp, "-----------------------------------------------------------------\n");
  }
  printf("%d\t ", k + 1);
  fprintf(fp, "%d\t ", k + 1);
  printf("%lf\t [ ", lambda);
  fprintf(fp, "%lf\t [ ", lambda);
  for(i = 0; i < dim; i++) {
    printf("%lf ", x[i]);
    fprintf(fp, "%lf ", x[i]);
  }
  printf("]'\n");
  fprintf(fp, "]'\n");
} // fim exibe

void power(int dim, int N, double TOL, double **A, double *x) { // calcula o autovalor e o autovetor
  double *y, lambda, c1, *aux, erro;
  int i, j, k, FLAG;
  // alocacao dinamica de memoria
  y = cria_vetor(dim);
  aux = cria_vetor(dim);
  i = 0;
  j = 0;
  k = 0;
  lambda = 0;
  FLAG = 0;
  c1 = norma_inf(x, dim);
  for(i = 0; i < dim; i++)
    x[i] = x[i]/c1;
  while((k < N)&&(FLAG == 0)){
    for(i = 0; i < dim; i++) {
      y[i] = 0;
      for(j = 0; j < dim; j++)
        y[i] += A[i][j]*x[j];
    }
    c1 = norma_inf(y, dim);

    for(int l = 0; l< dim; l++)
      aux[l] = x[l] - y[l]/c1;
    erro = norma_inf(aux, dim);
    for(i = 0; i < dim; i++)
      x[i] = y[i]/c1;
    FLAG = 0;
    if(fabs(erro) < TOL) FLAG = 1;
    lambda = c1;
    exibe(x, lambda, dim, k);
    k++;
  }
  free(y);
} // fim power

int main() {
  double TOL;
  double **A, *x;
  int dim, N;

  fp = fopen("dados.txt","w+");

  system("clear");
  printf(" ----------------------------------------------\n");
  printf("  Calcula o autovalor dominante de uma matriz  \n");
  printf("  quadrada e o seu autovetor associado pelo    \n");
  printf("  metodo da potencia.                          \n");
  printf(" ----------------------------------------------\n");
  printf("\n Dimensao da matriz ? "); scanf("%d", &dim);
  // alocacao dinamica de memoria
  A = (double **) calloc(dim, sizeof(double)); // matriz de entrada
  for (int i = 0; i < dim; i++) A[i] = (double *) calloc(dim, sizeof(double));
  x = cria_vetor(dim);  // vetor inicial
  dados(dim, &N, &TOL, A, x);

  power(dim, N, TOL, A, x);
  free(A);
  free(x);
  fclose(fp);
  //system(".\\dados.txt");
  getchar();
  return 0;
}

// fim power.cpp

Scripts recomendados

Teste de desempenho com números primos em C

Ler N números e ver qual é o maior

Squid - Modo de Trabalho

Algorítmo para Calcular Raiz Quadrada

Teoria do Caos - (Equação Logística)


  

Comentários
[1] Comentário enviado por gordon_freeman em 18/12/2005 - 02:07h

No título do programa é autovalor ao invés de autovelor...é isso. ;p


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts