multiarray 0.5.2 → 0.6.0
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 +2 -1
- data/TODO +7 -36
- data/lib/multiarray/bool.rb +14 -4
- data/lib/multiarray/complex.rb +467 -38
- data/lib/multiarray/composite.rb +44 -0
- data/lib/multiarray/diagonal.rb +10 -3
- data/lib/multiarray/element.rb +29 -3
- data/lib/multiarray/elementwise.rb +32 -3
- data/lib/multiarray/float.rb +120 -18
- data/lib/multiarray/gccfunction.rb +11 -21
- data/lib/multiarray/gcctype.rb +23 -17
- data/lib/multiarray/gccvalue.rb +25 -2
- data/lib/multiarray/histogram.rb +82 -0
- data/lib/multiarray/index.rb +23 -0
- data/lib/multiarray/inject.rb +13 -1
- data/lib/multiarray/int.rb +105 -9
- data/lib/multiarray/integral.rb +82 -0
- data/lib/multiarray/lambda.rb +58 -8
- data/lib/multiarray/list.rb +27 -1
- data/lib/multiarray/lookup.rb +60 -0
- data/lib/multiarray/lut.rb +102 -0
- data/lib/multiarray/malloc.rb +16 -0
- data/lib/multiarray/methods.rb +17 -0
- data/lib/multiarray/multiarray.rb +24 -2
- data/lib/multiarray/node.rb +115 -21
- data/lib/multiarray/object.rb +34 -4
- data/lib/multiarray/operations.rb +92 -100
- data/lib/multiarray/pointer.rb +74 -1
- data/lib/multiarray/rgb.rb +324 -2
- data/lib/multiarray/sequence.rb +69 -4
- data/lib/multiarray/shortcuts.rb +71 -0
- data/lib/multiarray/store.rb +72 -0
- data/lib/multiarray/variable.rb +25 -0
- data/lib/multiarray.rb +47 -5
- data/test/tc_int.rb +10 -0
- data/test/tc_multiarray.rb +47 -1
- data/test/tc_object.rb +10 -0
- data/test/tc_sequence.rb +237 -8
- metadata +9 -9
@@ -0,0 +1,71 @@
|
|
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
|
+
module ConstructorShortcuts
|
21
|
+
|
22
|
+
def method_missing( name, *args )
|
23
|
+
if name.to_s =~ /^[a-z]+$/
|
24
|
+
target = name.to_s.upcase
|
25
|
+
if Hornetseye.const_defined? target
|
26
|
+
target = Hornetseye.const_get target
|
27
|
+
if target.is_a? Class and target < Element
|
28
|
+
new target, *args
|
29
|
+
else
|
30
|
+
super name, *args
|
31
|
+
end
|
32
|
+
else
|
33
|
+
super name, *args
|
34
|
+
end
|
35
|
+
else
|
36
|
+
super name, *args
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
Sequence.extend ConstructorShortcuts
|
43
|
+
|
44
|
+
MultiArray.extend ConstructorShortcuts
|
45
|
+
|
46
|
+
module ConversionShortcuts
|
47
|
+
|
48
|
+
def method_missing( name, *args )
|
49
|
+
if name.to_s =~ /^to_[a-z]+$/
|
50
|
+
target = name.to_s[ 3 .. -1 ].upcase
|
51
|
+
if Hornetseye.const_defined? target
|
52
|
+
target = Hornetseye.const_get target
|
53
|
+
if target.is_a? Class and target < Element
|
54
|
+
to_type target, *args
|
55
|
+
else
|
56
|
+
super target, *args
|
57
|
+
end
|
58
|
+
else
|
59
|
+
super name, *args
|
60
|
+
end
|
61
|
+
else
|
62
|
+
super name, *args
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
Node.class_eval { include ConversionShortcuts }
|
69
|
+
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,72 @@
|
|
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
|
+
module Hornetseye
|
18
|
+
|
19
|
+
class Store < Node
|
20
|
+
|
21
|
+
def initialize( dest, source )
|
22
|
+
@dest, @source = dest, source
|
23
|
+
end
|
24
|
+
|
25
|
+
def descriptor( hash )
|
26
|
+
"Store(#{@dest.descriptor( hash )},#{@source.descriptor( hash )})"
|
27
|
+
end
|
28
|
+
|
29
|
+
def array_type
|
30
|
+
@dest.array_type
|
31
|
+
end
|
32
|
+
|
33
|
+
def demand
|
34
|
+
if variables.empty?
|
35
|
+
if dimension > 0
|
36
|
+
shape.last.times do |i|
|
37
|
+
dest = @dest.element INT.new( i )
|
38
|
+
source = @source.dimension == 0 ? @source :
|
39
|
+
@source.element( INT.new( i ) )
|
40
|
+
Store.new( dest, source ).demand
|
41
|
+
end
|
42
|
+
else
|
43
|
+
@dest.store @source.demand
|
44
|
+
end
|
45
|
+
@dest
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def subst( hash )
|
52
|
+
self.class.new @dest.subst( hash ), @source.subst( hash )
|
53
|
+
end
|
54
|
+
|
55
|
+
def variables
|
56
|
+
@dest.variables + @source.variables
|
57
|
+
end
|
58
|
+
|
59
|
+
def strip
|
60
|
+
vars1, values1, term1 = @dest.strip
|
61
|
+
vars2, values2, term2 = @source.strip
|
62
|
+
return vars1 + vars2, values1 + values2, Store.new( term1, term2 )
|
63
|
+
end
|
64
|
+
|
65
|
+
def compilable?
|
66
|
+
@dest.compilable? and @source.compilable?
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
data/lib/multiarray/variable.rb
CHANGED
@@ -28,6 +28,10 @@ module Hornetseye
|
|
28
28
|
@meta = meta
|
29
29
|
end
|
30
30
|
|
31
|
+
# Display string with information about this object
|
32
|
+
#
|
33
|
+
# @return [String] String with information about this object (e.g.
|
34
|
+
# 'Variable(INT)').
|
31
35
|
def inspect
|
32
36
|
"Variable(#{@meta.inspect})"
|
33
37
|
end
|
@@ -47,14 +51,27 @@ module Hornetseye
|
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
54
|
+
# Get array size for index variable
|
55
|
+
#
|
56
|
+
# @return [Node] Get the dimension of the array if this is an index variable.
|
50
57
|
def size
|
51
58
|
@meta.size
|
52
59
|
end
|
53
60
|
|
61
|
+
# Set array size for index variable
|
62
|
+
#
|
63
|
+
# Set the dimension of the array assuming this is an index variable.
|
64
|
+
#
|
65
|
+
# @param [Node] value The new size.
|
54
66
|
def size=( value )
|
55
67
|
@meta.size = value
|
56
68
|
end
|
57
69
|
|
70
|
+
# Get type of result of delayed operation
|
71
|
+
#
|
72
|
+
# @return [Class] Type of result.
|
73
|
+
#
|
74
|
+
# @private
|
58
75
|
def array_type
|
59
76
|
@meta.array_type
|
60
77
|
end
|
@@ -115,6 +132,14 @@ module Hornetseye
|
|
115
132
|
Lookup.new self, value, stride
|
116
133
|
end
|
117
134
|
|
135
|
+
# Skip elements of an array
|
136
|
+
#
|
137
|
+
# @param [Variable] index Variable identifying index of array.
|
138
|
+
# @param [Node] start Wrapped integer with number of elements to skip.
|
139
|
+
#
|
140
|
+
# @return [Node] Return variable with offset added or +self+.
|
141
|
+
#
|
142
|
+
# @private
|
118
143
|
def skip( index, start )
|
119
144
|
if index == self
|
120
145
|
self + start
|
data/lib/multiarray.rb
CHANGED
@@ -21,7 +21,13 @@ class Module
|
|
21
21
|
|
22
22
|
unless method_defined? :alias_method_chain
|
23
23
|
|
24
|
-
# Method for creating alias chains
|
24
|
+
# Method for creating alias chains
|
25
|
+
#
|
26
|
+
# @param [Symbol,String] target Method to rename.
|
27
|
+
# @param [Symbol,String] feature Feature to use for renaming.
|
28
|
+
# @param [Symbol,String] vocalize Override to use when renaming operators.
|
29
|
+
#
|
30
|
+
# @return [Module] Returns this module.
|
25
31
|
#
|
26
32
|
# @private
|
27
33
|
def alias_method_chain( target, feature, vocalize = target )
|
@@ -44,6 +50,8 @@ class Proc
|
|
44
50
|
#
|
45
51
|
# @param [Object] object Object to bind this instance of +Proc+ to.
|
46
52
|
#
|
53
|
+
# @return [Method] The bound method.
|
54
|
+
#
|
47
55
|
# @private
|
48
56
|
def bind( object )
|
49
57
|
block, time = self, Time.now
|
@@ -416,22 +424,39 @@ end
|
|
416
424
|
|
417
425
|
class Numeric
|
418
426
|
|
427
|
+
# Compute complex conjugate
|
428
|
+
#
|
429
|
+
# @return [Numeric] Returns +self+.
|
419
430
|
def conj
|
420
431
|
self
|
421
432
|
end
|
422
433
|
|
434
|
+
# Get red component
|
435
|
+
#
|
436
|
+
# @return [Numeric] Returns +self+.
|
423
437
|
def r
|
424
438
|
self
|
425
439
|
end
|
426
440
|
|
441
|
+
# Get green component
|
442
|
+
#
|
443
|
+
# @return [Numeric] Returns +self+.
|
427
444
|
def g
|
428
445
|
self
|
429
446
|
end
|
430
447
|
|
448
|
+
# Get blue component
|
449
|
+
#
|
450
|
+
# @return [Numeric] Returns +self+.
|
431
451
|
def b
|
432
452
|
self
|
433
453
|
end
|
434
454
|
|
455
|
+
# Get larger number of two numbers
|
456
|
+
#
|
457
|
+
# @param [Numeric] other The other number.
|
458
|
+
#
|
459
|
+
# @return [Numeric] The larger number of the two.
|
435
460
|
def major( other )
|
436
461
|
if other.is_a? Numeric
|
437
462
|
( self >= other ).conditional self, other
|
@@ -441,6 +466,11 @@ class Numeric
|
|
441
466
|
end
|
442
467
|
end
|
443
468
|
|
469
|
+
# Get smaller number of two numbers
|
470
|
+
#
|
471
|
+
# @param [Numeric] other The other number.
|
472
|
+
#
|
473
|
+
# @return [Numeric] The smaller number of the two.
|
444
474
|
def minor( other )
|
445
475
|
if other.is_a? Numeric
|
446
476
|
( self <= other ).conditional self, other
|
@@ -454,6 +484,13 @@ end
|
|
454
484
|
|
455
485
|
class Array
|
456
486
|
|
487
|
+
# Element-wise operation based on element and its index
|
488
|
+
#
|
489
|
+
# Same as +Array#collect+ but with index.
|
490
|
+
#
|
491
|
+
# @param &action Closure accepting an element and an index.
|
492
|
+
#
|
493
|
+
# @return [Array<Object>] Array with results.
|
457
494
|
def collect_with_index( &action )
|
458
495
|
zip( ( 0 ... size ).to_a ).collect &action
|
459
496
|
end
|
@@ -470,24 +507,29 @@ require 'multiarray/list'
|
|
470
507
|
require 'multiarray/node'
|
471
508
|
require 'multiarray/element'
|
472
509
|
require 'multiarray/composite'
|
510
|
+
require 'multiarray/store'
|
473
511
|
require 'multiarray/object'
|
474
512
|
require 'multiarray/index'
|
475
513
|
require 'multiarray/bool'
|
476
514
|
require 'multiarray/int'
|
477
515
|
require 'multiarray/float'
|
478
|
-
require 'multiarray/rgb'
|
479
|
-
require 'multiarray/complex'
|
480
516
|
require 'multiarray/pointer'
|
481
517
|
require 'multiarray/variable'
|
482
518
|
require 'multiarray/lambda'
|
483
519
|
require 'multiarray/lookup'
|
484
520
|
require 'multiarray/elementwise'
|
485
|
-
require 'multiarray/operations'
|
486
|
-
require 'multiarray/methods'
|
487
521
|
require 'multiarray/inject'
|
488
522
|
require 'multiarray/diagonal'
|
523
|
+
require 'multiarray/histogram'
|
524
|
+
require 'multiarray/lut'
|
525
|
+
require 'multiarray/integral'
|
526
|
+
require 'multiarray/operations'
|
527
|
+
require 'multiarray/methods'
|
528
|
+
require 'multiarray/rgb'
|
529
|
+
require 'multiarray/complex'
|
489
530
|
require 'multiarray/sequence'
|
490
531
|
require 'multiarray/multiarray'
|
532
|
+
require 'multiarray/shortcuts'
|
491
533
|
require 'multiarray/gcctype'
|
492
534
|
require 'multiarray/gccvalue'
|
493
535
|
require 'multiarray/gcccontext'
|
data/test/tc_int.rb
CHANGED
@@ -209,5 +209,15 @@ class TC_Int < Test::Unit::TestCase
|
|
209
209
|
assert_equal I( 4 ), I( 5 ).minor( I( 4 ) )
|
210
210
|
end
|
211
211
|
|
212
|
+
def test_fill
|
213
|
+
i = I 0
|
214
|
+
assert_equal I( 3 ), i.fill!( 3 )
|
215
|
+
assert_equal I( 3 ), i
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_integral
|
219
|
+
assert_equal I( 3 ), I( 3 ).integral
|
220
|
+
end
|
221
|
+
|
212
222
|
end
|
213
223
|
|
data/test/tc_multiarray.rb
CHANGED
@@ -364,6 +364,14 @@ class TC_MultiArray < Test::Unit::TestCase
|
|
364
364
|
assert_equal 7, M[ [ 5, 3, 7 ], [ 2, 1, 6 ] ].max
|
365
365
|
end
|
366
366
|
|
367
|
+
def test_sum
|
368
|
+
assert_equal 24, M[ [ 5, 3, 7 ], [ 2, 1, 6 ] ].sum
|
369
|
+
end
|
370
|
+
|
371
|
+
def test_range
|
372
|
+
assert_equal 1 .. 7, M[ [ 5, 3, 7 ], [ 2, 1, 6 ] ].range
|
373
|
+
end
|
374
|
+
|
367
375
|
def test_diagonal
|
368
376
|
assert_equal S[ 'b1a2', 'c1b2a3', 'c2b3' ],
|
369
377
|
M[ [ 'a1', 'a2', 'a3' ],
|
@@ -398,6 +406,32 @@ class TC_MultiArray < Test::Unit::TestCase
|
|
398
406
|
assert_raise( RuntimeError ) { M[ [ 1, 2, 3 ], [ 4, 5, 6 ] ].convolve S[ 1, 2 ] }
|
399
407
|
end
|
400
408
|
|
409
|
+
def test_histogram
|
410
|
+
assert_equal S( I, 5 )[ 0, 1, 1, 2, 0 ],
|
411
|
+
M[ [ 1, 2 ], [ 3, 3 ] ].histogram( 5, :target => I )
|
412
|
+
assert_equal M( I, 2, 2 )[ [ 1, 0 ], [ 1, 1 ] ],
|
413
|
+
M[ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ] ].histogram( 2, 2, :target => I )
|
414
|
+
assert_equal M( I, 2, 2, 1 )[ [ [ 0, 1 ], [ 1, 0 ] ] ],
|
415
|
+
S[ C( 1, 0, 0 ), C( 0, 1, 0 ) ].histogram( 2, 2, 1, :target => I )
|
416
|
+
assert_raise( RuntimeError ) { S[ 1, 2, 3 ].histogram 4, 4 }
|
417
|
+
assert_raise( RuntimeError ) { M[ [ -1, 0 ] ].histogram 3, 2 }
|
418
|
+
assert_raise( RuntimeError ) { M[ [ 0, -1 ] ].histogram 3, 2 }
|
419
|
+
assert_raise( RuntimeError ) { M[ [ 3, 0 ] ].histogram 3, 2 }
|
420
|
+
assert_raise( RuntimeError ) { M[ [ 0, 2 ] ].histogram 3, 2 }
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_lut
|
424
|
+
assert_equal M[ [ 1, 2 ], [ 3, 1 ] ],
|
425
|
+
M[ [ 0, 1 ], [ 2, 0 ] ].lut( S[ 1, 2, 3, 4 ] )
|
426
|
+
assert_equal M[ 1, 3, 4 ],
|
427
|
+
M[ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ] ].lut( M[ [ 1, 2 ], [ 3, 4 ] ] )
|
428
|
+
assert_raise( RuntimeError ) { S[ 0, 1, 2 ].lut M[ [ 1, 2 ], [ 3, 4 ] ] }
|
429
|
+
assert_raise( RuntimeError ) { M[ [ -1, 0 ] ].lut M[ [ 1, 2 ] ] }
|
430
|
+
assert_raise( RuntimeError ) { M[ [ 0, -1 ] ].lut M[ [ 1, 2 ] ] }
|
431
|
+
assert_raise( RuntimeError ) { M[ [ 2, 0 ] ].lut M[ [ 1, 2 ] ] }
|
432
|
+
assert_raise( RuntimeError ) { M[ [ 0, 1 ] ].lut M[ [ 1, 2 ] ] }
|
433
|
+
end
|
434
|
+
|
401
435
|
def test_zero
|
402
436
|
assert_equal M[ [ false, true ], [ true, false ] ],
|
403
437
|
M[ [ -1, 0 ], [ 0, 1 ] ].zero?
|
@@ -554,10 +588,22 @@ class TC_MultiArray < Test::Unit::TestCase
|
|
554
588
|
assert_equal M[ [ 1, 1 ], [ 0, -1 ] ], 3 <=> M[ [ 1, 2 ], [ 3, 4 ] ]
|
555
589
|
end
|
556
590
|
|
591
|
+
def test_fill
|
592
|
+
m = M( I, 3, 2 )[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
|
593
|
+
assert_equal M( I, 3, 2 )[ [ 1, 1, 1 ], [ 1, 1, 1 ] ], m.fill!( 1 )
|
594
|
+
assert_equal M( I, 3, 2 )[ [ 1, 1, 1 ], [ 1, 1, 1 ] ], m
|
595
|
+
end
|
596
|
+
|
557
597
|
def test_to_type
|
558
598
|
assert_equal M( C, 2, 2 )[ [ 1, 2 ], [ 3, 4 ] ],
|
559
|
-
M( I, 2, 2 )[ [ 1, 2 ], [ 3, 4 ] ].
|
599
|
+
M( I, 2, 2 )[ [ 1, 2 ], [ 3, 4 ] ].to_intrgb
|
560
600
|
end
|
561
601
|
|
602
|
+
def test_integral
|
603
|
+
assert_equal M( O, 3, 2 )[ [ 1, 3, 6 ], [ 5, 12, 21 ] ],
|
604
|
+
M( O, 3, 2 )[ [ 1, 2, 3 ], [ 4, 5, 6 ] ].integral
|
605
|
+
assert_equal M( I, 3, 2 )[ [ 1, 3, 6 ], [ 5, 12, 21 ] ],
|
606
|
+
M( I, 3, 2 )[ [ 1, 2, 3 ], [ 4, 5, 6 ] ].integral
|
607
|
+
end
|
562
608
|
|
563
609
|
end
|
data/test/tc_object.rb
CHANGED
@@ -134,4 +134,14 @@ class TC_Object < Test::Unit::TestCase
|
|
134
134
|
assert_equal O( 2 ), O( true ).conditional( O( 2 ), O( 1 ) )
|
135
135
|
end
|
136
136
|
|
137
|
+
def test_fill
|
138
|
+
o = O 3
|
139
|
+
assert_equal O( 1 ), o.fill!( 1 )
|
140
|
+
assert_equal O( 1 ), o
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_integral
|
144
|
+
assert_equal O( 3 ), O( 3 ).integral
|
145
|
+
end
|
146
|
+
|
137
147
|
end
|