Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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);
}