2
2
#include < algorithm>
3
3
#include < stdexcept>
4
4
#include < vector>
5
+ #include < cmath>
5
6
using namespace std ;
6
7
7
8
class EquationSolver
@@ -29,41 +30,45 @@ class EquationSolver
29
30
// to swap.
30
31
31
32
32
- void gaussianElimination (vector<vector<long double >> &eqns, int varc)
33
+ int gaussianElimination (vector<vector<long double >> &eqns, int varc)
33
34
{
34
35
// 'eqns' is the matrix, 'varc' is no. of vars
36
+ int err = 0 ; // marker for if matrix is singular
35
37
for (int i = 0 ; i < varc - 1 ; i++)
36
38
{
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++)
38
42
{
39
- for ( int j = i + 1 ; j < varc; j++ )
43
+ if ( fabsl (eqns[j][i]) > pivot )
40
44
{
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;
46
47
}
48
+ }
47
49
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 ;
51
54
}
55
+ if (newRow != i)
56
+ swapRow (eqns[newRow], eqns[i], i);
52
57
53
58
for (int j = i + 1 ; j < varc; j++)
54
59
if (eqns[j][i])
55
60
subRow (eqns[j], eqns[i], (eqns[j][i] / eqns[i][i]), i);
56
61
}
57
62
58
- if (eqns[varc - 1 ][varc - 1 ] == 0 )
63
+ if (eqns[varc - 1 ][varc - 1 ] == 0 || err )
59
64
{
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
63
67
else
64
- throw runtime_error ( " No solutions" );
68
+ return 2 ; // Error code: No solutions
65
69
// Cannot solve since final equation is '0*xn = c'
66
70
}
71
+ return 0 ; // Successful
67
72
}
68
73
69
74
@@ -73,11 +78,12 @@ class EquationSolver
73
78
for (int i = varc - 1 ; i >= 0 ; i--)
74
79
{
75
80
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
78
84
{
79
85
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
81
87
}
82
88
}
83
89
}
@@ -101,7 +107,19 @@ class EquationSolver
101
107
public:
102
108
vector<long double > solveByGaussJordan (vector< vector<long double > > eqns, int varc)
103
109
{
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
+
105
123
this ->gaussJordan (eqns, varc);
106
124
107
125
vector<long double > ans (varc);
@@ -112,30 +130,57 @@ class EquationSolver
112
130
113
131
vector<long double > solveByBacksubs (vector< vector<long double > > eqns, int varc)
114
132
{
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
+
116
146
vector<long double > ans = this ->backSubs (eqns, varc);
117
147
return ans;
118
148
}
119
149
};
120
150
121
151
int main () {
122
152
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 }};
126
156
EquationSolver solver;
127
157
vector<long double > ans;
128
158
try
129
159
{
130
160
ans = solver.solveByGaussJordan (equations, varc);
131
161
}
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)
133
178
{
134
179
cout << " Error found: " << e.what () << endl;
135
180
return -1 ;
136
181
}
137
182
138
- cout << " The solution is," << endl
183
+ cout << " The solution is (by Backsubstitution) ," << endl
139
184
<< " x == " << ans[0 ] << endl
140
185
<< " y == " << ans[1 ] << endl
141
186
<< " z == " << ans[2 ] << endl;
0 commit comments