@@ -2,122 +2,153 @@ package golsv
2
2
3
3
import (
4
4
"bytes"
5
+ "crypto/rand"
5
6
"fmt"
6
- "math/rand"
7
+ mathrand "math/rand"
8
+ "github.com/lukechampine/fastxor"
7
9
)
8
10
9
- // xxx densify?
10
- type BinaryVector []uint8
11
+ type BinaryVector struct {
12
+ length int
13
+ data []byte
14
+ }
11
15
12
16
func NewBinaryVector (n int ) BinaryVector {
13
- return make ([]uint8 , n )
17
+ return BinaryVector {
18
+ n ,
19
+ make ([]byte , words (n )),
20
+ }
21
+ }
22
+
23
+ func words (n int ) int {
24
+ return (n + 7 ) / 8
14
25
}
15
26
16
27
func NewBinaryVectorFromInts (ints []uint8 ) BinaryVector {
17
- cols := len (ints )
18
- V := NewBinaryVector (cols )
19
- for j := 0 ; j < cols ; j ++ {
20
- V [j ] = ints [j ]
28
+ rows := len (ints )
29
+ v := NewBinaryVector (rows )
30
+ for i , b := range ints {
31
+ if b != 0 {
32
+ v .Set (i , 1 )
33
+ }
34
+ }
35
+ return v
36
+ }
37
+
38
+ func NewBinaryVectorFromString (s string ) BinaryVector {
39
+ v := NewBinaryVector (len (s ))
40
+ for i , c := range s {
41
+ if c == '1' {
42
+ v .Set (i , 1 )
43
+ }
21
44
}
22
- return V
45
+ return v
23
46
}
24
47
25
48
func ZeroVector (n int ) BinaryVector {
26
- return make ([] uint8 , n )
49
+ return NewBinaryVector ( n )
27
50
}
28
51
29
52
// xxx test
30
- func (V BinaryVector ) Add (U BinaryVector ) BinaryVector {
31
- W := NewBinaryVector (len (V ))
32
- for i := 0 ; i < len (V ); i ++ {
33
- W [i ] = V [i ] ^ U [i ]
34
- }
35
- return W
53
+ func (v BinaryVector ) Add (u BinaryVector ) BinaryVector {
54
+ w := NewBinaryVector (v .Length ())
55
+ fastxor .Bytes (w .data , v .data , u .data )
56
+ return w
36
57
}
37
58
38
59
// xxx test
39
- func (V BinaryVector ) Equal (U BinaryVector ) bool {
40
- if len (V ) != len (U ) {
41
- return false
42
- }
43
- for i := 0 ; i < len (V ); i ++ {
44
- if V [i ] != U [i ] {
45
- return false
46
- }
47
- }
48
- return true
60
+ func (v BinaryVector ) AddInPlace (u BinaryVector ) {
61
+ fastxor .Bytes (v .data , v .data , u .data )
62
+ }
63
+
64
+ // xxx test
65
+ func (v BinaryVector ) Equal (u BinaryVector ) bool {
66
+ return v .length == u .length && bytes .Equal (v .data , u .data )
67
+ }
68
+
69
+ // xxx test
70
+ func (v BinaryVector ) Get (i int ) uint8 {
71
+ return (v .data [i / 8 ] >> uint (i % 8 )) & 1
49
72
}
50
73
51
74
// xxx experimental
52
- func (V BinaryVector ) IntegerDotProduct (U BinaryVector ) int {
75
+ func (v BinaryVector ) IntegerDotProduct (u BinaryVector ) int {
53
76
d := 0
54
- for i := 0 ; i < len ( V ); i ++ {
55
- d += int (V [ i ]) * int (U [ i ] )
77
+ for i := 0 ; i < v . Length ( ); i ++ {
78
+ d += int (v . Get ( i )) * int (u . Get ( i ) )
56
79
}
57
80
return d
58
81
}
59
82
60
83
// xxx test
61
- func (V BinaryVector ) Length () int {
62
- return len ( V )
84
+ func (v BinaryVector ) Length () int {
85
+ return v . length
63
86
}
64
87
65
- // xxx rename to DenseBinaryMatrix
66
- func (V BinaryVector ) Matrix () * DenseBinaryMatrix {
67
- rows := len (V )
68
- M := NewDenseBinaryMatrix (rows , 1 )
69
- for i := 0 ; i < rows ; i ++ {
70
- M .Set (i , 0 , V [i ])
71
- }
88
+ // xxx rename to DenseBinaryMatrix?
89
+ func (v BinaryVector ) Matrix () * DenseBinaryMatrix {
90
+ M := NewDenseBinaryMatrix (v .Length (), 1 )
91
+ copy (M .Data , v .data )
72
92
return M
73
93
}
74
94
75
- func (V BinaryVector ) IsZero () bool {
76
- for _ , elem := range V {
77
- if elem != 0 {
95
+ func (v BinaryVector ) IsZero () bool {
96
+ for _ , d := range v . data {
97
+ if d != 0 {
78
98
return false
79
99
}
80
100
}
81
101
return true
82
102
}
83
103
84
- func (V BinaryVector ) Project (n int , predicate func (i int ) bool ) BinaryVector {
85
- pV := NewBinaryVector (n )
104
+ func (v BinaryVector ) Project (n int , predicate func (i int ) bool ) BinaryVector {
105
+ pv := NewBinaryVector (n )
86
106
j := 0
87
- for i , b := range V {
107
+ for i := 0 ; i < v . Length (); i ++ {
88
108
if predicate (i ) {
89
- pV [ j ] = b
109
+ pv . Set ( j , v . Get ( i ))
90
110
j ++
91
111
}
92
112
}
93
- return pV
113
+ return pv
94
114
}
95
115
96
116
// xxx test
97
- func (V BinaryVector ) RandomizeWithWeight (weight int ) {
98
- n := len ( V )
117
+ func (v BinaryVector ) RandomizeWithWeight (weight int ) {
118
+ n := v . Length ( )
99
119
for i := 0 ; i < n ; i ++ {
100
- V [ i ] = 0
120
+ v . Set ( i , 0 )
101
121
}
102
122
for i := 0 ; i < weight ; i ++ {
103
- V [ rand . Intn (n )] = 1
123
+ v . Set ( mathrand . Intn (n ), 1 )
104
124
}
105
125
}
106
126
107
127
// xxx test
108
- func (V BinaryVector ) SparseBinaryMatrix () * Sparse {
109
- rows := len (V )
128
+ func (v BinaryVector ) Set (i int , b uint8 ) {
129
+ if b == 0 {
130
+ v .data [i / 8 ] &= ^ (1 << uint (i % 8 ))
131
+ } else {
132
+ v .data [i / 8 ] |= 1 << uint (i % 8 )
133
+ }
134
+ }
135
+
136
+ // xxx test
137
+ func (v BinaryVector ) SparseBinaryMatrix () * Sparse {
138
+ rows := v .Length ()
110
139
M := NewSparseBinaryMatrix (rows , 1 )
111
140
for i := 0 ; i < rows ; i ++ {
112
- M .Set (i , 0 , V [i ])
141
+ if v .Get (i ) == 1 {
142
+ M .Set (i , 0 , 1 )
143
+ }
113
144
}
114
145
return M
115
146
}
116
147
117
- func (V BinaryVector ) String () string {
148
+ func (v BinaryVector ) String () string {
118
149
var buf bytes.Buffer
119
- for _ , b := range V {
120
- if b == 0 {
150
+ for i := 0 ; i < v . Length (); i ++ {
151
+ if v . Get ( i ) == 0 {
121
152
buf .WriteString ("0" )
122
153
} else {
123
154
buf .WriteString ("1" )
@@ -126,12 +157,12 @@ func (V BinaryVector) String() string {
126
157
return buf .String ()
127
158
}
128
159
129
- func (V BinaryVector ) SupportString () string {
160
+ func (v BinaryVector ) SupportString () string {
130
161
var buf bytes.Buffer
131
162
first := true
132
163
buf .WriteString ("[+" )
133
- for i , b := range V {
134
- if b == 1 {
164
+ for i := 0 ; i < v . Length (); i ++ {
165
+ if v . Get ( i ) == 1 {
135
166
if ! first {
136
167
buf .WriteString ("," )
137
168
}
@@ -143,22 +174,23 @@ func (V BinaryVector) SupportString() string {
143
174
return buf .String ()
144
175
}
145
176
146
- func (V BinaryVector ) Weight () int {
177
+ func (v BinaryVector ) Weight () int {
147
178
weight := 0
148
- for _ , b := range V {
149
- if b == 1 {
179
+ for i := 0 ; i < v . Length (); i ++ {
180
+ if v . Get ( i ) == 1 {
150
181
weight ++
151
182
}
152
183
}
153
184
return weight
154
185
}
155
186
156
187
func randomBitVector (length int ) BinaryVector {
157
- vector := make ([]uint8 , length )
158
- for i := 0 ; i < length ; i ++ {
159
- vector [i ] = uint8 (rand .Intn (2 ))
188
+ v := NewBinaryVector (length )
189
+ _ , err := rand .Read (v .data )
190
+ if err != nil {
191
+ panic (err )
160
192
}
161
- return vector
193
+ return v
162
194
}
163
195
164
196
// xxx move to BinaryVector
0 commit comments