-
Notifications
You must be signed in to change notification settings - Fork 1
/
arrays.go
148 lines (120 loc) · 2.99 KB
/
arrays.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
142
143
144
145
146
147
148
package data
import (
"github.com/flowmatters/openwater-core/util/slice"
"github.com/joelrahman/genny/generic"
)
//go:generate genny -in=$GOFILE -out=gen-$GOFILE gen "ArrayType=float64,float32,int32,uint32,int64,uint64,int,uint"
type ArrayType generic.Number
// type NDArray interface {
// }
type NDArrayType interface {
Len(axis int) int
Shape() []int
NDims() int
NewIndex(val int) []int
Get(loc []int) ArrayType
Set(loc []int, val ArrayType)
Slice(loc []int, dims []int, step []int) NDArrayType
Apply(loc []int, dim int, step int, vals []ArrayType)
ApplySlice(loc []int, step []int, vals NDArrayType)
CopyFrom(other NDArrayType)
Contiguous() bool
Unroll() []ArrayType
Reshape(newShape []int) (NDArrayType, error)
MustReshape(newShape []int) NDArrayType
ReshapeFast(newShape []int) (NDArrayType, error)
Maximum() ArrayType
Minimum() ArrayType
}
type ND1ArrayType interface {
NDArrayType
Len1() int
Get1(loc int) ArrayType
Set1(loc int, val ArrayType)
Apply1(loc int, step int, vals []ArrayType)
}
type ND2ArrayType interface {
NDArrayType
Len2() int
Get2(loc1 int, loc2 int) ArrayType
Set2(loc1 int, loc2 int, val ArrayType)
}
type ND3ArrayType interface {
NDArrayType
Len3() int
Get3(loc1 int, loc2 int, loc3 int) ArrayType
Set3(loc1 int, loc2 int, loc3 int, val ArrayType)
}
type NdArrayTypeCommon struct {
OriginalDims []int
Dims []int
Start int
Offset []int
Step []int
OffsetStep []int
}
func (nd *NdArrayTypeCommon) Len(ax int) int {
return nd.Dims[ax]
}
func (nd *NdArrayTypeCommon) Shape() []int {
return nd.Dims
}
func (nd *NdArrayTypeCommon) NDims() int {
return len(nd.Dims)
}
func (nd *NdArrayTypeCommon) NewIndex(val int) []int {
return slice.Uniform(nd.NDims(), val)
}
func (nd *NdArrayTypeCommon) Index(loc []int) int {
result := nd.Start
for i := 0; i < len(loc); i++ {
result += loc[i] * nd.OffsetStep[i]
}
return result
// return nd.Start + dotProduct(multiply(loc, nd.Step), nd.Offset)
}
func (nd *NdArrayTypeCommon) Contiguous() bool {
// What about step!
var i int
contiguousOffset := 1
dimsMustBeOne := false
for i = len(nd.Dims) - 1; i >= 0; i-- {
if nd.Dims[i] > 1 {
if dimsMustBeOne {
return false
}
if nd.Step[i] > 1 {
return false
}
if nd.Offset[i] > contiguousOffset {
return false
}
}
if nd.Dims[i] != nd.OriginalDims[i] {
dimsMustBeOne = true
}
contiguousOffset *= nd.Dims[i]
}
return true
}
func (nd *NdArrayTypeCommon) Len1() int {
return nd.Dims[0]
}
func (nd *NdArrayTypeCommon) Len2() int {
return nd.Dims[1]
}
func (nd *NdArrayTypeCommon) Len3() int {
return nd.Dims[2]
}
func (nd *NdArrayTypeCommon) SliceInto(dest *NdArrayTypeCommon, loc []int, dims []int, step []int) {
dest.OriginalDims = nd.OriginalDims
dest.Dims = dims
dest.Start = nd.Start + dotProduct(loc, nd.Offset)
dest.Offset = Multiply(nd.Offset, nd.Step)
if step == nil {
dest.Step = nd.Step
} else {
dest.Step = Multiply(nd.Step, step)
}
dest.OffsetStep = Multiply(dest.Step, dest.Offset)
}