-
Notifications
You must be signed in to change notification settings - Fork 45
/
utils.go
59 lines (52 loc) · 1.45 KB
/
utils.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
package nlp
import (
"github.com/james-bowman/sparse"
"gonum.org/v1/gonum/mat"
)
// ColDo executes fn for each column j in m. If the matrix implements the mat.ColViewer
// interface then this interface will be used to iterate over the column vectors more
// efficiently. If the matrix implements the sparse.TypeConverter interface then the
// matrix will be converted to a CSC matrix (which implements the mat.ColViewer
// interface) so that it can benefit from the same optimisation.
func ColDo(m mat.Matrix, fn func(j int, vec mat.Vector)) {
if v, isOk := m.(mat.Vector); isOk {
fn(0, v)
return
}
if cv, isOk := m.(mat.ColViewer); isOk {
_, c := m.Dims()
for j := 0; j < c; j++ {
fn(j, cv.ColView(j))
}
return
}
if sv, isOk := m.(sparse.TypeConverter); isOk {
csc := sv.ToCSC()
_, c := csc.Dims()
for j := 0; j < c; j++ {
fn(j, csc.ColView(j))
}
return
}
r, c := m.Dims()
for j := 0; j < c; j++ {
fn(j, mat.NewVecDense(r, mat.Col(nil, j, m)))
}
}
// ColNonZeroElemDo executes fn for each non-zero element in column j of matrix m.
// If m implements mat.ColNonZeroDoer then this interface will be used to perform
// the iteration.
func ColNonZeroElemDo(m mat.Matrix, j int, fn func(i, j int, v float64)) {
colNonZeroDoer, isSparse := m.(mat.ColNonZeroDoer)
r, _ := m.Dims()
if isSparse {
colNonZeroDoer.DoColNonZero(j, fn)
} else {
for i := 0; i < r; i++ {
v := m.At(i, j)
if v != 0 {
fn(i, j, v)
}
}
}
}