multiarray 0.22.0 → 0.23.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 +1 -1
- data/lib/multiarray.rb +53 -16
- data/lib/multiarray/bool.rb +1 -1
- data/lib/multiarray/complex.rb +76 -68
- data/lib/multiarray/components.rb +11 -10
- data/lib/multiarray/composite.rb +1 -1
- data/lib/multiarray/diagonal.rb +11 -12
- data/lib/multiarray/element.rb +3 -3
- data/lib/multiarray/elementwise.rb +14 -14
- data/lib/multiarray/field.rb +380 -0
- data/lib/multiarray/float.rb +10 -10
- data/lib/multiarray/gcccache.rb +1 -1
- data/lib/multiarray/gcccontext.rb +35 -54
- data/lib/multiarray/gccfunction.rb +12 -19
- data/lib/multiarray/gcctype.rb +1 -1
- data/lib/multiarray/gccvalue.rb +63 -43
- data/lib/multiarray/histogram.rb +17 -19
- data/lib/multiarray/index.rb +7 -8
- data/lib/multiarray/inject.rb +11 -12
- data/lib/multiarray/int.rb +12 -11
- data/lib/multiarray/integral.rb +11 -12
- data/lib/multiarray/lambda.rb +23 -18
- data/lib/multiarray/list.rb +1 -1
- data/lib/multiarray/lookup.rb +18 -13
- data/lib/multiarray/lut.rb +13 -16
- data/lib/multiarray/malloc.rb +1 -1
- data/lib/multiarray/mask.rb +11 -8
- data/lib/multiarray/methods.rb +10 -10
- data/lib/multiarray/multiarray.rb +15 -44
- data/lib/multiarray/node.rb +64 -138
- data/lib/multiarray/object.rb +2 -6
- data/lib/multiarray/operations.rb +116 -134
- data/lib/multiarray/pointer.rb +7 -19
- data/lib/multiarray/random.rb +11 -8
- data/lib/multiarray/rgb.rb +53 -53
- data/lib/multiarray/sequence.rb +11 -496
- data/lib/multiarray/shortcuts.rb +4 -4
- data/lib/multiarray/store.rb +14 -11
- data/lib/multiarray/unmask.rb +10 -7
- data/lib/multiarray/variable.rb +11 -3
- data/test/tc_bool.rb +0 -8
- data/test/tc_compile.rb +72 -0
- data/test/tc_float.rb +0 -8
- data/test/tc_int.rb +0 -8
- data/test/tc_lazy.rb +22 -3
- data/test/tc_multiarray.rb +100 -126
- data/test/tc_object.rb +0 -16
- data/test/tc_rgb.rb +0 -16
- data/test/tc_sequence.rb +151 -165
- data/test/ts_multiarray.rb +2 -0
- metadata +7 -4
data/lib/multiarray/object.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# multiarray - Lazy multi-dimensional arrays for Ruby
|
2
|
-
# Copyright (C) 2010 Jan Wedekind
|
2
|
+
# Copyright (C) 2010, 2011 Jan Wedekind
|
3
3
|
#
|
4
4
|
# This program is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -77,11 +77,7 @@ module Hornetseye
|
|
77
77
|
#
|
78
78
|
# @private
|
79
79
|
def coercion( other )
|
80
|
-
|
81
|
-
other.coercion self
|
82
|
-
else
|
83
|
-
self
|
84
|
-
end
|
80
|
+
self
|
85
81
|
end
|
86
82
|
|
87
83
|
# Type coercion for native elements
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# multiarray - Lazy multi-dimensional arrays for Ruby
|
2
|
-
# Copyright (C) 2010, 2011 Jan Wedekind
|
2
|
+
# Copyright (C) 2010, 2011, 2011 Jan Wedekind
|
3
3
|
#
|
4
4
|
# This program is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -17,59 +17,59 @@
|
|
17
17
|
# Namespace of Hornetseye computer vision library
|
18
18
|
module Hornetseye
|
19
19
|
|
20
|
-
#
|
21
|
-
|
20
|
+
# Base class for representing native datatypes and operations (terms)
|
21
|
+
class Node
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
23
|
+
class << self
|
24
|
+
|
25
|
+
# Meta-programming method to define a unary operation
|
26
|
+
#
|
27
|
+
# @param [Symbol,String] op Name of unary operation.
|
28
|
+
# @param [Symbol,String] conversion Name of method for type conversion.
|
29
|
+
#
|
30
|
+
# @return [Proc] The new method.
|
31
|
+
#
|
32
|
+
# @private
|
33
|
+
def define_unary_op(op, conversion = :identity)
|
34
|
+
Node.class_eval do
|
35
|
+
define_method op do
|
36
|
+
if dimension == 0 and variables.empty?
|
37
|
+
target = typecode.send conversion
|
38
|
+
target.new simplify.get.send(op)
|
39
|
+
else
|
40
|
+
Hornetseye::ElementWise(lambda { |x| x.send op }, op,
|
41
|
+
lambda { |t| t.send conversion }).
|
42
|
+
new(self).force
|
43
|
+
end
|
44
|
+
end
|
40
45
|
end
|
41
46
|
end
|
42
|
-
end
|
43
|
-
|
44
|
-
module_function :define_unary_op
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
new( self, other ).force
|
48
|
+
# Meta-programming method to define a binary operation
|
49
|
+
#
|
50
|
+
# @param [Symbol,String] op Name of binary operation.
|
51
|
+
# @param [Symbol,String] conversion Name of method for type conversion.
|
52
|
+
#
|
53
|
+
# @return [Proc] The new method.
|
54
|
+
#
|
55
|
+
# @private
|
56
|
+
def define_binary_op(op, coercion = :coercion)
|
57
|
+
define_method op do |other|
|
58
|
+
other = Node.match(other, typecode).new other unless other.matched?
|
59
|
+
if dimension == 0 and variables.empty? and
|
60
|
+
other.dimension == 0 and other.variables.empty?
|
61
|
+
target = typecode.send coercion, other.typecode
|
62
|
+
target.new simplify.get.send(op, other.simplify.get)
|
63
|
+
else
|
64
|
+
Hornetseye::ElementWise(lambda { |x,y| x.send op, y }, op,
|
65
|
+
lambda { |t,u| t.send coercion, u } ).
|
66
|
+
new(sexp, other.sexp).force
|
67
|
+
end
|
67
68
|
end
|
68
69
|
end
|
69
|
-
end
|
70
|
-
|
71
|
-
module_function :define_binary_op
|
72
70
|
|
71
|
+
end
|
72
|
+
|
73
73
|
define_unary_op :zero?, :bool
|
74
74
|
define_unary_op :nonzero?, :bool
|
75
75
|
define_unary_op :not, :bool
|
@@ -101,7 +101,6 @@ module Hornetseye
|
|
101
101
|
define_binary_op :<, :coercion_bool
|
102
102
|
define_binary_op :>=, :coercion_bool
|
103
103
|
define_binary_op :>, :coercion_bool
|
104
|
-
define_binary_op :<=>, :coercion_byte
|
105
104
|
define_binary_op :minor
|
106
105
|
define_binary_op :major
|
107
106
|
|
@@ -121,9 +120,7 @@ module Hornetseye
|
|
121
120
|
#
|
122
121
|
# @return [Node] Array with result of operation.
|
123
122
|
def fmod_with_float( other )
|
124
|
-
unless other.
|
125
|
-
other = Node.match( other, typecode ).new other
|
126
|
-
end
|
123
|
+
other = Node.match( other, typecode ).new other unless other.matched?
|
127
124
|
if typecode < FLOAT_ or other.typecode < FLOAT_
|
128
125
|
fmod other
|
129
126
|
else
|
@@ -138,14 +135,14 @@ module Hornetseye
|
|
138
135
|
# @param [Class] dest Element type to convert to.
|
139
136
|
#
|
140
137
|
# @return [Node] Array based on the different element type.
|
141
|
-
def to_type(
|
138
|
+
def to_type(dest)
|
142
139
|
if dimension == 0 and variables.empty?
|
143
140
|
target = typecode.to_type dest
|
144
|
-
target.new(
|
141
|
+
target.new(simplify.get).simplify
|
145
142
|
else
|
146
143
|
key = "to_#{dest.to_s.downcase}"
|
147
144
|
Hornetseye::ElementWise( lambda { |x| x.to_type dest }, key,
|
148
|
-
lambda { |t| t.to_type dest } ).new(
|
145
|
+
lambda { |t| t.to_type dest } ).new(self).force
|
149
146
|
end
|
150
147
|
end
|
151
148
|
|
@@ -156,12 +153,12 @@ module Hornetseye
|
|
156
153
|
# @param [Class] dest Element type to convert to.
|
157
154
|
#
|
158
155
|
# @return [Node] Array based on the different element type.
|
159
|
-
def to_type_with_rgb(
|
156
|
+
def to_type_with_rgb(dest)
|
160
157
|
if typecode < RGB_
|
161
158
|
if dest < FLOAT_
|
162
159
|
lazy { r * 0.299 + g * 0.587 + b * 0.114 }.to_type dest
|
163
160
|
elsif dest < INT_
|
164
|
-
lazy { (
|
161
|
+
lazy { (r * 0.299 + g * 0.587 + b * 0.114).round }.to_type dest
|
165
162
|
else
|
166
163
|
to_type_without_rgb dest
|
167
164
|
end
|
@@ -197,13 +194,13 @@ module Hornetseye
|
|
197
194
|
# @param [Array<Integer>] ret_shape Desired shape of return value
|
198
195
|
#
|
199
196
|
# @return [Node] Array with desired shape.
|
200
|
-
def reshape(
|
201
|
-
|
202
|
-
if
|
203
|
-
raise "
|
204
|
-
"#{size}"
|
197
|
+
def reshape(*ret_shape)
|
198
|
+
target_size = ret_shape.inject { |a,b| a * b }
|
199
|
+
if target_size != size
|
200
|
+
raise "Target is of size #{target_size} but should be of size #{size}"
|
205
201
|
end
|
206
|
-
|
202
|
+
Hornetseye::MultiArray(typecode, ret_shape.size).
|
203
|
+
new *(ret_shape + [:memory => memorise.memory])
|
207
204
|
end
|
208
205
|
|
209
206
|
# Element-wise conditional selection of values
|
@@ -212,24 +209,19 @@ module Hornetseye
|
|
212
209
|
# @param [Node] b Second array of values.
|
213
210
|
#
|
214
211
|
# @return [Node] Array with selected values.
|
215
|
-
def conditional(
|
216
|
-
unless a.
|
217
|
-
|
218
|
-
end
|
219
|
-
unless b.is_a? Node
|
220
|
-
b = Node.match( b, a.is_a?( Node ) ? a : nil ).new b
|
221
|
-
end
|
212
|
+
def conditional(a, b)
|
213
|
+
a = Node.match(a, b.matched? ? b : nil).new a unless a.matched?
|
214
|
+
b = Node.match(b, a.matched? ? a : nil).new b unless b.matched?
|
222
215
|
if dimension == 0 and variables.empty? and
|
223
216
|
a.dimension == 0 and a.variables.empty? and
|
224
217
|
b.dimension == 0 and b.variables.empty?
|
225
|
-
target =
|
226
|
-
|
227
|
-
|
228
|
-
proc { b.simplify.get } )
|
218
|
+
target = typecode.cond a.typecode, b.typecode
|
219
|
+
target.new simplify.get.conditional(proc { a.simplify.get },
|
220
|
+
proc { b.simplify.get })
|
229
221
|
else
|
230
|
-
Hornetseye::ElementWise(
|
231
|
-
|
232
|
-
new(
|
222
|
+
Hornetseye::ElementWise(lambda { |x,y,z| x.conditional y, z }, :conditional,
|
223
|
+
lambda { |t,u,v| t.cond u, v }).
|
224
|
+
new(self, a.sexp, b.sexp).force
|
233
225
|
end
|
234
226
|
end
|
235
227
|
|
@@ -266,10 +258,10 @@ module Hornetseye
|
|
266
258
|
# @param [Node] other Array with values to compare with.
|
267
259
|
#
|
268
260
|
# @return [Node] Array with results.
|
269
|
-
def <=>(
|
270
|
-
Hornetseye::
|
271
|
-
(
|
272
|
-
end
|
261
|
+
def <=>(other)
|
262
|
+
Hornetseye::lazy do
|
263
|
+
(self < other).conditional -1, (self > other).conditional(1, 0)
|
264
|
+
end.force
|
273
265
|
end
|
274
266
|
|
275
267
|
# Lazy transpose of array
|
@@ -329,7 +321,7 @@ module Hornetseye
|
|
329
321
|
def collect( &action )
|
330
322
|
var = Variable.new typecode
|
331
323
|
block = action.call var
|
332
|
-
conversion = lambda { |t| t.to_type action.call(
|
324
|
+
conversion = lambda { |t| t.to_type action.call(Variable.new(t.typecode)).typecode }
|
333
325
|
Hornetseye::ElementWise( action, block.to_s, conversion ).new( self ).force
|
334
326
|
end
|
335
327
|
|
@@ -351,7 +343,7 @@ module Hornetseye
|
|
351
343
|
# @return [Object] Result of injection.
|
352
344
|
def inject( initial = nil, options = {} )
|
353
345
|
unless initial.nil?
|
354
|
-
initial = Node.match( initial ).new initial unless initial.
|
346
|
+
initial = Node.match( initial ).new initial unless initial.matched?
|
355
347
|
initial_typecode = initial.typecode
|
356
348
|
else
|
357
349
|
initial_typecode = typecode
|
@@ -369,7 +361,7 @@ module Hornetseye
|
|
369
361
|
index = Variable.new Hornetseye::INDEX( nil )
|
370
362
|
value = element( index ).inject nil, :block => block,
|
371
363
|
:var1 => var1, :var2 => var2
|
372
|
-
value = typecode.new value unless value.
|
364
|
+
value = typecode.new value unless value.matched?
|
373
365
|
if initial.nil? and index.size.get == 0
|
374
366
|
raise "Array was empty and no initial value for injection was given"
|
375
367
|
end
|
@@ -388,11 +380,11 @@ module Hornetseye
|
|
388
380
|
# Equality operator
|
389
381
|
#
|
390
382
|
# @return [Boolean] Returns result of comparison.
|
391
|
-
def eq_with_multiarray(
|
392
|
-
if other.
|
383
|
+
def eq_with_multiarray(other)
|
384
|
+
if other.matched?
|
393
385
|
if variables.empty?
|
394
|
-
if other.
|
395
|
-
Hornetseye::finalise { eq(
|
386
|
+
if other.typecode == typecode and other.shape == shape
|
387
|
+
Hornetseye::finalise { eq(other).inject( true ) { |a,b| a.and b } }
|
396
388
|
else
|
397
389
|
false
|
398
390
|
end
|
@@ -515,9 +507,7 @@ module Hornetseye
|
|
515
507
|
demand
|
516
508
|
else
|
517
509
|
if initial
|
518
|
-
unless initial.
|
519
|
-
initial = Node.match( initial ).new initial
|
520
|
-
end
|
510
|
+
initial = Node.match( initial ).new initial unless initial.matched?
|
521
511
|
initial_typecode = initial.typecode
|
522
512
|
else
|
523
513
|
initial_typecode = typecode
|
@@ -532,7 +522,7 @@ module Hornetseye
|
|
532
522
|
diagonal initial, :block => block, :var1 => var1, :var2 => var2
|
533
523
|
term = Diagonal.new( value, index0, index1, index2, initial,
|
534
524
|
block, var1, var2 )
|
535
|
-
index0.size
|
525
|
+
index0.size = index1.size
|
536
526
|
Lambda.new( index0, term ).force
|
537
527
|
end
|
538
528
|
end
|
@@ -550,7 +540,7 @@ module Hornetseye
|
|
550
540
|
#
|
551
541
|
# @private
|
552
542
|
def table( filter, &action )
|
553
|
-
filter = Node.match( filter, typecode ).new filter unless filter.
|
543
|
+
filter = Node.match( filter, typecode ).new filter unless filter.matched?
|
554
544
|
if filter.dimension > dimension
|
555
545
|
raise "Filter has #{filter.dimension} dimension(s) but should " +
|
556
546
|
"not have more than #{dimension}"
|
@@ -569,10 +559,10 @@ module Hornetseye
|
|
569
559
|
#
|
570
560
|
# @return [Node] Result of convolution.
|
571
561
|
def convolve( filter )
|
572
|
-
filter = Node.match( filter, typecode ).new filter unless filter.
|
562
|
+
filter = Node.match( filter, typecode ).new filter unless filter.matched?
|
573
563
|
array = self
|
574
|
-
(
|
575
|
-
array.table(
|
564
|
+
(dimension - filter.dimension).times { array = array.roll }
|
565
|
+
array.table(filter.sexp) { |a,b| a * b }.diagonal { |s,x| s + x }
|
576
566
|
end
|
577
567
|
|
578
568
|
# Erosion
|
@@ -606,8 +596,8 @@ module Hornetseye
|
|
606
596
|
# @return [Node] Result of Sobel operator.
|
607
597
|
def sobel( direction )
|
608
598
|
( dimension - 1 ).downto( 0 ).inject self do |retval,i|
|
609
|
-
filter = i == direction ? Hornetseye::Sequence(
|
610
|
-
Hornetseye::Sequence(
|
599
|
+
filter = i == direction ? Hornetseye::Sequence(SINT)[1, 0, -1] :
|
600
|
+
Hornetseye::Sequence(SINT)[1, 2, 1]
|
611
601
|
Hornetseye::lazy { retval.convolve filter }
|
612
602
|
end.force
|
613
603
|
end
|
@@ -660,9 +650,8 @@ module Hornetseye
|
|
660
650
|
def histogram( *ret_shape )
|
661
651
|
options = ret_shape.last.is_a?( Hash ) ? ret_shape.pop : {}
|
662
652
|
options = { :weight => UINT.new( 1 ), :safe => true }.merge options
|
663
|
-
unless options[
|
664
|
-
options[ :weight ]
|
665
|
-
Node.match( options[ :weight ] ).maxint.new options[ :weight ]
|
653
|
+
unless options[:weight].matched?
|
654
|
+
options[:weight] = Node.match(options[:weight]).maxint.new options[:weight]
|
666
655
|
end
|
667
656
|
if ( shape.first != 1 or dimension == 1 ) and ret_shape.size == 1
|
668
657
|
[ self ].histogram *( ret_shape + [ options ] )
|
@@ -718,8 +707,8 @@ module Hornetseye
|
|
718
707
|
#
|
719
708
|
# @return [Node] The integral image of this array.
|
720
709
|
def integral
|
721
|
-
left =
|
722
|
-
block = Integral.new left, self
|
710
|
+
left = allocate
|
711
|
+
block = Integral.new left.sexp, self
|
723
712
|
if block.compilable?
|
724
713
|
GCCFunction.run block
|
725
714
|
else
|
@@ -741,20 +730,21 @@ module Hornetseye
|
|
741
730
|
options = { :target => UINT, :default => typecode.default }.merge options
|
742
731
|
target = options[ :target ]
|
743
732
|
default = options[ :default ]
|
744
|
-
default = typecode.new default unless default.
|
745
|
-
left = Hornetseye::MultiArray(
|
733
|
+
default = typecode.new default unless default.matched?
|
734
|
+
left = Hornetseye::MultiArray(target, dimension).new *shape
|
746
735
|
labels = Sequence.new target, size; labels[0] = 0
|
747
736
|
rank = Sequence.uint size; rank[0] = 0
|
748
737
|
n = Hornetseye::Pointer( INT ).new; n.store INT.new( 0 )
|
749
|
-
block = Components.new left, self, default, target.new(
|
738
|
+
block = Components.new left.sexp, self, default.sexp, target.new(0),
|
739
|
+
labels.sexp, rank.sexp, n
|
750
740
|
if block.compilable?
|
751
741
|
Hornetseye::GCCFunction.run block
|
752
742
|
else
|
753
743
|
block.demand
|
754
744
|
end
|
755
|
-
labels = labels[
|
756
|
-
left.lut labels.lut(
|
757
|
-
|
745
|
+
labels = labels[0 .. n.demand.get]
|
746
|
+
left.lut labels.lut(labels.histogram(labels.size, :weight => target.new(1)).
|
747
|
+
minor(1).integral - 1)
|
758
748
|
end
|
759
749
|
|
760
750
|
# Select values from array using a mask
|
@@ -768,13 +758,13 @@ module Hornetseye
|
|
768
758
|
[ m.size ] )
|
769
759
|
index = Hornetseye::Pointer( INT ).new
|
770
760
|
index.store INT.new( 0 )
|
771
|
-
block = Mask.new left, self, m, index
|
761
|
+
block = Mask.new left.sexp, self, m.sexp, index
|
772
762
|
if block.compilable?
|
773
763
|
GCCFunction.run block
|
774
764
|
else
|
775
765
|
block.demand
|
776
766
|
end
|
777
|
-
left[
|
767
|
+
left[0 ... index[]].roll
|
778
768
|
end
|
779
769
|
|
780
770
|
# Distribute values in a new array using a mask
|
@@ -788,8 +778,8 @@ module Hornetseye
|
|
788
778
|
# @return [Node] The result of the inverse masking operation.
|
789
779
|
def unmask( m, options = {} )
|
790
780
|
options = { :safe => true, :default => typecode.default }.merge options
|
791
|
-
default = options[
|
792
|
-
default = typecode.new default unless default.
|
781
|
+
default = options[:default]
|
782
|
+
default = typecode.new default unless default.matched?
|
793
783
|
m.check_shape default
|
794
784
|
if options[ :safe ]
|
795
785
|
if m.to_ubyte.sum > shape.last
|
@@ -797,11 +787,11 @@ module Hornetseye
|
|
797
787
|
"dimension of the array for unmasking only has #{shape.last} value(s)"
|
798
788
|
end
|
799
789
|
end
|
800
|
-
left = Hornetseye::MultiArray(
|
801
|
-
|
802
|
-
index = Hornetseye::Pointer(
|
803
|
-
index.store INT.new(
|
804
|
-
block = Unmask.new left, self, m, index, default
|
790
|
+
left = Hornetseye::MultiArray(typecode, dimension - 1 + m.dimension).
|
791
|
+
coercion(default.typecode).new *(shape[1 .. -1] + m.shape)
|
792
|
+
index = Hornetseye::Pointer(INT).new
|
793
|
+
index.store INT.new(0)
|
794
|
+
block = Unmask.new left.sexp, self, m.sexp, index, default.sexp
|
805
795
|
if block.compilable?
|
806
796
|
GCCFunction.run block
|
807
797
|
else
|
@@ -836,7 +826,7 @@ module Hornetseye
|
|
836
826
|
raise "#{offset.size} offset(s) were given but array has " +
|
837
827
|
"#{dimension} dimension(s)"
|
838
828
|
end
|
839
|
-
retval =
|
829
|
+
retval = Hornetseye::MultiArray(typecode, dimension).new *shape
|
840
830
|
target, source, open, close = [], [], [], []
|
841
831
|
( shape.size - 1 ).step( 0, -1 ) do |i|
|
842
832
|
callcc do |pass|
|
@@ -905,12 +895,6 @@ module Hornetseye
|
|
905
895
|
|
906
896
|
end
|
907
897
|
|
908
|
-
class Node
|
909
|
-
|
910
|
-
include Operations
|
911
|
-
|
912
|
-
end
|
913
|
-
|
914
898
|
end
|
915
899
|
|
916
900
|
# The +Array+ class is extended with a few methods
|
@@ -929,8 +913,8 @@ class Array
|
|
929
913
|
def histogram( *ret_shape )
|
930
914
|
options = ret_shape.last.is_a?( Hash ) ? ret_shape.pop : {}
|
931
915
|
options = { :weight => Hornetseye::UINT. new( 1 ), :safe => true }.merge options
|
932
|
-
unless options[
|
933
|
-
options[
|
916
|
+
unless options[:weight].matched?
|
917
|
+
options[:weight] =
|
934
918
|
Hornetseye::Node.match( options[ :weight ] ).maxint.new options[ :weight ]
|
935
919
|
end
|
936
920
|
weight = options[ :weight ]
|
@@ -939,9 +923,8 @@ class Array
|
|
939
923
|
raise "Number of arrays for histogram (#{size}) differs from number of " +
|
940
924
|
"dimensions of histogram (#{ret_shape.size})"
|
941
925
|
end
|
942
|
-
|
943
|
-
source_type
|
944
|
-
source_type.check_shape *array_types
|
926
|
+
source_type = inject { |a,b| a.dimension > b.dimension ? a : b }
|
927
|
+
source_type.check_shape *self
|
945
928
|
source_type.check_shape options[ :weight ]
|
946
929
|
for i in 0 ... size
|
947
930
|
range = self[ i ].range 0 ... ret_shape[ i ]
|
@@ -955,9 +938,9 @@ class Array
|
|
955
938
|
end
|
956
939
|
end
|
957
940
|
end
|
958
|
-
left = Hornetseye::MultiArray
|
941
|
+
left = Hornetseye::MultiArray(weight.typecode, ret_shape.size).new *ret_shape
|
959
942
|
left[] = 0
|
960
|
-
block = Hornetseye::Histogram.new left, weight, *self
|
943
|
+
block = Hornetseye::Histogram.new left.sexp, weight.sexp, *self
|
961
944
|
if block.compilable?
|
962
945
|
Hornetseye::GCCFunction.run block
|
963
946
|
else
|
@@ -980,9 +963,8 @@ class Array
|
|
980
963
|
raise "Number of arrays for lookup (#{size}) is greater than the " +
|
981
964
|
"number of dimensions of LUT (#{table.dimension})"
|
982
965
|
end
|
983
|
-
|
984
|
-
source_type
|
985
|
-
source_type.check_shape *array_types
|
966
|
+
source_type = inject { |a,b| a.dimension > b.dimension ? a : b }
|
967
|
+
source_type.check_shape *self
|
986
968
|
for i in 0 ... size
|
987
969
|
offset = table.dimension - size
|
988
970
|
range = self[ i ].range 0 ... table.shape[ i + offset ]
|