Método de Power para calcular o autovelor dominante de uma matriz
Publicado por David Lorente 18/12/2005
[ Hits: 8.494 ]
Homepage: .
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.
/******************************************************************* * 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
Função boa para ler string em C
Teste de desempenho com números primos em C (corrigido)
Organizar variáveis em ordem crescente
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
É cada coisa que me aparece! - não é só 3% (3)
Melhorando a precisão de valores flutuantes em python[AJUDA] (5)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta