multiarray 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- "*(#{target.to_s})"
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
@@ -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
- target = Hornetseye::Sequence OBJECT, args.size if target.dimension > 1
46
- retval = target.new
47
- args.each_with_index { |arg,i| retval[ i ] = arg }
48
- retval
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
- if offset == 0
83
- if increment == 1
84
- i
85
- else
86
- increment * i
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
- if increment == 1
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