Пример #1
0
void ConjugateGradient( int n, double** A, double* b, double* x)
{
	int i, j, k, stop;
	double aux1 = 0, aux2 = 0, aux3 = 0;
	double *vaux = (double*)malloc(n*sizeof(double));
	double *d0 = (double*)malloc(n*sizeof(double)), *r0 = (double*)malloc(n*sizeof(double));
	double a0,b0;
	mat_multv(n,n, A, x, vaux);
	for(i = 0; i < n; i++)
	{
		d0[i] = b[i] - vaux[i];
		r0[i] = b[i] - vaux[i];
	}
	do
	{
		stop = 0;
		aux1 = 0;aux2 = 0;aux3=0;
		mat_multv(n,n,A, d0, vaux);
		for(j = 0; j < n; j++)
		{
			aux2 +=d0[j]*vaux[j];
			aux1 += r0[j]*r0[j];
		}
		a0 = aux1/aux2;
		for(j = 0; j < n; j++)
		{
			x[j] = x[j] + a0*d0[j];
			r0[j] = r0[j] - a0*vaux[j];
			aux3 += r0[j]*r0[j];
		}

		b0 = aux3/aux1;

		for(j = 0; j < n; j++)
			d0[j] = r0[j] +b0*d0[j];

		for (j = 0; j < n; j++)
		{
			if ( (r0[j]<0.02) && (r0[j]>-0.02) )
				stop++;
		}
	}while(stop != n);
	free(r0);
	free(d0);
	free(vaux);
}
Пример #2
0
int ConjugateGradient(int n, Matriz ***A, double* b, double *x, double tol){
    double * Rk, *Rk1, *Dk, *temp;
    double Alfa, Beta;
    int i;

    Rk = (double*) calloc(n+IDX,sizeof(double));
    Rk1 = (double*) calloc(n+IDX,sizeof(double));
    Dk = (double*) calloc(n+IDX,sizeof(double));
    temp = (double*) calloc(n+IDX,sizeof(double));

    // D0 = R0= b - Ax;
    mat_multv(n,A,x,temp); mat_sumV(n, -1, b, temp,Rk); copiaV(n,Dk,Rk);

    // For K= 0...n-1
    for (i = IDX; i < n+IDX; ++i){
        
        // if (Rk = 0) stop
        if(mat_modulo(n, Rk) < 0.5*pow(10,-tol)) break; 

        // Alfa = RkT*Rk / DkT * A *Dk
        mat_multv(n,A,Dk,temp); Alfa = mat_escalar_vu(n,Rk,Rk)/ mat_escalar_vu(n,temp,Dk);

        // Xk1 = Xk + Alfa*Dk
        mat_sumV(n,Alfa,x,Dk,x);

        //Rk1 = Rk - Alfa * A* Dk ;; Obs: temp já contém A*Dk
        mat_sumV(n, -1*Alfa,Rk,temp,Rk1);


        //Beta = Rk1T * Rk1 / RkT * Rk
        Beta = mat_escalar_vu(n,Rk1,Rk1) / mat_escalar_vu(n,Rk,Rk);

        //Dk1 = Rk1 + Beta*Dk
        mat_sumV(n,Beta,Rk1,Dk,Dk);

        //Atualiza o Rk
        copiaV(n,Rk,Rk1);

    }

    free(Rk);
    free(Rk1);
    free(Dk);
    free(temp);
    return i-IDX;
}
Пример #3
0
void test_mat_multv() {
  double a[6] = {1.0, 2.0, 3.0, 
                 4.0, 5.0, 6.0};
  double** A = mat_from_vector(a, 2, 3);

  double v[3] = {10.0, 20.0, 30.0};
  double w[2];

  mat_multv(2, 3, A, v, w);

  assert(w[0] == 140.0);
  assert(w[1] == 320.0);
}
Пример #4
0
int main (void)
{
	double** A = mat_cria(3,3);
	double** B = mat_cria(3,2);
	double** C = mat_cria(3,3);
	double** D = mat_cria(3,2);
	double** E = mat_cria(2,5);
	double x[5];
	double v[3];
	double w[3];
	double XE[2];
	// Vetor v
	v[0] = 0;
	v[1] = 1;
	v[2] = 2;
	// vetor x
	x[0] = 1;
	x[1] = 2;
	x[2] = 3;
	x[3] = 4;
	x[4] = 5;
	// Matriz A
	A[0][0] = 1;
	A[0][1] = 2;
	A[0][2] = 3;
	A[1][0] = 4;
	A[1][1] = 5;
	A[1][2] = 6;
	A[2][0] = 7;
	A[2][1] = 8;
	A[2][2] = 9;
	// Matriz B
	B[0][0] = 0;
	B[0][1] = 1;
	B[1][0] = 0;
	B[1][1] = 1;
	B[2][0] = 0;
	B[2][1] = 1;
	//Matriz E
	E[0][0] = 1;
	E[0][1] = 2;
	E[0][2] = 3;
	E[0][3] = 4;
	E[0][4] = 5;
	E[1][0] = 1;
	E[1][1] = 2;
	E[1][2] = 3;
	E[1][3] = 4;
	E[1][4] = 5;
	// Imprime a matriz
	printf(" Matriz A \n");
	printm(3,3,A);
	mat_transposta(3,3, A, C);
	printf("\n\n Matriz Transposta C \n");
	printm(3,3,C);
	printf("\n\n Vetor resultante da multiplicacao Matriz A x Vetor V \n");
	mat_multv(3,3, A, v, w);
	printf("%g\n%g\n%g\n", w[0], w[1], w[2]);
	mat_multm(3,3,2, A, B, D);
	printf(" Matriz resultante da multiplicacao Matriz A x Matriz B \n");
	printm(3,2,D);
	printf("\n\n Vetor resultante da multiplicacao vetor x * matriz E \n");
	mat_multv(2,5, E, x, XE);
	printf("%g\n%g\n\n", XE[0], XE[1]);
	mat_libera(3, A);
	mat_libera(3, B);
	mat_libera(3, C);
	mat_libera(3, D);
	return 0;
}
Пример #5
0
int main(){
    
    double *x,*b, *bbarra;
    int n =100, i, tol =5;
    Matriz*** A, ***M, ***N;

    for(n=100; n<=10000;n=n*10){
        A = mat_esparsa(n);
        x = (double*) calloc(n+IDX,sizeof(double));
        b = (double*) calloc(n+IDX,sizeof(double));
        bbarra = (double*) calloc(n+IDX,sizeof(double));
    
        //Vetor solução
        for(int i =IDX; i< n+IDX; i++)
            x[i]=1;
        
        // Calculo do vetor b correto obtido atraves de Ax = b
        mat_multv(n,A,x,b);


        /*****SEM PRECOND*****/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;

        printf("\n\tMetodo gradiente Conjugado com pre condicionador de Sem PreCond , n= %d \n",n );
        i = ConjugateGradient(n, A, b, x,tol);
        printf("\n\ti = %d \t\n",i );




        /******Jacobi*********/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                // Matriz pre condicionador de Jacobi  
                M = JacobiPC(A, n);
                //Minv Ax = Minv b/
                N = mat_cria(n,n);
                mat_multm(n,M,A,N);
                mat_multv(n, M, b, bbarra);
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de Jacobi , n= %d \n",n );


                // Metodo gradiente Conjugado com pre condicionador de Jacobi , n= 1000
                i = ConjugateGradient(n, N, bbarra, x,tol);
                printf("\n\ti = %d \t\n",i );


                mat_libera(n,M);
                mat_libera(n,N);



        /******Gaus Seidel****/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de GaussSeidel , n= %d \n",n );
                
                M = pre_cond(A,n,1);

                i = ConjugateGradientPC(n, A, M, b, x, tol);
                printf("\n\ti = %d \t\n",i );

                mat_libera(n,M);


        /*****  SSOR  *********/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;
        
        printf("\n\tMetodo gradiente Conjugado com pre condicionador de SSOR , n= %d \n",n );
        
        M = pre_cond(A,n,1.5);

        i = ConjugateGradientPC(n, A, M, b, x, tol);
        printf("\n\ti = %d \t\n",i );

        mat_libera(n,M);

            //=======Fim do Loop======//

        free(x);
        free(b);
        free(bbarra);
        mat_libera(n,A);
    }

    for(n=100; n<=10000;n=n*10){
        A = mat_esparsa_extend(n);
        x = (double*) calloc(n+IDX,sizeof(double));
        b = (double*) calloc(n+IDX,sizeof(double));
        bbarra = (double*) calloc(n+IDX,sizeof(double));
    
        //Vetor solução
        for(int i =IDX; i< n+IDX; i++)
            x[i]=1;
        
        // Calculo do vetor b correto obtido atraves de Ax = b
        mat_multv(n,A,x,b);


        /*****SEM PRECOND*****/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;

        printf("\n\tMetodo gradiente Conjugado com pre condicionador de Sem PreCond , n= %d \n",n );
        i = ConjugateGradient(n, A, b, x,tol);
        printf("\n\ti = %d \t\n",i );




        /******Jacobi*********/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                // Matriz pre condicionador de Jacobi  
                M = JacobiPC(A, n);
                //Minv Ax = Minv b/
                N = mat_cria(n,n);
                mat_multm(n,M,A,N);
                mat_multv(n, M, b, bbarra);
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de Jacobi , n= %d \n",n );


                // Metodo gradiente Conjugado com pre condicionador de Jacobi , n= 1000
                i = ConjugateGradient(n, N, bbarra, x,tol);
                printf("\n\ti = %d \t\n",i );


                mat_libera(n,M);
                mat_libera(n,N);



        /******Gaus Seidel****/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de GaussSeidel , n= %d \n",n );
                
                M = pre_cond(A,n,1);

                i = ConjugateGradientPC(n, A, M, b, x, tol);
                printf("\n\ti = %d \t\n",i );

                mat_libera(n,M);


        /*****  SSOR  *********/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;
        
        printf("\n\tMetodo gradiente Conjugado com pre condicionador de SSOR , n= %d \n",n );
        
        M = pre_cond(A,n,1.5);

        i = ConjugateGradientPC(n, A, M, b, x, tol);
        printf("\n\ti = %d \t\n",i );

        mat_libera(n,M);

            //=======Fim do Loop======//

        free(x);
        free(b);
        free(bbarra);
        mat_libera(n,A);
    }

}
Пример #6
0
int ConjugateGradientPC(int n, Matriz ***A,Matriz ***M, double *b, double *x, double tol){

    double * Rk, *Rk1, *Dk, *temp, *w;
    double Alfa, Beta,y;
    int i;

    Rk = (double*) calloc(n+IDX,sizeof(double));
    Rk1 = (double*) calloc(n+IDX,sizeof(double));
    Dk = (double*) calloc(n+IDX,sizeof(double));
    temp = (double*) calloc(n+IDX,sizeof(double));
    w = (double*) calloc(n+IDX,sizeof(double));

    //R0= b - Ax;
    mat_multv(n,A,x,temp); mat_sumV(n, -1, b, temp,Rk);

    //D0 = M_inv * R0 ou M*D0 = R0
    ConjugateGradient(n,M,Rk,Dk,tol+1);

    ///Para a 1a vez o y eh diferente, muda o calculo de alpha
    y = mat_escalar_vu(n,Rk,Dk);

    // For K= 0...n-1
    for (i = IDX; i < n+IDX; ++i){
        
       // puts("A1");
        // if (Rk = 0) stop
        if(mat_modulo(n, Rk) < 0.5*pow(10,-tol)) break; 
       // puts("A2");
        // Alfa = RkT*(Dk ou W) / DkT * A *Dk
        mat_multv(n,A,Dk,temp); Alfa = y/ mat_escalar_vu(n,temp,Dk);

        // Xk1 = Xk + Alfa*Dk
        mat_sumV(n,Alfa,x,Dk,x);

        //Rk1 = Rk - Alfa * A* Dk ;; Obs: temp já contém A*Dk
        mat_sumV(n, -1*Alfa,Rk,temp,Rk1);

        ////w = M_inv * R0 ou M*w = R0
        ConjugateGradient(n,M,Rk,w,tol+1);
        
        ///
        y = mat_escalar_vu(n,Rk1,w);

        //Beta = Rk1T * w / RkT * Rk
        Beta = y / mat_escalar_vu(n,Rk,Rk);

        //Dk1 = w + Beta*Dk
        mat_sumV(n,Beta,w,Dk,Dk);

        //Atualiza o Rk
        copiaV(n,Rk,Rk1);

    }

    free(Rk);
    free(Rk1);
    free(Dk);
    free(temp);
    free(w);
    return i-IDX;

}