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; }
void dj(double val[],int col[],int rowp[],double f[],double ui[], double us[], double u[]) { int n = N; // Size of matrix // Jacobi Parameter double omega = 2.0/3.0; // Stoping Parameters double rm[n],rnorm=0.0,rnorm_min=1e-6; // Residual double em[n],enorm=0.0,enorm_min=0.0; // Error // double e1m[n],e1norm=0.0,e1norm_min=0.0; // um+1 - um = wD^-1(rm); int itr=0, itr_max = 10000; // No. of iterations performed int i=0; //char s2; multi(val,col,rowp,ui,rm); // rm = au - multiply A and ui for (i=0;i<n;i++){ rm[i]=f[i]-rm[i]; em[i]=us[i]-u[i]; // e1m[i]=(omega/val[0])*(rm[i]); u[i]=ui[i]; // Initilizing u, just in case for redundant u } rnorm = linfnorm(rm); enorm = linfnorm(em); // e1norm = linfnorm(e1m); // Computations involved in iterations while (itr<=itr_max && rnorm>=rnorm_min && enorm>=enorm_min){ // e1norm>=e1norm_min for(i=1;i<n-1;i++){ u[i] = u[i] + (omega/val[2])*rm[i]; // val[0] for aii } u[0] = u[0] + (omega)*rm[0]; u[n-1] = u[n-1] + (omega)*rm[n-1]; multi(val,col,rowp,u,rm); // rm = au - multiply a and u-new for (i=0;i<n;i++) { em[i]=us[i]-u[i]; rm[i]=f[i]-rm[i]; // e1m[i]=(omega/val[0])*(rm[i]); } rnorm = linfnorm(rm); enorm = linfnorm(em); // e1norm = linfnorm(e1m); itr++; } // printf("No. of Iteration: %d\n",itr-1); // printf("Residual rm: %lf\n",rnorm); // printf("Error em: %lf\n",enorm); // printf("Improvement in last iteration: %lf\n",e1norm); }
double linfnorm(int mpi_rank, std::vector<double>& v1, std::vector<double>& v2) { if (v1.size() != v2.size()) { std::cout << "Error! in linfnorm(...): vectors are not same length. assuming 0's for missing elements" << std::endl; //exit(EXIT_FAILURE); } return linfnorm(mpi_rank, v1, v2, 0, v1.size()); }
double linfnorm(int mpi_rank, std::vector<double>& v1, std::vector<double>& v2, int n1, int n2) { double global_val = 0; // reuse the local norms from norms.h double local_val = linfnorm(v1, v2, n1, n2); // Get max of max (will bcast norm to all ranks) NORM_REDUCE(&local_val, &global_val, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); return global_val; }
double linfnorm(int mpi_rank, std::vector<double>& v1, int n1, int n2) { double global_val = 0; double local_val = linfnorm(v1, n1, n2); NORM_REDUCE(&local_val, &global_val, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); return global_val; }
double linfnorm(int mpi_rank, std::vector<double>& v1) { return linfnorm(mpi_rank, v1, 0, v1.size()); }