Skip to content

Commit 0f16f25

Browse files
jasmaajune128
authored andcommitted
Implement gaussian elimination in python (#370)
* initial implementation * Debug ref and rref * Add to gitbook * Make requested changes * Change ref to row echelon form
1 parent 838ae9d commit 0f16f25

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import numpy as np
2+
3+
def gaussian_elimination(A):
4+
5+
pivot_row = 0
6+
7+
# Step 1: Go by column
8+
for pivot_col in range(min(A.shape[0], A.shape[1])):
9+
10+
# Step 2: Swap row with highest element in col
11+
max_i = np.argmax(abs(A[pivot_row:, pivot_col])) + pivot_row
12+
13+
temp = A[pivot_row, :].copy()
14+
A[pivot_row, :] = A[max_i, :]
15+
A[max_i, :] = temp
16+
17+
# Skip on singular matrix, not actually a pivot
18+
if A[pivot_row, pivot_col] == 0:
19+
continue
20+
21+
# Steps 3 & 4: Zero out elements below pivot
22+
for r in range(pivot_row + 1, A.shape[0]):
23+
# Step 3: Get fraction
24+
frac = -A[r, pivot_col] / A[pivot_row, pivot_col]
25+
# Step 4: Add rows
26+
A[r, :] += frac * A[pivot_row, :]
27+
28+
pivot_row += 1
29+
30+
31+
# Assumes A is already row echelon form
32+
def gauss_jordan_elimination(A):
33+
34+
col = 0
35+
36+
# Scan for pivots
37+
for row in range(A.shape[0]):
38+
while col < A.shape[1] and A[row, col] == 0:
39+
col += 1
40+
41+
if col >= A.shape[1]:
42+
continue
43+
44+
# Set each pivot to one via row scaling
45+
A[row, :] /= A[row, col]
46+
47+
# Zero out elements above pivot
48+
for r in range(row):
49+
A[r, :] -= A[r, col] * A[row, :]
50+
51+
52+
# Assumes A has a unique solution and A in row echelon form
53+
def back_substitution(A):
54+
55+
sol = np.zeros(A.shape[0]).T
56+
57+
# Go by pivots along diagonal
58+
for pivot_i in range(A.shape[0] - 1, -1, -1):
59+
s = 0
60+
for col in range(pivot_i + 1, A.shape[1] - 1):
61+
s += A[pivot_i, col] * sol[col]
62+
sol[pivot_i] = (A[pivot_i, A.shape[1] - 1] - s) / A[pivot_i, pivot_i]
63+
64+
return sol
65+
66+
67+
def main():
68+
A = np.array([[2, 3, 4, 6],
69+
[1, 2, 3, 4,],
70+
[3, -4, 0, 10]], dtype=float)
71+
72+
print("Original")
73+
print(A, "\n")
74+
75+
gaussian_elimination(A)
76+
print("Gaussian elimination")
77+
print(A, "\n")
78+
79+
print("Back subsitution")
80+
print(back_substitution(A), "\n")
81+
82+
gauss_jordan_elimination(A)
83+
print("Gauss-Jordan")
84+
print(A, "\n")
85+
86+
87+
if __name__ == "__main__":
88+
main()
89+

contents/gaussian_elimination/gaussian_elimination.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ In code, this looks like:
360360
[import:41-78, lang:"rust"](code/rust/gaussian_elimination.rs)
361361
{% sample lang="hs" %}
362362
[import:10-36, lang:"haskell"](code/haskell/gaussianElimination.hs)
363+
{% sample lang="py" %}
364+
[import:3-28, lang:"python"](code/python/gaussian_elimination.py)
363365
{% endmethod %}
364366

365367
Now, to be clear: this algorithm creates an upper-triangular matrix.
@@ -393,6 +395,8 @@ This code does not exist yet in rust, so here's Julia code (sorry for the inconv
393395
[import:67-93, lang:"julia"](code/julia/gaussian_elimination.jl)
394396
{% sample lang="hs" %}
395397
[import:38-46, lang:"haskell"](code/haskell/gaussianElimination.hs)
398+
{% sample lang="py" %}
399+
[import:31-49, lang:"python"](code/python/gaussian_elimination.py)
396400
{% endmethod %}
397401

398402
## Back-substitution
@@ -423,6 +427,8 @@ In code, this involves keeping a rolling sum of all the values we substitute in
423427
[import:79-94, lang:"rust"](code/rust/gaussian_elimination.rs)
424428
{% sample lang="hs" %}
425429
[import:48-53, lang:"haskell"](code/haskell/gaussianElimination.hs)
430+
{% sample lang="py" %}
431+
[import:52-64, lang:"python"](code/python/gaussian_elimination.py)
426432
{% endmethod %}
427433

428434
## Conclusions
@@ -445,6 +451,8 @@ As for what's next... Well, we are in for a treat! The above algorithm clearly h
445451
[import, lang:"rust"](code/rust/gaussian_elimination.rs)
446452
{% sample lang="hs" %}
447453
[import, lang:"haskell"](code/haskell/gaussianElimination.hs)
454+
{% sample lang="py" %}
455+
[import, lang:"python"](code/python/gaussian_elimination.py)
448456
{% endmethod %}
449457

450458

0 commit comments

Comments
 (0)