-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlup.go
96 lines (76 loc) · 1.41 KB
/
lup.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
package matrix
import (
"math"
)
func lupDecomposition(a [][]float64) ([][]float64, [][]float64, []int) {
n := len(a)
pv := make([]int, n)
for k := range pv {
pv[k] = k
}
for k := 0; k < n; k++ {
var p float64
ks := 0
for i := k; i < n; i++ {
if math.Abs(a[i][k]) > p {
p = math.Abs(a[i][k])
ks = i
}
}
if p == 0 {
panic("degenerate matrix")
}
pv[k], pv[ks] = pv[ks], pv[k]
for i := 0; i < n; i++ {
a[k][i], a[ks][i] = a[ks][i], a[k][i]
}
for i := k + 1; i < n; i++ {
a[i][k] = a[i][k] / a[k][k]
for j := k + 1; j < n; j++ {
a[i][j] -= a[i][k] * a[k][j]
}
}
}
l, u := makeMatrix(n), makeMatrix(n)
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if i > j {
l[i][j] = a[i][j]
} else {
u[i][j] = a[i][j]
}
if i == j {
l[i][j] = 1
}
}
}
return l, u, pv
}
func makeMatrix(n int) [][]float64 {
m := make([][]float64, n)
for i := 0; i < n; i++ {
m[i] = make([]float64, n)
}
return m
}
func LUPSolve(a [][]float64, b []float64) []float64 {
n := len(a)
l, u, p := lupDecomposition(a)
y := make([]float64, n)
for i := 0; i < n; i++ {
var sum float64
for j := 0; j <= i-1; j++ {
sum += l[i][j] * y[j]
}
y[i] = b[p[i]] - sum
}
x := make([]float64, n)
for i := n - 1; i >= 0; i-- {
var sum float64
for j := i + 1; j < n; j++ {
sum += u[i][j] * x[j]
}
x[i] = (y[i] - sum) / u[i][i]
}
return x
}