Método de Power para calcular o autovelor dominante de uma matriz
Publicado por David Lorente 18/12/2005
[ Hits: 8.308 ]
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
Teste de desempenho com números primos em C
Ler N números e ver qual é o maior
Algorítmo para Calcular Raiz Quadrada
Teoria do Caos - (Equação Logística)
Melhorando o tempo de boot do Fedora e outras distribuições
Como instalar as extensões Dash To Dock e Hide Top Bar no Gnome 45/46
E a guerra contra bots continua
Tradução do artigo do filósofo Gottfried Wilhelm Leibniz sobre o sistema binário
Conheça o firewall OpenGFW, uma implementação do (Great Firewall of China).
Instalando o FreeOffice no LMDE 6
Anki: Remover Tags de Estilo HTML de Todas as Cartas
Colocando uma opção de redimensionamento de imagem no menu de contexto do KDE
Não consigo acessar os modos de desempenho (2)
Ubuntu — tentando iniciar o windows? (0)
[Shell Script] Script para desinstalar pacotes desnecessários no OpenSuse
[Shell Script] Script para criar certificados de forma automatizada no OpenVpn
[Shell Script] Conversor de vídeo com opção de legenda
[C/C++] BRT - Bulk Renaming Tool
[Shell Script] Criação de Usuarios , Grupo e instalação do servidor de arquivos samba