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,174 @@
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 for representing binary operations on scalars and arrays
21
+ class Binary_ < Node
22
+
23
+ class << self
24
+
25
+ # Name of operation
26
+ #
27
+ # @return [Symbol,String] The name of this operation.
28
+ attr_accessor :operation
29
+
30
+ # Name of method for type conversion
31
+ #
32
+ # @return [Symbol,String] The name of the method for type conversion.
33
+ attr_accessor :coercion
34
+
35
+ # Get string with information about this class
36
+ #
37
+ # @return [String] Return string with information about this class.
38
+ def inspect
39
+ operation.to_s
40
+ end
41
+
42
+ # Get unique descriptor of this class
43
+ #
44
+ # @param [Hash] hash Labels for any variables.
45
+ #
46
+ # @return [String] Descriptor of this class.
47
+ #
48
+ # @private
49
+ def descriptor( hash )
50
+ operation.to_s
51
+ end
52
+
53
+ end
54
+
55
+ # Initialise binary operation
56
+ #
57
+ # @param [Node] value1 First operand to apply operation to.
58
+ # @param [Node] value2 Second operand to apply operation to.
59
+ def initialize( value1, value2 )
60
+ @value1, @value2 = value1, value2
61
+ end
62
+
63
+ # Get unique descriptor of this object
64
+ #
65
+ # @param [Hash] hash Labels for any variables.
66
+ #
67
+ # @return [String] Descriptor of this object,
68
+ #
69
+ # @private
70
+ def descriptor( hash )
71
+ "(#{@value1.descriptor( hash )}).#{self.class.descriptor( hash )}(#{@value2.descriptor( hash )})"
72
+ end
73
+
74
+ # Array type of this term
75
+ #
76
+ # @return [Class] Resulting array type.
77
+ #
78
+ # @private
79
+ def array_type
80
+ @value1.array_type.send self.class.coercion, @value2.array_type
81
+ end
82
+
83
+ # Substitute variables
84
+ #
85
+ # Substitute the variables with the values given in the hash.
86
+ #
87
+ # @param [Hash] hash Substitutions to apply.
88
+ #
89
+ # @return [Node] Term with substitutions applied.
90
+ #
91
+ # @private
92
+ def subst( hash )
93
+ self.class.new @value1.subst( hash ), @value2.subst( hash )
94
+ end
95
+
96
+ # Get variables contained in this term
97
+ #
98
+ # @return [Set] Returns set of variables.
99
+ #
100
+ # @private
101
+ def variables
102
+ @value1.variables + @value2.variables
103
+ end
104
+
105
+ # Strip of all values
106
+ #
107
+ # Split up into variables, values, and a term where all values have been
108
+ # replaced with variables.
109
+ #
110
+ # @return [Array<Array,Node>] Returns an array of variables, an array of
111
+ # values, and the term based on variables.
112
+ #
113
+ # @private
114
+ def strip
115
+ vars1, values1, term1 = @value1.strip
116
+ vars2, values2, term2 = @value2.strip
117
+ return vars1 + vars2, values1 + values2, self.class.new( term1, term2 )
118
+ end
119
+
120
+ # Reevaluate computation
121
+ #
122
+ # @return [Node,Object] Result of computation
123
+ #
124
+ # @see #force
125
+ #
126
+ # @private
127
+ def demand
128
+ @value1.send self.class.operation, @value2
129
+ end
130
+
131
+ # Get element of unary operation
132
+ #
133
+ # @param [Integer,Node] i Index of desired element.
134
+ #
135
+ # @return [Node,Object] Element of unary operation.
136
+ def element( i )
137
+ element1 = @value1.dimension == 0 ? @value1 : @value1.element( i )
138
+ element2 = @value2.dimension == 0 ? @value2 : @value2.element( i )
139
+ element1.send self.class.operation, element2
140
+ end
141
+
142
+ # Check whether this term is compilable
143
+ #
144
+ # @return [FalseClass,TrueClass] Returns whether this term is compilable.
145
+ #
146
+ # @private
147
+ def compilable?
148
+ @value1.compilable? and @value2.compilable?
149
+ end
150
+
151
+ end
152
+
153
+ # Create a class deriving from +Binary_+
154
+ #
155
+ # @param [Symbol,String] operation Name of operation.
156
+ # @param [Symbol,String] conversion Name of method for type conversion.
157
+ #
158
+ # @return [Class] A class deriving from +Binary_+.
159
+ #
160
+ # @see Binary_
161
+ # @see Binary_.operation
162
+ # @see Binary_.coercion
163
+ #
164
+ # @private
165
+ def Binary( operation, coercion = :coercion )
166
+ retval = Class.new Binary_
167
+ retval.operation = operation
168
+ retval.coercion = coercion
169
+ retval
170
+ end
171
+
172
+ module_function :Binary
173
+
174
+ end
@@ -0,0 +1,138 @@
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 BOOL < Element
21
+
22
+ class << self
23
+
24
+ # Get string with information about this class
25
+ #
26
+ # @return [String] Returns +'BOOL'+
27
+ def inspect
28
+ 'BOOL'
29
+ end
30
+
31
+ # Get unique descriptor of this class
32
+ #
33
+ # @param [Hash] hash Labels for any variables.
34
+ #
35
+ # @return [String] Descriptor of this class.
36
+ #
37
+ # @private
38
+ def descriptor( hash )
39
+ 'BOOL'
40
+ end
41
+
42
+ # Retrieve element from memory
43
+ #
44
+ # @param [Malloc] ptr Memory to load element from.
45
+ #
46
+ # @see Malloc#load
47
+ #
48
+ # @return [BOOL] Result of fetch operation.
49
+ #
50
+ # @private
51
+ def fetch( ptr )
52
+ new ptr.load( self ).ne( 0 )
53
+ end
54
+
55
+ # Memory type required to store elements of this type
56
+ #
57
+ # @return [Class] Returns +Malloc+.
58
+ #
59
+ # @private
60
+ def memory
61
+ Malloc
62
+ end
63
+
64
+ # Get storage size to store an element of this type
65
+ #
66
+ # @return [Integer] Returns +1+.
67
+ #
68
+ # @private
69
+ def storage_size
70
+ 1
71
+ end
72
+
73
+ # Get default value for elements of this type
74
+ #
75
+ # @return [Object] Returns +false+.
76
+ #
77
+ # @private
78
+ def default
79
+ false
80
+ end
81
+
82
+ # Directive for packing/unpacking elements of this type
83
+ #
84
+ # @return [String] Returns +'c'+.
85
+ #
86
+ # @private
87
+ def directive
88
+ 'c'
89
+ end
90
+
91
+ end
92
+
93
+ # Write element to memory
94
+ #
95
+ # @param [Malloc] ptr Memory to write element to.
96
+ #
97
+ # @return [BOOL] Returns +self+.
98
+ #
99
+ # @see Malloc#save
100
+ #
101
+ # @private
102
+ def write( ptr )
103
+ ptr.save UBYTE.new( get.conditional( 1, 0 ) )
104
+ self
105
+ end
106
+
107
+ # Namespace containing method for matching elements of type BOOL
108
+ #
109
+ # @see BOOL
110
+ #
111
+ # @private
112
+ module Match
113
+
114
+ # Method for matching elements of type BOOL
115
+ #
116
+ # @param [Array<Object>] *values Values to find matching native element
117
+ # type for.
118
+ #
119
+ # @return [Class] Native type fitting all values.
120
+ #
121
+ # @see BOOL
122
+ #
123
+ # @private
124
+ def fit( *values )
125
+ if values.all? { |value| [ false, true ].member? value }
126
+ BOOL
127
+ else
128
+ super *values
129
+ end
130
+ end
131
+
132
+ end
133
+
134
+ Node.extend Match
135
+
136
+ end
137
+
138
+ end
@@ -0,0 +1,167 @@
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 for representing diagonal injections
21
+ class Diagonal < Node
22
+
23
+ # Constructor
24
+ #
25
+ # @param [Node] value Initial value of injection
26
+ # @param [Node] index0 Index for
27
+ def initialize( value, index0, index1, index2, initial, block, var1, var2 )
28
+ @value, @index0, @index1, @index2, @initial, @block, @var1, @var2 =
29
+ value, index0, index1, index2, initial, block, var1, var2
30
+ end
31
+
32
+ # Get unique descriptor of this object
33
+ #
34
+ # @param [Hash] hash Labels for any variables.
35
+ #
36
+ # @return [String] Descriptor of this object,
37
+ #
38
+ # @private
39
+ def descriptor( hash )
40
+ hash = hash.merge @index0 => ( ( hash.values.max || 0 ) + 1 )
41
+ hash = hash.merge @index1 => ( ( hash.values.max || 0 ) + 1 )
42
+ hash = hash.merge @index2 => ( ( hash.values.max || 0 ) + 1 )
43
+ hash = hash.merge @var1 => ( ( hash.values.max || 0 ) + 1 )
44
+ hash = hash.merge @var2 => ( ( hash.values.max || 0 ) + 1 )
45
+ "Diagonal(#{@value.descriptor( hash )},#{@initial ? @initial.descriptor( hash ) : 'nil'},#{@block.descriptor( hash )})"
46
+ end
47
+
48
+ # Array type of this term
49
+ #
50
+ # @return [Class] Resulting array type.
51
+ #
52
+ # @private
53
+ def array_type
54
+ Hornetseye::MultiArray @block.typecode, *@value.shape
55
+ end
56
+
57
+ # Reevaluate computation
58
+ #
59
+ # @return [Node,Object] Result of computation
60
+ #
61
+ # @see #force
62
+ #
63
+ # @private
64
+ def demand
65
+ retval = @initial
66
+ offset = @index2.size.get / 2
67
+ @index2.size.get.times do |j|
68
+ k = j - offset
69
+ i = @index0.get - k
70
+ if i >= 0 and i < @index1.size.get
71
+ sub = @value.subst( @index1 => INT.new( i ),
72
+ @index2 => INT.new( j ) ).simplify
73
+ retval = retval ? @block.subst( @var1 => retval,
74
+ @var2 => sub ).simplify :
75
+ sub
76
+ end
77
+ end
78
+ retval
79
+ end
80
+
81
+ # Get element of diagonal injection
82
+ #
83
+ # @param [Integer,Node] i Index of desired element.
84
+ #
85
+ # @return [Node,Object] Element of diagonal injection.
86
+ def element( i )
87
+ Diagonal.new @value.element( i ), @index0, @index1, @index2, @initial,
88
+ @block, @var1, @var2
89
+ end
90
+
91
+ # Get variables contained in this term
92
+ #
93
+ # @return [Set] Returns list of variables.
94
+ #
95
+ # @private
96
+ def variables
97
+ initial_variables = @initial ? @initial.variables : Set[]
98
+ @value.variables + initial_variables -
99
+ ( @index1.variables + @index2.variables )
100
+ end
101
+
102
+ def variables
103
+ initial_variables = @initial ? @initial.variables : Set[]
104
+ @value.variables + initial_variables -
105
+ ( @index1.variables + @index2.variables )
106
+ end
107
+
108
+ # Strip of all values
109
+ #
110
+ # Split up into variables, values, and a term where all values have been
111
+ # replaced with variables.
112
+ #
113
+ # @return [Array<Array,Node>] Returns an array of variables, an array of
114
+ # values, and the term based on variables.
115
+ #
116
+ # @private
117
+ def strip
118
+ vars1, values1, term1 = @value.strip
119
+ meta_vars1, meta_values1, var1 = @index1.strip
120
+ meta_vars2, meta_values2, var2 = @index2.strip
121
+ if @initial
122
+ vars2, values2, term2 = @initial.strip
123
+ else
124
+ vars2, values2, term2 = [], [], nil
125
+ end
126
+ vars3, values3, term3 = @block.strip
127
+ return vars1 + meta_vars1 + meta_vars2 + vars2 + vars3,
128
+ values1 + meta_values1 + meta_values2 + values2 + values3,
129
+ Diagonal.new( term1.subst( @index1 => var1, @index2 => var2 ),
130
+ @index0, var1, var2, term2, term3, @var1, @var2 )
131
+ end
132
+
133
+ # Substitute variables
134
+ #
135
+ # Substitute the variables with the values given in the hash.
136
+ #
137
+ # @param [Hash] hash Substitutions to apply.
138
+ #
139
+ # @return [Node] Term with substitutions applied.
140
+ #
141
+ # @private
142
+ def subst( hash )
143
+ subst_var0 = @index0.subst hash
144
+ subst_var1 = @index1.subst hash
145
+ subst_var2 = @index2.subst hash
146
+ value = @value.subst( @index0 => subst_var0, @index1 => subst_var1,
147
+ @index2 => subst_var2 ).subst hash
148
+ initial = @intial ? @initial.subst( hash ) : nil
149
+ block = @block.subst hash
150
+ Diagonal.new value, subst_var0, subst_var1, subst_var2, initial,
151
+ block, @var1, @var2
152
+ end
153
+
154
+ # Check whether this term is compilable
155
+ #
156
+ # @return [FalseClass,TrueClass] Returns whether this term is compilable.
157
+ #
158
+ # @private
159
+ def compilable?
160
+ initial_compilable = @initial ? @initial.compilable? : true
161
+ @value.compilable? and initial_compilable and @block.compilable?
162
+ false # !!!
163
+ end
164
+
165
+ end
166
+
167
+ end