22#include < algorithm>
33#include < stdexcept>
44#include < vector>
5+ #include < cmath>
56using namespace std ;
67
78class EquationSolver
@@ -29,41 +30,45 @@ class EquationSolver
2930 // to swap.
3031
3132
32- void gaussianElimination (vector<vector<long double >> &eqns, int varc)
33+ int gaussianElimination (vector<vector<long double >> &eqns, int varc)
3334 {
3435 // 'eqns' is the matrix, 'varc' is no. of vars
36+ int err = 0 ; // marker for if matrix is singular
3537 for (int i = 0 ; i < varc - 1 ; i++)
3638 {
37- if (eqns[i][i] == 0 )
39+ long double pivot = fabsl (eqns[i][i]);
40+ int newRow = i;
41+ for (int j = i + 1 ; j < varc; j++)
3842 {
39- for ( int j = i + 1 ; j < varc; j++ )
43+ if ( fabsl (eqns[j][i]) > pivot )
4044 {
41- if (eqns[j][i] != 0 )
42- {
43- swapRow (eqns[j], eqns[i], i);
44- break ;
45- }
45+ pivot = fabsl (eqns[j][i]);
46+ newRow = j;
4647 }
48+ }
4749
48- if (eqns[i][i] == 0 )
49- throw runtime_error (" Singular matrix" );
50- // Cannot solve since coefficient of one variable is always zero
50+ if (pivot == 0.0 )
51+ {
52+ err = 1 ; // Marking that matrix is singular
53+ continue ;
5154 }
55+ if (newRow != i)
56+ swapRow (eqns[newRow], eqns[i], i);
5257
5358 for (int j = i + 1 ; j < varc; j++)
5459 if (eqns[j][i])
5560 subRow (eqns[j], eqns[i], (eqns[j][i] / eqns[i][i]), i);
5661 }
5762
58- if (eqns[varc - 1 ][varc - 1 ] == 0 )
63+ if (eqns[varc - 1 ][varc - 1 ] == 0 || err )
5964 {
60- if (eqns[varc - 1 ][varc] == 0 )
61- throw runtime_error (" Singular matrix" );
62- // Cannot solve since final equation is '0*xn = 0'
65+ if (eqns[varc - 1 ][varc] == 0 || err)
66+ return 1 ; // Error code: Singular matrix
6367 else
64- throw runtime_error ( " No solutions" );
68+ return 2 ; // Error code: No solutions
6569 // Cannot solve since final equation is '0*xn = c'
6670 }
71+ return 0 ; // Successful
6772 }
6873
6974
@@ -73,11 +78,12 @@ class EquationSolver
7378 for (int i = varc - 1 ; i >= 0 ; i--)
7479 {
7580 eqns[i][varc] /= eqns[i][i];
76- eqns[i][i] = 1 ;
77- for (int j = i - 1 ; j >= 0 ; j--)
81+ eqns[i][i] = 1 ; // We know that the only entry in this row is 1
82+
83+ for (int j = i - 1 ; j >= 0 ; j--) // subtracting rows from below
7884 {
7985 eqns[j][varc] -= eqns[j][i] * eqns[i][varc];
80- eqns[j][i] = 0 ;
86+ eqns[j][i] = 0 ; // We also set all the other values in row to 0 directly
8187 }
8288 }
8389 }
@@ -101,7 +107,19 @@ class EquationSolver
101107public:
102108 vector<long double > solveByGaussJordan (vector< vector<long double > > eqns, int varc)
103109 {
104- this ->gaussianElimination (eqns, varc);
110+ int status = this ->gaussianElimination (eqns, varc);
111+ switch (status)
112+ {
113+ case 0 :
114+ break ;
115+
116+ case 1 :
117+ throw runtime_error (" Singular matrix" );
118+
119+ case 2 :
120+ throw runtime_error (" No solutions" );
121+ }
122+
105123 this ->gaussJordan (eqns, varc);
106124
107125 vector<long double > ans (varc);
@@ -112,30 +130,57 @@ class EquationSolver
112130
113131 vector<long double > solveByBacksubs (vector< vector<long double > > eqns, int varc)
114132 {
115- this ->gaussianElimination (eqns, varc);
133+ int status = this ->gaussianElimination (eqns, varc);
134+ switch (status)
135+ {
136+ case 0 :
137+ break ;
138+
139+ case 1 :
140+ throw runtime_error (" Singular matrix" );
141+
142+ case 2 :
143+ throw runtime_error (" No solutions" );
144+ }
145+
116146 vector<long double > ans = this ->backSubs (eqns, varc);
117147 return ans;
118148 }
119149};
120150
121151int main () {
122152 int varc = 3 ;
123- vector< vector<long double > > equations { { 2 , 3 , 4 , 6 },
124- { 1 , 2 , 3 , 4 },
125- { 3 , -4 , 0 , 10 }};
153+ vector< vector<long double > > equations { { 2 , 3 , 4 , 6 },
154+ { 1 , 2 , 3 , 4 },
155+ { 3 , -4 , 0 , 10 }};
126156 EquationSolver solver;
127157 vector<long double > ans;
128158 try
129159 {
130160 ans = solver.solveByGaussJordan (equations, varc);
131161 }
132- catch (runtime_error e)
162+ catch (runtime_error &e)
163+ {
164+ cout << " Error found: " << e.what () << endl;
165+ return -1 ;
166+ }
167+
168+ cout << " The solution is (by Gauss-Jordan)," << endl
169+ << " x == " << ans[0 ] << endl
170+ << " y == " << ans[1 ] << endl
171+ << " z == " << ans[2 ] << endl << endl;
172+
173+ try
174+ {
175+ ans = solver.solveByBacksubs (equations, varc);
176+ }
177+ catch (runtime_error &e)
133178 {
134179 cout << " Error found: " << e.what () << endl;
135180 return -1 ;
136181 }
137182
138- cout << " The solution is," << endl
183+ cout << " The solution is (by Backsubstitution) ," << endl
139184 << " x == " << ans[0 ] << endl
140185 << " y == " << ans[1 ] << endl
141186 << " z == " << ans[2 ] << endl;
0 commit comments