-
Notifications
You must be signed in to change notification settings - Fork 0
/
constructors.go
88 lines (70 loc) · 2.12 KB
/
constructors.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
package matrix
import (
"fmt"
"math/rand"
"time"
)
// New creates a new empty matrix of a given size.
func New(rows, cols int) Matrix {
assertValidSize(rows, cols)
return createWithData(rows, cols, make([]float64, rows*cols))
}
// NewSquare creates an empty square matrix of a given size.
func NewSquare(size int) Matrix {
assertValidSize(size, size)
return createWithData(size, size, make([]float64, size*size))
}
// NewRandom creates a matrix of a given size and fills the vectors with random
// floating point number ranging from 0..1
func NewRandom(rows, cols int) Matrix {
assertValidSize(rows, cols)
data := make([]float64, rows*cols)
gen := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := range data {
data[i] = gen.Float64()
}
return createWithData(rows, cols, data)
}
// NewFrom creates a matrix instance from a slice of slices
func NewFrom(data [][]float64) Matrix {
rows, cols := len(data), len(data[0])
assertValidSize(rows, cols)
assertAllRowsSameSize(data, cols)
return createWithData(rows, cols, sliceJoin(data))
}
// NewFromVector creates a matrix from long vector. It just makes sure it can have a
// rectangular shape
func NewFromVec(rows, cols int, data []float64) Matrix {
assertValidSize(rows, cols)
if rows*cols != len(data) {
panic(fmt.Sprintf("tried to create %dx%d matrix with %v", rows, cols, data))
}
return createWithData(rows, cols, data)
}
// createWithData is called from all constructors and returns a struct
func createWithData(rows, cols int, data []float64) Matrix {
return Matrix{
NumRows: rows,
NumCols: cols,
data: data,
}
}
func assertValidSize(rows, cols int) {
if rows < 1 || cols < 1 {
panic(fmt.Sprintf("tried to create matrix with %d rows and %d columns", rows, cols))
}
}
func assertAllRowsSameSize(data [][]float64, cols int) {
for _, r := range data {
if len(r) != cols {
panic(fmt.Sprintf("tried to create matrix from slice of different sized slices: %v", data))
}
}
}
func sliceJoin(data [][]float64) []float64 {
result := make([]float64, 0, len(data)*len(data[0]))
for _, r := range data {
result = append(result, r...)
}
return result
}