multiarray 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/TODO +63 -0
- data/lib/multiarray.rb +34 -0
- data/lib/multiarray/int_.rb +46 -0
- data/lib/multiarray/lazy.rb +7 -2
- data/lib/multiarray/multiarray.rb +1 -13
- data/lib/multiarray/object.rb +20 -6
- data/lib/multiarray/pointer_.rb +41 -4
- data/lib/multiarray/sequence.rb +5 -1
- data/lib/multiarray/sequence_.rb +51 -0
- data/lib/multiarray/type.rb +33 -3
- data/test/tc_int.rb +21 -1
- data/test/tc_multiarray.rb +2 -2
- data/test/tc_object.rb +18 -1
- data/test/tc_sequence.rb +11 -3
- metadata +3 -2
data/Rakefile
CHANGED
@@ -6,11 +6,11 @@ require 'rake/packagetask'
|
|
6
6
|
require 'rbconfig'
|
7
7
|
|
8
8
|
PKG_NAME = 'multiarray'
|
9
|
-
PKG_VERSION = '0.4.
|
9
|
+
PKG_VERSION = '0.4.1'
|
10
10
|
RB_FILES = FileList[ 'lib/**/*.rb' ]
|
11
11
|
TC_FILES = FileList[ 'test/tc_*.rb' ]
|
12
12
|
TS_FILES = FileList[ 'test/ts_*.rb' ]
|
13
|
-
PKG_FILES = [ 'Rakefile', 'README', 'COPYING', '.document' ] +
|
13
|
+
PKG_FILES = [ 'Rakefile', 'README', 'COPYING', 'TODO', '.document' ] +
|
14
14
|
RB_FILES + TS_FILES + TC_FILES
|
15
15
|
SUMMARY = %q{Multi-dimensional and uniform Ruby arrays}
|
16
16
|
DESCRIPTION = %q{This Ruby-extension defines Hornetseye::MultiArray and other native datatypes. Hornetseye::MultiArray provides multi-dimensional Ruby arrays with elements of same type. The extension is designed to be mostly compatible with Masahiro Tanaka's NArray. However it allows the definition of custom element types and operations on them. This work was also inspired by Ronald Garcia's boost::multi_array and by Todd Veldhuizen's Blitz++.}
|
data/TODO
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
ranges (rolling, lazy rolling, lazy ranges)
|
2
|
+
tensor indices to enable transpose of lazy array
|
3
|
+
test lazyness
|
4
|
+
sums/injections? nesting? tensors?
|
5
|
+
JIT?
|
6
|
+
test type conversions
|
7
|
+
fancy README
|
8
|
+
|
9
|
+
a = lazy( 16 ) { |i| i }
|
10
|
+
a = lazy( 16 ) { |i| i }[ 4 ... 12 ] # offsets: apply sel-operation to all
|
11
|
+
members; index array?
|
12
|
+
a = lazy( 16, 32 ) { |i,j| Sequence[ i, j ] } # ???
|
13
|
+
a = lazy( 8, 8 ) { |i,j| Sequence[ i, a[j] * sin( i + b[j] ) ] }.hist 8, 8
|
14
|
+
a = b.class.new.op { |x| set -x }
|
15
|
+
a = lazy { |i| -b[i] }
|
16
|
+
a = lazy { -b }
|
17
|
+
a = array { -b }
|
18
|
+
a = array { |i| -b[i] }
|
19
|
+
a = array( :dim => [ b.size ] ) { |i| -b[i] }
|
20
|
+
a = -b
|
21
|
+
array { |i| sum { |j| a[i,j] } }
|
22
|
+
lazy { |i| sum { |j| a[i,j] } }
|
23
|
+
parallel { ... }
|
24
|
+
lazy { |i| lazy { |j| a[i,j] } }
|
25
|
+
array { lazy { |i| sum { |j| a[i,j] } } }
|
26
|
+
|
27
|
+
correlate?
|
28
|
+
|
29
|
+
lines:
|
30
|
+
[ i, a[j] * sin( i + b[j] ) ].hist
|
31
|
+
|
32
|
+
lines:
|
33
|
+
lazy { |i,j| i.zip( a[j] * sin( i + b[j] ) ) }.histogram 32, 20
|
34
|
+
|
35
|
+
lines:
|
36
|
+
lazy { |i,j| Sequence[ i, a[j] * sin( i + b[j] ) ] }.histogram 32, 20
|
37
|
+
combined histograms?
|
38
|
+
|
39
|
+
circle:
|
40
|
+
[ sin( i ) * r, cos( i ) * r ].hist
|
41
|
+
|
42
|
+
Geometric Hashing? Bounded Hough Transform!!! RANSAC? histogram weights?
|
43
|
+
|
44
|
+
array: lazy retrieval? jit code for address computation
|
45
|
+
OBJECT: object with type information
|
46
|
+
Lazy( Sequence( INT, 3 ) )
|
47
|
+
|
48
|
+
interpretation: type coercion, actual operation, jit,
|
49
|
+
collection of jit arguments (e.g. tensor)
|
50
|
+
|
51
|
+
proc { |i| proc { |j| i+j } }.call( 5 ).call 3
|
52
|
+
|
53
|
+
gem install flay: http://ruby.sadi.st/Flay.html
|
54
|
+
|
55
|
+
How to nest/cascade mode-environments?
|
56
|
+
(how to specify nested modes for recursive algorithms and called algorithms?)
|
57
|
+
ruby and jit compiles, lazy and parallel forwards
|
58
|
+
|
59
|
+
* Ruby
|
60
|
+
* Lazy (Lazy histogram -> hough transform, lazy transpose, unused indices?)
|
61
|
+
* Multithreading
|
62
|
+
* JIT
|
63
|
+
* GCC
|
data/lib/multiarray.rb
CHANGED
@@ -37,6 +37,40 @@ class Object
|
|
37
37
|
|
38
38
|
end
|
39
39
|
|
40
|
+
# Range#min and Range#max are replaced for performance reasons
|
41
|
+
class Range
|
42
|
+
|
43
|
+
public
|
44
|
+
|
45
|
+
alias_method :orig_min, :min
|
46
|
+
|
47
|
+
alias_method :orig_max, :max
|
48
|
+
|
49
|
+
# For performance reasons a specialised method for integers is added
|
50
|
+
def min
|
51
|
+
if self.begin.is_a? Integer
|
52
|
+
self.begin
|
53
|
+
else
|
54
|
+
orig_min
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# For performance reasons a specialised method for integers is added.
|
59
|
+
def max
|
60
|
+
if self.end.is_a? Integer
|
61
|
+
exclude_end? ? self.end - 1 : self.end
|
62
|
+
else
|
63
|
+
orig_max
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Compute the size of a range.
|
68
|
+
def size
|
69
|
+
max + 1 - min
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
40
74
|
# Module#alias_method_chain is defined.
|
41
75
|
#
|
42
76
|
# @private
|
data/lib/multiarray/int_.rb
CHANGED
@@ -120,6 +120,22 @@ module Hornetseye
|
|
120
120
|
( bits + 7 ).div 8
|
121
121
|
end
|
122
122
|
|
123
|
+
def coercion( other )
|
124
|
+
if other < INT_
|
125
|
+
Hornetseye::INT [ bits, other.bits ].max, ( signed or other.signed )
|
126
|
+
else
|
127
|
+
super other
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def coerce( other )
|
132
|
+
if other < INT_
|
133
|
+
return other, self
|
134
|
+
else
|
135
|
+
super other
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
123
139
|
def ==( other )
|
124
140
|
if other.is_a? Class
|
125
141
|
if other < INT_ and bits == other.bits and signed == other.signed
|
@@ -147,6 +163,36 @@ module Hornetseye
|
|
147
163
|
self
|
148
164
|
end
|
149
165
|
|
166
|
+
module RubyMatching
|
167
|
+
|
168
|
+
def fit( *values )
|
169
|
+
if values.all? { |value| value.is_a? Integer }
|
170
|
+
bits = 8
|
171
|
+
ubits = 8
|
172
|
+
signed = false
|
173
|
+
values.each do |value|
|
174
|
+
bits *= 2 until ( -2**(bits-1) ... 2**(bits-1) ).include? value
|
175
|
+
if value < 0
|
176
|
+
signed = true
|
177
|
+
else
|
178
|
+
ubits *= 2 until ( 0 ... 2**ubits ).include? value
|
179
|
+
end
|
180
|
+
end
|
181
|
+
bits = signed ? bits : ubits
|
182
|
+
if bits <= 64
|
183
|
+
Hornetseye::INT bits, signed
|
184
|
+
else
|
185
|
+
super *values
|
186
|
+
end
|
187
|
+
else
|
188
|
+
super *values
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
Type.extend RubyMatching
|
195
|
+
|
150
196
|
end
|
151
197
|
|
152
198
|
end
|
data/lib/multiarray/lazy.rb
CHANGED
@@ -29,8 +29,13 @@ module Hornetseye
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def element( index )
|
32
|
-
|
33
|
-
Lazy.new( *(
|
32
|
+
values = @values.collect { |value| value.element index }
|
33
|
+
Lazy.new( *( values + [ :action => @action ] ) )
|
34
|
+
end
|
35
|
+
|
36
|
+
def elements( range )
|
37
|
+
values = @values.collect { |value| value.elements range }
|
38
|
+
Lazy.new( *( values + [ :action => @action ] ) )
|
34
39
|
end
|
35
40
|
|
36
41
|
def -@
|
@@ -22,19 +22,7 @@ module Hornetseye
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def []( *args )
|
25
|
-
|
26
|
-
if a.is_a? Array
|
27
|
-
if s.empty?
|
28
|
-
a.inject( [], &probe ) + [ a.size ]
|
29
|
-
else
|
30
|
-
a.inject( s[ 0 ... -1 ], &probe ) + [ [ a.size, s.last ].max ]
|
31
|
-
end
|
32
|
-
else
|
33
|
-
s
|
34
|
-
end
|
35
|
-
end
|
36
|
-
shape = probe.call [], args
|
37
|
-
retval = MultiArray.new OBJECT, *shape
|
25
|
+
retval = Type.fit( args ).new
|
38
26
|
retval[] = args
|
39
27
|
retval
|
40
28
|
end
|
data/lib/multiarray/object.rb
CHANGED
@@ -48,6 +48,18 @@ module Hornetseye
|
|
48
48
|
1
|
49
49
|
end
|
50
50
|
|
51
|
+
def coercion( other )
|
52
|
+
if other < Pointer_
|
53
|
+
other.coercion self
|
54
|
+
else
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def coerce( other )
|
60
|
+
return self, self
|
61
|
+
end
|
62
|
+
|
51
63
|
end
|
52
64
|
|
53
65
|
def store( ptr )
|
@@ -55,16 +67,18 @@ module Hornetseye
|
|
55
67
|
self
|
56
68
|
end
|
57
69
|
|
58
|
-
|
70
|
+
raise '\'multiarray/object\' must be loaded first' if Type.respond_to? :fit
|
59
71
|
|
60
|
-
|
72
|
+
module RubyMatching
|
73
|
+
|
74
|
+
def fit( *values )
|
75
|
+
OBJECT
|
76
|
+
end
|
61
77
|
|
62
|
-
def fit( *value )
|
63
|
-
OBJECT
|
64
78
|
end
|
65
79
|
|
66
|
-
|
80
|
+
Type.extend RubyMatching
|
67
81
|
|
68
|
-
|
82
|
+
end
|
69
83
|
|
70
84
|
end
|
data/lib/multiarray/pointer_.rb
CHANGED
@@ -42,6 +42,26 @@ module Hornetseye
|
|
42
42
|
primitive.dereference
|
43
43
|
end
|
44
44
|
|
45
|
+
def to_type( typecode, options = {} )
|
46
|
+
Hornetseye::Pointer primitive.to_type( typecode, options )
|
47
|
+
end
|
48
|
+
|
49
|
+
def coercion( other )
|
50
|
+
if other < Pointer_
|
51
|
+
Hornetseye::Pointer primitive.coercion( other.primitive )
|
52
|
+
else
|
53
|
+
Hornetseye::Pointer primitive.coercion( other )
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def coerce( other )
|
58
|
+
if other < Pointer_
|
59
|
+
return other, self
|
60
|
+
else
|
61
|
+
super other
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
45
65
|
end
|
46
66
|
|
47
67
|
def inspect( indent = nil, lines = nil )
|
@@ -119,7 +139,12 @@ module Hornetseye
|
|
119
139
|
end
|
120
140
|
else
|
121
141
|
index = args.pop
|
122
|
-
|
142
|
+
case index
|
143
|
+
when Range
|
144
|
+
elements( index )[ *args ]
|
145
|
+
else
|
146
|
+
element( index )[ *args ]
|
147
|
+
end
|
123
148
|
end
|
124
149
|
end
|
125
150
|
|
@@ -182,13 +207,25 @@ module Hornetseye
|
|
182
207
|
end
|
183
208
|
|
184
209
|
def element( index )
|
210
|
+
target = Hornetseye::Pointer self.class.primitive.element_type
|
185
211
|
if @value.is_a? Lazy
|
186
|
-
|
187
|
-
new @value.element( index )
|
212
|
+
target.new @value.element( index )
|
188
213
|
else
|
189
214
|
pointer = @value + index * self.class.primitive.stride *
|
190
215
|
self.class.primitive.typecode.storage_size
|
191
|
-
|
216
|
+
target.new pointer
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def elements( range )
|
221
|
+
target = Sequence self.class.primitive.element_type, range.size,
|
222
|
+
self.class.primitive.stride
|
223
|
+
if @value.is_a? Lazy
|
224
|
+
target.new @value.elements( range )
|
225
|
+
else
|
226
|
+
pointer = @value + range.min * self.class.primitive.stride *
|
227
|
+
self.class.primitive.typecode.storage_size
|
228
|
+
target.new pointer
|
192
229
|
end
|
193
230
|
end
|
194
231
|
|
data/lib/multiarray/sequence.rb
CHANGED
@@ -21,7 +21,11 @@ module Hornetseye
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def []( *args )
|
24
|
-
|
24
|
+
target = Type.fit args
|
25
|
+
if target.primitive.dimension > 1
|
26
|
+
target = Hornetseye::Sequence OBJECT, args.size
|
27
|
+
end
|
28
|
+
retval = target.new
|
25
29
|
retval[] = args
|
26
30
|
retval
|
27
31
|
end
|
data/lib/multiarray/sequence_.rb
CHANGED
@@ -93,12 +93,63 @@ module Hornetseye
|
|
93
93
|
element_type.shape + [ num_elements ]
|
94
94
|
end
|
95
95
|
|
96
|
+
def dimension
|
97
|
+
element_type.dimension.succ
|
98
|
+
end
|
99
|
+
|
96
100
|
def storage_size
|
97
101
|
element_type.storage_size * num_elements
|
98
102
|
end
|
99
103
|
|
104
|
+
def to_type( typecode, options = {} )
|
105
|
+
options = { :preserve_strides => false }.merge options
|
106
|
+
target_element = element_type.to_type typecode, options
|
107
|
+
target_stride = options[ :preserve_strides ] ?
|
108
|
+
stride : target_element.size
|
109
|
+
Hornetseye::Sequence( target_element, num_elements,
|
110
|
+
target_stride ).dereference
|
111
|
+
end
|
112
|
+
|
113
|
+
def coercion( other )
|
114
|
+
if other < Sequence_
|
115
|
+
Hornetseye::Sequence( element_type.coercion( other.element_type ),
|
116
|
+
num_elements ).primitive
|
117
|
+
else
|
118
|
+
Hornetseye::Sequence( element_type.coercion( other ),
|
119
|
+
num_elements ).primitive
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def coerce( other )
|
124
|
+
if other < Sequence_
|
125
|
+
return other, self
|
126
|
+
else
|
127
|
+
return Hornetseye::Sequence( other, num_elements ), self
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
100
131
|
end
|
101
132
|
|
133
|
+
module RubyMatching
|
134
|
+
|
135
|
+
def fit( *values )
|
136
|
+
n = values.inject( 0 ) do |size,value|
|
137
|
+
value.is_a?( Array ) ? [ size, value.size ].max : size
|
138
|
+
end
|
139
|
+
if n > 0
|
140
|
+
subvalues = values.inject( [] ) do |flat,value|
|
141
|
+
flat + ( value.is_a?( Array ) ? value : [ value ] )
|
142
|
+
end
|
143
|
+
Hornetseye::Sequence fit( *subvalues ), n
|
144
|
+
else
|
145
|
+
super *values
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
Type.extend RubyMatching
|
152
|
+
|
102
153
|
end
|
103
154
|
|
104
155
|
end
|
data/lib/multiarray/type.rb
CHANGED
@@ -35,6 +35,10 @@ module Hornetseye
|
|
35
35
|
[]
|
36
36
|
end
|
37
37
|
|
38
|
+
def dimension
|
39
|
+
0
|
40
|
+
end
|
41
|
+
|
38
42
|
# Number of elements
|
39
43
|
#
|
40
44
|
# @return [Integer] Number of elements
|
@@ -44,6 +48,27 @@ module Hornetseye
|
|
44
48
|
shape.inject( 1 ) { |a,b| a * b }
|
45
49
|
end
|
46
50
|
|
51
|
+
def to_type( typecode, options = {} )
|
52
|
+
typecode
|
53
|
+
end
|
54
|
+
|
55
|
+
def coercion( other )
|
56
|
+
if self == other
|
57
|
+
self
|
58
|
+
else
|
59
|
+
x, y = other.coerce self
|
60
|
+
x.coercion y
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def coerce( other )
|
65
|
+
if self == other
|
66
|
+
return other, self
|
67
|
+
else
|
68
|
+
raise "Cannot coerce #{self} and #{other.inspect}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
47
72
|
def ===( other )
|
48
73
|
( other == self ) or ( other.is_a? self ) or ( other.class == self )
|
49
74
|
end
|
@@ -134,6 +159,10 @@ module Hornetseye
|
|
134
159
|
end
|
135
160
|
end
|
136
161
|
|
162
|
+
def to_type( target, options = {} )
|
163
|
+
self.class.to_type( target, options ).new.operation( self ) { |x| set x }
|
164
|
+
end
|
165
|
+
|
137
166
|
def -@
|
138
167
|
if is_a?( Pointer_ ) and self.class.primitive < Sequence_
|
139
168
|
retval = self.class.new
|
@@ -149,10 +178,11 @@ module Hornetseye
|
|
149
178
|
end
|
150
179
|
|
151
180
|
def +( other )
|
152
|
-
|
153
|
-
|
181
|
+
target = self.class.coercion( other.class )
|
182
|
+
if target < Pointer_ and target.primitive < Sequence_
|
183
|
+
retval = target.new
|
154
184
|
else
|
155
|
-
retval =
|
185
|
+
retval = target.dereference.new
|
156
186
|
end
|
157
187
|
retval.operation( self, other ) { |x,y| set x + y }
|
158
188
|
retval
|
data/test/tc_int.rb
CHANGED
@@ -94,7 +94,15 @@ class TC_Int < Test::Unit::TestCase
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
97
|
+
def test_plus
|
98
|
+
T.each do |t1|
|
99
|
+
T.each do |t2|
|
100
|
+
assert_equal 5, ( t1.new( 3 ) + t2.new( 2 ) )[]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_lazy_unary
|
98
106
|
T.select { |t| SIGNED[ t ] }.each do |t|
|
99
107
|
i = lazy { -t.new( 3 ) }
|
100
108
|
assert_not_equal t.new( -3 ), i
|
@@ -115,4 +123,16 @@ class TC_Int < Test::Unit::TestCase
|
|
115
123
|
end
|
116
124
|
end
|
117
125
|
|
126
|
+
def test_lazy_binary
|
127
|
+
a = U16.new 3
|
128
|
+
b = S8.new -5
|
129
|
+
i = lazy { a + b }
|
130
|
+
assert_not_equal a + b, i
|
131
|
+
assert_equal 'SINT(<delayed>)', i.inspect
|
132
|
+
assert_equal S16.new( -2 ), i.force
|
133
|
+
assert_equal S32.new( -1 ), i + S32.new( 1 )
|
134
|
+
assert_equal S32.new( -1 ), S32.new( 1 ) + i
|
135
|
+
end
|
136
|
+
|
137
|
+
|
118
138
|
end
|
data/test/tc_multiarray.rb
CHANGED
@@ -81,12 +81,12 @@ class TC_MultiArray < Test::Unit::TestCase
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def test_negate
|
84
|
-
m = M[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
|
84
|
+
m = M[ [ 1, 2, 3 ], [ 4, 5, 6 ] ].to_type O
|
85
85
|
assert_equal [ [ -1, -2, -3 ], [ -4, -5, -6 ] ], ( -m ).to_a
|
86
86
|
end
|
87
87
|
|
88
88
|
def test_lazy
|
89
|
-
m = M[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
|
89
|
+
m = M[ [ 1, 2, 3 ], [ 4, 5, 6 ] ].to_type O
|
90
90
|
u = lazy { -m }
|
91
91
|
assert_equal 'MultiArray.object(3,2):<delayed>', u.inspect
|
92
92
|
assert_equal [ [ -1, -2, -3 ], [ -4, -5, -6 ] ], u.force.to_a
|
data/test/tc_object.rb
CHANGED
@@ -64,7 +64,13 @@ class TC_Object < Test::Unit::TestCase
|
|
64
64
|
assert_equal O.new( -5 ), -o
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
67
|
+
def test_plus
|
68
|
+
v = O.new 3
|
69
|
+
w = O.new 5
|
70
|
+
assert_equal O.new( 3 + 5 ), v + w
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_lazy_unary
|
68
74
|
o = lazy { -O.new( 3 ) }
|
69
75
|
assert_not_equal O.new( -3 ), o
|
70
76
|
assert_equal 'OBJECT(<delayed>)', o.inspect
|
@@ -83,4 +89,15 @@ class TC_Object < Test::Unit::TestCase
|
|
83
89
|
assert_equal O.new( 3 ), o
|
84
90
|
end
|
85
91
|
|
92
|
+
def test_lazy_binary
|
93
|
+
v = O.new 3
|
94
|
+
w = O.new 5
|
95
|
+
o = lazy { v + w }
|
96
|
+
assert_not_equal v + w, o
|
97
|
+
assert_equal 'OBJECT(<delayed>)', o.inspect
|
98
|
+
assert_equal O.new( 8 ), o.force
|
99
|
+
assert_equal O.new( 9 ), o + O.new( 1 )
|
100
|
+
assert_equal O.new( 9 ), O.new( 1 ) + o
|
101
|
+
end
|
102
|
+
|
86
103
|
end
|
data/test/tc_sequence.rb
CHANGED
@@ -72,6 +72,7 @@ class TC_Sequence < Test::Unit::TestCase
|
|
72
72
|
|
73
73
|
def test_sequence_assign
|
74
74
|
assert_equal [ :a, :b, :c ], S[ :a, :b, :c ].to_a
|
75
|
+
assert_equal [ :a, :b, [ :c ] ], S[ :a, :b, [ :c ] ].to_a
|
75
76
|
end
|
76
77
|
|
77
78
|
def test_inspect
|
@@ -98,12 +99,19 @@ class TC_Sequence < Test::Unit::TestCase
|
|
98
99
|
end
|
99
100
|
|
100
101
|
def test_negate
|
101
|
-
s = S[ 1, 2, 3 ]
|
102
|
+
s = S[ 1, 2, 3 ].to_type O
|
102
103
|
assert_equal [ -1, -2, -3 ], ( -s ).to_a
|
103
104
|
end
|
104
105
|
|
105
|
-
def
|
106
|
-
s = S[ 1, 2, 3 ]
|
106
|
+
def test_plus
|
107
|
+
s = S[ 1, 2, 3 ].to_type O
|
108
|
+
assert_equal [ 2, 4, 6 ], ( s + s ).to_a
|
109
|
+
assert_equal [ 2, 3, 4 ], ( s + O.new( 1 ) ).to_a
|
110
|
+
assert_equal [ 2, 3, 4 ], ( O.new( 1 ) + s ).to_a
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_lazy_unary
|
114
|
+
s = S[ 1, 2, 3 ].to_type O
|
107
115
|
u = lazy { -s }
|
108
116
|
assert_equal 'Sequence.object(3):<delayed>', u.inspect
|
109
117
|
assert_equal [ -1, -2, -3 ], u.force.to_a
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multiarray
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Wedekind
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-28 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- Rakefile
|
35
35
|
- README
|
36
36
|
- COPYING
|
37
|
+
- TODO
|
37
38
|
- .document
|
38
39
|
- lib/multiarray.rb
|
39
40
|
- lib/multiarray/sequence_.rb
|