multiarray 0.22.0 → 0.23.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/Rakefile +1 -1
  2. data/lib/multiarray.rb +53 -16
  3. data/lib/multiarray/bool.rb +1 -1
  4. data/lib/multiarray/complex.rb +76 -68
  5. data/lib/multiarray/components.rb +11 -10
  6. data/lib/multiarray/composite.rb +1 -1
  7. data/lib/multiarray/diagonal.rb +11 -12
  8. data/lib/multiarray/element.rb +3 -3
  9. data/lib/multiarray/elementwise.rb +14 -14
  10. data/lib/multiarray/field.rb +380 -0
  11. data/lib/multiarray/float.rb +10 -10
  12. data/lib/multiarray/gcccache.rb +1 -1
  13. data/lib/multiarray/gcccontext.rb +35 -54
  14. data/lib/multiarray/gccfunction.rb +12 -19
  15. data/lib/multiarray/gcctype.rb +1 -1
  16. data/lib/multiarray/gccvalue.rb +63 -43
  17. data/lib/multiarray/histogram.rb +17 -19
  18. data/lib/multiarray/index.rb +7 -8
  19. data/lib/multiarray/inject.rb +11 -12
  20. data/lib/multiarray/int.rb +12 -11
  21. data/lib/multiarray/integral.rb +11 -12
  22. data/lib/multiarray/lambda.rb +23 -18
  23. data/lib/multiarray/list.rb +1 -1
  24. data/lib/multiarray/lookup.rb +18 -13
  25. data/lib/multiarray/lut.rb +13 -16
  26. data/lib/multiarray/malloc.rb +1 -1
  27. data/lib/multiarray/mask.rb +11 -8
  28. data/lib/multiarray/methods.rb +10 -10
  29. data/lib/multiarray/multiarray.rb +15 -44
  30. data/lib/multiarray/node.rb +64 -138
  31. data/lib/multiarray/object.rb +2 -6
  32. data/lib/multiarray/operations.rb +116 -134
  33. data/lib/multiarray/pointer.rb +7 -19
  34. data/lib/multiarray/random.rb +11 -8
  35. data/lib/multiarray/rgb.rb +53 -53
  36. data/lib/multiarray/sequence.rb +11 -496
  37. data/lib/multiarray/shortcuts.rb +4 -4
  38. data/lib/multiarray/store.rb +14 -11
  39. data/lib/multiarray/unmask.rb +10 -7
  40. data/lib/multiarray/variable.rb +11 -3
  41. data/test/tc_bool.rb +0 -8
  42. data/test/tc_compile.rb +72 -0
  43. data/test/tc_float.rb +0 -8
  44. data/test/tc_int.rb +0 -8
  45. data/test/tc_lazy.rb +22 -3
  46. data/test/tc_multiarray.rb +100 -126
  47. data/test/tc_object.rb +0 -16
  48. data/test/tc_rgb.rb +0 -16
  49. data/test/tc_sequence.rb +151 -165
  50. data/test/ts_multiarray.rb +2 -0
  51. metadata +7 -4
@@ -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
@@ -47,6 +47,10 @@ module Hornetseye
47
47
  dest, source, default, zero, labels, rank, n
48
48
  end
49
49
 
50
+ def sexp?
51
+ true
52
+ end
53
+
50
54
  # Get unique descriptor of this object
51
55
  #
52
56
  # @param [Hash] hash Labels for any variables.
@@ -61,15 +65,12 @@ module Hornetseye
61
65
  "#{@n.descriptor( hash )})"
62
66
  end
63
67
 
64
- # Get type of result of delayed operation
65
- #
66
- # @return [Class] Type of result.
67
- def array_type
68
- retval = @dest.array_type
69
- ( class << self; self; end ).instance_eval do
70
- define_method( :array_type ) { retval }
71
- end
72
- retval
68
+ def typecode
69
+ @dest.typecode
70
+ end
71
+
72
+ def shape
73
+ @dest.shape
73
74
  end
74
75
 
75
76
  # Reevaluate computation
@@ -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
@@ -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
@@ -53,6 +53,10 @@ module Hornetseye
53
53
  value, index0, index1, index2, initial, block, var1, var2
54
54
  end
55
55
 
56
+ def sexp?
57
+ true
58
+ end
59
+
56
60
  # Get unique descriptor of this object
57
61
  #
58
62
  # @param [Hash] hash Labels for any variables.
@@ -71,17 +75,12 @@ module Hornetseye
71
75
  "#{@block.descriptor( hash )})"
72
76
  end
73
77
 
74
- # Get type of result of delayed operation
75
- #
76
- # @return [Class] Type of result.
77
- #
78
- # @private
79
- def array_type
80
- retval = Hornetseye::MultiArray @block.typecode, *@value.shape
81
- ( class << self; self; end ).instance_eval do
82
- define_method( :array_type ) { retval }
83
- end
84
- retval
78
+ def typecode
79
+ @block.typecode
80
+ end
81
+
82
+ def shape
83
+ @value.shape
85
84
  end
86
85
 
87
86
  # Reevaluate computation
@@ -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
@@ -29,7 +29,7 @@ module Hornetseye
29
29
  # @see Malloc#load
30
30
  # @see List#load
31
31
  def fetch( ptr )
32
- construct *ptr.load( self )
32
+ construct *ptr.load(self)
33
33
  end
34
34
 
35
35
  # Construct new object from arguments
@@ -39,7 +39,7 @@ module Hornetseye
39
39
  # @return [Element] New object of this type.
40
40
  #
41
41
  # @private
42
- def construct( *args )
42
+ def construct(*args)
43
43
  new *args
44
44
  end
45
45
 
@@ -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
@@ -74,6 +74,10 @@ module Hornetseye
74
74
  check_shape *values
75
75
  end
76
76
 
77
+ def sexp?
78
+ true
79
+ end
80
+
77
81
  # Get unique descriptor of this object
78
82
  #
79
83
  # @param [Hash] hash Labels for any variables.
@@ -86,18 +90,14 @@ module Hornetseye
86
90
  "(#{@values.collect { |value| value.descriptor( hash ) }.join ','})"
87
91
  end
88
92
 
89
- # Get type of result of delayed operation
90
- #
91
- # @return [Class] Type of result.
92
- #
93
- # @private
94
- def array_type
95
- array_types = @values.collect { |value| value.array_type }
96
- retval = self.class.conversion.call *array_types
97
- ( class << self; self; end ).instance_eval do
98
- define_method( :array_type ) { retval }
99
- end
100
- retval
93
+ def typecode
94
+ typecodes = @values.collect { |value| value.typecode }
95
+ self.class.conversion.call *typecodes
96
+ end
97
+
98
+ def shape
99
+ shapes = @values.collect { |value| value.shape }
100
+ shapes.inject { |a,b| a.size > b.size ? a : b }
101
101
  end
102
102
 
103
103
  # Reevaluate computation
@@ -208,7 +208,7 @@ module Hornetseye
208
208
  #
209
209
  # @private
210
210
  def compilable?
211
- array_type.compilable? and @values.all? { |value| value.compilable? }
211
+ typecode.compilable? and @values.all? { |value| value.compilable? }
212
212
  end
213
213
 
214
214
  end
@@ -0,0 +1,380 @@
1
+ # multiarray - Lazy multi-dimensional arrays for Ruby
2
+ # Copyright (C) 2010, 2011 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
+ # Class for representing n-dimensional native arrays
21
+ class Field_
22
+
23
+ class << self
24
+
25
+ # Type of array elements
26
+ #
27
+ # @return [Class] Type of array elements.
28
+ attr_accessor :typecode
29
+
30
+ # Number of dimensions
31
+ #
32
+ # @return [Integer] Number of dimensions.
33
+ attr_accessor :dimension
34
+
35
+ def inherit(typecode, dimension)
36
+ retval = Class.new self
37
+ retval.typecode = typecode
38
+ retval.dimension = dimension
39
+ retval
40
+ end
41
+
42
+ def new(*shape)
43
+ options = shape.last.is_a?( Hash ) ? shape.pop : {}
44
+ raise "Constructor requires #{dimension} arguments" unless dimension == shape.size
45
+ count = options[:count] || 1
46
+ if shape.empty?
47
+ memory = options[:memory] ||
48
+ typecode.memory_type.new(typecode.storage_size * count)
49
+ Hornetseye::Pointer( typecode ).new memory
50
+ else
51
+ size = shape.pop
52
+ stride = shape.inject 1, :*
53
+ Hornetseye::lazy(size) do |index|
54
+ pointer = Field_.inherit(typecode, dimension - 1).
55
+ new *(shape + [:count => count * size, :memory => options[:memory]])
56
+ Lookup.new pointer, index, INT.new(stride)
57
+ end
58
+ end
59
+ end
60
+
61
+ # Display this type
62
+ #
63
+ # @return [String] String with description of this type.
64
+ def inspect
65
+ if typecode and dimension
66
+ if dimension != 1
67
+ "MultiArray(#{typecode.inspect},#{dimension})"
68
+ else
69
+ "Sequence(#{typecode.inspect})"
70
+ end
71
+ else
72
+ 'Field(?,?)'
73
+ end
74
+ end
75
+
76
+ def to_s
77
+ inspect
78
+ end
79
+
80
+ # Construct native array from Ruby array
81
+ #
82
+ # @param [Array<Object>] args Array with Ruby values.
83
+ #
84
+ # @return [Node] Native array with specified values.
85
+ def [](*args)
86
+ def arr_shape(args)
87
+ if args.is_a? Array
88
+ args.collect do |arg|
89
+ arr_shape arg
90
+ end.inject([]) do |a,b|
91
+ (0 ... [a.size, b.size].max).collect do |i|
92
+ [i < a.size ? a[i] : 0, i < b.size ? b[i] : 0].max
93
+ end
94
+ end + [args.size]
95
+ else
96
+ []
97
+ end
98
+ end
99
+ retval = new *arr_shape(args)
100
+ def recursion(element, args)
101
+ if element.dimension > 0
102
+ args.each_with_index do |arg,i|
103
+ recursion element.element(INT.new(i)), arg
104
+ end
105
+ else
106
+ element[] = args
107
+ end
108
+ end
109
+ recursion retval, args
110
+ retval
111
+ end
112
+
113
+ # Create (lazy) index array
114
+ #
115
+ # @overload indgen(*shape, offset = 0, increment = 1)
116
+ # @param [Array<Integer>] shape Dimensions of resulting array.
117
+ # @param [Object] offset (0) First value of array.
118
+ # @param [Object] increment (1) Increment for subsequent values.
119
+ #
120
+ # @return [Node] Lazy term generating the array.
121
+ def indgen(*args)
122
+ unless args.size.between? dimension, dimension + 2
123
+ raise "#{inspect}.indgen requires between #{dimension} and #{dimension + 2} arguments"
124
+ end
125
+ shape = args[0 ... dimension]
126
+ offset = args.size > dimension ? args[dimension] : 0
127
+ increment = args.size > dimension + 1 ? args[dimension + 1] : 1
128
+ step = shape[0 ... -1].inject 1, :*
129
+ Hornetseye::lazy(shape.last) do |i|
130
+ (step * increment * i +
131
+ Hornetseye::MultiArray(typecode, dimension - 1).
132
+ indgen(*(shape[0 ... -1] + [offset, increment]))).to_type typecode
133
+ end
134
+ end
135
+
136
+ # Generate random number array
137
+ #
138
+ # Generate integer or floating point random numbers in the range 0 ... n.
139
+ #
140
+ # @overload random(*shape, n)
141
+ # @param [Array<Integer>] shape Dimensions of resulting array.
142
+ # @param [Integer,Float] n (1) Upper boundary for random numbers
143
+ #
144
+ # @return [Node] Array with random numbers.
145
+ def random(*args)
146
+ unless args.size.between? dimension, dimension + 1
147
+ raise "#{inspect}.random requires between #{dimension} and #{dimension + 1} arguments"
148
+ end
149
+ shape = args[0 ... dimension]
150
+ n = args.size > dimension ? args[dimension] : 1
151
+ n = typecode.maxint.new n unless n.matched?
152
+ retval = new *shape
153
+ unless compilable? and dimension > 0
154
+ Random.new(retval.sexp, n).demand
155
+ else
156
+ GCCFunction.run Random.new(retval.sexp, n)
157
+ end
158
+ retval
159
+ end
160
+
161
+ # Base type of this data type
162
+ #
163
+ # @return [Class] Returns +element_type+.
164
+ #
165
+ # @private
166
+ def basetype
167
+ typecode.basetype
168
+ end
169
+
170
+ # Get storage size of array type
171
+ #
172
+ # @param [Array<Integer>] shape Shape of desired array.
173
+ #
174
+ # @return [Integer] Storage size of array.
175
+ def storage_size(*shape)
176
+ shape.inject typecode.storage_size, :*
177
+ end
178
+
179
+ # Type coercion for native elements
180
+ #
181
+ # @param [Class] other Other native datatype to coerce with.
182
+ #
183
+ # @return [Class] Result of coercion.
184
+ #
185
+ # @private
186
+ def coercion( other )
187
+ Hornetseye::MultiArray typecode.coercion(other.typecode),
188
+ [dimension, other.dimension].max
189
+ end
190
+
191
+ # Check whether delayed operation will have colour
192
+ #
193
+ # @return [Boolean] Boolean indicating whether the array has elements of type
194
+ # RGB.
195
+ def rgb?
196
+ typecode.rgb?
197
+ end
198
+
199
+ # Get this type
200
+ #
201
+ # @return [Class] Returns +self+.
202
+ #
203
+ # @private
204
+ def identity
205
+ self
206
+ end
207
+
208
+ # Get corresponding boolean type
209
+ #
210
+ # @return [Class] Returns type for array of boolean values.
211
+ #
212
+ # @private
213
+ def bool
214
+ Hornetseye::MultiArray typecode.bool, dimension
215
+ end
216
+
217
+ # Coerce and convert to boolean type
218
+ #
219
+ # @return [Class] Returns type for array of boolean values.
220
+ #
221
+ # @private
222
+ def coercion_bool(other)
223
+ coercion(other).bool
224
+ end
225
+
226
+ # Get corresponding scalar type
227
+ #
228
+ # @return [Class] Returns type for array of scalars.
229
+ #
230
+ # @private
231
+ def scalar
232
+ Hornetseye::MultiArray typecode.scalar, dimension
233
+ end
234
+
235
+ # Get corresponding floating point type
236
+ #
237
+ # @return [Class] Returns type for array of floating point numbers.
238
+ #
239
+ # @private
240
+ def float_scalar
241
+ Hornetseye::MultiArray typecode.float_scalar, dimension
242
+ end
243
+
244
+ # Get corresponding maximum integer type
245
+ #
246
+ # @return [Class] Returns type based on maximum integers.
247
+ #
248
+ # @private
249
+ def maxint
250
+ Hornetseye::MultiArray typecode.maxint, dimension
251
+ end
252
+
253
+ # Coerce and convert to maximum integer type
254
+ #
255
+ # @return [Class] Returns type based on maximum integers.
256
+ #
257
+ # @private
258
+ def coercion_maxint(other)
259
+ coercion(other).maxint
260
+ end
261
+
262
+ # Get corresponding byte type
263
+ #
264
+ # @return [Class] Returns type based on byte.
265
+ #
266
+ # @private
267
+ def byte
268
+ Hornetseye::MultiArray typecode.byte, dimension
269
+ end
270
+
271
+ # Coerce and convert to byte type
272
+ #
273
+ # @return [Class] Returns type based on byte.
274
+ #
275
+ # @private
276
+ def coercion_byte(other)
277
+ coercion(other).byte
278
+ end
279
+
280
+ # Convert to type based on floating point numbers
281
+ #
282
+ # @return [Class] Corresponding type based on floating point numbers.
283
+ #
284
+ # @private
285
+ def float
286
+ Hornetseye::MultiArray typecode.field, dimension
287
+ end
288
+
289
+ # Coerce and convert to type based on floating point numbers
290
+ #
291
+ # @return [Class] Corresponding type based on floating point numbers.
292
+ #
293
+ # @private
294
+ def floating(other)
295
+ coercion(other).float
296
+ end
297
+
298
+ # Coerce with two other types
299
+ #
300
+ # @return [Class] Result of coercion.
301
+ #
302
+ # @private
303
+ def cond(a, b)
304
+ t = a.coercion b
305
+ Hornetseye::MultiArray t.typecode, dimension
306
+ end
307
+
308
+ # Replace element type
309
+ #
310
+ # @return [Class] Result of conversion.
311
+ #
312
+ # @private
313
+ def to_type(dest)
314
+ Hornetseye::MultiArray typecode.to_type(dest), dimension
315
+ end
316
+
317
+ # Check whether this array expression allows compilation
318
+ #
319
+ # @return [Boolean] Returns +true+ if this expression supports compilation.
320
+ def compilable?
321
+ typecode.compilable?
322
+ end
323
+
324
+ end
325
+
326
+ # Namespace containing method for matching elements of type Field_
327
+ #
328
+ # @see Field_
329
+ #
330
+ # @private
331
+ module Match
332
+
333
+ # Method for matching elements of type Field_
334
+ #
335
+ # @param [Array<Object>] *values Values to find matching native element
336
+ # type for.
337
+ #
338
+ # @return [Class] Native type fitting all values.
339
+ #
340
+ # @see Field_
341
+ #
342
+ # @private
343
+ def fit( *values )
344
+ n = values.inject 0 do |size,value|
345
+ value.is_a?(Array) ? [size, value.size].max : size
346
+ end
347
+ if n > 0
348
+ elements = values.inject [] do |flat,value|
349
+ flat + (value.is_a?(Array) ? value : [value])
350
+ end
351
+ Hornetseye::MultiArray fit( *elements ), 1
352
+ else
353
+ super *values
354
+ end
355
+ end
356
+
357
+ # Perform type alignment
358
+ #
359
+ # Align this type to another. This is used to prefer single-precision
360
+ # floating point in certain cases.
361
+ #
362
+ # @param [Class] context Other type to align with.
363
+ #
364
+ # @private
365
+ def align(context)
366
+ if self < Field_
367
+ Hornetseye::MultiArray typecode.align(context), dimension
368
+ else
369
+ super context
370
+ end
371
+ end
372
+
373
+ end
374
+
375
+ Node.extend Match
376
+
377
+ end
378
+
379
+ end
380
+