multiarray 0.5.0 → 0.5.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 +39 -5
- data/TODO +11 -66
- data/lib/multiarray.rb +59 -12
- data/lib/multiarray/binarymethod.rb +195 -0
- data/lib/multiarray/{binary.rb → binaryop.rb} +27 -12
- data/lib/multiarray/bool.rb +8 -2
- data/lib/multiarray/diagonal.rb +26 -27
- data/lib/multiarray/element.rb +23 -5
- data/lib/multiarray/float.rb +142 -0
- data/lib/multiarray/gcccontext.rb +29 -25
- data/lib/multiarray/gccfunction.rb +24 -7
- data/lib/multiarray/gcctype.rb +26 -16
- data/lib/multiarray/gccvalue.rb +144 -74
- data/lib/multiarray/inject.rb +12 -15
- data/lib/multiarray/int.rb +109 -82
- data/lib/multiarray/lambda.rb +23 -1
- data/lib/multiarray/lookup.rb +14 -1
- data/lib/multiarray/malloc.rb +2 -2
- data/lib/multiarray/methods.rb +93 -0
- data/lib/multiarray/multiarray.rb +2 -12
- data/lib/multiarray/node.rb +103 -173
- data/lib/multiarray/object.rb +19 -1
- data/lib/multiarray/operations.rb +189 -9
- data/lib/multiarray/pointer.rb +9 -1
- data/lib/multiarray/rgb.rb +401 -0
- data/lib/multiarray/sequence.rb +56 -14
- data/lib/multiarray/unarymethod.rb +185 -0
- data/lib/multiarray/{unary.rb → unaryop.rb} +20 -11
- data/lib/multiarray/variable.rb +8 -0
- data/test/tc_bool.rb +32 -20
- data/test/tc_float.rb +192 -0
- data/test/tc_int.rb +52 -24
- data/test/tc_lazy.rb +109 -0
- data/test/tc_multiarray.rb +136 -2
- data/test/tc_object.rb +29 -11
- data/test/tc_rgb.rb +217 -0
- data/test/tc_sequence.rb +184 -52
- data/test/ts_multiarray.rb +3 -0
- metadata +42 -15
data/lib/multiarray/int.rb
CHANGED
@@ -60,6 +60,10 @@ module Hornetseye
|
|
60
60
|
0
|
61
61
|
end
|
62
62
|
|
63
|
+
def maxint
|
64
|
+
Hornetseye::INT [ 32, bits ].max, signed
|
65
|
+
end
|
66
|
+
|
63
67
|
def coercion( other )
|
64
68
|
if other < INT_
|
65
69
|
Hornetseye::INT [ bits, other.bits ].max, ( signed or other.signed )
|
@@ -68,30 +72,28 @@ module Hornetseye
|
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
75
|
+
def coerce( other )
|
76
|
+
if other < INT_
|
77
|
+
return other, self
|
78
|
+
else
|
79
|
+
super other
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
71
83
|
# Directive for packing/unpacking elements of this type
|
72
84
|
#
|
73
85
|
# @private
|
74
86
|
def directive
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
'i'
|
86
|
-
when [ 32, false ]
|
87
|
-
'I'
|
88
|
-
when [ 64, true ]
|
89
|
-
'q'
|
90
|
-
when [ 64, false ]
|
91
|
-
'Q'
|
92
|
-
else
|
93
|
-
raise "No directive for packing/unpacking #{inspect}"
|
94
|
-
end
|
87
|
+
retval = { [ 8, true ] => 'c',
|
88
|
+
[ 8, false ] => 'C',
|
89
|
+
[ 16, true ] => 's',
|
90
|
+
[ 16, false ] => 'S',
|
91
|
+
[ 32, true ] => 'i',
|
92
|
+
[ 32, false ] => 'I',
|
93
|
+
[ 64, true ] => 'q',
|
94
|
+
[ 64, false ] => 'Q' }[ [ bits, signed ] ]
|
95
|
+
raise "No directive for packing/unpacking #{inspect}" unless retval
|
96
|
+
retval
|
95
97
|
end
|
96
98
|
|
97
99
|
# Get string with information about this class
|
@@ -99,26 +101,15 @@ module Hornetseye
|
|
99
101
|
# @return [String] Returns string with information about this class.
|
100
102
|
def inspect
|
101
103
|
unless bits.nil? or signed.nil?
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
when [ 32, true ]
|
112
|
-
'INT'
|
113
|
-
when [ 32, false ]
|
114
|
-
'UINT'
|
115
|
-
when [ 64, true ]
|
116
|
-
'LONG'
|
117
|
-
when [ 64, false ]
|
118
|
-
'ULONG'
|
119
|
-
else
|
120
|
-
"INT(#{bits.inspect},#{ signed ? 'SIGNED' : 'UNSIGNED' })"
|
121
|
-
end
|
104
|
+
retval = { [ 8, true ] => 'BYTE',
|
105
|
+
[ 8, false ] => 'UBYTE',
|
106
|
+
[ 16, true ] => 'SINT',
|
107
|
+
[ 16, false ] => 'USINT',
|
108
|
+
[ 32, true ] => 'INT',
|
109
|
+
[ 32, false ] => 'UINT',
|
110
|
+
[ 64, true ] => 'LONG',
|
111
|
+
[ 64, false ] => 'ULONG' }[ [ bits, signed ] ] ||
|
112
|
+
"INT(#{bits.inspect},#{ signed ? 'SIGNED' : 'UNSIGNED' })"
|
122
113
|
else
|
123
114
|
super
|
124
115
|
end
|
@@ -133,28 +124,9 @@ module Hornetseye
|
|
133
124
|
# @private
|
134
125
|
def descriptor( hash )
|
135
126
|
unless bits.nil? or signed.nil?
|
136
|
-
|
137
|
-
when [ 8, true ]
|
138
|
-
'BYTE'
|
139
|
-
when [ 8, false ]
|
140
|
-
'UBYTE'
|
141
|
-
when [ 16, true ]
|
142
|
-
'SINT'
|
143
|
-
when [ 16, false ]
|
144
|
-
'USINT'
|
145
|
-
when [ 32, true ]
|
146
|
-
'INT'
|
147
|
-
when [ 32, false ]
|
148
|
-
'UINT'
|
149
|
-
when [ 64, true ]
|
150
|
-
'LONG'
|
151
|
-
when [ 64, false ]
|
152
|
-
'ULONG'
|
153
|
-
else
|
154
|
-
"INT(#{bits.to_s},#{ signed ? 'SIGNED' : 'UNSIGNED' })"
|
155
|
-
end
|
127
|
+
inspect
|
156
128
|
else
|
157
|
-
super
|
129
|
+
super hash
|
158
130
|
end
|
159
131
|
end
|
160
132
|
|
@@ -178,6 +150,16 @@ module Hornetseye
|
|
178
150
|
|
179
151
|
end
|
180
152
|
|
153
|
+
def times( &action )
|
154
|
+
get.times &action
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
def upto( other, &action )
|
159
|
+
get.upto other.get, &action
|
160
|
+
self
|
161
|
+
end
|
162
|
+
|
181
163
|
# Namespace containing method for matching elements of type INT_
|
182
164
|
#
|
183
165
|
# @see INT_
|
@@ -225,27 +207,6 @@ module Hornetseye
|
|
225
207
|
|
226
208
|
end
|
227
209
|
|
228
|
-
# Create a class deriving from +INT_+
|
229
|
-
#
|
230
|
-
# he aprameters +bits+ and +signed+ are assigned to the corresponding
|
231
|
-
# attributes of the resulting class.
|
232
|
-
#
|
233
|
-
# @param [Integer] bits Number of bits of native integer.
|
234
|
-
# @param [FalseClass,TrueClass] signed Specify +UNSIGNED+ or +SIGNED+ here.
|
235
|
-
# @return [Class] A class deriving from +INT_+.
|
236
|
-
#
|
237
|
-
# @see INT_
|
238
|
-
# @see INT_.bits
|
239
|
-
# @see INT_.signed
|
240
|
-
def INT( bits, signed )
|
241
|
-
retval = Class.new INT_
|
242
|
-
retval.bits = bits
|
243
|
-
retval.signed = signed
|
244
|
-
retval
|
245
|
-
end
|
246
|
-
|
247
|
-
module_function :INT
|
248
|
-
|
249
210
|
# Boolean constant to use as a parameter for creating integer classes
|
250
211
|
#
|
251
212
|
# The value is +false+.
|
@@ -260,6 +221,35 @@ module Hornetseye
|
|
260
221
|
# @see #INT
|
261
222
|
SIGNED = true
|
262
223
|
|
224
|
+
# Create a class deriving from +INT_+ or instantiate an +INT+ object
|
225
|
+
#
|
226
|
+
# @overload INT( bits, signed )
|
227
|
+
# Create a class deriving from +INT_+. The aprameters +bits+ and +signed+
|
228
|
+
# are assigned to the corresponding attributes of the resulting class.
|
229
|
+
# @param [Integer] bits Number of bits of native integer.
|
230
|
+
# @param [FalseClass,TrueClass] signed Specify +UNSIGNED+ or +SIGNED+ here.
|
231
|
+
# @return [Class] A class deriving from +INT_+.
|
232
|
+
#
|
233
|
+
# @overload INT( value )
|
234
|
+
# This is a shortcut for +INT.new( value )+.
|
235
|
+
# @param [Integer] value Initial value for integer object.
|
236
|
+
#
|
237
|
+
# @see INT_
|
238
|
+
# @see INT_.bits
|
239
|
+
# @see INT_.signed
|
240
|
+
def INT( arg, signed = nil )
|
241
|
+
if signed.nil?
|
242
|
+
INT.new arg
|
243
|
+
else
|
244
|
+
retval = Class.new INT_
|
245
|
+
retval.bits = arg
|
246
|
+
retval.signed = signed
|
247
|
+
retval
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
module_function :INT
|
252
|
+
|
263
253
|
# 8-bit signed integer
|
264
254
|
BYTE = INT 8, SIGNED
|
265
255
|
|
@@ -284,4 +274,41 @@ module Hornetseye
|
|
284
274
|
# 64-bit unsigned integer
|
285
275
|
ULONG = INT 64, UNSIGNED
|
286
276
|
|
277
|
+
def BYTE( value )
|
278
|
+
BYTE.new value
|
279
|
+
end
|
280
|
+
|
281
|
+
def UBYTE( value )
|
282
|
+
UBYTE.new value
|
283
|
+
end
|
284
|
+
|
285
|
+
def SINT( value )
|
286
|
+
SINT.new value
|
287
|
+
end
|
288
|
+
|
289
|
+
def USINT( value )
|
290
|
+
USINT.new value
|
291
|
+
end
|
292
|
+
|
293
|
+
def UINT( value )
|
294
|
+
UINT.new value
|
295
|
+
end
|
296
|
+
|
297
|
+
def LONG( value )
|
298
|
+
LONG.new value
|
299
|
+
end
|
300
|
+
|
301
|
+
def ULONG( value )
|
302
|
+
ULONG.new value
|
303
|
+
end
|
304
|
+
|
305
|
+
module_function :BYTE
|
306
|
+
module_function :UBYTE
|
307
|
+
module_function :SINT
|
308
|
+
module_function :USINT
|
309
|
+
module_function :UINT
|
310
|
+
module_function :LONG
|
311
|
+
module_function :ULONG
|
312
|
+
|
313
|
+
|
287
314
|
end
|
data/lib/multiarray/lambda.rb
CHANGED
@@ -57,7 +57,7 @@ module Hornetseye
|
|
57
57
|
meta_vars, meta_values, var = @index.strip
|
58
58
|
vars, values, term = @term.subst( @index => var ).strip
|
59
59
|
return vars + meta_vars, values + meta_values,
|
60
|
-
Lambda.new( var, term
|
60
|
+
Lambda.new( var, term )
|
61
61
|
end
|
62
62
|
|
63
63
|
def subst( hash )
|
@@ -89,12 +89,34 @@ module Hornetseye
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
def skip( index, start )
|
93
|
+
Lambda.new @index, @term.skip( index, start )
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get element of this term
|
97
|
+
# Pass +i+ as argument to this lambda object.
|
98
|
+
#
|
99
|
+
# @param [Integer,Node] i Index of desired element.
|
100
|
+
#
|
101
|
+
# @return [Node,Object] Result of inserting +i+ for lambda argument.
|
92
102
|
def element( i )
|
93
103
|
i = Node.match( i ).new i unless i.is_a? Node
|
94
104
|
i.size.store @index.size if @index.size.get and i.is_a? Variable
|
95
105
|
@term.subst @index => i
|
96
106
|
end
|
97
107
|
|
108
|
+
def slice( start, length )
|
109
|
+
start = Node.match( start ).new start unless start.is_a? Node
|
110
|
+
length = Node.match( length ).new length unless length.is_a? Node
|
111
|
+
index = Variable.new Hornetseye::INDEX( length )
|
112
|
+
Lambda.new( index, @term.subst( @index => index ).
|
113
|
+
skip( index, start ) ).unroll
|
114
|
+
end
|
115
|
+
|
116
|
+
def compilable?
|
117
|
+
@term.compilable?
|
118
|
+
end
|
119
|
+
|
98
120
|
end
|
99
121
|
|
100
122
|
end
|
data/lib/multiarray/lookup.rb
CHANGED
@@ -31,7 +31,8 @@ module Hornetseye
|
|
31
31
|
#
|
32
32
|
# @private
|
33
33
|
def descriptor( hash )
|
34
|
-
"Lookup(#{@p.descriptor( hash )},#{@index.descriptor( hash )}
|
34
|
+
"Lookup(#{@p.descriptor( hash )},#{@index.descriptor( hash )}," +
|
35
|
+
"#{@stride.descriptor( hash )})"
|
35
36
|
end
|
36
37
|
|
37
38
|
def array_type
|
@@ -76,10 +77,22 @@ module Hornetseye
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
80
|
+
def skip( index, start )
|
81
|
+
if @index == index
|
82
|
+
Lookup.new @p.lookup( start, @stride ), @index, @stride
|
83
|
+
else
|
84
|
+
Lookup.new @p.skip( index, start ), @index, @stride
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
79
88
|
def element( i )
|
80
89
|
Lookup.new @p.element( i ), @index, @stride
|
81
90
|
end
|
82
91
|
|
92
|
+
def slice( start, length )
|
93
|
+
Lookup.new @p.slice( start, length ), @index, @stride
|
94
|
+
end
|
95
|
+
|
83
96
|
end
|
84
97
|
|
85
98
|
end
|
data/lib/multiarray/malloc.rb
CHANGED
@@ -20,11 +20,11 @@ module Hornetseye
|
|
20
20
|
class Malloc
|
21
21
|
|
22
22
|
def load( typecode )
|
23
|
-
read( typecode.storage_size ).unpack( typecode.directive )
|
23
|
+
read( typecode.storage_size ).unpack( typecode.directive )
|
24
24
|
end
|
25
25
|
|
26
26
|
def save( value )
|
27
|
-
write
|
27
|
+
write value.values.pack( value.typecode.directive )
|
28
28
|
value
|
29
29
|
end
|
30
30
|
|
@@ -0,0 +1,93 @@
|
|
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 Methods
|
21
|
+
|
22
|
+
def Methods.included( mod )
|
23
|
+
define_unary_method mod, :sqrt , :float
|
24
|
+
define_unary_method mod, :log , :float
|
25
|
+
define_unary_method mod, :exp , :float
|
26
|
+
define_unary_method mod, :cos , :float
|
27
|
+
define_unary_method mod, :sin , :float
|
28
|
+
define_unary_method mod, :tan , :float
|
29
|
+
define_unary_method mod, :acos , :float
|
30
|
+
define_unary_method mod, :asin , :float
|
31
|
+
define_unary_method mod, :atan , :float
|
32
|
+
define_unary_method mod, :cosh , :float
|
33
|
+
define_unary_method mod, :sinh , :float
|
34
|
+
define_unary_method mod, :tanh , :float
|
35
|
+
define_binary_method mod, :atan2, :floating
|
36
|
+
define_binary_method mod, :hypot, :floating
|
37
|
+
end
|
38
|
+
|
39
|
+
def define_unary_method( mod, op, conversion = :contiguous )
|
40
|
+
mod.module_eval do
|
41
|
+
define_method( "#{op}_with_hornetseye" ) do |a|
|
42
|
+
if a.is_a? Node
|
43
|
+
if a.dimension == 0 and a.variables.empty?
|
44
|
+
target = a.typecode.send conversion
|
45
|
+
target.new mod.send( op, a.simplify.get )
|
46
|
+
else
|
47
|
+
Hornetseye::UnaryMethod( mod, op, conversion ).new( a ).force
|
48
|
+
end
|
49
|
+
else
|
50
|
+
send "#{op}_without_hornetseye", a
|
51
|
+
end
|
52
|
+
end
|
53
|
+
alias_method_chain op, :hornetseye
|
54
|
+
module_function "#{op}_without_hornetseye"
|
55
|
+
module_function op
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module_function :define_unary_method
|
60
|
+
|
61
|
+
def define_binary_method( mod, op, coercion = :coercion )
|
62
|
+
mod.module_eval do
|
63
|
+
define_method( "#{op}_with_hornetseye" ) do |a,b|
|
64
|
+
if a.is_a? Node or b.is_a? Node
|
65
|
+
a = Node.match( a, b.typecode ).new a unless a.is_a? Node
|
66
|
+
b = Node.match( b, a.typecode ).new b unless b.is_a? Node
|
67
|
+
if a.dimension == 0 and a.variables.empty? and
|
68
|
+
b.dimension == 0 and b.variables.empty?
|
69
|
+
target = a.typecode.send coercion, b.typecode
|
70
|
+
target.new mod.send( op, a.simplify.get, b.simplify.get )
|
71
|
+
else
|
72
|
+
Hornetseye::BinaryMethod( mod, op, coercion ).new( a, b ).force
|
73
|
+
end
|
74
|
+
else
|
75
|
+
send "#{op}_without_hornetseye", a, b
|
76
|
+
end
|
77
|
+
end
|
78
|
+
alias_method_chain op, :hornetseye
|
79
|
+
module_function "#{op}_without_hornetseye"
|
80
|
+
module_function op
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
module_function :define_binary_method
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
module Math
|
91
|
+
include Hornetseye::Methods
|
92
|
+
end
|
93
|
+
|
@@ -38,18 +38,8 @@ module Hornetseye
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def []( *args )
|
41
|
-
|
42
|
-
|
43
|
-
if element.dimension > 0
|
44
|
-
args.each_with_index do |arg,i|
|
45
|
-
recursion.call element.element( i ), arg
|
46
|
-
end
|
47
|
-
else
|
48
|
-
element[] = args
|
49
|
-
end
|
50
|
-
end
|
51
|
-
recursion.call retval, args
|
52
|
-
retval
|
41
|
+
target = Node.fit args
|
42
|
+
target[ *args ]
|
53
43
|
end
|
54
44
|
|
55
45
|
end
|