int main (int argc, char **argv) { srand( 20141 ); int c, //guarda a opçao (-i, -o, -r) n = -1; //guarta a dimensao da matriz (n x n) char *arq_out; //string p/ guardar o caminho do arquivo de saida FILE *input = stdin, *output = stdout; double *A = NULL, tempo_inv, tempo_err; while ((c = getopt(argc, argv, "i:o:r:")) != -1) { switch (c) { case 'i': A = le_entrada (optarg, &n); break; case 'o': output = fopen (optarg, "w"); break; case 'r': n = atoi(optarg); break; default: //err = 1; break; } } if ( (A == NULL) && (n == -1) ) // se n foi dado um arquivo como entrada A = le_entrada ("stdin", &n);// le da entrada padrao if ( (A == NULL) && (n != -1) ) // se foi dado apenas a dimensao da matriz A = generateSquareRandomPositiveDefiniteMatrix( n ); // if (!Check_Matrix(A, n)) { // fprintf (stderr, "Matriz não definida positiva.\n"); // return -1; // } double *A_inv = inverse (A, n, &tempo_inv); double res = residuo (A, A_inv, n, &tempo_err); imprime_saida (A_inv, n, tempo_inv, tempo_err, res, output); free(A); free(A_inv); return 0; }
int gmres_precond(MAT* A, MAT* L, MAT* U, double* x, double* b, double tol, int kmax, int lmax) { int i, j, I, J, N, ciclos, iter; double Eps, inv_aux, r, res, n_u, t; double *c, *s, *e, *y, *Beta, *b_cond, *aux, *aux_cond; double **up, **h; N = A->n; Beta = createVector(kmax); c = createVector(kmax); s = createVector(kmax); y = createVector(kmax); e = createVector(kmax+1); up = createMatrix(kmax+1, N); aux = createVector(N); aux_cond = createVector(N); b_cond = createVector(N); h = (double**) calloc(kmax,sizeof(double*)); for (I=0;I<kmax;I++) h[I] = (double*) calloc((I+2),sizeof(double)); // Condicionando b precondLU(L, U, b_cond, b, N); Eps = tol*sqrt(InnerProduct(b_cond, b_cond, N)); //printf("Eps = %.12lf\n", Eps); res = Eps + 1.0; ciclos = 0; //while (ciclos<lmax) while (ciclos<lmax && res>Eps) { // Ação do precondicionador double* p = createVector(N); residuo(A, x, b, p, N); MATRIX_matvec(A, aux, x); precondLU(L, U, p, aux, N); for (J=0; J<N; J++) { up[0][J] = b_cond[J] - p[J]; } e[0] = sqrt(InnerProduct(up[0], up[0], N)); inv_aux = 1./e[0]; for (I=0; I<N; I++) up[0][I] = inv_aux*up[0][I]; res = e[0]; i = 0; //while (i<kmax) while (i<kmax && res>Eps ) { for (J=0; J<N; J++) { aux[J] = 0; } MATRIX_matvec(A, aux, up[i]); precondLU(L, U, p, aux, N); for (J=0; J<N; J++) { up[i+1][J] = p[J]; } // Gram-Schmidt for (j=0;j<i+1;j++) { Beta[j] = InnerProduct(up[i+1],up[j],N); for (I=0; I<N; I++) up[i+1][I] -= Beta[j] * up[j][I]; h[i][j] = Beta[j]; } n_u = sqrt((InnerProduct(up[i+1],up[i+1],N))); h[i][i+1] = n_u; inv_aux = 1./n_u; for (I=0; I<N; I++) up[i+1][I] = inv_aux*up[i+1][I]; // Algoritmo QR for (j=0;j<i;j++) { t = h[i][j]; h[i][j] = c[j]*t + s[j]*h[i][j+1]; h[i][j+1] = -s[j]*t + c[j]*h[i][j+1]; } r = sqrt(h[i][i]*h[i][i] + h[i][i+1]*h[i][i+1]); inv_aux = 1./r; c[i] = inv_aux*h[i][i]; s[i] = inv_aux*h[i][i+1]; h[i][i] = r; h[i][i+1]= 0.0; e[i+1] = -s[i]*e[i]; e[i] = c[i]*e[i]; res = fabs(e[i+1]); i++; } i--; substRetroativas(h,y,e,i); for (j=0;j<i+1;j++) for (I=0;I<N;I++) x[I] += y[j]*up[j][I]; iter = ciclos*kmax + i+1; ciclos++; } printf(" - Ciclos : %d\n", ciclos); printf(" - Iteracoes : %d\n", iter); printf(" - Residuo : %.15lf\n", res); // Liberando memória free(aux_cond); free(b_cond); free(Beta); free(c); free(s); free(e); free(y); free(aux); freeMatrix(up, kmax+1); freeMatrix(h, kmax); return(0); }