Skip to content

Commit 64426a1

Browse files
committed
Removed singular matrix checking & made the code simpler
1 parent 08bf7f4 commit 64426a1

File tree

2 files changed

+47
-86
lines changed

2 files changed

+47
-86
lines changed

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

Lines changed: 41 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -5,60 +5,49 @@
55
#include <vector>
66

77

8-
int gaussianElimination(std::vector< std::vector<double> > &eqns, int varc) {
8+
void gaussianElimination(std::vector< std::vector<double> > &eqns, int varc) {
99
// 'eqns' is the matrix, 'varc' is no. of vars
1010
int err = 0; // marker for if matrix is singular
11+
1112
for (int i = 0; i < varc - 1; i++) {
12-
double pivot = fabs(eqns[i][i]);
13-
int newRow = i;
13+
int pivot = i;
1414

15-
for (int j = i + 1; j < varc; j++) {
16-
if (fabs(eqns[j][i]) > pivot) {
17-
pivot = fabs(eqns[j][i]);
18-
newRow = j;
19-
}
20-
}
15+
for (int j = i + 1; j < varc; j++)
16+
if (fabs(eqns[j][i]) > fabs(eqns[pivot][i]))
17+
pivot = j;
2118

22-
if (pivot == 0.0) {
19+
if (eqns[pivot][i] == 0.0) {
2320
err = 1; // Marking that matrix is singular
24-
continue;
21+
continue; // But continuing to simplify the matrix as much as possible
2522
}
2623

27-
if (newRow != i) // Swapping the rows if new row with higher pivot is found
28-
std::swap(eqns[newRow], eqns[i]); // C++ swap function
24+
if (i != pivot) // Swapping the rows if new row with higher maxVals is found
25+
std::swap(eqns[pivot], eqns[i]); // C++ swap function
2926

3027
for (int j = i + 1; j < varc; j++) {
31-
if (eqns[j][i]) {
32-
double mult = eqns[j][i] / eqns[i][i];
33-
eqns[j][i] = 0.0;
34-
for (int k = i + 1; k < (varc + 1); k++) // k doesn't start at 0, since
35-
eqns[j][k] -= mult * eqns[i][k]; // values before from 0 to i
36-
} // are already 0
37-
}
38-
}
28+
double scale = eqns[j][i] / eqns[i][i];
3929

40-
if (eqns[varc - 1][varc - 1] == 0 || err) {
41-
if (eqns[varc - 1][varc] == 0 || err)
42-
return 1; // Error code: Singular matrix
43-
else
44-
return 2; // Error code: No solutions
45-
// Cannot solve since final equation is '0*xn = c'
30+
for (int k = i + 1; k < (varc + 1); k++) // k doesn't start at 0, since
31+
eqns[j][k] -= scale * eqns[i][k]; // values before from 0 to i
32+
// are already 0
33+
eqns[j][i] = 0.0;
34+
}
4635
}
47-
48-
return 0; // Successful
4936
}
5037

5138

5239
void gaussJordan(std::vector< std::vector<double> > &eqns, int varc) {
5340
// 'eqns' is the (Row-echelon) matrix, 'varc' is no. of vars
5441
for (int i = varc - 1; i >= 0; i--) {
55-
eqns[i][varc] /= eqns[i][i];
56-
eqns[i][i] = 1; // We know that the only entry in this row is 1
57-
58-
// subtracting rows from below
59-
for (int j = i - 1; j >= 0; j--) {
60-
eqns[j][varc] -= eqns[j][i] * eqns[i][varc];
61-
eqns[j][i] = 0; // We also set all the other values in row to 0 directly
42+
if (eqns[i][i] != 0) {
43+
eqns[i][varc] /= eqns[i][i];
44+
eqns[i][i] = 1; // We know that the only entry in this row is 1
45+
46+
// subtracting rows from below
47+
for (int j = i - 1; j >= 0; j--) {
48+
eqns[j][varc] -= eqns[j][i] * eqns[i][varc];
49+
eqns[j][i] = 0; // We also set all the other values in row to 0 directly
50+
}
6251
}
6352
}
6453
}
@@ -69,30 +58,22 @@ std::vector<double> backSubs(std::vector<std::vector<double>> &eqns, int varc)
6958
// 'eqns' is matrix, 'varc' is no. of variables
7059
std::vector<double> ans(varc);
7160
for (int i = varc - 1; i >= 0; i--) {
72-
double sum = 0;
61+
double sum = 0.0;
62+
7363
for (int j = i + 1; j < varc; j++)
7464
sum += eqns[i][j] * ans[j];
7565

76-
ans[i] = (eqns[i][varc] - sum) / eqns[i][i];
66+
if (eqns[i][i] != 0)
67+
ans[i] = (eqns[i][varc] - sum) / eqns[i][i];
68+
else
69+
return std::vector<double>(0);
7770
}
7871
return ans;
7972
}
8073

8174

8275
std::vector<double> solveByGaussJordan(std::vector<std::vector<double>> eqns, int varc) {
83-
int status = gaussianElimination(eqns, varc);
84-
switch (status) {
85-
case 0:
86-
break;
87-
88-
case 1:
89-
std::cout << "Singular matrix" << std::endl;
90-
return std::vector<double>(0); // return empty vector in case of no solutions
91-
92-
case 2:
93-
std::cout << "No solutions" << std::endl;
94-
return std::vector<double>(0); // return empty vectors in case of no solutions
95-
}
76+
gaussianElimination(eqns, varc);
9677

9778
gaussJordan(eqns, varc);
9879

@@ -104,19 +85,7 @@ std::vector<double> solveByGaussJordan(std::vector<std::vector<double>> eqns, in
10485

10586

10687
std::vector<double> solveByBacksubs(std::vector<std::vector<double>> eqns, int varc) {
107-
int status = gaussianElimination(eqns, varc);
108-
switch (status) {
109-
case 0:
110-
break;
111-
112-
case 1:
113-
std::cout << "Singular matrix" << std::endl;
114-
return std::vector<double>(0); // return empty vectors in case of no solutions
115-
116-
case 2:
117-
std::cout << "No solutions" << std::endl;
118-
return std::vector<double>(0); // return empty vectors in case of no solutions
119-
}
88+
gaussianElimination(eqns, varc);
12089

12190
std::vector<double> ans = backSubs(eqns, varc);
12291
return ans;
@@ -134,23 +103,15 @@ int main() {
134103

135104
ans = solveByGaussJordan(equations, varc);
136105

137-
if (ans.empty()) { // If ans is empty, then no unique solutions exist
138-
std::cout << "No solution" << std::endl;
139-
} else {
140-
std::cout << "The solution is (by Gauss Jordan)," << std::endl
141-
<< "x == " << ans[0] << std::endl
142-
<< "y == " << ans[1] << std::endl
143-
<< "z == " << ans[2] << std::endl;
144-
}
106+
std::cout << "The solution is (by Gauss Jordan)," << std::endl
107+
<< "x == " << ans[0] << std::endl
108+
<< "y == " << ans[1] << std::endl
109+
<< "z == " << ans[2] << std::endl;
145110

146111
ans = solveByBacksubs(equations, varc);
147112

148-
if (ans.empty()) { // If ans is empty, then no unique solutions exist
149-
std::cout << "No solution" << std::endl;
150-
} else {
151-
std::cout << "The solution is (by Backsubstitution)," << std::endl
152-
<< "x == " << ans[0] << std::endl
153-
<< "y == " << ans[1] << std::endl
154-
<< "z == " << ans[2] << std::endl;
155-
}
113+
std::cout << "The solution is (by Backsubstitution)," << std::endl
114+
<< "x == " << ans[0] << std::endl
115+
<< "y == " << ans[1] << std::endl
116+
<< "z == " << ans[2] << std::endl;
156117
}

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"](code/c/gaussian_elimination.c)
316316
[import:19-34, lang:"c"](code/c/gaussian_elimination.c)
317317
{% sample lang="cpp" %}
318-
[import:27-28, lang:"cpp"](code/c++/gaussian_elimination.cpp)
319-
[import:12-28, lang:"cpp"](code/c++/gaussian_elimination.cpp)
318+
[import:25-25, lang:"cpp"](code/c++/gaussian_elimination.cpp)
319+
[import:13-25, lang:"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"](code/c/gaussian_elimination.c)
390390
{% sample lang="cpp" %}
391-
[import:32-35, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
391+
[import:28-32, 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"](code/c/gaussian_elimination.c)
411411
{% sample lang="cpp" %}
412-
[import:8-49, lang:"cpp"](code/c++/gaussian_elimination.cpp)
412+
[import:8-36, lang:"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"](code/c/gaussian_elimination.c)
450450
{% sample lang="cpp" %}
451-
[import:52-64, lang:"cpp"](code/c++/gaussian_elimination.cpp)
451+
[import:39-53, lang:"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"](code/c/gaussian_elimination.c)
493493
{% sample lang="cpp" %}
494-
[import:67-79, lang:"cpp"](code/c++/gaussian_elimination.cpp)
494+
[import:56-72, lang:"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)