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.
@@ -21,6 +21,14 @@ module Hornetseye
21
21
 
22
22
  class << self
23
23
 
24
+ # Check compatibility of other type.
25
+ #
26
+ # This method checks whether binary operations with the other Ruby object can
27
+ # be performed without requiring coercion.
28
+ #
29
+ # @param [Object] value The other Ruby object.
30
+ #
31
+ # @return [Boolean] Returns +false+ if Ruby object requires coercion.
24
32
  def generic?( value )
25
33
  value.is_a?( GCCValue ) or value.is_a?( Fixnum ) or
26
34
  value.is_a?( Float )
@@ -83,14 +91,25 @@ module Hornetseye
83
91
  @descriptor = descriptor
84
92
  end
85
93
 
94
+ # Display descriptor of this object
95
+ #
96
+ # @return [String] Returns the descriptor of this object.
86
97
  def inspect
87
98
  @descriptor
88
99
  end
89
100
 
101
+ # Get descriptor of this object
102
+ #
103
+ # @return [String] Returns the descriptor of this object.
90
104
  def to_s
91
105
  @descriptor
92
106
  end
93
107
 
108
+ # Store new value in this object
109
+ #
110
+ # @param [Object] value The new value.
111
+ #
112
+ # @return [Object] Returns +value+.
94
113
  def store( value )
95
114
  @function << "#{@function.indent}#{self} = #{value};\n"
96
115
  value
@@ -104,7 +123,7 @@ module Hornetseye
104
123
  offset = 0
105
124
  typecode.typecodes.collect do |t|
106
125
  value = GCCValue.new @function,
107
- "*(#{GCCType.new( t ).identifiers.first} *)( #{self} + #{offset} )" # !!!
126
+ "*(#{GCCType.new( t ).identifier} *)( #{self} + #{offset} )"
108
127
  offset += t.storage_size
109
128
  value
110
129
  end
@@ -113,7 +132,7 @@ module Hornetseye
113
132
  def save( value )
114
133
  offset = 0
115
134
  value.class.typecodes.zip( value.values ).each do |t,v|
116
- @function << "#{@function.indent}*(#{GCCType.new( t ).identifiers.first} *)( #{self} + #{offset} ) = #{v};\n" # !!!
135
+ @function << "#{@function.indent}*(#{GCCType.new( t ).identifier} *)( #{self} + #{offset} ) = #{v};\n"
117
136
  offset += t.storage_size
118
137
  end
119
138
  end
@@ -177,6 +196,7 @@ module Hornetseye
177
196
  define_binary_op :>=
178
197
  define_unary_method Math, :sqrt
179
198
  define_unary_method Math, :log
199
+ define_unary_method Math, :log10
180
200
  define_unary_method Math, :exp
181
201
  define_unary_method Math, :cos
182
202
  define_unary_method Math, :sin
@@ -187,6 +207,9 @@ module Hornetseye
187
207
  define_unary_method Math, :cosh
188
208
  define_unary_method Math, :sinh
189
209
  define_unary_method Math, :tanh
210
+ define_unary_method Math, :acosh
211
+ define_unary_method Math, :asinh
212
+ define_unary_method Math, :atanh
190
213
  define_binary_method Math, :atan2
191
214
  define_binary_method Math, :hypot
192
215
 
@@ -0,0 +1,82 @@
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 Histogram < Node
20
+
21
+ class << self
22
+
23
+ def finalised?
24
+ false
25
+ end
26
+
27
+ end
28
+
29
+ def initialize( dest, source )
30
+ @dest, @source = dest, source
31
+ end
32
+
33
+ def descriptor( hash )
34
+ "Histogram(#{@dest.descriptor( hash )},#{@source.descriptor( hash )})"
35
+ end
36
+
37
+ def array_type
38
+ @dest.array_type
39
+ end
40
+
41
+ def demand
42
+ if variables.empty?
43
+ if @source.dimension > 1
44
+ @source.shape.last.times do |i|
45
+ source = @source.element INT.new( i )
46
+ Histogram.new( @dest, source ).demand
47
+ end
48
+ else
49
+ dest = @dest
50
+ ( @dest.dimension - 1 ).downto( 0 ) do |i|
51
+ dest = dest.element @source.element( INT.new( i ) ).demand
52
+ end
53
+ dest.store dest + 1
54
+ end
55
+ @dest
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+ def subst( hash )
62
+ self.class.new @dest.subst( hash ), @source.subst( hash )
63
+ end
64
+
65
+ def variables
66
+ @dest.variables + @source.variables
67
+ end
68
+
69
+ def strip
70
+ vars1, values1, term1 = @dest.strip
71
+ vars2, values2, term2 = @source.strip
72
+ return vars1 + vars2, values1 + values2, self.class.new( term1, term2 )
73
+ end
74
+
75
+ def compilable?
76
+ @dest.compilable? and @source.compilable?
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+
@@ -26,6 +26,10 @@ module Hornetseye
26
26
  # @return [Object] Size of range for this index.
27
27
  attr_accessor :size
28
28
 
29
+ # Display information about this class
30
+ #
31
+ # @return [String] Returns string with information about this class (e.g.
32
+ # "INDEX(INT(5))").
29
33
  def inspect
30
34
  "INDEX(#{size.inspect})"
31
35
  end
@@ -41,6 +45,11 @@ module Hornetseye
41
45
  "INDEX(#{size.descriptor( hash )})"
42
46
  end
43
47
 
48
+ # Get type of result of delayed operation
49
+ #
50
+ # @return [Class] Type of result.
51
+ #
52
+ # @private
44
53
  def array_type
45
54
  INT
46
55
  end
@@ -63,10 +72,24 @@ module Hornetseye
63
72
  end
64
73
  end
65
74
 
75
+ # Substitute variables
76
+ #
77
+ # Substitute the variables with the values given in the hash.
78
+ #
79
+ # @param [Hash] hash Substitutions to apply.
80
+ #
81
+ # @return [Class] Class with substitutions applied.
82
+ #
83
+ # @private
66
84
  def subst( hash )
67
85
  Hornetseye::INDEX size.subst( hash )
68
86
  end
69
87
 
88
+ # Get variables contained in this class
89
+ #
90
+ # @return [Set] Returns set of variables.
91
+ #
92
+ # @private
70
93
  def variables
71
94
  size.variables
72
95
  end
@@ -21,6 +21,11 @@ module Hornetseye
21
21
 
22
22
  class << self
23
23
 
24
+ # Check whether objects of this class are finalised computations
25
+ #
26
+ # @return [Boolean] Returns +false+.
27
+ #
28
+ # @private
24
29
  def finalised?
25
30
  false
26
31
  end
@@ -48,6 +53,11 @@ module Hornetseye
48
53
  "#{@index.descriptor( hash )},#{@block.descriptor( hash )})"
49
54
  end
50
55
 
56
+ # Get type of result of delayed operation
57
+ #
58
+ # @return [Class] Type of result.
59
+ #
60
+ # @private
51
61
  def array_type
52
62
  @value.to_type( @block.typecode ).array_type
53
63
  end
@@ -79,6 +89,8 @@ module Hornetseye
79
89
  # @param [Integer,Node] i Index of desired element.
80
90
  #
81
91
  # @return [Node,Object] Element of injection.
92
+ #
93
+ # @private
82
94
  def element( i )
83
95
  Inject.new @value.element( i ), @index, @initial, @block, @var1, @var2
84
96
  end
@@ -135,7 +147,7 @@ module Hornetseye
135
147
 
136
148
  # Check whether this term is compilable
137
149
  #
138
- # @return [FalseClass,TrueClass] Returns whether this term is compilable.
150
+ # @return [Boolean] Returns whether this term is compilable.
139
151
  #
140
152
  # @private
141
153
  def compilable?
@@ -29,7 +29,7 @@ module Hornetseye
29
29
 
30
30
  # Boolean indicating whether this is a signed integer or not
31
31
  #
32
- # @return [FalseClass,TrueClass] Boolean indicating whether this is a
32
+ # @return [Boolean] Boolean indicating whether this is a
33
33
  # signed integer or not.
34
34
  attr_accessor :signed
35
35
 
@@ -53,17 +53,29 @@ module Hornetseye
53
53
 
54
54
  # Get default value for elements of this type
55
55
  #
56
- # @return [Object] Returns +false+.
56
+ # @return [Object] Returns +0+.
57
57
  #
58
58
  # @private
59
59
  def default
60
60
  0
61
61
  end
62
62
 
63
+ # Get corresponding maximal integer type.
64
+ #
65
+ # @return [Class] Returns 32 bit integer or self whichever has more bits.
66
+ #
67
+ # @private
63
68
  def maxint
64
69
  Hornetseye::INT [ 32, bits ].max, signed
65
70
  end
66
71
 
72
+ # Compute balanced type for binary operation
73
+ #
74
+ # @param [Class] other Other native datatype to coerce with.
75
+ #
76
+ # @return [Class] Result of coercion.
77
+ #
78
+ # @private
67
79
  def coercion( other )
68
80
  if other < INT_
69
81
  Hornetseye::INT [ bits, other.bits ].max, ( signed or other.signed )
@@ -72,6 +84,13 @@ module Hornetseye
72
84
  end
73
85
  end
74
86
 
87
+ # Type coercion for native elements
88
+ #
89
+ # @param [Class] other Other type to coerce with.
90
+ #
91
+ # @return [Array<Class>] Result of coercion.
92
+ #
93
+ # @private
75
94
  def coerce( other )
76
95
  if other < INT_
77
96
  return other, self
@@ -98,7 +117,8 @@ module Hornetseye
98
117
 
99
118
  # Get string with information about this class
100
119
  #
101
- # @return [String] Returns string with information about this class.
120
+ # @return [String] Returns string with information about this class (e.g.
121
+ # "BYTE").
102
122
  def inspect
103
123
  unless bits.nil? or signed.nil?
104
124
  retval = { [ 8, true ] => 'BYTE',
@@ -130,20 +150,32 @@ module Hornetseye
130
150
  end
131
151
  end
132
152
 
133
- # Comparison operator
153
+ # Test equality of classes
134
154
  #
135
- # @param [Object] other Other object to compare with.
155
+ # @param [Object] other Object to compare with.
136
156
  #
137
- # @return [FalseClass,TrueClass] Result of comparison.
157
+ # @return [Boolean] Boolean indicating whether classes are equal.
138
158
  def ==( other )
139
159
  other.is_a? Class and other < INT_ and
140
160
  bits == other.bits and signed == other.signed
141
161
  end
142
162
 
163
+ # Compute hash value for this class.
164
+ #
165
+ # @return [Fixnum] Hash value
166
+ #
167
+ # @private
143
168
  def hash
144
169
  [ :INT_, bits, signed ].hash
145
170
  end
146
171
 
172
+ # Equality for hash operations
173
+ #
174
+ # @param [Object] other Object to compare with.
175
+ #
176
+ # @return [Boolean] Returns +true+ if objects are equal.
177
+ #
178
+ # @private
147
179
  def eql?( other )
148
180
  self == other
149
181
  end
@@ -169,8 +201,8 @@ module Hornetseye
169
201
 
170
202
  # Method for matching elements of type INT_
171
203
  #
172
- # 'param [Array<Object>] *values Values to find matching native element
173
- # type for.
204
+ # @param [Array<Object>] *values Values to find matching native element
205
+ # type for.
174
206
  #
175
207
  # @return [Class] Native type fitting all values.
176
208
  #
@@ -227,12 +259,13 @@ module Hornetseye
227
259
  # Create a class deriving from +INT_+. The aprameters +bits+ and +signed+
228
260
  # are assigned to the corresponding attributes of the resulting class.
229
261
  # @param [Integer] bits Number of bits of native integer.
230
- # @param [FalseClass,TrueClass] signed Specify +UNSIGNED+ or +SIGNED+ here.
262
+ # @param [Boolean] signed Specify +UNSIGNED+ or +SIGNED+ here.
231
263
  # @return [Class] A class deriving from +INT_+.
232
264
  #
233
265
  # @overload INT( value )
234
266
  # This is a shortcut for +INT.new( value )+.
235
267
  # @param [Integer] value Initial value for integer object.
268
+ # @return [INT] Wrapped integer value.
236
269
  #
237
270
  # @see INT_
238
271
  # @see INT_.bits
@@ -274,30 +307,93 @@ module Hornetseye
274
307
  # 64-bit unsigned integer
275
308
  ULONG = INT 64, UNSIGNED
276
309
 
310
+ # Shortcut for constructor
311
+ #
312
+ # The method calls +BYTE.new+.
313
+ #
314
+ # @param [Integer] value Integer value.
315
+ #
316
+ # @return [BYTE] The wrapped integer value.
317
+ #
318
+ # @private
277
319
  def BYTE( value )
278
320
  BYTE.new value
279
321
  end
280
322
 
323
+ # Shortcut for constructor
324
+ #
325
+ # The method calls +UBYTE.new+.
326
+ #
327
+ # @param [Integer] value Integer value.
328
+ #
329
+ # @return [UBYTE] The wrapped integer value.
330
+ #
331
+ # @private
281
332
  def UBYTE( value )
282
333
  UBYTE.new value
283
334
  end
284
335
 
336
+ # Shortcut for constructor
337
+ #
338
+ # The method calls +SINT.new+.
339
+ #
340
+ # @param [Integer] value Integer value.
341
+ #
342
+ # @return [SINT] The wrapped integer value.
343
+ #
344
+ # @private
285
345
  def SINT( value )
286
346
  SINT.new value
287
347
  end
288
348
 
349
+ # Shortcut for constructor
350
+ #
351
+ # The method calls +USINT.new+.
352
+ #
353
+ # @param [Integer] value Integer value.
354
+ #
355
+ # @return [USINT] The wrapped integer value.
356
+ #
357
+ # @private
289
358
  def USINT( value )
290
359
  USINT.new value
291
360
  end
292
361
 
362
+ # Shortcut for constructor
363
+ #
364
+ # The method calls +UINT.new+.
365
+ #
366
+ # @param [Integer] value Integer value.
367
+ #
368
+ # @return [UINT] The wrapped integer value.
369
+ #
370
+ # @private
293
371
  def UINT( value )
294
372
  UINT.new value
295
373
  end
296
374
 
375
+ # Shortcut for constructor
376
+ #
377
+ # The method calls +LONG.new+.
378
+ #
379
+ # @param [Integer] value Integer value.
380
+ #
381
+ # @return [LONG] The wrapped integer value.
382
+ #
383
+ # @private
297
384
  def LONG( value )
298
385
  LONG.new value
299
386
  end
300
387
 
388
+ # Shortcut for constructor
389
+ #
390
+ # The method calls +ULONG.new+.
391
+ #
392
+ # @param [Integer] value Integer value.
393
+ #
394
+ # @return [ULONG] The wrapped integer value.
395
+ #
396
+ # @private
301
397
  def ULONG( value )
302
398
  ULONG.new value
303
399
  end
@@ -0,0 +1,82 @@
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 Integral < Node
20
+
21
+ class << self
22
+
23
+ def finalised?
24
+ false
25
+ end
26
+
27
+ end
28
+
29
+ def initialize( dest, source )
30
+ @dest, @source = dest, source
31
+ end
32
+
33
+ def descriptor( hash )
34
+ "Integral(#{@dest.descriptor( hash )},#{@source.descriptor( hash )})"
35
+ end
36
+
37
+ def array_type
38
+ @dest.array_type
39
+ end
40
+
41
+ def demand
42
+ if variables.empty?
43
+ if @source.dimension > 0
44
+ self.class.new( @dest.element( INT.new( 0 ) ),
45
+ @source.element( INT.new( 0 ) ) ).demand
46
+ INT.new( 1 ).upto INT.new( @source.shape.last ) - 1 do |i|
47
+ dest = @dest.element INT.new( i )
48
+ source = @source.element INT.new( i )
49
+ self.class.new( dest, source ).demand
50
+ Store.new( dest, dest + @dest.element( INT.new( i ) - 1 ) ).demand
51
+ end
52
+ else
53
+ Store.new( @dest, @source ).demand
54
+ end
55
+ @dest
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+ def subst( hash )
62
+ self.class.new @dest.subst( hash ), @source.subst( hash )
63
+ end
64
+
65
+ def variables
66
+ @dest.variables + @source.variables
67
+ end
68
+
69
+ def strip
70
+ vars1, values1, term1 = @dest.strip
71
+ vars2, values2, term2 = @source.strip
72
+ return vars1 + vars2, values1 + values2, self.class.new( term1, term2 )
73
+ end
74
+
75
+ def compilable?
76
+ @dest.compilable? and @source.compilable?
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+
@@ -24,6 +24,10 @@ module Hornetseye
24
24
  @term = term
25
25
  end
26
26
 
27
+ def memory
28
+ @term.memory
29
+ end
30
+
27
31
  # Get unique descriptor of this object
28
32
  #
29
33
  # @param [Hash] hash Labels for any variables.
@@ -36,10 +40,20 @@ module Hornetseye
36
40
  "Lambda(#{@index.descriptor( hash )},#{@term.descriptor( hash )})"
37
41
  end
38
42
 
43
+ # Get type of result of delayed operation
44
+ #
45
+ # @return [Class] Type of result.
46
+ #
47
+ # @private
39
48
  def array_type
40
49
  Hornetseye::Sequence @term.array_type, @index.size.get
41
50
  end
42
51
 
52
+ # Get variables contained in this term
53
+ #
54
+ # @return [Set] Returns list of variables.
55
+ #
56
+ # @private
43
57
  def variables
44
58
  @term.variables - @index.variables + @index.meta.variables
45
59
  end
@@ -59,19 +73,20 @@ module Hornetseye
59
73
  return vars + meta_vars, values + meta_values, Lambda.new( var, term )
60
74
  end
61
75
 
76
+ # Substitute variables
77
+ #
78
+ # Substitute the variables with the values given in the hash.
79
+ #
80
+ # @param [Hash] hash Substitutions to apply.
81
+ #
82
+ # @return [Node] Term with substitutions applied.
83
+ #
84
+ # @private
62
85
  def subst( hash )
63
86
  subst_var = @index.subst hash
64
87
  Lambda.new subst_var, @term.subst( @index => subst_var ).subst( hash )
65
88
  end
66
89
 
67
- def store( value )
68
- shape.last.times do |i|
69
- node = value.dimension == 0 ? value : value.element( INT.new( i ) )
70
- element( INT.new( i ) ).store node
71
- end
72
- value
73
- end
74
-
75
90
  # Lookup element of an array
76
91
  #
77
92
  # @param [Node] value Index of element.
@@ -88,16 +103,27 @@ module Hornetseye
88
103
  end
89
104
  end
90
105
 
106
+ # Skip elements of an array
107
+ #
108
+ # @param [Variable] index Variable identifying index of array.
109
+ # @param [Node] start Wrapped integer with number of elements to skip.
110
+ #
111
+ # @return [Node] Return lambda expression with elements skipped.
112
+ #
113
+ # @private
91
114
  def skip( index, start )
92
115
  Lambda.new @index, @term.skip( index, start )
93
116
  end
94
117
 
95
118
  # Get element of this term
119
+ #
96
120
  # Pass +i+ as argument to this lambda object.
97
121
  #
98
122
  # @param [Integer,Node] i Index of desired element.
99
123
  #
100
124
  # @return [Node,Object] Result of inserting +i+ for lambda argument.
125
+ #
126
+ # @private
101
127
  def element( i )
102
128
  unless i.is_a? Node
103
129
  unless ( 0 ... shape.last ).member? i
@@ -109,6 +135,14 @@ module Hornetseye
109
135
  @term.subst @index => i
110
136
  end
111
137
 
138
+ # Extract array view with part of array
139
+ #
140
+ # @param [Integer,Node] start Number of elements to skip.
141
+ # @param [Integer,Node] length Size of array view.
142
+ #
143
+ # @return [Node] Array view with the specified elements.
144
+ #
145
+ # @private
112
146
  def slice( start, length )
113
147
  unless start.is_a?( Node ) or length.is_a?( Node )
114
148
  if start < 0 or start + length > shape.last
@@ -123,14 +157,30 @@ module Hornetseye
123
157
  skip( index, start ) ).unroll
124
158
  end
125
159
 
160
+ # Decompose composite elements
161
+ #
162
+ # This method decomposes composite elements into array.
163
+ #
164
+ # @return [Node] Result of decomposition.
126
165
  def decompose
127
166
  Lambda.new @index, @term.decompose
128
167
  end
129
168
 
169
+ # Check whether this term is compilable
170
+ #
171
+ # @return [Boolean] Returns whether this term is compilable.
172
+ #
173
+ # @private
130
174
  def compilable?
131
175
  @term.compilable?
132
176
  end
133
177
 
178
+ # Check whether this object is a finalised computation
179
+ #
180
+ # @return [Boolean] Returns boolean indicating whether the lambda
181
+ # term is finalised or not.
182
+ #
183
+ # @private
134
184
  def finalised?
135
185
  @term.finalised?
136
186
  end