multiarray 0.4.1 → 0.5.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.
- data/COPYING +1 -1
- data/README.md +3 -0
- data/Rakefile +7 -6
- data/TODO +79 -2
- data/lib/multiarray.rb +452 -31
- data/lib/multiarray/binary.rb +174 -0
- data/lib/multiarray/bool.rb +138 -0
- data/lib/multiarray/diagonal.rb +167 -0
- data/lib/multiarray/element.rb +146 -0
- data/lib/multiarray/gcccache.rb +23 -0
- data/lib/multiarray/gcccontext.rb +144 -0
- data/lib/multiarray/gccfunction.rb +109 -0
- data/lib/multiarray/gcctype.rb +73 -0
- data/lib/multiarray/gccvalue.rb +152 -0
- data/lib/multiarray/index.rb +91 -0
- data/lib/multiarray/inject.rb +143 -0
- data/lib/multiarray/int.rb +238 -13
- data/lib/multiarray/lambda.rb +100 -0
- data/lib/multiarray/list.rb +27 -50
- data/lib/multiarray/lookup.rb +85 -0
- data/lib/multiarray/malloc.rb +28 -2
- data/lib/multiarray/multiarray.rb +44 -30
- data/lib/multiarray/node.rb +596 -0
- data/lib/multiarray/object.rb +74 -31
- data/lib/multiarray/operations.rb +78 -0
- data/lib/multiarray/pointer.rb +134 -4
- data/lib/multiarray/sequence.rb +209 -38
- data/lib/multiarray/unary.rb +170 -0
- data/lib/multiarray/variable.rb +120 -0
- data/test/tc_bool.rb +117 -0
- data/test/tc_int.rb +122 -85
- data/test/tc_multiarray.rb +196 -55
- data/test/tc_object.rb +54 -49
- data/test/tc_sequence.rb +177 -83
- data/test/ts_multiarray.rb +17 -0
- metadata +40 -16
- data/README +0 -1
- data/lib/multiarray/int_.rb +0 -198
- data/lib/multiarray/lazy.rb +0 -81
- data/lib/multiarray/pointer_.rb +0 -260
- data/lib/multiarray/sequence_.rb +0 -155
- data/lib/multiarray/type.rb +0 -207
@@ -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
|