Skip to content

Commit d532840

Browse files
committed
Implement Gaussian Elimination in C++
1 parent 0d89be5 commit d532840

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <algorithm>
2+
#include <cassert>
3+
#include <iostream>
4+
#include <vector>
5+
6+
void gaussian_elimination(std::vector<double>& a, size_t cols) {
7+
assert(a.size() % cols == 0);
8+
auto rows = a.size() / cols;
9+
10+
// Main loop going through all columns
11+
for (auto k = 0u; k < std::min(rows, cols); ++k) {
12+
// Step 1: finding the maximum element for each column
13+
auto max_index = [&]() {
14+
auto res = k;
15+
auto max_element = a[k + k * cols];
16+
for (auto r = k + 1; r < rows; ++r)
17+
if (max_element < a[k + r * cols]) {
18+
max_element = a[k + r * cols];
19+
res = r;
20+
}
21+
return res;
22+
}();
23+
24+
// Check to make sure matrix is good!
25+
if (a[k + max_index * cols] == 0) {
26+
std::cout << "matrix is singular! End!\n";
27+
return;
28+
}
29+
30+
// Step 2: swap row with highest value for that column to the top
31+
for (auto c = 0u; c < cols; ++c)
32+
std::swap(a[c + k * cols], a[c + max_index * cols]);
33+
34+
// Loop for all remaining rows
35+
for (auto i = k + 1; i < rows; ++i) {
36+
37+
// Step 3: finding fraction
38+
auto fraction = a[k + i * cols] / a[k + k * cols];
39+
40+
// loop through all columns for that row
41+
for (auto j = k + 1; j < cols; ++j) {
42+
43+
// Step 4: re-evaluate each element
44+
a[j + i * cols] -= a[j + k * cols] * fraction;
45+
}
46+
47+
// Step 5: Set lower elements to 0
48+
a[k + i * cols] = 0;
49+
}
50+
}
51+
}
52+
53+
std::vector<double> back_substitution(std::vector<double>& a, size_t cols) {
54+
assert(a.size() % cols == 0);
55+
auto rows = a.size() / cols;
56+
57+
// Creating the solution Vector
58+
std::vector<double> soln;
59+
soln.resize(rows);
60+
61+
// initialize the final element
62+
soln[rows - 1] =
63+
a[cols - 1 + (rows - 1) * cols] / a[cols - 1 - 1 + (rows - 1) * cols];
64+
65+
for (int i = rows - 1; i >= 0; --i) {
66+
auto sum = 0.0;
67+
for (int j = cols - 2; j > i; --j) {
68+
sum += soln[j] * a[j + i * cols];
69+
}
70+
71+
soln[i] = (a[cols - 1 + i * cols] - sum) / a[i + i * cols];
72+
}
73+
74+
return soln;
75+
}
76+
77+
int main() {
78+
std::vector<double> a = {2, 3, 4, 6,
79+
1, 2, 3, 4,
80+
3, -4, 0, 10};
81+
const auto cols = 4u;
82+
assert(a.size() % cols == 0);
83+
const auto rows = a.size() / cols;
84+
85+
gaussian_elimination(a, cols);
86+
87+
for (auto i = 0u; i < rows; ++i) {
88+
std::cout << "[";
89+
for (auto j = 0u; j < cols; ++j) {
90+
std::cout << a[j + i * cols] << " ";
91+
}
92+
std::cout << "]\n";
93+
}
94+
95+
auto soln = back_substitution(a, 4);
96+
97+
for (auto element : soln)
98+
std::cout << element << std::endl;
99+
}

chapters/algorithms/gaussian_elimination/gaussian_elimination.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ In code, this looks like:
259259
[import:1-42, lang:"julia"](code/julia/gaussian_elimination.jl)
260260
{% sample lang="c" %}
261261
[import:13-44, lang:"c_cpp"](code/c/gaussian_elimination.c)
262+
{% sample lang="cpp" %}
263+
[import:6-51, lang:"c_cpp"](code/c++/gaussian_elimination.cpp)
262264
{% sample lang="rs" %}
263265
[import:41-78, lang:"rust"](code/rust/gaussian_elimination.rs)
264266
{% endmethod %}

0 commit comments

Comments
 (0)