multiarray 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,152 @@
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
+ class GCCValue
21
+
22
+ def initialize( function, descriptor )
23
+ @function = function
24
+ @descriptor = descriptor
25
+ end
26
+
27
+ def inspect
28
+ @descriptor
29
+ end
30
+
31
+ def to_s
32
+ @descriptor
33
+ end
34
+
35
+ # Store result of computation in new variable
36
+ #
37
+ # @return [Node,Object] Result of computation
38
+ #
39
+ # @see #force
40
+ #
41
+ # @private
42
+ def duplicate( typecode )
43
+ result = @function.variable( typecode, 'v' ).get
44
+ result.store self
45
+ result
46
+ end
47
+
48
+ def store( value )
49
+ @function << "#{@function.indent}#{self} = #{value};\n"
50
+ value
51
+ end
52
+
53
+ def compilable?
54
+ false
55
+ end
56
+
57
+ def load( typecode )
58
+ GCCValue.new @function, "*(#{GCCType.new( typecode ).identifier} *)( #{self} )"
59
+ end
60
+
61
+ def save( value )
62
+ @function << "#{@function.indent}*(#{GCCType.new( value.typecode ).identifier} *)( #{self} ) = #{value.get};\n"
63
+ end
64
+
65
+ def eq( other )
66
+ GCCValue.new @function, "( #{self} ) == ( #{other} )"
67
+ end
68
+
69
+ def ne( other )
70
+ GCCValue.new @function, "( #{self} ) != ( #{other} )"
71
+ end
72
+
73
+ def conditional( a, b )
74
+ GCCValue.new @function, "( #{self} ) ? ( #{a} ) : ( #{b} )"
75
+ end
76
+
77
+ def not
78
+ GCCValue.new @function, "!( #{self} )"
79
+ end
80
+
81
+ def ~
82
+ GCCValue.new @function, "~( #{self} )"
83
+ end
84
+
85
+ def and( other )
86
+ GCCValue.new @function, "( #{self} ) && ( #{other} )"
87
+ end
88
+
89
+ def or( other )
90
+ GCCValue.new @function, "( #{self} ) || ( #{other} )"
91
+ end
92
+
93
+ def &( other )
94
+ GCCValue.new @function, "( #{self} ) & ( #{other} )"
95
+ end
96
+
97
+ def |( other )
98
+ GCCValue.new @function, "( #{self} ) | ( #{other} )"
99
+ end
100
+
101
+ def ^( other )
102
+ GCCValue.new @function, "( #{self} ) ^ ( #{other} )"
103
+ end
104
+
105
+ def <<( other )
106
+ GCCValue.new @function, "( #{self} ) << ( #{other} )"
107
+ end
108
+
109
+ def >>( other )
110
+ GCCValue.new @function, "( #{self} ) >> ( #{other} )"
111
+ end
112
+
113
+ def -@
114
+ GCCValue.new @function, "-( #{self} )"
115
+ end
116
+
117
+ def +( other )
118
+ GCCValue.new @function, "( #{self} ) + ( #{other} )"
119
+ end
120
+
121
+ def -( other )
122
+ GCCValue.new @function, "( #{self} ) - ( #{other} )"
123
+ end
124
+
125
+ def *( other )
126
+ GCCValue.new @function, "( #{self} ) * ( #{other} )"
127
+ end
128
+
129
+ def /( other )
130
+ GCCValue.new @function, "( #{self} ) / ( #{other} )"
131
+ end
132
+
133
+ def zero?
134
+ GCCValue.new @function, "( #{self} ) == 0"
135
+ end
136
+
137
+ def nonzero?
138
+ GCCValue.new @function, "( #{self} ) != 0"
139
+ end
140
+
141
+ def times( &action )
142
+ i = @function.variable INT, 'i'
143
+ @function << "#{@function.indent}for ( #{i.get} = 0; #{i.get} != #{self}; #{i.get}++ ) {\n"
144
+ @function.indent_offset +1
145
+ action.call i.get
146
+ @function.indent_offset -1
147
+ @function << "#{@function.indent}};\n"
148
+ end
149
+
150
+ end
151
+
152
+ end
@@ -0,0 +1,91 @@
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
+ class INDEX_ < Element
21
+
22
+ class << self
23
+
24
+ # Size of range for this index
25
+ #
26
+ # @return [Object] Size of range for this index.
27
+ attr_accessor :size
28
+
29
+ def inspect
30
+ "INDEX(#{size.inspect})"
31
+ end
32
+
33
+ # Get unique descriptor of this class
34
+ #
35
+ # @param [Hash] hash Labels for any variables.
36
+ #
37
+ # @return [String] Descriptor of this class.
38
+ #
39
+ # @private
40
+ def descriptor( hash )
41
+ "INDEX(#{size.descriptor( hash )})"
42
+ end
43
+
44
+ def array_type
45
+ INT
46
+ end
47
+
48
+ # Strip of all values
49
+ #
50
+ # Split up into variables, values, and a term where all values have been
51
+ # replaced with variables.
52
+ #
53
+ # @return [Array<Array,Node>] Returns an array of variables, an array of
54
+ # values, and the term based on variables.
55
+ #
56
+ # @private
57
+ def strip
58
+ meta_vars, meta_values = size.strip
59
+ if meta_vars.empty?
60
+ return [], [], self
61
+ else
62
+ return meta_vars, meta_values, Hornetseye::INDEX( meta_vars.first )
63
+ end
64
+ end
65
+
66
+ def subst( hash )
67
+ Hornetseye::INDEX size.subst( hash )
68
+ end
69
+
70
+ def variables
71
+ size.variables
72
+ end
73
+
74
+ end
75
+
76
+ def initialize
77
+ raise "#{self.class.inspect} must not be instantiated"
78
+ end
79
+
80
+ end
81
+
82
+ def INDEX( size )
83
+ retval = Class.new INDEX_
84
+ size = INT.new( size ) unless size.is_a? Node
85
+ retval.size = size
86
+ retval
87
+ end
88
+
89
+ module_function :INDEX
90
+
91
+ end
@@ -0,0 +1,143 @@
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
+ class Inject < Node
21
+
22
+ def initialize( value, index, initial, block, var1, var2 )
23
+ @value, @index, @initial, @block, @var1, @var2 =
24
+ value, index, initial, block, var1, var2
25
+ end
26
+
27
+ # Get unique descriptor of this object
28
+ #
29
+ # @param [Hash] hash Labels for any variables.
30
+ #
31
+ # @return [String] Descriptor of this object,
32
+ #
33
+ # @private
34
+ def descriptor( hash )
35
+ hash = hash.merge @index => ( ( hash.values.max || 0 ) + 1 )
36
+ hash = hash.merge @var1 => ( ( hash.values.max || 0 ) + 1 )
37
+ hash = hash.merge @var2 => ( ( hash.values.max || 0 ) + 1 )
38
+ "Inject(#{@value.descriptor( hash )},#{@initial ? @initial.descriptor( hash ) : 'nil'},#{@index.descriptor( hash )},#{@block.descriptor( hash )})"
39
+ end
40
+
41
+ def array_type
42
+ @value.array_type
43
+ end
44
+
45
+ # Reevaluate computation
46
+ #
47
+ # @return [Node,Object] Result of computation
48
+ #
49
+ # @see #force
50
+ #
51
+ # @private
52
+ def demand
53
+ if @initial
54
+ retval = @initial.simplify # !!!
55
+ @index.size.get.times do |i|
56
+ sub = @value.subst( @index => INT.new( i ) ).simplify # !!!
57
+ retval.store @block.subst( @var1 => retval,
58
+ @var2 => sub ).simplify
59
+ end
60
+ else
61
+ retval = @value.subst( @index => INT.new( 0 ) ).simplify # !!!
62
+ ( @index.size - 1 ).get.times do |i|
63
+ sub = @value.subst( @index => INT.new( i ) + 1 ).simplify # !!!
64
+ retval.store @block.subst( @var1 => retval,
65
+ @var2 => sub ).simplify
66
+ end
67
+ end
68
+ retval
69
+ end
70
+
71
+ # Get element of injection
72
+ #
73
+ # @param [Integer,Node] i Index of desired element.
74
+ #
75
+ # @return [Node,Object] Element of injection.
76
+ def element( i )
77
+ Inject.new @value.element( i ), @index, @initial, @block, @var1, @var2
78
+ end
79
+
80
+ # Get variables contained in this term
81
+ #
82
+ # @return [Set] Returns set of variables.
83
+ #
84
+ # @private
85
+ def variables
86
+ initial_variables = @initial ? @initial.variables : Set[]
87
+ ( @value.variables + initial_variables ) - @index.variables
88
+ end
89
+
90
+ # Strip of all values
91
+ #
92
+ # Split up into variables, values, and a term where all values have been
93
+ # replaced with variables.
94
+ #
95
+ # @return [Array<Array,Node>] Returns an array of variables, an array of
96
+ # values, and the term based on variables.
97
+ #
98
+ # @private
99
+ def strip
100
+ vars1, values1, term1 = @value.strip
101
+ if @initial
102
+ vars2, values2, term2 = @initial.strip
103
+ else
104
+ vars2, values2 = [], [], nil
105
+ end
106
+ vars3, values3, term3 = @block.strip
107
+ meta_vars, meta_values, var = @index.strip
108
+ return vars1 + vars2 + vars3 + meta_vars,
109
+ values1 + values2 + values3 + meta_values,
110
+ Inject.new( term1.subst( @index => var ),
111
+ var, term2, term3, @var1, @var2 )
112
+ end
113
+
114
+ # Substitute variables
115
+ #
116
+ # Substitute the variables with the values given in the hash.
117
+ #
118
+ # @param [Hash] hash Substitutions to apply.
119
+ #
120
+ # @return [Node] Term with substitutions applied.
121
+ #
122
+ # @private
123
+ def subst( hash )
124
+ subst_var = @index.subst hash
125
+ value = @value.subst( @index => subst_var ).subst hash
126
+ initial = @initial ? @initial.subst( hash ) : nil
127
+ block = @block.subst hash
128
+ Inject.new value, subst_var, initial, block, @var1, @var2
129
+ end
130
+
131
+ # Check whether this term is compilable
132
+ #
133
+ # @return [FalseClass,TrueClass] Returns whether this term is compilable.
134
+ #
135
+ # @private
136
+ def compilable?
137
+ initial_compilable = @initial ? @initial.compilable? : true
138
+ @value.compilable? and initial_compilable and @block.compilable?
139
+ end
140
+
141
+ end
142
+
143
+ end
@@ -1,22 +1,233 @@
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
1
18
  module Hornetseye
2
19
 
3
- # Boolean constant to use as a parameter for creating integer classes
4
- #
5
- # The value is +false+.
6
- #
7
- # @see #INT
8
- UNSIGNED = false
20
+ # Class for representing native integers
21
+ class INT_ < Element
9
22
 
10
- # Boolean constant to use as a parameter for creating integer classes
11
- #
12
- # The value is +true+.
13
- #
14
- # @see #INT
15
- SIGNED = true
23
+ class << self
24
+
25
+ # Number of bits of this integer
26
+ #
27
+ # @return [Integer] Number of bits of this integer.
28
+ attr_accessor :bits
29
+
30
+ # Boolean indicating whether this is a signed integer or not
31
+ #
32
+ # @return [FalseClass,TrueClass] Boolean indicating whether this is a
33
+ # signed integer or not.
34
+ attr_accessor :signed
35
+
36
+ # Memory type required to store elements of this type
37
+ #
38
+ # @return [Class] Returns +Malloc+.
39
+ #
40
+ # @private
41
+ def memory
42
+ Malloc
43
+ end
44
+
45
+ # Get storage size to store an element of this type
46
+ #
47
+ # @return [Integer] Returns +1+.
48
+ #
49
+ # @private
50
+ def storage_size
51
+ ( bits + 7 ).div 8
52
+ end
53
+
54
+ # Get default value for elements of this type
55
+ #
56
+ # @return [Object] Returns +false+.
57
+ #
58
+ # @private
59
+ def default
60
+ 0
61
+ end
62
+
63
+ def coercion( other )
64
+ if other < INT_
65
+ Hornetseye::INT [ bits, other.bits ].max, ( signed or other.signed )
66
+ else
67
+ super other
68
+ end
69
+ end
70
+
71
+ # Directive for packing/unpacking elements of this type
72
+ #
73
+ # @private
74
+ def directive
75
+ case [ bits, signed ]
76
+ when [ 8, true ]
77
+ 'c'
78
+ when [ 8, false ]
79
+ 'C'
80
+ when [ 16, true ]
81
+ 's'
82
+ when [ 16, false ]
83
+ 'S'
84
+ when [ 32, true ]
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
95
+ end
96
+
97
+ # Get string with information about this class
98
+ #
99
+ # @return [String] Returns string with information about this class.
100
+ def inspect
101
+ unless bits.nil? or signed.nil?
102
+ case [ bits, signed ]
103
+ when [ 8, true ]
104
+ 'BYTE'
105
+ when [ 8, false ]
106
+ 'UBYTE'
107
+ when [ 16, true ]
108
+ 'SINT'
109
+ when [ 16, false ]
110
+ 'USINT'
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
122
+ else
123
+ super
124
+ end
125
+ end
126
+
127
+ # Get unique descriptor of this class
128
+ #
129
+ # @param [Hash] hash Labels for any variables.
130
+ #
131
+ # @return [String] Descriptor of this class.
132
+ #
133
+ # @private
134
+ def descriptor( hash )
135
+ unless bits.nil? or signed.nil?
136
+ case [ bits, signed ]
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
156
+ else
157
+ super
158
+ end
159
+ end
160
+
161
+ # Comparison operator
162
+ #
163
+ # @param [Object] other Other object to compare with.
164
+ #
165
+ # @return [FalseClass,TrueClass] Result of comparison.
166
+ def ==( other )
167
+ other.is_a? Class and other < INT_ and
168
+ bits == other.bits and signed == other.signed
169
+ end
170
+
171
+ def hash
172
+ [ :INT_, bits, signed ].hash
173
+ end
174
+
175
+ def eql?( other )
176
+ self == other
177
+ end
178
+
179
+ end
180
+
181
+ # Namespace containing method for matching elements of type INT_
182
+ #
183
+ # @see INT_
184
+ #
185
+ # @private
186
+ module Match
187
+
188
+ # Method for matching elements of type INT_
189
+ #
190
+ # 'param [Array<Object>] *values Values to find matching native element
191
+ # type for.
192
+ #
193
+ # @return [Class] Native type fitting all values.
194
+ #
195
+ # @see INT_
196
+ #
197
+ # @private
198
+ def fit( *values )
199
+ if values.all? { |value| value.is_a? Integer }
200
+ bits = 8
201
+ ubits = 8
202
+ signed = false
203
+ values.each do |value|
204
+ bits *= 2 until ( -2**(bits-1) ... 2**(bits-1) ).include? value
205
+ if value < 0
206
+ signed = true
207
+ else
208
+ ubits *= 2 until ( 0 ... 2**ubits ).include? value
209
+ end
210
+ end
211
+ bits = signed ? bits : ubits
212
+ if bits <= 64
213
+ Hornetseye::INT bits, signed
214
+ else
215
+ super *values
216
+ end
217
+ else
218
+ super *values
219
+ end
220
+ end
221
+
222
+ end
223
+
224
+ Node.extend Match
225
+
226
+ end
16
227
 
17
228
  # Create a class deriving from +INT_+
18
229
  #
19
- # The parameters +bits+ and +signed+ are assigned to the corresponding
230
+ # he aprameters +bits+ and +signed+ are assigned to the corresponding
20
231
  # attributes of the resulting class.
21
232
  #
22
233
  # @param [Integer] bits Number of bits of native integer.
@@ -35,6 +246,20 @@ module Hornetseye
35
246
 
36
247
  module_function :INT
37
248
 
249
+ # Boolean constant to use as a parameter for creating integer classes
250
+ #
251
+ # The value is +false+.
252
+ #
253
+ # @see #INT
254
+ UNSIGNED = false
255
+
256
+ # Boolean constant to use as a parameter for creating integer classes
257
+ #
258
+ # The value is +true+.
259
+ #
260
+ # @see #INT
261
+ SIGNED = true
262
+
38
263
  # 8-bit signed integer
39
264
  BYTE = INT 8, SIGNED
40
265