-
-
Notifications
You must be signed in to change notification settings - Fork 357
/
Copy pathgaussian_elimination.go
135 lines (115 loc) · 2.26 KB
/
gaussian_elimination.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Package demonstrates Gaussian Elimination
package main
import (
"fmt"
"math"
)
func gaussianElimination(a [][]float64) {
singular := false
rows := len(a)
cols := len(a[0])
for c, r := 0, 0; c < cols && r < rows; c++ {
// 1. find highest value in column below row to be pivot
p, highest := r, 0.
for i, row := range a[r:] {
if abs := math.Abs(row[c]); abs > highest {
p = r + i
highest = abs
}
}
highest = a[p][c] // correct sign
if highest == 0. {
if !singular {
singular = true
fmt.Println("This matrix is singular.")
}
continue
}
// 2. swap pivot with current row
if p != r {
a[r], a[p] = a[p], a[r]
}
for _, row := range a[r+1:] {
// 3. find fraction from pivot value
frac := row[c] / highest
// 4. subtract row to set rest of column to zero
for j := range row {
row[j] -= frac * a[r][j]
}
// 5. ensure col goes to zero (no float rounding)
row[c] = 0.
}
r++
}
}
func gaussJordan(a [][]float64) {
for r := len(a) - 1; r >= 0; r-- {
// Find pivot col
p := -1
for c, cell := range a[r] {
if cell != 0. {
p = c
break
}
}
if p < 0 {
continue
}
// Scale pivot r to 1.
scale := a[r][p]
for c := range a[r][p:] {
a[r][p+c] /= scale
}
// Subtract pivot row from each row above
for _, row := range a[:r] {
scale = row[p]
for c, cell := range a[r][p:] {
row[p+c] -= cell * scale
}
}
}
}
func backSubstitution(a [][]float64) []float64 {
rows := len(a)
cols := len(a[0])
x := make([]float64, rows)
for r := rows - 1; r >= 0; r-- {
sum := 0.
for c := cols - 2; c > r; c-- {
sum += x[c] * a[r][c]
}
x[r] = (a[r][cols-1] - sum) / a[r][r]
}
return x
}
func printMatrixRow(row []float64) {
fmt.Print("[")
for _, cell := range row {
fmt.Printf("%9.4f ", cell)
}
fmt.Println("]")
}
func printMatrix(a [][]float64) {
for _, row := range a {
printMatrixRow(row)
}
fmt.Println()
}
func main() {
a := [][]float64{
{2, 3, 4, 6},
{1, 2, 3, 4},
{3, -4, 0, 10},
}
fmt.Println("Original Matrix:")
printMatrix(a)
fmt.Println("Gaussian elimination:")
gaussianElimination(a)
printMatrix(a)
gaussJordan(a)
fmt.Println("Gauss-Jordan:")
printMatrix(a)
fmt.Println("Solutions are:")
x := backSubstitution(a)
printMatrixRow(x)
}