multiarray 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +39 -5
- data/TODO +11 -66
- data/lib/multiarray.rb +59 -12
- data/lib/multiarray/binarymethod.rb +195 -0
- data/lib/multiarray/{binary.rb → binaryop.rb} +27 -12
- data/lib/multiarray/bool.rb +8 -2
- data/lib/multiarray/diagonal.rb +26 -27
- data/lib/multiarray/element.rb +23 -5
- data/lib/multiarray/float.rb +142 -0
- data/lib/multiarray/gcccontext.rb +29 -25
- data/lib/multiarray/gccfunction.rb +24 -7
- data/lib/multiarray/gcctype.rb +26 -16
- data/lib/multiarray/gccvalue.rb +144 -74
- data/lib/multiarray/inject.rb +12 -15
- data/lib/multiarray/int.rb +109 -82
- data/lib/multiarray/lambda.rb +23 -1
- data/lib/multiarray/lookup.rb +14 -1
- data/lib/multiarray/malloc.rb +2 -2
- data/lib/multiarray/methods.rb +93 -0
- data/lib/multiarray/multiarray.rb +2 -12
- data/lib/multiarray/node.rb +103 -173
- data/lib/multiarray/object.rb +19 -1
- data/lib/multiarray/operations.rb +189 -9
- data/lib/multiarray/pointer.rb +9 -1
- data/lib/multiarray/rgb.rb +401 -0
- data/lib/multiarray/sequence.rb +56 -14
- data/lib/multiarray/unarymethod.rb +185 -0
- data/lib/multiarray/{unary.rb → unaryop.rb} +20 -11
- data/lib/multiarray/variable.rb +8 -0
- data/test/tc_bool.rb +32 -20
- data/test/tc_float.rb +192 -0
- data/test/tc_int.rb +52 -24
- data/test/tc_lazy.rb +109 -0
- data/test/tc_multiarray.rb +136 -2
- data/test/tc_object.rb +29 -11
- data/test/tc_rgb.rb +217 -0
- data/test/tc_sequence.rb +184 -52
- data/test/ts_multiarray.rb +3 -0
- metadata +42 -15
data/lib/multiarray/pointer.rb
CHANGED
@@ -25,6 +25,10 @@ module Hornetseye
|
|
25
25
|
# @return [Node] Type of object the pointer is pointing at.
|
26
26
|
attr_accessor :target
|
27
27
|
|
28
|
+
def construct( *args )
|
29
|
+
new *args
|
30
|
+
end
|
31
|
+
|
28
32
|
def inspect
|
29
33
|
"*(#{target.inspect})"
|
30
34
|
end
|
@@ -37,7 +41,7 @@ module Hornetseye
|
|
37
41
|
#
|
38
42
|
# @private
|
39
43
|
def descriptor( hash )
|
40
|
-
|
44
|
+
inspect
|
41
45
|
end
|
42
46
|
|
43
47
|
# Get default value for elements of this type
|
@@ -128,6 +132,10 @@ module Hornetseye
|
|
128
132
|
end
|
129
133
|
end
|
130
134
|
|
135
|
+
def values
|
136
|
+
[ @value ]
|
137
|
+
end
|
138
|
+
|
131
139
|
end
|
132
140
|
|
133
141
|
def Pointer( target )
|
@@ -0,0 +1,401 @@
|
|
1
|
+
# multiarray - Lazy multi-dimensional arrays for Ruby
|
2
|
+
# Copyright (C) 2010 Jan Wedekind
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
# Namespace of Hornetseye computer vision library
|
18
|
+
module Hornetseye
|
19
|
+
|
20
|
+
class RGB
|
21
|
+
|
22
|
+
class << self
|
23
|
+
|
24
|
+
def generic?( value )
|
25
|
+
value.is_a?( Numeric ) or value.is_a?( GCCValue )
|
26
|
+
end
|
27
|
+
|
28
|
+
def define_unary_op( op )
|
29
|
+
define_method( op ) do
|
30
|
+
RGB.new r.send( op ), g.send( op ), b.send( op )
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def define_binary_op( op )
|
35
|
+
define_method( op ) do |other|
|
36
|
+
if other.is_a? RGB
|
37
|
+
RGB.new r.send( op, other.r ), g.send( op, other.g ),
|
38
|
+
b.send( op, other.b )
|
39
|
+
elsif RGB.generic? other
|
40
|
+
RGB.new r.send( op, other ), g.send( op, other ),
|
41
|
+
b.send( op, other )
|
42
|
+
else
|
43
|
+
x, y = other.coerce self
|
44
|
+
x.send op, y
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :r, :g, :b
|
52
|
+
|
53
|
+
def initialize( r, g, b )
|
54
|
+
@r, @g, @b = r, g, b
|
55
|
+
end
|
56
|
+
|
57
|
+
def inspect
|
58
|
+
"RGB(#{@r.inspect},#{@g.inspect},#{@b.inspect})"
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
"RGB(#{@r.to_s},#{@g.to_s},#{@b.to_s})"
|
63
|
+
end
|
64
|
+
|
65
|
+
def store( value )
|
66
|
+
@r, @g, @b = value.r, value.g, value.b
|
67
|
+
end
|
68
|
+
|
69
|
+
def coerce( other )
|
70
|
+
if other.is_a? RGB
|
71
|
+
return other, self
|
72
|
+
else
|
73
|
+
return RGB.new( other, other, other ), self
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def +@
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
define_unary_op :~
|
82
|
+
define_unary_op :-@
|
83
|
+
define_binary_op :+
|
84
|
+
define_binary_op :-
|
85
|
+
define_binary_op :*
|
86
|
+
define_binary_op :/
|
87
|
+
define_binary_op :%
|
88
|
+
define_binary_op :&
|
89
|
+
define_binary_op :|
|
90
|
+
define_binary_op :^
|
91
|
+
define_binary_op :<<
|
92
|
+
define_binary_op :>>
|
93
|
+
define_binary_op :minor
|
94
|
+
define_binary_op :major
|
95
|
+
|
96
|
+
def zero?
|
97
|
+
@r.zero?.and( @g.zero? ).and( @b.zero? )
|
98
|
+
end
|
99
|
+
|
100
|
+
def nonzero?
|
101
|
+
@r.nonzero?.or( @g.nonzero? ).or( @b.nonzero? )
|
102
|
+
end
|
103
|
+
|
104
|
+
def ==( other )
|
105
|
+
if other.is_a? RGB
|
106
|
+
@r.eq( other.r ).and( @g.eq( other.g ) ).and( @b.eq( other.b ) )
|
107
|
+
elsif RGB.generic? other
|
108
|
+
@r.eq( other ).and( @g.eq( other ) ).and( @b.eq( other ) )
|
109
|
+
else
|
110
|
+
false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
class RGB_ < Element
|
117
|
+
|
118
|
+
class << self
|
119
|
+
|
120
|
+
attr_accessor :element_type
|
121
|
+
|
122
|
+
def fetch( ptr )
|
123
|
+
construct *ptr.load( self )
|
124
|
+
end
|
125
|
+
|
126
|
+
def construct( r, g, b )
|
127
|
+
new Hornetseye::RGB( r, g, b )
|
128
|
+
end
|
129
|
+
|
130
|
+
def memory
|
131
|
+
element_type.memory
|
132
|
+
end
|
133
|
+
|
134
|
+
def storage_size
|
135
|
+
element_type.storage_size * 3
|
136
|
+
end
|
137
|
+
|
138
|
+
def default
|
139
|
+
Hornetseye::RGB 0, 0, 0
|
140
|
+
end
|
141
|
+
|
142
|
+
def directive
|
143
|
+
element_type.directive * 3
|
144
|
+
end
|
145
|
+
|
146
|
+
def inspect
|
147
|
+
unless element_type.nil?
|
148
|
+
{ BYTE => 'BYTERGB',
|
149
|
+
UBYTE => 'UBYTERGB',
|
150
|
+
SINT => 'SINTRGB',
|
151
|
+
USINT => 'USINTRGB',
|
152
|
+
INT => 'INTRGB',
|
153
|
+
UINT => 'UINTRGB',
|
154
|
+
LONG => 'LONGRGB',
|
155
|
+
ULONG => 'ULONGRGB',
|
156
|
+
SFLOAT => 'SFLOATRGB',
|
157
|
+
DFLOAT => 'DFLOATRGB' }[ element_type ] ||
|
158
|
+
"RGB(#{element_type.inspect})"
|
159
|
+
else
|
160
|
+
super
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def descriptor( hash )
|
165
|
+
unless element_type.nil?
|
166
|
+
inspect
|
167
|
+
else
|
168
|
+
super
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def basetype
|
173
|
+
element_type
|
174
|
+
end
|
175
|
+
|
176
|
+
def typecodes
|
177
|
+
[ element_type ] * 3
|
178
|
+
end
|
179
|
+
|
180
|
+
def maxint
|
181
|
+
Hornetseye::RGB element_type.maxint
|
182
|
+
end
|
183
|
+
|
184
|
+
def float
|
185
|
+
Hornetseye::RGB element_type.float
|
186
|
+
end
|
187
|
+
|
188
|
+
def coercion( other )
|
189
|
+
if other < RGB_
|
190
|
+
Hornetseye::RGB element_type.coercion( other.element_type )
|
191
|
+
elsif other < INT_ or other < FLOAT_
|
192
|
+
Hornetseye::RGB element_type.coercion( other )
|
193
|
+
else
|
194
|
+
super other
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def coerce( other )
|
199
|
+
if other < RGB_
|
200
|
+
return other, self
|
201
|
+
elsif other < INT_ or other < FLOAT_
|
202
|
+
return Hornetseye::RGB( other ), self
|
203
|
+
else
|
204
|
+
super other
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def ==( other )
|
209
|
+
other.is_a? Class and other < RGB_ and
|
210
|
+
element_type == other.element_type
|
211
|
+
end
|
212
|
+
|
213
|
+
def hash
|
214
|
+
[ :RGB_, element_type ].hash
|
215
|
+
end
|
216
|
+
|
217
|
+
def eql?( other )
|
218
|
+
self == other
|
219
|
+
end
|
220
|
+
|
221
|
+
#def compilable?
|
222
|
+
# false # !!!
|
223
|
+
#end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
def initialize( value = self.class.default )
|
228
|
+
if Thread.current[ :function ].nil? or
|
229
|
+
[ value.r, value.g, value.b ].all? { |c| c.is_a? GCCValue }
|
230
|
+
@value = value
|
231
|
+
else
|
232
|
+
r = GCCValue.new Thread.current[ :function ], value.r.to_s
|
233
|
+
g = GCCValue.new Thread.current[ :function ], value.r.to_s
|
234
|
+
b = GCCValue.new Thread.current[ :function ], value.r.to_s
|
235
|
+
@value = RGB.new r, g, b
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def dup
|
240
|
+
if Thread.current[ :function ]
|
241
|
+
r = Thread.current[ :function ].variable self.class.element_type, 'v'
|
242
|
+
g = Thread.current[ :function ].variable self.class.element_type, 'v'
|
243
|
+
b = Thread.current[ :function ].variable self.class.element_type, 'v'
|
244
|
+
r.get.store @value.r
|
245
|
+
g.get.store @value.g
|
246
|
+
b.get.store @value.b
|
247
|
+
self.class.new RGB.new( r.get, g.get, b.get )
|
248
|
+
else
|
249
|
+
self.class.new get
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def store( value )
|
254
|
+
value = value.simplify
|
255
|
+
if @value.r.respond_to? :store
|
256
|
+
@value.r.store value.get.r
|
257
|
+
else
|
258
|
+
@value.r = value.get.r
|
259
|
+
end
|
260
|
+
if @value.g.respond_to? :store
|
261
|
+
@value.g.store value.get.g
|
262
|
+
else
|
263
|
+
@value.g = value.get.g
|
264
|
+
end
|
265
|
+
if @value.b.respond_to? :store
|
266
|
+
@value.b.store value.get.b
|
267
|
+
else
|
268
|
+
@value.b = value.get.b
|
269
|
+
end
|
270
|
+
value
|
271
|
+
end
|
272
|
+
|
273
|
+
def values
|
274
|
+
[ @value.r, @value.g, @value.b ]
|
275
|
+
end
|
276
|
+
|
277
|
+
module Match
|
278
|
+
|
279
|
+
def fit( *values )
|
280
|
+
if values.all? { |value| value.is_a? RGB or value.is_a? Float or
|
281
|
+
value.is_a? Integer }
|
282
|
+
if values.any? { |value| value.is_a? RGB }
|
283
|
+
elements = values.inject( [] ) do |arr,value|
|
284
|
+
if value.is_a? RGB
|
285
|
+
arr + [ value.r, value.g, value.b ]
|
286
|
+
else
|
287
|
+
arr + [ value ]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
element_fit = fit *elements
|
291
|
+
if element_fit == OBJECT
|
292
|
+
super *values
|
293
|
+
else
|
294
|
+
Hornetseye::RGB element_fit
|
295
|
+
end
|
296
|
+
else
|
297
|
+
super *values
|
298
|
+
end
|
299
|
+
else
|
300
|
+
super *values
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def align( context )
|
305
|
+
if self < RGB_
|
306
|
+
Hornetseye::RGB element_type.align( context )
|
307
|
+
else
|
308
|
+
super context
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
Node.extend Match
|
315
|
+
|
316
|
+
end
|
317
|
+
|
318
|
+
def RGB( arg, g = nil, b = nil )
|
319
|
+
if g.nil? and b.nil?
|
320
|
+
retval = Class.new RGB_
|
321
|
+
retval.element_type = arg
|
322
|
+
retval
|
323
|
+
else
|
324
|
+
RGB.new arg, g, b
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
module_function :RGB
|
329
|
+
|
330
|
+
BYTERGB = RGB BYTE
|
331
|
+
|
332
|
+
UBYTERGB = RGB UBYTE
|
333
|
+
|
334
|
+
SINTRGB = RGB SINT
|
335
|
+
|
336
|
+
USINTRGB = RGB USINT
|
337
|
+
|
338
|
+
INTRGB = RGB INT
|
339
|
+
|
340
|
+
UINTRGB = RGB UINT
|
341
|
+
|
342
|
+
LONGRGB = RGB LONG
|
343
|
+
|
344
|
+
ULONGRGB = RGB ULONG
|
345
|
+
|
346
|
+
SFLOATRGB = RGB SFLOAT
|
347
|
+
|
348
|
+
DFLOATRGB = RGB DFLOAT
|
349
|
+
|
350
|
+
def BYTERGB( value )
|
351
|
+
BYTERGB.new value
|
352
|
+
end
|
353
|
+
|
354
|
+
def UBYTERGB( value )
|
355
|
+
UBYTERGB.new value
|
356
|
+
end
|
357
|
+
|
358
|
+
def SINTRGB( value )
|
359
|
+
SINTRGB.new value
|
360
|
+
end
|
361
|
+
|
362
|
+
def USINTRGB( value )
|
363
|
+
USINTRGB.new value
|
364
|
+
end
|
365
|
+
|
366
|
+
def INTRGB( value )
|
367
|
+
INTRGB.new value
|
368
|
+
end
|
369
|
+
|
370
|
+
def UINTRGB( value )
|
371
|
+
UINTRGB.new value
|
372
|
+
end
|
373
|
+
|
374
|
+
def LONGRGB( value )
|
375
|
+
LONGRGB.new value
|
376
|
+
end
|
377
|
+
|
378
|
+
def ULONGRGB( value )
|
379
|
+
ULONGRGB.new value
|
380
|
+
end
|
381
|
+
|
382
|
+
def SFLOATRGB( value )
|
383
|
+
SFLOATRGB.new value
|
384
|
+
end
|
385
|
+
|
386
|
+
def DFLOATRGB( value )
|
387
|
+
DFLOATRGB.new value
|
388
|
+
end
|
389
|
+
|
390
|
+
module_function :BYTERGB
|
391
|
+
module_function :UBYTERGB
|
392
|
+
module_function :SINTRGB
|
393
|
+
module_function :USINTRGB
|
394
|
+
module_function :INTRGB
|
395
|
+
module_function :UINTRGB
|
396
|
+
module_function :LONGRGB
|
397
|
+
module_function :ULONGRGB
|
398
|
+
module_function :SFLOATRGB
|
399
|
+
module_function :DFLOATRGB
|
400
|
+
|
401
|
+
end
|
data/lib/multiarray/sequence.rb
CHANGED
@@ -42,10 +42,12 @@ module Hornetseye
|
|
42
42
|
# @return [Node] Returns native array with values.
|
43
43
|
def []( *args )
|
44
44
|
target = Node.fit args
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
if target.dimension == 0
|
46
|
+
target = Hornetseye::Sequence target, 0
|
47
|
+
elsif target.dimension > 1
|
48
|
+
target = Hornetseye::Sequence OBJECT, args.size
|
49
|
+
end
|
50
|
+
target[ *args ]
|
49
51
|
end
|
50
52
|
|
51
53
|
end
|
@@ -79,30 +81,46 @@ module Hornetseye
|
|
79
81
|
|
80
82
|
def indgen( offset = 0, increment = 1 )
|
81
83
|
Hornetseye::lazy( num_elements ) do |i|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
element_type.size * increment * i +
|
85
|
+
element_type.indgen( offset, increment )
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def []( *args )
|
90
|
+
retval = new
|
91
|
+
recursion = proc do |element,args|
|
92
|
+
if element.dimension > 0
|
93
|
+
args.each_with_index do |arg,i|
|
94
|
+
recursion.call element.element( i ), arg
|
87
95
|
end
|
88
96
|
else
|
89
|
-
|
90
|
-
offset + i
|
91
|
-
else
|
92
|
-
offset + increment * i
|
93
|
-
end
|
97
|
+
element[] = args
|
94
98
|
end
|
95
99
|
end
|
100
|
+
recursion.call retval, args
|
101
|
+
retval
|
96
102
|
end
|
97
103
|
|
98
104
|
def shape
|
99
105
|
element_type.shape + [ num_elements ]
|
100
106
|
end
|
101
107
|
|
108
|
+
def size
|
109
|
+
num_elements * element_type.size
|
110
|
+
end
|
111
|
+
|
112
|
+
def empty?
|
113
|
+
size == 0
|
114
|
+
end
|
115
|
+
|
102
116
|
def typecode
|
103
117
|
element_type.typecode
|
104
118
|
end
|
105
119
|
|
120
|
+
def basetype
|
121
|
+
element_type.basetype
|
122
|
+
end
|
123
|
+
|
106
124
|
def array_type
|
107
125
|
self
|
108
126
|
end
|
@@ -127,6 +145,22 @@ module Hornetseye
|
|
127
145
|
coercion( other ).bool
|
128
146
|
end
|
129
147
|
|
148
|
+
def maxint
|
149
|
+
Hornetseye::Sequence element_type.maxint, num_elements
|
150
|
+
end
|
151
|
+
|
152
|
+
def largeint( other )
|
153
|
+
coercion( other ).maxint
|
154
|
+
end
|
155
|
+
|
156
|
+
def float
|
157
|
+
Hornetseye::Sequence element_type.float, num_elements
|
158
|
+
end
|
159
|
+
|
160
|
+
def floating( other )
|
161
|
+
coercion( other ).float
|
162
|
+
end
|
163
|
+
|
130
164
|
def inspect
|
131
165
|
if dimension == 1
|
132
166
|
"Sequence(#{typecode.inspect},#{num_elements.inspect})"
|
@@ -215,6 +249,14 @@ module Hornetseye
|
|
215
249
|
end
|
216
250
|
end
|
217
251
|
|
252
|
+
def align( context )
|
253
|
+
if self < Sequence_
|
254
|
+
Hornetseye::Sequence element_type.align( context ), num_elements
|
255
|
+
else
|
256
|
+
super context
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
218
260
|
end
|
219
261
|
|
220
262
|
Node.extend Match
|