Created
May 28, 2014 18:51
-
-
Save nootanghimire/22247eb7eb18317b2d08 to your computer and use it in GitHub Desktop.
Trying to create a Data Structure AugmentedMatrix and implement it as System of Lineqr Equations solving using Gauss-Elimination Method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* @Author : Nootan Ghimire <[email protected]> | |
* | |
* Algorithm | |
* | |
* Here I try to Write the Algorithm | |
* | |
* Step 01 : Start (Yeah) | |
* Step 02 : Get the Augmented Matrix | |
* Step 03 : Convert it to Lower Triangular | |
* Step 04 : Perform Backward Substitution, and store values of unknowns | |
* Step 05 : Stop | |
* | |
* Algorithm: Convert it to Lower Triangular | |
* | |
* Step 01 : Start | |
* Step 02 : Get Augmented Matrix. Actually get a vector and one matrix | |
* Step 03 : In Matrix only, Find the dimensions. It would be square matrix of dimension 'n x n' | |
* Step 04 : Using Row (i = 1 to (n-1)), Make (ith) element of Row (i+1 to n) Zero (See explaination below) | |
* Step 05 : Return the Matrix | |
* Step 06 : Stop | |
* | |
* Explaination -- | |
* Step 4a : Using Row 1, Make 1st element of Row 2->n Zero | |
* Step 4b : Using Row 2, Make 2nd Element of Row 3->n Zero | |
* | |
* | |
* Algorithm : Perform Backward Substituion | |
* | |
* Step 01 : Start | |
* Step 02 : Get to last row | |
* Step 04 : x[last] = vector(n)/matrix(n*n) | |
* | |
*/ | |
#include <iostream> | |
using namespace std; | |
template <typename T1> | |
class Vector{ | |
private: | |
T1 *vec; | |
int counter; | |
int size; | |
//initCode | |
void initVector(){ | |
size = 0; | |
counter = -1; | |
} | |
//Create a new array of size newSize and put all the old contents | |
//on the back | |
void cpArray(int newSize){ | |
T1 *newvec = new T1[newSize]; | |
for(int i=0; i<size; i++){ | |
newvec[i] = vec[i]; | |
} | |
delete[] vec; | |
vec = newvec; | |
/*vec = new T1[newSize]; | |
for (int i = 0; i < size; i++){ | |
vec[i] = newvec[i]; | |
} | |
delete[] newvec;*/ | |
} | |
public: | |
/* Constructors */ | |
Vector(){ | |
initVector(); | |
} | |
Vector(T1 val){ | |
//Call Default | |
initVector(); | |
vec = new T1[++size]; | |
vec[++counter]=val; | |
} | |
//Some little trick to know the size of the array (not pointer) | |
template <size_t N> | |
Vector(T1 (&arr)[N] ){ | |
//Call Default | |
initVector(); | |
vec = new T1[N]; | |
size = N; | |
for(int i = 0; i<N; i++){ | |
vec[i] = arr[i]; | |
counter++; | |
} | |
} | |
Vector(T1 *arr, size_t N){ | |
//Call Default | |
initVector(); | |
vec = new T1[N]; | |
size = N; | |
for(int i = 0; i<N; i++){ | |
vec[i] = arr[i]; | |
counter++; | |
} | |
} | |
/*Copy Constructor */ | |
Vector(Vector& v){ | |
initVector(); | |
vec = new T1[v.getSize()]; | |
size = v.getSize(); | |
for (int i = 0; i < v.getSize(); i++) { | |
vec[i] = v[i]; | |
counter++; | |
} | |
} | |
/* If you have Constructor, and Copy Constructor, make a habit of overloading | |
equal to (=) operator and destructor. | |
*/ | |
void operator=(Vector& v){ | |
initVector(); | |
vec = new T1[v.getSize()]; | |
size = v.getSize(); | |
for (int i = 0; i < v.getSize(); i++) { | |
vec[i] = v[i]; | |
counter++; | |
} | |
} | |
/* End Constructors */ | |
/* Destructor */ | |
~Vector(){ | |
delete[] vec; | |
} | |
/* Start public Methods */ | |
void add(T1 val){ | |
cpArray(++size); | |
vec[++counter]=val; | |
} | |
template <class typeOperation> | |
void doOperation(int on_elem, int resp_to_elem, typeOperation resp_to_coef){ | |
vec[on_elem] = (vec[on_elem]) + (resp_to_coef * vec[resp_to_elem]); | |
} | |
void debug_printAll(){ | |
//cout<<endl; | |
for (int i = 0; i < size; i++){ | |
cout<<vec[i]<<endl; | |
} | |
cout<<"Size: "<<size<<endl; | |
cout<<"Counter: "<<counter; | |
cout<<endl; | |
} | |
int getSize(){return size;} | |
/* Operator Overloading */ | |
T1& operator[](int index){ | |
return vec[index]; | |
} | |
}; | |
template <typename T_Matrix> | |
class Matrix{ | |
private: | |
T_Matrix *matx; | |
int rows; | |
int columns; | |
int current_row; | |
int current_column; | |
int initMatrix(int row, int column){ | |
rows = row; | |
columns = column; | |
current_row = current_column = 0; | |
matx = new T_Matrix[row*column]; | |
} | |
int getArrayIndex(int row, int column){ | |
return ((row-1)*columns + column)-1 ; | |
//Note columns is total columns and column is current column | |
//The Extra -1 is because. | |
} | |
public: | |
Matrix(int row=1, int column=1){ | |
initMatrix(row, column); | |
} | |
Matrix(Matrix& m ){ | |
initMatrix(m.getRow(), m.getCol()); | |
//Now copy | |
for (int i = 1; i <= m.getRow(); i++){ | |
for (int j = 1; j <= m.getCol(); j++) | |
{ | |
matx[getArrayIndex(i,j)]= m.getElem(i,j); | |
} | |
} | |
} | |
void operator=(Matrix& m){ | |
delete[] matx; //because it's already initiated | |
initMatrix(m.getRow(), m.getCol()); | |
//Now copy | |
for (int i = 1; i <= m.getRow(); i++){ | |
for (int j = 1; j <= m.getCol(); j++) | |
{ | |
matx[getArrayIndex(i,j)]= m.getElem(i,j); | |
} | |
} | |
} | |
~Matrix(){ | |
delete[] matx; | |
} | |
int getRow(){return rows;} | |
int getCol(){return columns;} | |
T_Matrix getElem(int row, int col){return matx[getArrayIndex(row, col)];} | |
void changeMatrixSize(int new_row, int new_col, bool ZERO_FLAG=false){ | |
//change matrix size | |
} | |
//Trick for size: Again only for arrays and no pointers | |
template <size_t N> | |
void setMatrixRow(int row, T_Matrix (&arr)[N]){ | |
for (int i = 1; i <= N; i++){ | |
matx[getArrayIndex(row, i)]=arr[i-1]; | |
} | |
} | |
void setMatrixRow(int row, T_Matrix* arr, size_t N){ | |
for (int i = 1; i <= N; i++){ | |
matx[getArrayIndex(row, i)]=arr[i-1]; | |
} | |
} | |
void doRowOperation(int row, int resp_to_row, T_Matrix coef_resp_to_row, bool showOp=false){ | |
if(showOp){ | |
cout<<"Doing Row Operation: "; | |
cout<<"R"<<row<<" = "<<"R"<<row<<" + ("<<coef_resp_to_row<<")R"<<resp_to_row<<endl; | |
} | |
//do everything for entire row | |
for(int i = 1; i<=columns; i++){ | |
matx[getArrayIndex(row,i)] = (matx[getArrayIndex(row,i)]) | |
+ (coef_resp_to_row * matx[getArrayIndex(resp_to_row,i)]); | |
} | |
} | |
void printMatrix(){ | |
for (int i = 1; i <= rows; i++){ | |
for (int j = 1; j <= columns; j++) | |
{ | |
cout<<matx[getArrayIndex(i,j)]<<" "; | |
} | |
cout<<"\n"; | |
} | |
cout<<endl<<"Rows: "<<rows<<" Columns: "<<columns<<endl; | |
} | |
}; | |
template <typename AugM_T> | |
class AugmentedMatrix{ | |
private: | |
Matrix<AugM_T>mat; | |
Vector<AugM_T>vec; | |
bool mat_set_flag; | |
bool vec_set_flag; | |
void initAugMat(){ | |
mat_set_flag = vec_set_flag = false; | |
} | |
public: | |
AugmentedMatrix(){ | |
initAugMat(); | |
} | |
AugmentedMatrix(AugmentedMatrix& AugM){ | |
mat = AugM.getMatrix(); | |
vec = AugM.getVector(); | |
mat_set_flag = vec_set_flag = true; | |
} | |
void operator=(AugmentedMatrix& AugM){ | |
mat = AugM.getMatrix(); | |
vec = AugM.getVector(); | |
mat_set_flag = vec_set_flag = true; | |
} | |
//TODO: Make Copy Constructor and (X) | |
//overload '=' operator so that | |
//the assignment will be easier. | |
void setMatrix(Matrix<AugM_T>m){ | |
mat = m; //We've already overloaded the = operator | |
mat_set_flag = true; | |
} | |
void setVector(Vector<AugM_T>v){ | |
vec = v; //Again, We've overloaded it too. | |
vec_set_flag = true; | |
} | |
Matrix<AugM_T>& getMatrix(){ | |
return mat; | |
} | |
Vector<AugM_T>& getVector(){ | |
return vec; | |
} | |
~AugmentedMatrix() {} | |
void doAugmentedOperation(int row, int resp_to_row, AugM_T coeff, bool ShowOp=false){ | |
mat.doRowOperation(row, resp_to_row, coeff, ShowOp); | |
vec.doOperation(row-1, resp_to_row-1, coeff); //Vector is zero-indexed | |
} | |
void displayAugmentedMatrix(){ | |
for(int i=1; i<=mat.getRow();i++){ | |
for (int j = 1; j<=mat.getCol(); j++){ | |
cout<<mat.getElem(i,j)<<"\t"; | |
} | |
cout<<":\t"<<vec[i-1]; | |
cout<<endl; | |
} | |
cout<<endl; | |
} | |
}; | |
/* | |
* Algorithm: Convert it to Lower Triangular | |
* | |
* Step 01 : Start | |
* Step 02 : Get Augmented Matrix. Actually get a vector and one matrix | |
* Step 03 : In Matrix only, Find the dimensions. It would be square matrix of dimension 'n x n' | |
* Step 04 : Using Row (i = 1 to (n-1)), Make (ith) element of Row (i+1 to n) Zero (See explaination below) | |
* Step 05 : Return the Matrix | |
* Step 06 : Stop | |
* | |
* Explaination -- | |
* Step 4a : Using Row 1, Make 1st element of Row 2->n Zero | |
* Step 4b : Using Row 2, Make 2nd Element of Row 3->n Zero | |
* | |
* | |
* Algorithm : Perform Backward Substituion | |
*/ | |
template <class T> | |
void makeUpperTriangular(AugmentedMatrix<T>& AugM, bool showSteps = false){ | |
//Since it would be a square matrix, We just take care with rows | |
int n = AugM.getMatrix().getRow(); | |
for(int i = 1; i<n; i++){ | |
for(int j = i+1; j<=n; j++){ | |
//find out how would you make [j,i] zero using [i,1] | |
T k = -(AugM.getMatrix().getElem(j,i)/AugM.getMatrix().getElem(i,i)); | |
AugM.doAugmentedOperation(j,i,k,showSteps); | |
} | |
if(showSteps){ | |
AugM.displayAugmentedMatrix(); | |
} | |
} | |
} | |
int main(){ | |
float* arr; | |
int n; | |
cout<<"Enter number of Equations: "; cin>>n; | |
arr = new float[n]; | |
//Enter Matrix | |
//Init Matrix first | |
cout<<"Enter Equation Matrix\n"; | |
Matrix<float>equationMatrix(n,n); | |
for (int i = 0; i < n; i++){ | |
cout<<"Enter Row "<<i+1<<" of (Matrix): \n"; | |
for (int j = 0; j < n; j++){ | |
cout<<"Column "<<j+1<<": "; cin>>arr[j]; | |
} | |
equationMatrix.setMatrixRow(i+1,arr, n); | |
} | |
//Matrix Set | |
//Set Vector | |
cout<<"Enter Result Vector\n"; | |
for (int i = 0; i < n; i++){ | |
cout<<i+1<<": "; cin>>arr[i]; | |
} | |
Vector<float>resultVector(arr,n); | |
//Clear Screen Would be nice now. | |
//Make Augmented Matrix | |
AugmentedMatrix<float>AugMatrix; | |
AugMatrix.setMatrix(equationMatrix); | |
AugMatrix.setVector(resultVector); | |
cout<<"Your Augmented Matrix is: \n"; | |
AugMatrix.displayAugmentedMatrix(); | |
cout<<"\nSteps you Should Perform to get Upper Triangular Matrix is :\n\n"; | |
makeUpperTriangular(AugMatrix,true); | |
cout<<"\nNow, Perform Back Substituion to get the Required Values"; | |
cout<<"\n\n\n*THE END*\n"; | |
return 0; | |
} | |
/* Dev Time Debugging Codes */ | |
/*int main(){ | |
float* arr = new float[3]; | |
arr[0] = -12; | |
arr[1] = -4; | |
arr[2] = 11; | |
Vector<float> resultVector(arr, 3); | |
Matrix<float> equationMatrix(3,3); | |
arr[0] = 5; | |
arr[1] = -4; | |
arr[2] = 3; | |
equationMatrix.setMatrixRow(1,arr,3); | |
arr[0] = 1; | |
arr[1] = -1; | |
arr[2] = 1; | |
equationMatrix.setMatrixRow(2,arr,3); | |
arr[0] = 2; | |
arr[1] = 1; | |
arr[2] = 1; | |
equationMatrix.setMatrixRow(3,arr,3); | |
AugmentedMatrix<float>AugMatrix; | |
AugMatrix.setMatrix(equationMatrix); | |
AugMatrix.setVector(resultVector); | |
AugMatrix.displayAugmentedMatrix(); | |
cout<<"---------------------------"<<endl; | |
makeLowerTriangular(AugMatrix,true); | |
//AugMatrix.displayAugmentedMatrix(); | |
return 0; | |
}*/ | |
/* | |
float *arr; | |
arr = new float[2]; | |
arr[0] = 9; | |
arr[1] = 13; | |
Vector<float>v1(arr,2); | |
v1.add(12); | |
v1.debug_printAll(); | |
cout<<"\n----------\n"; | |
v1.doOperation(3,2,-1); //R3 = R3 - R2 | |
v1.debug_printAll(); | |
Vector<float>v2; | |
v2 = v1; | |
cout<<"\n----------\n"; | |
v2.debug_printAll(); | |
cout<<"\n----------\n"; | |
float *matrixRow = new float[3]; | |
matrixRow[0] = 2; | |
matrixRow[1] = 3; | |
matrixRow[2] = 4; | |
Matrix<float>M1(3,3); | |
M1.setMatrixRow(1, matrixRow,3); | |
matrixRow[0] = 5; | |
matrixRow[1] = 6; | |
matrixRow[2] = 7; | |
M1.setMatrixRow(2, matrixRow,3); | |
matrixRow[0] = 8; | |
matrixRow[1] = 9; | |
matrixRow[2] = 10; | |
M1.setMatrixRow(3, matrixRow,3); | |
M1.printMatrix(); | |
cout<<"\n----------\n"; | |
Matrix<float>M2 = M1; | |
M2.doRowOperation(2,1,2, true); //R2 = R2 + 2R1 ((R)2,(R)1,2(R1)) | |
M2.printMatrix(); | |
cout<<"\n----------\n"; | |
Matrix<float>M3(M1); | |
M3.printMatrix(); | |
cout<<"\n----------\n"; | |
//Piece of Advise: Do your best to avoid: | |
// 1) double free or corruption | |
// 2) munmap_chunk | |
// 3) Segfaults | |
// 4) If possible, avoid error with valgrind too | |
AugmentedMatrix<float>Aug1; | |
Aug1.setMatrix(M1); | |
Aug1.setVector(v1); | |
Matrix<float>testMatrix = Aug1.getMatrix(); | |
Vector<float>testVector = Aug1.getVector(); | |
testMatrix.printMatrix(); | |
cout<<"\n----------\n"; | |
testVector.debug_printAll(); | |
delete[] arr; //For valgrind to return good results | |
delete[] matrixRow; | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Completed one iteration. Now need to implement Backward Substitution!