multiarray 0.5.2 → 0.6.0

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