示例#1
0
int EVqr(MAT &A,double tol,int maxiter){
    int iter = 0 ;
    MAT T(A);
    MAT R(A.dim()), Q(A.dim());
    //since we are not able to access column of a matrix easily, so we access row of matrices as substitute.
    
    do{
	//QR decomposition
	QRDecomp(T,Q,R);	
	T = R * Q;
	
	iter++;
	
    }while(  (iter < maxiter) && (QRerror(T) > tol)  );
    
    
    printf("Largest 3 eigenvalues: ");
    for (int i = 0; i < 3; i++)
	printf(" %lf;",T[i][i]);
    printf("\nSmallest 3 eigenvalues: ");
    for (int i = A.dim()-1; i > A.dim()-4; i--)
	printf(" %lf;",T[i][i]);
    //printf("\niter %d\nerror: %E\n",iter,QRerror(A_k));
    return iter;

}
示例#2
0
double invPowerShift(MAT &A, double omega, VEC q, int maxIter){
    int k = 1;
    //I: identity matrix; LU: LU in-place; 
    MAT I(A.dim()), LU(A.dim()), shiftedA(A.dim());
    //q: 
    VEC z(A.dim()), temp(A.dim()),r(A.dim()), u(A.dim()), w(A.dim());
	
    
    double lambdaN= 100.0, newlambdaN=0.0, tol = 1.0;
    //Form identity matrix
    for (int i =0; i < A.dim(); i++){
	I[i][i] = 1;
    }
    shiftedA = A-(omega*I);
    LU = luFact(shiftedA);       //LU in-place decomposition
    
    while( (k < maxIter) && tol >= 0.000000001 ){
			
		temp = fwdSubs(LU,q);   //forward substitution
		z = bckSubs(LU,temp);//backward substitution
		q = z/l2norm(z);
		lambdaN = q * A * q;
		r = A * q - lambdaN * q;
		u = q * A;
		w = u/l2norm(u);
		tol = l2norm(r)/std::abs(w*q);

    }
    //printf("Iteration: %d\n",k);
    return lambdaN;
}
示例#3
0
VEC fwdSubs(MAT &m1, VEC b) {
        VEC y(b);
        for(int i = 0 ; i < m1.dim() ; i++) y[i] = b[i];
        for(int i = 0 ; i < m1.dim() ; i++){
		
                for(int j = i+1 ; j<m1.dim() ; j++){
                        y[j] -= m1[j][i] * y[i];
                }
        }
        return y;
}
示例#4
0
VEC fwdSubs(MAT &m1,VEC b)//fwdSubs must be modified from the one used by LU Decomposition
{
    VEC y = b;
    //y[0]=b[0]/m1[0][0];
    for(int i=0; i<m1.dim();i++){
      //y[i]/=m1[i][i];//Add this step for modification about Cholesky method
		for(int j=i+1; j<m1.dim(); j++)
			y[j] -= m1[j][i]*y[i];
    }
    return y;
}
示例#5
0
VEC bckSubs(MAT &m1,VEC y){
        VEC x(y);
        for(int i = 0 ; i < m1.dim() ; i++) x[i] = y[i];
        for(int i = m1.dim()-1 ; i >= 0 ; i--){
                x[i] /= m1[i][i];
                for(int j = i-1 ; j >= 0 ; j--){
                        x[j] -= m1[j][i] *x[i];
                }
        }
        return x;
}
示例#6
0
VEC fwdSubs1(MAT &m1, VEC b) {
        VEC y(b);
        for(int i = 0 ; i < m1.dim() ; i++) y[i] = b[i];
        for(int i = 0 ; i < m1.dim() ; i++){
		y[i] /= m1[i][i];		//because the diagonal elements are not 1's, modify by adding this line
                for(int j = i+1 ; j<m1.dim() ; j++){
                        y[j] -= m1[j][i] * y[i];
                }
        }
        return y;
}
示例#7
0
VEC operator*(VEC &v1,MAT &m1)
{
	VEC v2(m1.n);
	for(int i = 0; i <m1.dim();i++){
		v2[i]=0;
		for(int j = 0; j<m1.dim();j++){
			v2[i]+=v1[j]*m1[j][i];
		}
	}
	return v2;
}
示例#8
0
double ConvErr(MAT A){		//find the maximum among the elements just below the diagonal 
	double error = 0;
	for(int i=1;i<A.dim();i++){
		error = max(error,fabs(A[i][i-1]));
	}
	return error;
}
示例#9
0
double invpower(MAT A,VEC q,int maxiter,double eps,double &v,int aw){
        double tol = 1+eps;
        int k=0;
        int n=A.dim();
        VEC y(n);
        VEC z(n);
        VEC r(n);
        VEC Aq(n);
        VEC u(n);
        VEC w(n);
        MAT A1(n);
        MAT S(n);
        for(int i=0;i<n;i++){
        	S[i][i] = aw;			//define the shifting matrix
        }
        A1 = A-S;
        luFact(A1);					//use LU to solve the equation
        while((tol>=eps) && (k<=maxiter)){
            k = k+1;
            y = fwdSubs(A1,q);		//forward subsitution
            z = bckSubs(A1,y);		//backward substitution
            q = z/norm2(z);
            Aq = A*q;
            v = q*Aq;
            r = Aq - v*q;
            u = Aq;
            w = u/norm2(u);
            tol = norm2(r)/fabs(q*w);
        }
        printf("accuracy of lambda min = %e\n",norm2(r));
        return k;
}
示例#10
0
double power(MAT A,VEC q,int maxiter,double eps,double &v){
        double tol = 1 + eps;
        int k = 0;
        int n = A.dim();
        VEC z(n);
        VEC r(n);
        VEC Aq(n);
        VEC u(n);
        VEC w(n);
        while((tol>=eps) && (k<=maxiter)){

                Aq = A*q;
                k = k+1;
                q = Aq/norm2(Aq);
                Aq = A*q;
                v = q*Aq;
                r = Aq-v*q;
                u = Aq;
                w = u/norm2(u);
                tol = norm2(r)/fabs(q*w);

        }
        printf("accuracy of lambda max = %e\n",norm2(r));		//set 2-norm error of residue as accuracy term
        return k;
}
示例#11
0
// A = Q * R  QR Decomposition
void QRDecomp(MAT &A,MAT &Q, MAT &R){
    int n=A.dim();
    MAT AT(A.tpose());
    MAT QT(Q.tpose());
    VEC S(n);			//sum vector
    R[0][0]=sqrt(AT[0]*AT[0]);	//initial R
    QT[0]=AT[0]/R[0][0];		//initial Q

    for(int j=1;j<n;j++){
    	for(int i=0;i<n;i++){
            S[i] = 0;
        }       //initialization of sum vector
        for(int i=0;i<=j;i++){
          	R[i][j] = QT[i]*AT[j];
        } 
        for(int i=0;i<=j-1;i++){ 
          	S = S + R[i][j]*QT[i];		//do the summation
        }
        S = AT[j] - S;  
        R[j][j]=sqrt(S*S);
        QT[j] = S/R[j][j];
    }
    Q=QT.tpose(); 
        
}
示例#12
0
int EVqrShifted(MAT &A,double mu, double tol,int maxiter){
	int n=A.dim();
    int k=0;
    double err=10;
    MAT Q(n),R(n),T(A); 
    while(err>tol && k<maxiter){
    	for(int i=0;i<n;i++){		//subtract mu*I before QR factorization
    			T[i][i] = T[i][i] - mu;
    	}
        QRDecomp(T,Q,R);  			//QR factorization
        T=R*Q;						//matrix multiplication
        for(int i=0;i<n;i++){		//add mu*I back
    			T[i][i] = T[i][i] + mu;
    	}
        err = ConvErr(T);
        k++;
    }
        
    printf("the three largest EV:\n");
	printf("%lf %lf %lf\n",T[0][0],T[1][1],T[2][2]);
	printf("the three smallest EV:\n");
	printf("%lf %lf %lf\n",T[n-1][n-1],T[n-2][n-2],T[n-3][n-3]);
	printf("iter = %d\n",k);
	printf("error = %e\n",err);
    A=T;
    return k;
}
示例#13
0
double invPowerShift(MAT &A, double omega, VEC q, int maxIter){
    int k = 1;
    //I: identity matrix; LU: LU in-place; iLU: LU in-place for invA; invA: inverse of A
    MAT I(A.dim()), LU(A.dim()),iLU(A.dim()), invA = inverse(A), shiftedA(A.dim());
    //q: 
    VEC z(A.dim()), temp(A.dim());// q(A.dim()),iq(A.dim()), iz(A.dim()), 
    
    double lambdaN= 100.0, newlambdaN=0.0;
    //Form identity matrix
    for (int i =0; i < A.dim(); i++){
	I[i][i] = 1;
    }
    shiftedA = A-(omega*I);
    LU = luFact(shiftedA);       //LU in-place decomposition
    //iLU = luFact(invA-(w*I));       //LU in-place decomposition
    while( (k < maxIter) && (std::abs(newlambdaN - lambdaN) >= 10E-9) ){
		lambdaN = newlambdaN;	
		temp = fwdSubs(LU,q);   //forward substitution
		z = bckSubs(LU,temp);//backward substitution
		q = z/l2norm(z);
		newlambdaN = q * A * q;
/*
	temp = fwdSubs(iLU,iq);   //forward substitution
	iz = bckSubs(iLU,temp);//backward substitution
	iq = iz / l2norm(iz);
	imu = iq * invA * iq;

	//newCond = mu/imu;	
	*/
    }
    printf("Iteration: %d\n",k);
    return newlambdaN;
}
示例#14
0
double powerMethod(MAT &A, VEC q, int maxIter){
	VEC z(A.dim()), r(A.dim()), u(A.dim()), w(A.dim());
	MAT A_k(A.dim());
	double lambda1, tol= 1.0;
	//double new_lambda
	int iter = 0;
	
	while( (iter < maxIter) && (tol >= 0.000000001) ){
		z = A * q;
		iter++;
		q = z/l2norm(z);
		lambda1 = q * A * q;
		r = A * q - lambda1 * q;
		u = q * A;
		w = u/l2norm(u);
		tol = l2norm(r)/std::abs(w*q);	
	}
	return lambda1;
}
示例#15
0
VEC bckSubs(MAT &m1,VEC b)//b as y
{
    int i,j,k;
    VEC x=b;
    for(i=m1.dim()-1 ;i>=0 ;i--){
		x[i] /= m1[i][i];
		for(j=i-1; j>=0; j--)
			x[j] -= m1[j][i] * x[i];
    }
    return x;
}
示例#16
0
double invPowerShift(MAT &A, double omega, VEC q, int maxIter){
    int k = 1;
    //I: identity matrix; LU: LU in-place; 
    MAT I(A.dim()), LU(A.dim()), shiftedA(A.dim());
    //q: 
    VEC z(A.dim()), temp(A.dim());// q(A.dim())
    
    double lambdaN = 100.0, newlambdaN=0.0;
    //Form identity matrix
    for (int i =0; i < A.dim(); i++){
	I[i][i] = 1;
    }
    shiftedA = A-(omega*I);
    LU = luFact(shiftedA);       //LU in-place decomposition
    
    while( (k < maxIter) && (std::abs(newlambdaN - lambdaN) >= 0.000000001) ){
		lambdaN = newlambdaN;	
		temp = fwdSubs(LU,q);   //forward substitution
		z = bckSubs(LU,temp);//backward substitution
		q = z/l2norm(z);
		newlambdaN = q * A * q;

    }
    printf("Iteration: %d\n",k);
    return newlambdaN;
}
示例#17
0
int gaussSeidel(MAT &A,VEC b,VEC &x,int maxIter,double tol)
{
    int k = 0;
    double theta=0.0;
    VEC newx(A.dim()),ans(A.dim()),temp(A.dim());
    MAT LU(A.dim()),a = A;

    LU = luFact(a);       //LU in-place decomposition
    temp=fwdSubs(LU,b);   //forward substitution
    ans= bckSubs(LU,temp);//backward substitution
   
    while( k < maxIter)
    {
		x = newx;
		for(int i=0; i< A.dim(); i++)
		{
			theta = 0.0;
			for(int j=0; j < A.dim();j++){
				if(i!=j){
					theta += (A[i][j]*newx[j]);
				}
			}
			newx[i]= (b[i]-theta)/A[i][i];
		}
		k++;        
		if (linfnorm(newx - x) < tol)
			break;
    }
    printf("Diffrence w.r.t. hw4: %E\n",linfnorm(newx-ans));
    
    return k;
}
示例#18
0
int cg(MAT &A,VEC b,VEC &x,int maxIter, double tol)
{	
	//A_p: A * p
	VEC  A_p(A.dim());
    int node = std::sqrt(A.dim());
    //p: search direction; 
    VEC p(A.dim()), r(A.dim()), newr(A.dim()), newx(A.dim());//,ans(A.dim()),temp(A.dim());
    //MAT LU(A.dim()),a = A;
    //r2: rT * r
    double alpha, beta, r2, newr2, err;//,g;
    //g = (double)(node-1)/2000.0;
    int iter = 0;//
    /*
    LU = luFact(a);       //LU in-place decomposition
    temp=fwdSubs(LU,b);   //forward substitution
    ans= bckSubs(LU,temp);//backward substitution
    */

    
    //Initial condition for CGM
    p = r = b - (A * x);
    r2 = r * r;
   
    while(iter < maxIter)
    {
	A_p = A * p;
	alpha = r2 / (p * A_p);
	newx = x + (alpha * p);
	err = std::sqrt(r2/A.dim());
	if ( err < tol )
            break;

	newr = r - (alpha * A_p);
	newr2 = newr * newr;
	beta = newr2 / r2;
	p = newr + beta * p;


	//Re-initialization for next iteration
	x = newx;
	r = newr;
	r2 = newr2;
	//////////////////////////////////////
	iter++;		
    }
    //printf("cg:Vne: %lf; Vsw: %lf; Vse: %lf; R:%lf\n",newx[node-1],newx[(node-1)*node],newx[node*node-1], std::abs( 1/(g*(newx[0]-newx[1])+g*(newx[0]-newx[node] )) ) );
    //printf("LU:Vne: %lf; Vsw: %lf; Vse: %lf; R:%lf\n",ans[node-1],ans[(node-1)*node],ans[node*node-1], std::abs( 1/(g*(ans[0]-ans[1])+g*(ans[0]-ans[node] )) )  );
    //printf("Difference w.r.t. hw4: %E\n",linfnorm(ans - newx));
    return iter;
}
示例#19
0
int cg(MAT &A,VEC b,VEC &x,int maxIter,double tol){
	int n = A.dim();
	int k = 0;
	VEC x_next(n);
	VEC r_next(n);
	VEC p_next(n);
	VEC r(n);
	VEC p(n);
	MAT L(n);
    VEC cpr(n);
	double alpha,beta;
	double err;
	double diff;
	r = b - A*x;					//initial condition
	p = r;
	while(k<maxIter){				//conjugate gradient decent
		alpha = (r*r)/(p*(A*p));
		x_next = x + alpha*p;
		r_next = r - alpha*(A*p);
		beta = (r_next*r_next)/(r*r);
		p_next = r_next + beta*p;
		k++;
		x = x_next;					//assign to the x,r,p of the next iteration 
		r = r_next;
		p = p_next;
		err = pow((r*r)/n,0.5);
		if(err<tol)					//see if the error is smaller than the defined tolerance. if so, break out of the loop 
			break;
	}
        diff = 0;
        //the answer from hw4

        L = cholesky(A);                        //in-place Cholesky Decomposition
        cpr = choSolve(L,b);                      //solve the linear system by forward and backward substitution
        //use the same method to compute the error between hw4 and hw5, see if < 10^-7. if not, decrease the tol
        for(int i=0;i<n;i++){
                diff = max(diff,fabs(x[i]-cpr[i]));		//use infinity norm to compute the error
        }
        printf("error between hw4 and hw6(infinity-norm): %e\n",diff);

	return k;	
}
示例#20
0
int EVqr(MAT &A,double tol,int maxiter){
    int n=A.dim();
    int k=0;
    double err=10;
    MAT Q(n),R(n),T(A); 
    while(err>tol && k<maxiter){
        QRDecomp(T,Q,R);  			//QR factorization
        T=R*Q;						//matrix multiplication
        err = ConvErr(T);			//get the error term in each iteration
        k++;
    }
        
    printf("the three largest EV:\n");
	printf("%lf %lf %lf\n",T[0][0],T[1][1],T[2][2]);
	printf("the three smallest EV:\n");
	printf("%lf %lf %lf\n",T[n-1][n-1],T[n-2][n-2],T[n-3][n-3]);
	printf("iter = %d\n",k);
	printf("error = %e\n",err);
    A=T;
    return k;
}
示例#21
0
int EVqrShifted(MAT &A,double mu,double tol,int maxiter){
    int iter = 0 ;
    MAT T(A);
    MAT R(A.dim()), Q(A.dim()),muI(A.dim());
    
    //since we are not able to access column of a matrix easily, so we access row of matrices as substitute.
    for (int i =0 ; i < A.dim(); i++)
		muI[i][i] = mu;

    do{
	for(int i=0;i<A.dim();i++){           //subtract mu*I before QR factorization
		T[i][i] = T[i][i] - mu;
	}
	
	//QR decomposition
	QRDecomp(T,Q,R);	
	T = R * Q;
	//QR decomposition ends		
	for(int i=0;i<A.dim();i++){           //add mu*I back
		T[i][i] = T[i][i] + mu;
    }

	iter++;	
	
    }while(  (iter < maxiter) && (QRerror(T) > tol)  );
        
    printf("Largest 3 eigenvalues: ");
    for (int i = 0; i < 3; i++)
	printf(" %lf;",T[i][i]);
    printf("\nSmallest 3 eigenvalues: ");
    for (int i = A.dim()-1; i > A.dim()-4; i--)
	printf(" %lf;",T[i][i]);
    //printf("\niter %d\nerror: %E\n",iter,QRerror(A_k));
    return iter;

}
示例#22
0
VEC choSolve(MAT &L,VEC b)
{
    VEC x(b);

	//forward substitutions
	for (int i=0; i<x.len(); i++)
	{	
		x[i] /= L[i][i];
		for (int j=i+1; j<L.dim(); j++)
			x[j] -= L[j][i]*x[i];
		
	}
	
	//backward substitutions
	for (int i=(x.len()-1); i>=0; i--)
	{
		x[i] /= L[i][i];
		for (int j=i-1; j>=0; j--)
			x[j] -= L[i][j]*x[i];
	}	

	return x;
} 
示例#23
0
MAT inverse(MAT &A)
{
    VEC temp(A.dim());
    // I: identity matrix; inv: inverse of A; LU: LU in-place
    MAT LU(A.dim()), a = A, I(A.dim()), inv(A.dim());
    LU = luFact(a);       //LU in-place decomposition
    // Form identity matrix
    for (int i =0; i < A.dim(); i++){
	I[i][i] = 1;
    }
    // solve inverse of A. Answer is stored row by row
    for (int i = 0; i< A.dim(); i++){	
	temp=fwdSubs(LU,I[i]);   //forward substitution
	inv[i]= bckSubs(LU,temp);//backward substitution
    }
    // we need the result of inverse() column by column, so return transpose matrix of inv
    return inv.tpose();
}
示例#24
0
double QRerror(MAT &A){
    double max = std::abs(A[1][0]);
    for (int i = 2; i< A.dim(); i++)
	max = std::max(std::abs(A[i][i-1]),max);
    return max;
}
示例#25
0
int jacobi(MAT &A,VEC b,VEC &x, int maxIter, double tol){
	int n = A.dim();
	VEC S(n);			//summation vector
	VEC G(n);			//diagonal of A
	VEC tmp(n);			//save the x before iterative method
	MAT L(n);			
	VEC cpr(n);			//the result of hw4
	//iterative
	int k=0;
	double err1;
	double err2;
	double errinf;
	double diff1,diff2,diffinf;
	while(k<maxIter){
		for(int i=0;i<n;i++){
			S[i] = 0;		//initialize the sum vector to 0
		}
		for(int i=0;i<n;i++){
			G[i] = A[i][i];		
			//save the previous vector x to tmp(for comparison between iteration k and k+1)
			tmp[i] = x[i]; 
			for(int j=0;j<n;j++){
				if(j!=i){
					S[i] = S[i] + A[i][j]*x[j];	//sum the Aij*xj, where i is not equal to j
				}
			}
		}
		for(int i=0;i<n;i++){
			x[i] = (1/G[i])*(b[i]-S[i]);		//compute the new solution of x at iteration k
		}
		k++;						//after each iteration, k=k+1
		err1 = 0;	//1-norm
		err2 = 0;	//2-norm
		errinf = 0;	//infinity-norm
		
		
		for(int i=0;i<n;i++){
			err1 += fabs(x[i] - tmp[i]);		//sum of absolute error
			err2 += pow(x[i] - tmp[i], 2);		//sum of square error
			errinf = max(errinf,fabs(x[i]-tmp[i]));	//take the maximum absolute difference as error
		}						//max(a,b) defined on the top
		err2 = pow(err2,0.5);				//find the square root of err2 and get the 2-norm
//you can change err1 to err2 or errinf to get different number of iterations k based on which p-norm you preferred
        		
		if(err1<tol){
			break;
		}
	}
	diff1 = 0;
        diff2 = 0;
        diffinf = 0;
	//the answer from hw4

        L = cholesky(A);                        //in-place Cholesky Decomposition
        cpr = choSolve(L,b);                      //solve the linear system by forward and backward substitution
        //use the same method to compute the error between hw4 and hw5, see if < 10^-7. if not, decrease the tol
        for(int i=0;i<n;i++){
        	diff1 += fabs(x[i] - cpr[i]);
                diff2 += pow(x[i] - cpr[i], 2);
                diffinf = max(diffinf,fabs(x[i]-cpr[i]));
        }
        diff2 = pow(diff2,0.5);
        printf("error between hw4 and hw5(1-norm 2-norm infinity-norm): %e %e %e\n",diff1,diff2,diffinf);
	return k;
}
示例#26
0
int gaussSeidel(MAT &A,VEC b,VEC &x,int maxIter,double tol)
{
	int n = A.dim();
	VEC S(n);
	VEC G(n);
	VEC tmp(n);
	MAT L(n);
	VEC cpr(n);
	//iterative
	int k=0;
	double err1;
	double err2;
	double errinf;
	double diff1,diff2,diffinf;
	while(k<maxIter){
		for(int i=0;i<n;i++){
			S[i] = 0;
		}
		for(int i=0;i<n;i++){
			G[i] = A[i][i];
			tmp[i] = x[i];
			for(int j=0;j<n;j++){
				if(j!=i){
					S[i] = S[i] + A[i][j]*x[j];
				}
			}
			x[i] = (1/G[i])*(b[i]-S[i]);	
		//both x[i] and S[i] are computed in the same for loop, so some updated values are used in the current iteration
		}
		k++;
		err1 = 0;
		err2 = 0;
		errinf = 0;
		for(int i=0;i<n;i++){
			err1 += fabs(x[i] - tmp[i]);
			err2 += pow(x[i] - tmp[i], 2);
			errinf = max(errinf,fabs(x[i]-tmp[i]));
		}
		err2 = pow(err2,0.5);
	
		if(err1<tol){
			break;
		}
	}
	diff1 = 0;
        diff2 = 0;
        diffinf = 0;
	//the answer from hw4

        L = cholesky(A);                        //in-place Cholesky Decomposition
        cpr = choSolve(L,b);                      //solve the linear system by forward and backward substitution
        //use the same method to compute the error between hw4 and hw5, see if < 10^-7. if not, decrease the tol
        for(int i=0;i<n;i++){
        	diff1 += fabs(x[i] - cpr[i]);
                diff2 += pow(x[i] - cpr[i], 2);
                diffinf = max(diffinf,fabs(x[i]-cpr[i]));
        }
        diff2 = pow(diff2,0.5);
        printf("error between hw4 and hw5(1-norm 2-norm infinity-norm): %e %e %e\n",diff1,diff2,diffinf);

	return k;	
}
示例#27
0
int sgs(MAT &A,VEC b,VEC &x,int maxIter,double tol)
{
        int n = A.dim();
        VEC S(n);
        VEC G(n);
        VEC tmp(n);
	MAT L(n);
	VEC cpr(n);
        //iterative
        int k=0;
        double err1;
        double err2;
        double errinf;
	double diff1,diff2,diffinf;
        while(k<maxIter){
                for(int i=0;i<n;i++){
                        S[i] = 0;
                }
		//forward gauss-seidel 
		//compute vector x from x[0] to x[n-1]
                for(int i=0;i<n;i++){
                        G[i] = A[i][i];
                        tmp[i] = x[i];
                        for(int j=0;j<n;j++){
                                if(j!=i){
                                        S[i] = S[i] + A[i][j]*x[j];
                                }
                        }
                        x[i] = (1/G[i])*(b[i]-S[i]);
              	}
		//backward gauss-seidel
		//use the reslults of forward gauss-seidel to compute vector x
		//direction : from x[n-1] to x[0]
		for(int i=0;i<n;i++){
                        S[i] = 0;	//we also need to initialize the sum vector.
                }
		for(int i=n-1;i>=0;i--){
                        for(int j=n-1;j>=0;j--){
                                if(j!=i){
                                        S[i] = S[i] + A[i][j]*x[j];
                                }
                        }
                        x[i] = (1/G[i])*(b[i]-S[i]);
                }
                k++;
                err1 = 0;
                err2 = 0;
                errinf = 0;
                for(int i=0;i<n;i++){
                        err1 += fabs(x[i] - tmp[i]);
                        err2 += pow(x[i] - tmp[i], 2);
                        errinf = max(errinf,fabs(x[i]-tmp[i]));
                }
                err2 = pow(err2,0.5);
               
		if(err1<tol){
			break;
		}

	}
	diff1 = 0;
        diff2 = 0;
        diffinf = 0;
	//the answer from hw4

        L = cholesky(A);                        //in-place Cholesky Decomposition
        cpr = choSolve(L,b);                      //solve the linear system by forward and backward substitution
        //use the same method to compute the error between hw4 and hw5, see if < 10^-7. if not, decrease the tol
        for(int i=0;i<n;i++){
        	diff1 += fabs(x[i] - cpr[i]);
                diff2 += pow(x[i] - cpr[i], 2);
                diffinf = max(diffinf,fabs(x[i]-cpr[i]));
        }
        diff2 = pow(diff2,0.5);
        printf("error between hw4 and hw5(1-norm 2-norm infinity-norm): %e %e %e\n",diff1,diff2,diffinf);
        return k;
}