multiarray 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|