multiarray 0.11.3 → 0.11.4

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.
@@ -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