Skip to content

Commit 53dbd1f

Browse files
committed
Modified to upmove the row with highest pivot & added more comments
1 parent e9527bb commit 53dbd1f

File tree

2 files changed

+77
-32
lines changed

2 files changed

+77
-32
lines changed

contents/gaussian_elimination/code/c++/gaussian_elimination.cpp

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <algorithm>
33
#include <stdexcept>
44
#include <vector>
5+
#include <cmath>
56
using namespace std;
67

78
class 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
101107
public:
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

121151
int 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;

contents/gaussian_elimination/gaussian_elimination.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,8 @@ In code, this process might look like this:
315315
[import:5-13, lang:"c_cpp"](code/c/gaussian_elimination.c)
316316
[import:19-34, lang:"c_cpp"](code/c/gaussian_elimination.c)
317317
{% sample lang="cpp" %}
318-
[import:22-29, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
319-
[import:37-51, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
318+
[import:23-30, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
319+
[import:36-56, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
320320
{% sample lang="hs" %}
321321
[import:10-17, lang:"haskell"](code/haskell/gaussianElimination.hs)
322322
[import:44-46, lang:"haskell"](code/haskell/gaussianElimination.hs)
@@ -388,7 +388,7 @@ Here is what it might look like in code:
388388
{% sample lang="c" %}
389389
[import:36-41, lang:"c_cpp"](code/c/gaussian_elimination.c)
390390
{% sample lang="cpp" %}
391-
[import:11-19, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
391+
[import:12-20, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
392392
{% sample lang="hs" %}
393393
[import:19-33, lang:"haskell"](code/haskell/gaussianElimination.hs)
394394
[import:42-42, lang:"haskell"](code/haskell/gaussianElimination.hs)
@@ -409,7 +409,7 @@ When we put everything together, it looks like this:
409409
{% sample lang="c" %}
410410
[import:15-48, lang:"c_cpp"](code/c/gaussian_elimination.c)
411411
{% sample lang="cpp" %}
412-
[import:11-67, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
412+
[import:12-72, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
413413
{% sample lang="rs" %}
414414
[import:41-78, lang:"rust"](code/rust/gaussian_elimination.rs)
415415
{% sample lang="hs" %}
@@ -448,7 +448,7 @@ Here it is in code:
448448
{% sample lang="c" %}
449449
[import:64-82, lang:"c_cpp"](code/c/gaussian_elimination.c)
450450
{% sample lang="cpp" %}
451-
[import:70-83, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
451+
[import:75-89, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
452452
{% sample lang="rs" %}
453453
This code does not exist yet in rust, so here's Julia code (sorry for the inconvenience)
454454
[import:67-93, lang:"julia"](code/julia/gaussian_elimination.jl)
@@ -491,7 +491,7 @@ In code, it looks like this:
491491
{% sample lang="c" %}
492492
[import:50-62, lang:"c_cpp"](code/c/gaussian_elimination.c)
493493
{% sample lang="cpp" %}
494-
[import:86-99, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
494+
[import:92-105, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
495495
{% sample lang="rs" %}
496496
[import:79-94, lang:"rust"](code/rust/gaussian_elimination.rs)
497497
{% sample lang="hs" %}

0 commit comments

Comments
 (0)