multiarray 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,185 @@
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 applying a unary method to scalars and arrays
21
+ class UnaryMethod_ < Node
22
+
23
+ class << self
24
+
25
+ # Name of module
26
+ #
27
+ # @return [Module] The module with the method.
28
+ attr_accessor :mod
29
+
30
+ # Name of operation
31
+ #
32
+ # @return [Symbol,String] The name of this operation.
33
+ attr_accessor :operation
34
+
35
+ # Name of method for type conversion
36
+ #
37
+ # @return [Symbol,String] The name of the method for type conversion.
38
+ attr_accessor :conversion
39
+
40
+ # Get string with information about this class
41
+ #
42
+ # @return [String] Return string with information about this class.
43
+ def inspect
44
+ "#{mod.to_s}.#{operation.to_s}"
45
+ end
46
+
47
+ # Get unique descriptor of this class
48
+ #
49
+ # @param [Hash] hash Labels for any variables.
50
+ #
51
+ # @return [String] Descriptor of this class.
52
+ #
53
+ # @private
54
+ def descriptor( hash )
55
+ inspect
56
+ end
57
+
58
+ end
59
+
60
+ # Initialise unary operation
61
+ #
62
+ # @param [Node] value Value to apply operation to.
63
+ def initialize( value )
64
+ @value = value
65
+ end
66
+
67
+ # Get unique descriptor of this object
68
+ #
69
+ # @param [Hash] hash Labels for any variables.
70
+ #
71
+ # @return [String] Descriptor of this object,
72
+ #
73
+ # @private
74
+ def descriptor( hash )
75
+ "#{self.class.descriptor( hash )}(#{@value.descriptor( hash )})"
76
+ end
77
+
78
+ # Array type of this term
79
+ #
80
+ # @return [Class] Resulting array type.
81
+ #
82
+ # @private
83
+ def array_type
84
+ @value.array_type.send self.class.conversion
85
+ end
86
+
87
+ # Substitute variables
88
+ #
89
+ # Substitute the variables with the values given in the hash.
90
+ #
91
+ # @param [Hash] hash Substitutions to apply.
92
+ #
93
+ # @return [Node] Term with substitutions applied.
94
+ #
95
+ # @private
96
+ def subst( hash )
97
+ self.class.new @value.subst( hash )
98
+ end
99
+
100
+ # Get variables contained in this term
101
+ #
102
+ # @return [Set] Returns set of variables.
103
+ #
104
+ # @private
105
+ def variables
106
+ @value.variables
107
+ end
108
+
109
+ # Strip of all values
110
+ #
111
+ # Split up into variables, values, and a term where all values have been
112
+ # replaced with variables.
113
+ #
114
+ # @return [Array<Array,Node>] Returns an array of variables, an array of
115
+ # values, and the term based on variables.
116
+ #
117
+ # @private
118
+ def strip
119
+ vars, values, term = @value.strip
120
+ return vars, values, self.class.new( term )
121
+ end
122
+
123
+ # Reevaluate computation
124
+ #
125
+ # @return [Node,Object] Result of computation
126
+ #
127
+ # @see #force
128
+ #
129
+ # @private
130
+ def demand
131
+ self.class.mod.send self.class.operation, @value
132
+ end
133
+
134
+ def skip( index, start )
135
+ self.class.new( @value.skip( index, start ) ).demand
136
+ end
137
+
138
+ # Get element of unary operation
139
+ #
140
+ # @param [Integer,Node] i Index of desired element.
141
+ #
142
+ # @return [Node,Object] Element of unary operation.
143
+ def element( i )
144
+ self.class.new( @value.element( i ) ).demand
145
+ end
146
+
147
+ def slice( start, length )
148
+ self.class.new( @value.slice( start, length ) ).demand
149
+ end
150
+
151
+ # Check whether this term is compilable
152
+ #
153
+ # @return [FalseClass,TrueClass] Returns whether this term is compilable.
154
+ #
155
+ # @private
156
+ def compilable?
157
+ @value.compilable?
158
+ end
159
+
160
+ end
161
+
162
+ # Create a class deriving from +UnaryMethod_+
163
+ #
164
+ # @param [Symbol,String] operation Name of operation.
165
+ # @param [Symbol,String] conversion Name of method for type conversion.
166
+ #
167
+ # @return [Class] A class deriving from +UnaryMethod_+.
168
+ #
169
+ # @see UnaryMethod_
170
+ # @see UnaryMethod_.operation
171
+ # @see UnaryMethod_.conversion
172
+ #
173
+ # @private
174
+ def UnaryMethod( mod, operation, conversion = :contiguous )
175
+ retval = Class.new UnaryMethod_
176
+ retval.mod = mod
177
+ retval.operation = operation
178
+ retval.conversion = conversion
179
+ retval
180
+ end
181
+
182
+ module_function :UnaryMethod
183
+
184
+ end
185
+
@@ -18,7 +18,7 @@
18
18
  module Hornetseye
19
19
 
20
20
  # Class for representing unary operations on scalars and arrays
21
- class Unary_ < Node
21
+ class UnaryOp_ < Node
22
22
 
23
23
  class << self
24
24
 
@@ -47,7 +47,7 @@ module Hornetseye
47
47
  #
48
48
  # @private
49
49
  def descriptor( hash )
50
- operation.to_s
50
+ inspect
51
51
  end
52
52
 
53
53
  end
@@ -126,13 +126,21 @@ module Hornetseye
126
126
  @value.send self.class.operation
127
127
  end
128
128
 
129
+ def skip( index, start )
130
+ self.class.new( @value.skip( index, start ) ).demand
131
+ end
132
+
129
133
  # Get element of unary operation
130
134
  #
131
135
  # @param [Integer,Node] i Index of desired element.
132
136
  #
133
137
  # @return [Node,Object] Element of unary operation.
134
138
  def element( i )
135
- @value.element( i ).send self.class.operation
139
+ self.class.new( @value.element( i ) ).demand
140
+ end
141
+
142
+ def slice( start, length )
143
+ self.class.new( @value.slice( start, length ) ).demand
136
144
  end
137
145
 
138
146
  # Check whether this term is compilable
@@ -146,25 +154,26 @@ module Hornetseye
146
154
 
147
155
  end
148
156
 
149
- # Create a class deriving from +Unary_+
157
+ # Create a class deriving from +UnaryOp_+
150
158
  #
151
159
  # @param [Symbol,String] operation Name of operation.
152
160
  # @param [Symbol,String] conversion Name of method for type conversion.
153
161
  #
154
- # @return [Class] A class deriving from +Unary_+.
162
+ # @return [Class] A class deriving from +UnaryOp_+.
155
163
  #
156
- # @see Unary_
157
- # @see Unary_.operation
158
- # @see Unary_.conversion
164
+ # @see UnaryOp_
165
+ # @see UnaryOp_.operation
166
+ # @see UnaryOp_.conversion
159
167
  #
160
168
  # @private
161
- def Unary( operation, conversion = :contiguous )
162
- retval = Class.new Unary_
169
+ def UnaryOp( operation, conversion = :contiguous )
170
+ retval = Class.new UnaryOp_
163
171
  retval.operation = operation
164
172
  retval.conversion = conversion
165
173
  retval
166
174
  end
167
175
 
168
- module_function :Unary
176
+ module_function :UnaryOp
169
177
 
170
178
  end
179
+
@@ -115,6 +115,14 @@ module Hornetseye
115
115
  Lookup.new self, value, stride
116
116
  end
117
117
 
118
+ def skip( index, start )
119
+ if index == self
120
+ self + start
121
+ else
122
+ self
123
+ end
124
+ end
125
+
118
126
  end
119
127
 
120
128
  end
data/test/tc_bool.rb CHANGED
@@ -25,6 +25,10 @@ class TC_Bool < Test::Unit::TestCase
25
25
 
26
26
  B = Hornetseye::BOOL
27
27
 
28
+ def B( *args )
29
+ Hornetseye::BOOL *args
30
+ end
31
+
28
32
  def setup
29
33
  end
30
34
 
@@ -55,12 +59,16 @@ class TC_Bool < Test::Unit::TestCase
55
59
  assert_equal [], B.shape
56
60
  end
57
61
 
62
+ def test_bool_size
63
+ assert_equal 1, B.size
64
+ end
65
+
58
66
  def test_inspect
59
- assert_equal 'BOOL(true)', B.new( true ).inspect
67
+ assert_equal 'BOOL(true)', B( true ).inspect
60
68
  end
61
69
 
62
70
  def test_marshal
63
- assert_equal B.new( true ), Marshal.load( Marshal.dump( B.new( true ) ) )
71
+ assert_equal B( true ), Marshal.load( Marshal.dump( B( true ) ) )
64
72
  end
65
73
 
66
74
  def test_typecode
@@ -75,43 +83,47 @@ class TC_Bool < Test::Unit::TestCase
75
83
  assert_equal [], B.new.shape
76
84
  end
77
85
 
86
+ def test_size
87
+ assert_equal 1, B.new.size
88
+ end
89
+
78
90
  def test_at_assign
79
- b = B.new false
91
+ b = B false
80
92
  assert !b[]
81
93
  assert b[] = true
82
94
  assert b[]
83
95
  end
84
96
 
85
97
  def test_equal
86
- assert_equal B.new( false ), B.new( false )
87
- assert_not_equal B.new( false ), B.new( true )
88
- assert_not_equal B.new( true ), B.new( false )
89
- assert_equal B.new( true ), B.new( true )
98
+ assert_equal B( false ), B( false )
99
+ assert_not_equal B( false ), B( true )
100
+ assert_not_equal B( true ), B( false )
101
+ assert_equal B( true ), B( true )
90
102
  end
91
103
 
92
104
  def test_inject
93
- assert B.new( true ).inject { |a,b| a.and b }[]
94
- assert !B.new( false ).inject( true ) { |a,b| a.and b }[]
95
- assert !B.new( true ).inject( false ) { |a,b| a.and b }[]
105
+ assert B( true ).inject { |a,b| a.and b }[]
106
+ assert !B( false ).inject( true ) { |a,b| a.and b }[]
107
+ assert !B( true ).inject( false ) { |a,b| a.and b }[]
96
108
  end
97
109
 
98
110
  def test_not
99
- assert_equal B.new( true ), B.new( false ).not
100
- assert_equal B.new( false ), B.new( true ).not
111
+ assert_equal B( true ), B( false ).not
112
+ assert_equal B( false ), B( true ).not
101
113
  end
102
114
 
103
115
  def test_and
104
- assert_equal B.new( false ), B.new( false ).and( B.new( false ) )
105
- assert_equal B.new( false ), B.new( false ).and( B.new( true ) )
106
- assert_equal B.new( false ), B.new( true ).and( B.new( false ) )
107
- assert_equal B.new( true ), B.new( true ).and( B.new( true ) )
116
+ assert_equal B( false ), B( false ).and( B( false ) )
117
+ assert_equal B( false ), B( false ).and( B( true ) )
118
+ assert_equal B( false ), B( true ).and( B( false ) )
119
+ assert_equal B( true ), B( true ).and( B( true ) )
108
120
  end
109
121
 
110
122
  def test_or
111
- assert_equal B.new( false ), B.new( false ).or( B.new( false ) )
112
- assert_equal B.new( true ), B.new( false ).or( B.new( true ) )
113
- assert_equal B.new( true ), B.new( true ).or( B.new( false ) )
114
- assert_equal B.new( true ), B.new( true ).or( B.new( true ) )
123
+ assert_equal B( false ), B( false ).or( B( false ) )
124
+ assert_equal B( true ), B( false ).or( B( true ) )
125
+ assert_equal B( true ), B( true ).or( B( false ) )
126
+ assert_equal B( true ), B( true ).or( B( true ) )
115
127
  end
116
128
 
117
129
  end
data/test/tc_float.rb ADDED
@@ -0,0 +1,192 @@
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
+ require 'test/unit'
18
+ begin
19
+ require 'rubygems'
20
+ rescue LoadError
21
+ end
22
+ Kernel::require 'multiarray'
23
+
24
+ class TC_Float < Test::Unit::TestCase
25
+
26
+ F = Hornetseye::SFLOAT
27
+ D = Hornetseye::DFLOAT
28
+
29
+ def F( *args )
30
+ Hornetseye::SFLOAT *args
31
+ end
32
+
33
+ def D( *args )
34
+ Hornetseye::DFLOAT *args
35
+ end
36
+
37
+ def sum( *args, &action )
38
+ Hornetseye::sum *args, &action
39
+ end
40
+
41
+ def setup
42
+ end
43
+
44
+ def teardown
45
+ end
46
+
47
+ def test_float_inspect
48
+ assert_equal 'SFLOAT', F.inspect
49
+ assert_equal 'DFLOAT', D.inspect
50
+ end
51
+
52
+ def test_float_to_s
53
+ assert_equal 'SFLOAT', F.to_s
54
+ assert_equal 'DFLOAT', D.to_s
55
+ end
56
+
57
+ def test_float_default
58
+ assert_equal 0.0, F.new[]
59
+ assert_equal 0.0, D.new[]
60
+ end
61
+
62
+ def test_float_indgen
63
+ assert_equal 0, F.indgen
64
+ assert_equal 1, F.indgen( 1 )
65
+ assert_equal 1, F.indgen( 1, 2 )
66
+ end
67
+
68
+ def test_float_typecode
69
+ assert_equal F, F.typecode
70
+ assert_equal D, D.typecode
71
+ end
72
+
73
+ def test_float_dimension
74
+ assert_equal 0, F.dimension
75
+ end
76
+ !
77
+ def test_float_shape
78
+ assert_equal [], F.shape
79
+ end
80
+
81
+ def test_float_size
82
+ assert_equal 1, F.size
83
+ end
84
+
85
+ def test_inspect
86
+ assert_equal 'DFLOAT(42.0)', D( 42.0 ).inspect
87
+ end
88
+
89
+ def test_marshal
90
+ assert_equal D( 42.0 ), Marshal.load( Marshal.dump( D( 42.0 ) ) )
91
+ end
92
+
93
+ def test_typecode
94
+ assert_equal D, D.new.typecode
95
+ end
96
+
97
+ def test_dimension
98
+ assert_equal 0.0, D.new.dimension
99
+ end
100
+
101
+ def test_shape
102
+ assert_equal [], D.new.shape
103
+ end
104
+
105
+ def test_size
106
+ assert_equal 1, D.new.size
107
+ end
108
+
109
+ def test_at_assign
110
+ d = D 42.0
111
+ assert_equal 42.0, d[]
112
+ assert_equal 3.0, d[] = 3
113
+ assert_equal 3.0, d[]
114
+ end
115
+
116
+ def test_equal
117
+ assert_not_equal D( 3.0 ), D( 4.0 )
118
+ assert_equal D( 3.0 ), D( 3.0 )
119
+ end
120
+
121
+ if false
122
+
123
+ def test_inject
124
+ assert_equal 2, I( 2 ).inject { |a,b| a + b }[]
125
+ assert_equal 3, I( 2 ).inject( 1 ) { |a,b| a + b }[]
126
+ end
127
+
128
+ def test_not
129
+ assert !I( 0 ).not[]
130
+ assert !I( 3 ).not[]
131
+ end
132
+
133
+ def test_sum
134
+ assert_equal 3, sum { || 3 }
135
+ end
136
+
137
+ def test_zero
138
+ assert I( 0 ).zero?[]
139
+ assert !I( 3 ).zero?[]
140
+ end
141
+
142
+ def test_nonzero
143
+ assert !I( 0 ).nonzero?[]
144
+ assert I( 3 ).nonzero?[]
145
+ end
146
+
147
+ def test_bitwise_not
148
+ assert_equal I( -3 ), ~I( 2 )
149
+ end
150
+
151
+ def test_bitwise_and
152
+ assert_equal I( 2 ), I( 3 ) & I( 6 )
153
+ end
154
+
155
+ def test_bitwise_or
156
+ assert_equal I( 7 ), I( 3 ) | I( 6 )
157
+ end
158
+
159
+ def test_bitwise_xor
160
+ assert_equal I( 1 ), I( 3 ) ^ I( 2 )
161
+ end
162
+
163
+ def test_shl
164
+ assert_equal I( 4 ), I( 2 ) << I( 1 )
165
+ end
166
+
167
+ def test_shr
168
+ assert_equal I( 2 ), I( 4 ) >> I( 1 )
169
+ end
170
+
171
+ def test_negate
172
+ assert_equal I( -5 ), -I( 5 )
173
+ end
174
+
175
+ def test_plus
176
+ assert_equal I( 3 + 5 ), I( 3 ) + I( 5 )
177
+ end
178
+
179
+ def test_major
180
+ assert_equal I( 4 ), I( 3 ).major( I( 4 ) )
181
+ assert_equal I( 5 ), I( 5 ).major( I( 3 ) )
182
+ end
183
+
184
+ def test_minor
185
+ assert_equal I( 3 ), I( 3 ).minor( I( 4 ) )
186
+ assert_equal I( 4 ), I( 5 ).minor( I( 4 ) )
187
+ end
188
+
189
+ end
190
+
191
+ end
192
+