-
Notifications
You must be signed in to change notification settings - Fork 2
/
linalg.go
141 lines (132 loc) · 2.63 KB
/
linalg.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
136
137
138
139
140
141
// package lap is a pure-Go implementation of compact linear algebra operations.
//
// It has the purpose of being a smaller dependency than gonum for use
// in constrained applications, such as deploying to web and embedded systems.
//
// It shall always be buildable with tinygo.
package lap
import (
"math"
)
// Dot returns the sum of the element-wise product of a and b.
//
// Dot panics with ErrShape if the vector sizes are unequal.
func Dot(a, b Vector) float64 {
la := a.Len()
lb := b.Len()
if la != lb {
panic(ErrDim)
}
if la == 0 {
return 0
}
var sum float64
for i := 0; i < la; i++ {
sum += a.At(i, 0) * b.At(i, 0)
}
return sum
}
// Max returns the largest element value of the matrix A.
func Max(m Matrix) float64 {
r, c := m.Dims()
max := math.Inf(-1)
for i := 0; i < r; i++ {
for j := 0; j < c; j++ {
v := m.At(i, j)
if v > max {
max = v
}
}
}
return max
}
// Min returns the smallest element value of the matrix A.
func Min(m Matrix) float64 {
r, c := m.Dims()
min := math.Inf(1)
for i := 0; i < r; i++ {
for j := 0; j < c; j++ {
v := m.At(i, j)
if v > min {
min = v
}
}
}
return min
}
// Norm returns the specified norm of the matrix A. Valid norms are:
//
// 1 - The maximum absolute column sum
// 2 - The Frobenius norm, the square root of the sum of the squares of the elements
// Inf - The maximum absolute row sum
func Norm(A Matrix, norm float64) float64 {
r, c := A.Dims()
switch norm {
default:
panic("Bad norm order, accept 1, 2, +Inf")
case 1:
var max float64
for j := 0; j < c; j++ {
var sum float64
for i := 0; i < r; i++ {
sum += math.Abs(A.At(i, j))
}
if sum > max {
max = sum
}
}
return max
case 2:
var sum float64
for i := 0; i < r; i++ {
for j := 0; j < c; j++ {
v := A.At(i, j)
sum += v * v
}
}
return math.Sqrt(sum)
case math.Inf(1):
var max float64
for i := 0; i < r; i++ {
var sum float64
for j := 0; j < c; j++ {
sum += math.Abs(A.At(i, j))
}
if sum > max {
max = sum
}
}
return max
}
}
// Sum returns the sum of the elements of the matrix.
func Sum(A Matrix) (sum float64) {
r, c := A.Dims()
for i := 0; i < r; i++ {
for j := 0; j < c; j++ {
sum += A.At(i, j)
}
}
return sum
}
// Argmax returns indices of maximum value in matrix.
func Argmax(A Matrix) (imax, jmax int) {
max := math.Inf(-1)
r, c := A.Dims()
for i := 0; i < r; i++ {
for j := 0; j < c; j++ {
v := A.At(i, j)
if v > max {
max = v
imax = i
jmax = j
}
}
}
return imax, jmax
}
func irange(dst []int, start, stride int) {
for i := 0; i < len(dst); i++ {
dst[i] = start + i*stride
}
}