MatrixCSR<T>::MatrixCSR(const MatrixNxN<T> &matrix) { int entries = matrix.m_iN * matrix.m_iN; entries = entries - matrix.NumZeros(); m_dValues = new T[entries]; m_iColInd = new int[entries]; m_iRowPtr = new int[matrix.m_iN+1]; m_iN = matrix.m_iN; m_iNumVal = entries; int index = 0; m_iRowPtr[0] = 0; //for every row for(int i=0;i<matrix.m_iN;i++) { int EntriesInRow = 0; //iterate through the columns of the row for(int j=0;j<matrix.m_iN;j++) { if(matrix(i,j)!=0.0) { m_dValues[index] = matrix(i,j); m_iColInd[index] = j; index++; EntriesInRow++; } } m_iRowPtr[i+1]=m_iRowPtr[i]+EntriesInRow; } }
void CLinearSolverLU<T>::SolveForwardBackward(MatrixNxN<T>& A, VectorN<T>& b, VectorN<T>& x, int iperm[]) { int i,j,k,n; n=A.rows(); for(i=0;i<n;i++) { j = iperm[i]; x(i)=b(j); } for(i=1;i<n;i++) { T sum=0.0; for(k=0;k<i;k++) sum+=A(i,k)*x(k); x(i)=(x(i)-sum); } //x(n-1) is already done, because of: x(n-1)=x(n-1)/A(n-1,n-1); for(i=n-2;i>=0;i--) { T sum = 0.0; for(k=i+1;k<n;k++) sum += A(i,k)*x(k); x(i)=(x(i)-sum)/A(i,i); } x.OutputVector(); }
void CLinearSolverLU<T>::Linsolve(MatrixNxN<T> &A, VectorN<T> &b, VectorN<T> &x) { T sum=0; int i,j,k,n,p; n=A.rows(); int *iperm = new int[n]; for(i=0;i<n;i++)iperm[i]=i; for(j=0;j<=n-1;j++) { //partial pivoting p=j; //check for largest |a_ij| as pivot for(i=j+1;i<n;i++) { if(fabs(A(i,j)) > fabs(A(j,j))) { //swap rows if we find a bigger element A.SwapRows(j,i); T temp = b(j); b(j)=b(i); b(i)=temp; } } //check if there are only zero pivots while((A(p,j)==0.0) && (p<n)) { p++; } if(p==n) { std::cout<<"No solution exists..."<<std::endl; return; } else { if(p !=j ) { A.SwapRows(j,p); T temp = b(j); b(j)=b(p); b(p)=temp; } } //compute the betas : colums of U for(i=0;i<=j;i++) { sum=0.0; for(k=0;k<=i-1;k++) sum+=A(i,k)*A(k,j); //set the beta_ij A(i,j) = A(i,j) - sum; }//end i //compute the alphas colums of L for(i=j+1;i<=n-1;i++) { sum=0.0; for(k=0;k<=j-1;k++) { //sum up the alphas before the diagonal and the //betas above the diagonal sum+=A(i,k)*A(k,j); }//end k //set alpha(i,j) A(i,j) = (1.0/A(j,j))*(A(i,j) - sum); }//end for i }//end for j SolveForwardBackward(A,b,x,iperm); }
void CLinearSolverGauss<T>::Linsolve(MatrixNxN<T> &A, VectorN<T> &b, VectorN<T> &x) { int n = A.m_iN; int k=0; int p; for(;k<n-1;k++) { p=k; //check for largest |a_ij| as pivot for(int i=k+1;i<n;i++) { if(fabs(A(i,k)) > fabs(A(k,k))) { //swap rows if we find a bigger element A.SwapRows(k,i); T temp = b(k); b(k)=b(i); b(i)=temp; } } //check if there are only zero pivots while((A(p,k)==0.0) && (p<n)) { p++; } if(p==n) { std::cout<<"No solution exists..."<<std::endl; return; } else { if(p !=k ) { A.SwapRows(k,p); T temp = b(k); b(k)=b(p); b(p)=temp; } } for(int i=k+1;i<n;i++) { T p = A(i,k); T pivot = A(i,k)/A(k,k); //reduce the k+1-row for(int j=0;j<n;j++) A(i,j)=A(i,j) - pivot * A(k,j); //reduce the rhs b(i) = b(i) - pivot * b(k); }//end for i }//end for k if(A(n-1,n-1) == 0) { std::cout<<"No solution exists..."<<std::endl; return; } //backwards substitution for(int i=n-1;i>=0;i--) { T Sum = 0; x(i)=0; for(int j=i; j<=n-1;j++) { Sum += A(i,j) * x(j); } x(i)=(b(i)-Sum)/A(i,i); } }