/
mat.go
167 lines (140 loc) · 3.83 KB
/
mat.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package base
import (
"bytes"
"fmt"
"gonum.org/v1/gonum/mat"
)
type Mat64Instances struct {
attributes []Attribute
classAttrs map[int]bool
Data *mat.Dense
rows int
}
// InstancesFromMat64 returns a new Mat64Instances from a literal provided.
func InstancesFromMat64(rows, cols int, data *mat.Dense) *Mat64Instances {
var ret Mat64Instances
for i := 0; i < cols; i++ {
ret.attributes = append(ret.attributes, NewFloatAttribute(fmt.Sprintf("%d", i)))
}
ret.classAttrs = make(map[int]bool)
ret.Data = data
ret.rows = rows
return &ret
}
// GetAttribute returns an AttributeSpec from an Attribute field.
func (m *Mat64Instances) GetAttribute(a Attribute) (AttributeSpec, error) {
for i, at := range m.attributes {
if at.Equals(a) {
return AttributeSpec{0, i, at}, nil
}
}
return AttributeSpec{}, fmt.Errorf("Couldn't find a matching attribute")
}
// AllAttributes returns every defined Attribute.
func (m *Mat64Instances) AllAttributes() []Attribute {
ret := make([]Attribute, len(m.attributes))
for i, a := range m.attributes {
ret[i] = a
}
return ret
}
// AddClassAttribute adds an attribute to the class set.
func (m *Mat64Instances) AddClassAttribute(a Attribute) error {
as, err := m.GetAttribute(a)
if err != nil {
return err
}
m.classAttrs[as.position] = true
return nil
}
// RemoveClassAttribute removes an attribute to the class set.
func (m *Mat64Instances) RemoveClassAttribute(a Attribute) error {
as, err := m.GetAttribute(a)
if err != nil {
return err
}
m.classAttrs[as.position] = false
return nil
}
// AllClassAttributes returns every class attribute.
func (m *Mat64Instances) AllClassAttributes() []Attribute {
ret := make([]Attribute, 0)
for i := range m.classAttrs {
if m.classAttrs[i] {
ret = append(ret, m.attributes[i])
}
}
return ret
}
// Get returns the bytes at a given position
func (m *Mat64Instances) Get(as AttributeSpec, row int) []byte {
val := m.Data.At(row, as.position)
return PackFloatToBytes(val)
}
// MapOverRows is a convenience function for iteration
func (m *Mat64Instances) MapOverRows(as []AttributeSpec, f func([][]byte, int) (bool, error)) error {
rowData := make([][]byte, len(as))
for j, _ := range as {
rowData[j] = make([]byte, 8)
}
for i := 0; i < m.rows; i++ {
for j, as := range as {
PackFloatToBytesInline(m.Data.At(i, as.position), rowData[j])
}
stat, err := f(rowData, i)
if !stat {
return err
}
}
return nil
}
// RowString: should print the values of a row
// TODO: make this less half-assed
func (m *Mat64Instances) RowString(row int) string {
return fmt.Sprintf("%d", row)
}
// Size returns the number of Attributes, then the number of rows
func (m *Mat64Instances) Size() (int, int) {
return len(m.attributes), m.rows
}
// String returns a human-readable summary of this dataset.
func (m *Mat64Instances) String() string {
var buffer bytes.Buffer
// Get all Attribute information
as := ResolveAllAttributes(m)
// Print header
cols, rows := m.Size()
buffer.WriteString("Instances with ")
buffer.WriteString(fmt.Sprintf("%d row(s) ", rows))
buffer.WriteString(fmt.Sprintf("%d attribute(s)\n", cols))
buffer.WriteString(fmt.Sprintf("Attributes: \n"))
cnt := 0
for _, a := range as {
prefix := "\t"
if m.classAttrs[cnt] {
prefix = "*\t"
}
cnt++
buffer.WriteString(fmt.Sprintf("%s%s\n", prefix, a.attr))
}
buffer.WriteString("\nData:\n")
maxRows := 30
if rows < maxRows {
maxRows = rows
}
for i := 0; i < maxRows; i++ {
buffer.WriteString("\t")
for _, a := range as {
val := m.Get(a, i)
buffer.WriteString(fmt.Sprintf("%s ", a.attr.GetStringFromSysVal(val)))
}
buffer.WriteString("\n")
}
missingRows := rows - maxRows
if missingRows != 0 {
buffer.WriteString(fmt.Sprintf("\t...\n%d row(s) undisplayed", missingRows))
} else {
buffer.WriteString("All rows displayed")
}
return buffer.String()
}