Skip to content

Instantly share code, notes, and snippets.

@nootanghimire
Created May 28, 2014 18:51
Show Gist options
  • Save nootanghimire/22247eb7eb18317b2d08 to your computer and use it in GitHub Desktop.
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
/*
*
* @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;
*/
@nootanghimire
Copy link
Author

Completed one iteration. Now need to implement Backward Substitution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment