multiarray 0.11.3 → 0.11.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,11 +17,15 @@
17
17
  # Namespace of Hornetseye computer vision library
18
18
  module Hornetseye
19
19
 
20
+ # Module providing the methods to manipulate array expressions
20
21
  module Methods
21
22
 
22
- # Extend some methods in the specified module.
23
+ # Extend some methods in the specified module
23
24
  #
24
25
  # @param [Module] mod The mathematics module.
26
+ # @return The return value should be ignored.
27
+ #
28
+ # @private
25
29
  def Methods.included( mod )
26
30
  define_unary_method mod, :sqrt , :float
27
31
  define_unary_method mod, :log , :float
@@ -43,11 +47,14 @@ module Hornetseye
43
47
  define_binary_method mod, :hypot, :floating
44
48
  end
45
49
 
46
- # Extend unary method with capability to handle arrays.
50
+ # Extend unary method with capability to handle arrays
47
51
  #
48
52
  # @param [Module] mod The mathematics module.
49
53
  # @param [Symbol,String] op The unary method to extend.
50
54
  # @param [Symbol,String] conversion A method for doing the type conversion.
55
+ # @return [Proc] The new method.
56
+ #
57
+ # @private
51
58
  def define_unary_method( mod, op, conversion = :contiguous )
52
59
  mod.module_eval do
53
60
  define_method( "#{op}_with_hornetseye" ) do |a|
@@ -73,11 +80,14 @@ module Hornetseye
73
80
 
74
81
  module_function :define_unary_method
75
82
 
76
- # Extend binary method with capability to handle arrays.
83
+ # Extend binary method with capability to handle arrays
77
84
  #
78
85
  # @param [Module] mod The mathematics module.
79
86
  # @param [Symbol,String] op The binary method to extend.
80
87
  # @param [Symbol,String] conversion A method for doing the type balancing.
88
+ # @return [Proc] The new method.
89
+ #
90
+ # @private
81
91
  def define_binary_method( mod, op, coercion = :coercion )
82
92
  mod.module_eval do
83
93
  define_method( "#{op}_with_hornetseye" ) do |a,b|
@@ -26,6 +26,8 @@ module Hornetseye
26
26
  #
27
27
  # @param [Class] typecode The type of elements
28
28
  # @param [Array<Integer>] *shape The shape of the multi-dimensional array.
29
+ #
30
+ # @return [Node] Returns uninitialised native array.
29
31
  def new( typecode, *shape )
30
32
  options = shape.last.is_a?( Hash ) ? shape.pop : {}
31
33
  count = options[ :count ] || 1
@@ -44,6 +46,15 @@ module Hornetseye
44
46
  end
45
47
  end
46
48
 
49
+ # Import array from string
50
+ #
51
+ # Create an array from raw data provided as a string.
52
+ #
53
+ # @param [Class] typecode Type of the elements in the string.
54
+ # @param [String] string String with raw data.
55
+ # @param [Array<Integer>] shape Array with dimensions of array.
56
+ #
57
+ # @return [Node] Multi-dimensional array with imported data.
47
58
  def import( typecode, string, *shape )
48
59
  t = Hornetseye::MultiArray typecode, *shape
49
60
  if string.is_a? Malloc
@@ -43,7 +43,7 @@ module Hornetseye
43
43
  #
44
44
  # @private
45
45
  def descriptor( hash )
46
- 'Node'
46
+ name
47
47
  end
48
48
 
49
49
  # Find matching native datatype to a Ruby value
@@ -117,10 +117,16 @@ module Hornetseye
117
117
  []
118
118
  end
119
119
 
120
+ # Get width of two-dimensional array
121
+ #
122
+ # @return [Integer] Width of array.
120
123
  def width
121
124
  shape[0]
122
125
  end
123
126
 
127
+ # Get height of two-dimensional array
128
+ #
129
+ # @return [Integer] Height of array.
124
130
  def height
125
131
  shape[1]
126
132
  end
@@ -155,6 +161,9 @@ module Hornetseye
155
161
  self
156
162
  end
157
163
 
164
+ # Check whether this object is an RGB value
165
+ #
166
+ # @return [Boolean] Returns +false+.
158
167
  def rgb?
159
168
  false
160
169
  end
@@ -237,6 +246,12 @@ module Hornetseye
237
246
  coercion( other ).byte
238
247
  end
239
248
 
249
+ # Get byte-based datatype for ternary operation
250
+ #
251
+ # @param [Class] a The second type.
252
+ # @param [Class] a The third type.
253
+ #
254
+ # @return [Class] Returns type based on bytes.
240
255
  def cond( a, b )
241
256
  t = a.coercion b
242
257
  Hornetseye::MultiArray( t.typecode, *shape ).coercion t
@@ -336,6 +351,9 @@ module Hornetseye
336
351
  array_type.typecode
337
352
  end
338
353
 
354
+ # Base-type of this term
355
+ #
356
+ # @return [Class] Base-type of this datatype.
339
357
  def basetype
340
358
  array_type.basetype
341
359
  end
@@ -347,10 +365,16 @@ module Hornetseye
347
365
  array_type.shape
348
366
  end
349
367
 
368
+ # Get width of two-dimensional array
369
+ #
370
+ # @return [Integer] Width of array.
350
371
  def width
351
372
  array_type.width
352
373
  end
353
374
 
375
+ # Get height of two-dimensional array
376
+ #
377
+ # @return [Integer] Height of array.
354
378
  def height
355
379
  array_type.height
356
380
  end
@@ -362,15 +386,21 @@ module Hornetseye
362
386
  array_type.size
363
387
  end
364
388
 
389
+ # Get memory size of object
390
+ #
391
+ # @return [Integer] Returns required storage size of this array.
365
392
  def storage_size
366
393
  array_type.storage_size
367
394
  end
368
395
 
396
+ # Get memory object
397
+ #
398
+ # @return [Malloc,List,NilClass] This method will return +nil+.
369
399
  def memory
370
400
  nil
371
401
  end
372
402
 
373
- # Check whether this object is an empty array.
403
+ # Check whether this object is an empty array
374
404
  #
375
405
  # @return [Boolean] Returns whether this object is an empty array.
376
406
  def empty?
@@ -384,6 +414,9 @@ module Hornetseye
384
414
  array_type.dimension
385
415
  end
386
416
 
417
+ # Check whether this object is an RGB value
418
+ #
419
+ # @return [Boolean] Returns +false+.
387
420
  def rgb?
388
421
  array_type.rgb?
389
422
  end
@@ -553,14 +586,24 @@ module Hornetseye
553
586
  end
554
587
  end
555
588
 
589
+ # Check arguments for compatible shape
590
+ #
591
+ # The method will throw an exception if one of the arguments has an incompatible
592
+ # shape.
593
+ #
594
+ # @param [Array<Node>] args Arguments to check for compatibility.
595
+ #
596
+ # @return [Object] The return value should be ignored.
556
597
  def check_shape( *args )
598
+ _shape = shape
557
599
  args.each do |arg|
558
- if dimension < arg.dimension
600
+ _arg_shape = arg.shape
601
+ if _shape.size < _arg_shape.size
559
602
  raise "#{arg.array_type.inspect} has #{arg.dimension} dimension(s) " +
560
603
  "but should not have more than #{dimension}"
561
604
  end
562
- if ( shape + arg.shape ).all? { |s| s.is_a? Integer }
563
- if shape.last( arg.dimension ) != arg.shape
605
+ if ( _shape + _arg_shape ).all? { |s| s.is_a? Integer }
606
+ if _shape.last( _arg_shape.size ) != _arg_shape
564
607
  raise "#{arg.array_type.inspect} has shape #{arg.shape.inspect} " +
565
608
  "(does not match last value(s) of #{shape.inspect})"
566
609
  end
@@ -578,7 +621,7 @@ module Hornetseye
578
621
  # @return [Object,Node] Returns the value.
579
622
  def []=( *indices )
580
623
  value = indices.pop
581
- value = Node.match( value ).new value unless value.is_a? Node
624
+ value = typecode.new value unless value.is_a? Node
582
625
  if indices.empty?
583
626
  check_shape value
584
627
  unless compilable? and value.compilable? and dimension > 0
@@ -638,10 +681,10 @@ module Hornetseye
638
681
  #
639
682
  # @private
640
683
  def force
641
- if ( dimension > 0 and Thread.current[ :lazy ] ) or not variables.empty?
642
- self
643
- elsif finalised?
684
+ if finalised?
644
685
  get
686
+ elsif ( dimension > 0 and Thread.current[ :lazy ] ) or not variables.empty?
687
+ self
645
688
  elsif compilable?
646
689
  retval = pointer_type.new
647
690
  GCCFunction.run Store.new( retval, self )
@@ -17,8 +17,17 @@
17
17
  # Namespace of Hornetseye computer vision library
18
18
  module Hornetseye
19
19
 
20
+ # Module providing the operations to manipulate array expressions
20
21
  module Operations
21
22
 
23
+ # Meta-programming method to define a unary operation
24
+ #
25
+ # @param [Symbol,String] op Name of unary operation.
26
+ # @param [Symbol,String] conversion Name of method for type conversion.
27
+ #
28
+ # @return [Proc] The new method.
29
+ #
30
+ # @private
22
31
  def define_unary_op( op, conversion = :contiguous )
23
32
  define_method( op ) do
24
33
  if dimension == 0 and variables.empty?
@@ -34,6 +43,14 @@ module Hornetseye
34
43
 
35
44
  module_function :define_unary_op
36
45
 
46
+ # Meta-programming method to define a binary operation
47
+ #
48
+ # @param [Symbol,String] op Name of binary operation.
49
+ # @param [Symbol,String] conversion Name of method for type conversion.
50
+ #
51
+ # @return [Proc] The new method.
52
+ #
53
+ # @private
37
54
  def define_binary_op( op, coercion = :coercion )
38
55
  define_method( op ) do |other|
39
56
  unless other.is_a? Node
@@ -87,10 +104,20 @@ module Hornetseye
87
104
  define_binary_op :minor
88
105
  define_binary_op :major
89
106
 
107
+ # This operation has no effect
108
+ #
109
+ # @return [Node] Returns +self+.
110
+ #
111
+ # @private
90
112
  def +@
91
113
  self
92
114
  end
93
115
 
116
+ # Convert array elements to different element type
117
+ #
118
+ # @param [Class] dest Element type to convert to.
119
+ #
120
+ # @return [Node] Array based on the different element type.
94
121
  def to_type( dest )
95
122
  if dimension == 0 and variables.empty?
96
123
  target = typecode.to_type dest
@@ -102,6 +129,13 @@ module Hornetseye
102
129
  end
103
130
  end
104
131
 
132
+ # Convert RGB array to scalar array
133
+ #
134
+ # This operation is a special case handling colour to greyscale conversion.
135
+ #
136
+ # @param [Class] dest Element type to convert to.
137
+ #
138
+ # @return [Node] Array based on the different element type.
105
139
  def to_type_with_rgb( dest )
106
140
  if typecode < RGB_
107
141
  if dest < FLOAT_
@@ -118,6 +152,12 @@ module Hornetseye
118
152
 
119
153
  alias_method_chain :to_type, :rgb
120
154
 
155
+ # Element-wise conditional selection of values
156
+ #
157
+ # @param [Node] a First array of values.
158
+ # @param [Node] b Second array of values.
159
+ #
160
+ # @return [Node] Array with selected values.
121
161
  def conditional( a, b )
122
162
  unless a.is_a? Node
123
163
  a = Node.match( a, b.is_a?( Node ) ? b : nil ).new a
@@ -137,6 +177,11 @@ module Hornetseye
137
177
  end
138
178
  end
139
179
 
180
+ # Element-wise comparison of values
181
+ #
182
+ # @param [Node] other Array with values to compare with.
183
+ #
184
+ # @return [Node] Array with results.
140
185
  def <=>( other )
141
186
  Hornetseye::lazy do
142
187
  ( self < other ).conditional -1, ( self > other ).conditional( 1, 0 )
@@ -162,6 +207,11 @@ module Hornetseye
162
207
  inject( term ) { |retval,var| Lambda.new var, retval }
163
208
  end
164
209
 
210
+ # Cycle indices of array
211
+ #
212
+ # @param [Integer] n Number of times to cycle indices of array.
213
+ #
214
+ # @return [Node] Resulting array expression with different order of indices.
165
215
  def roll( n = 1 )
166
216
  if n < 0
167
217
  unroll -n
@@ -172,6 +222,11 @@ module Hornetseye
172
222
  end
173
223
  end
174
224
 
225
+ # Reverse-cycle indices of array
226
+ #
227
+ # @param [Integer] n Number of times to cycle back indices of array.
228
+ #
229
+ # @return [Node] Resulting array expression with different order of indices.
175
230
  def unroll( n = 1 )
176
231
  if n < 0
177
232
  roll -n
@@ -182,6 +237,11 @@ module Hornetseye
182
237
  end
183
238
  end
184
239
 
240
+ # Perform element-wise operation on array
241
+ #
242
+ # @param [Proc] action Operation(s) to perform on elements.
243
+ #
244
+ # @return [Node] The resulting array.
185
245
  def collect( &action )
186
246
  var = Variable.new typecode
187
247
  block = action.call var
@@ -189,8 +249,22 @@ module Hornetseye
189
249
  Hornetseye::ElementWise( action, block.to_s, conversion ).new( self ).force
190
250
  end
191
251
 
252
+ # Perform element-wise operation on array
253
+ #
254
+ # @param [Proc] action Operation(s) to perform on elements.
255
+ #
256
+ # @return [Node] The resulting array.
192
257
  alias_method :map, :collect
193
258
 
259
+ # Perform cummulative operation on array
260
+ #
261
+ # @param [Object] initial Initial value for cummulative operation.
262
+ # @option options [Variable] :var1 First variable defining operation.
263
+ # @option options [Variable] :var1 Second variable defining operation.
264
+ # @option options [Variable] :block (yield( var1, var2 )) The operation to
265
+ # apply.
266
+ #
267
+ # @return [Object] Result of injection.
194
268
  def inject( initial = nil, options = {} )
195
269
  unless initial.nil?
196
270
  initial = Node.match( initial ).new initial unless initial.is_a? Node
@@ -209,8 +283,9 @@ module Hornetseye
209
283
  end
210
284
  else
211
285
  index = Variable.new Hornetseye::INDEX( nil )
212
- value = element( index ).
213
- inject nil, :block => block, :var1 => var1, :var2 => var2
286
+ value = element( index ).inject nil, :block => block,
287
+ :var1 => var1, :var2 => var2
288
+ value = typecode.new value unless value.is_a? Node
214
289
  Inject.new( value, index, initial, block, var1, var2 ).force
215
290
  end
216
291
  end
@@ -236,22 +311,39 @@ module Hornetseye
236
311
 
237
312
  alias_method_chain :==, :multiarray, :eq
238
313
 
314
+ # Find minimum value of array
315
+ #
316
+ # @return [Object] Minimum value of array.
239
317
  def min
240
318
  inject { |a,b| a.minor b }
241
319
  end
242
320
 
321
+ # Find maximum value of array
322
+ #
323
+ # @return [Object] Maximum value of array.
243
324
  def max
244
325
  inject { |a,b| a.major b }
245
326
  end
246
327
 
328
+ # Compute sum of array
329
+ #
330
+ # @return [Object] Sum of array.
247
331
  def sum
248
332
  inject { |a,b| a + b }
249
333
  end
250
334
 
335
+ # Find range of values of array
336
+ #
337
+ # @return [Object] Range of values of array.
251
338
  def range
252
339
  min .. max
253
340
  end
254
341
 
342
+ # Normalise values of array
343
+ #
344
+ # @param [Range] range Target range of normalisation.
345
+ #
346
+ # @return [Node] Array with normalised values.
255
347
  def normalise( range = 0 .. 0xFF )
256
348
  if range.exclude_end?
257
349
  raise "Normalisation does not support ranges with end value " +
@@ -273,6 +365,11 @@ module Hornetseye
273
365
  end
274
366
  end
275
367
 
368
+ # Fill array with a value
369
+ #
370
+ # @param [Object] value Value to fill array with.
371
+ #
372
+ # @return [Node] Return +self+.
276
373
  def fill!( value = typecode.default )
277
374
  self[] = value
278
375
  self
@@ -355,12 +452,20 @@ module Hornetseye
355
452
  product( filter ).diagonal { |s,x| s + x }
356
453
  end
357
454
 
455
+ # Compute histogram of this array
456
+ #
457
+ # @overload histogram( *ret_shape, options = {} )
458
+ # @param [Array<Integer>] ret_shape Dimensions of resulting histogram.
459
+ # @option options [Boolean] :safe (true) Do a boundary check before creating the
460
+ # histogram.
461
+ #
462
+ # @return [Node] The histogram.
358
463
  def histogram( *ret_shape )
359
464
  options = ret_shape.last.is_a?( Hash ) ? ret_shape.pop : {}
360
465
  options = { :target => UINT, :safe => true }.merge options
361
466
  if options[ :safe ]
362
467
  if shape.first != 1 and ret_shape.size == 1
363
- right = Hornetseye::lazy( 1 ) { |i| self }.unroll
468
+ right = Hornetseye::lazy( 1 ) { self }.unroll
364
469
  else
365
470
  if shape.first != ret_shape.size
366
471
  raise "First dimension of array (#{shape.first}) differs from number of " +
@@ -395,12 +500,13 @@ module Hornetseye
395
500
  left
396
501
  end
397
502
 
398
- #def histogram_with_composite( *ret_shape )
399
- # decompose.histogram_without_composite *ret_shape
400
- #end
401
-
402
- #alias_method_chain :histogram, :composite
403
-
503
+ # Perform element-wise lookup
504
+ #
505
+ # @param [Node] table The lookup table (LUT).
506
+ # @option options [Boolean] :safe (true) Do a boundary check before creating the
507
+ # element-wise lookup.
508
+ #
509
+ # @return [Node] The result of the lookup operation.
404
510
  def lut( table, options = {} )
405
511
  options = { :safe => true }.merge options
406
512
  if options[ :safe ]
@@ -441,12 +547,9 @@ module Hornetseye
441
547
  end
442
548
  end
443
549
 
444
- #def lut_with_composite( table, options = {} )
445
- # decompose.lut_without_composite table, options
446
- #end
447
-
448
- #alias_method_chain :lut, :composite
449
-
550
+ # Compute integral image
551
+ #
552
+ # @return [Node] The integral image of this array.
450
553
  def integral
451
554
  left = pointer_type.new
452
555
  block = Integral.new left, self