ruby-gsl-ng 0.1.0 → 0.2.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/History.txt +6 -1
- data/Manifest.txt +12 -4
- data/README.txt +5 -2
- data/Rakefile +1 -0
- data/ext/extconf.rb +2 -0
- data/ext/gslng_extensions.cpp +77 -0
- data/lib/gslng/backend.rb +19 -0
- data/lib/gslng/backend_components/error_handling.rb +12 -0
- data/lib/gslng/backend_components/matrix.rb +73 -0
- data/lib/{gsl/backend.rb → gslng/backend_components/vector.rb} +24 -32
- data/lib/gslng/finalizer.rb +5 -0
- data/lib/gslng/matrix.rb +406 -0
- data/lib/gslng/matrix_view.rb +39 -0
- data/lib/gslng/vector.rb +353 -0
- data/lib/gslng/vector_view.rb +39 -0
- data/lib/gslng.rb +11 -0
- data/test/benchmark.rb +49 -0
- data/test/matrix_test.rb +105 -0
- data/test/test_gsl.rb +1 -0
- data/test/vector_test.rb +72 -39
- metadata +17 -9
- data/lib/gsl/finalizer.rb +0 -5
- data/lib/gsl/vector.rb +0 -236
- data/lib/gsl.rb +0 -8
data/test/vector_test.rb
CHANGED
@@ -5,71 +5,104 @@ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
|
5
5
|
$:.unshift File.join(File.dirname(__FILE__),'..','ext')
|
6
6
|
|
7
7
|
require 'test/unit'
|
8
|
-
require '
|
8
|
+
require 'gslng'
|
9
|
+
|
10
|
+
include GSLng
|
9
11
|
|
10
12
|
class VectorTest < Test::Unit::TestCase
|
11
13
|
def test_initialize
|
12
|
-
assert_equal(10,
|
13
|
-
assert_equal(10,
|
14
|
-
assert(
|
15
|
-
assert_nothing_raised {
|
14
|
+
assert_equal(10, Vector.new(10).size)
|
15
|
+
assert_equal(10, Vector.zero(10).size)
|
16
|
+
assert(Vector.zero(10).zero?)
|
17
|
+
assert_nothing_raised { Vector.random(10) }
|
16
18
|
end
|
17
19
|
|
18
20
|
def test_to_s
|
19
|
-
assert_equal("[0.0]",
|
20
|
-
assert_equal("[0.0, 0.0, 0.0]",
|
21
|
-
assert_equal("[0.0, 1.0, 2.0]",
|
22
|
-
assert_equal("[1.0, 2.0, 3.0]",
|
21
|
+
assert_equal("[0.0]", Vector.zero(1).to_s)
|
22
|
+
assert_equal("[0.0, 0.0, 0.0]", Vector.zero(3).to_s)
|
23
|
+
assert_equal("[0.0, 1.0, 2.0]", Vector.new(3) {|i| i}.to_s)
|
24
|
+
assert_equal("[1.0, 2.0, 3.0]", Vector[1,2,3].to_s)
|
25
|
+
assert_equal("1.0 2.0 3.0", Vector[1,2,3].join(' '))
|
23
26
|
end
|
24
27
|
|
25
28
|
def test_equal
|
26
|
-
assert_equal(
|
27
|
-
assert_equal(
|
28
|
-
|
29
|
-
|
29
|
+
assert_equal(Vector[1,2,3], [1,2,3])
|
30
|
+
assert_equal(Vector[1,2,3], Vector[1,2,3])
|
31
|
+
assert_equal(Vector[0...3], [0,1,2])
|
32
|
+
assert_equal(Vector.zero(3), Vector.zero(3))
|
33
|
+
assert_not_equal(Vector.zero(4), Vector.zero(3))
|
30
34
|
end
|
31
35
|
|
32
36
|
def test_copies
|
33
|
-
v1 =
|
34
|
-
v2 =
|
37
|
+
v1 = Vector[1,2,3]
|
38
|
+
v2 = Vector[2,3,4]
|
35
39
|
assert_not_equal(v1, v2)
|
36
40
|
assert_equal(v1.copy(v2), v2)
|
37
41
|
assert_equal(v1.dup, v2)
|
38
42
|
end
|
39
43
|
|
40
44
|
def test_sets
|
41
|
-
assert_equal(
|
42
|
-
assert_equal(
|
43
|
-
assert_equal(
|
45
|
+
assert_equal(Vector.zero(3).set!(1), Vector[1,1,1])
|
46
|
+
assert_equal(Vector.zero(3).set!(1).zero!, Vector.zero(3))
|
47
|
+
assert_equal(Vector.zero(3).basis!(1), Vector[0,1,0])
|
44
48
|
end
|
45
49
|
|
46
50
|
def test_operators
|
47
|
-
assert_equal(
|
48
|
-
assert_equal(
|
49
|
-
assert_equal(
|
50
|
-
assert_equal(
|
51
|
-
|
52
|
-
assert_equal(
|
53
|
-
assert_equal(
|
54
|
-
|
55
|
-
assert_equal(
|
51
|
+
assert_equal(Vector[2,3,4],Vector[1,2,3] + Vector[1,1,1])
|
52
|
+
assert_equal(Vector[1,0,3],Vector[1,2,3] * Vector[1,0,1])
|
53
|
+
assert_equal(Vector[0,1,2],Vector[1,2,3] - Vector[1,1,1])
|
54
|
+
assert_equal(Vector[0.5,1,1.5],Vector[1,2,3] / Vector[2,2,2])
|
55
|
+
assert_equal(Vector[3,6,9],Vector[1,2,3] * 3)
|
56
|
+
assert_equal(Vector[4,5,6],3 + Vector[1,2,3])
|
57
|
+
assert_equal(Vector[4,5,6],Vector[1,2,3] + 3)
|
58
|
+
assert_equal(Vector[2,1,0],3 - Vector[1,2,3])
|
59
|
+
assert_equal(Vector[-2,-1,0],Vector[1,2,3] - 3)
|
60
|
+
assert_equal(Vector[3,6,9],3 * Vector[1,2,3])
|
61
|
+
assert_equal(Vector[0.5,1,1.5],Vector[1,2,3] / 2)
|
56
62
|
end
|
57
63
|
|
58
64
|
def test_other
|
59
|
-
|
60
|
-
assert_equal(
|
61
|
-
assert_equal(
|
62
|
-
assert_equal(
|
63
|
-
assert_equal(3,
|
64
|
-
assert_equal(
|
65
|
+
assert_equal(Matrix[1,2,3], Vector[1,2,3].to_matrix)
|
66
|
+
assert_equal(Vector[1,2,3], Vector[1,2,3].to_a)
|
67
|
+
assert_equal(Vector[1,2,3], Vector[3,1,2].sort)
|
68
|
+
assert_equal(6, Vector[3,1,2].sum)
|
69
|
+
assert_equal(Vector[3,1,2].mul_add(Vector[1,0,1],0.5), Vector[3.5,1,2.5])
|
70
|
+
assert_equal(3, Vector[2,1,2].norm)
|
71
|
+
assert_equal(5, Vector[3,1,2] ^ Vector[1,0,1])
|
65
72
|
end
|
66
73
|
|
67
74
|
def test_minmax
|
68
|
-
assert_equal(1,
|
69
|
-
assert_equal(3,
|
70
|
-
assert_equal([1,3],
|
71
|
-
assert_equal(0, (
|
72
|
-
assert_equal(2, (
|
73
|
-
assert_equal([0,2],
|
75
|
+
assert_equal(1, Vector[1,2,3].min)
|
76
|
+
assert_equal(3, Vector[1,2,3].max)
|
77
|
+
assert_equal([1,3], Vector[1,2,3].minmax)
|
78
|
+
assert_equal(0, (Vector[1,2,3]).min_index)
|
79
|
+
assert_equal(2, (Vector[1,2,3]).max_index)
|
80
|
+
assert_equal([0,2], Vector[1,2,3].minmax_index)
|
74
81
|
end
|
82
|
+
|
83
|
+
def test_set_get
|
84
|
+
assert_equal(2, Vector[1,2,3][1])
|
85
|
+
assert_raise { Vector[1,2,3][3] }
|
86
|
+
assert_equal(3, Vector[1,2,3][-1])
|
87
|
+
assert_raise { Vector[1,2,3][-5] }
|
88
|
+
|
89
|
+
v = Vector[1,2,3]
|
90
|
+
v[1] = 3
|
91
|
+
assert_equal(Vector[1,3,3], v)
|
92
|
+
v[-1] = 0
|
93
|
+
assert_equal(Vector[1,3,0], v)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_view
|
97
|
+
v,view = nil,nil
|
98
|
+
assert_nothing_raised {
|
99
|
+
v = Vector[1,2,3]
|
100
|
+
view = v.view
|
101
|
+
view[1] = 3
|
102
|
+
}
|
103
|
+
assert_equal(Vector[1,3,3], v)
|
104
|
+
assert_equal(Vector[1,3,3], view)
|
105
|
+
assert_equal(Vector[1,3], Vector[0,1,2,3].view(1,nil,2))
|
106
|
+
assert_equal(Vector[0,2], Vector[0,1,2,3].view(0,nil,2))
|
107
|
+
end
|
75
108
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-gsl-ng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- v01d
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-05 00:00:00 -03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -30,9 +30,9 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: 2.4.0
|
34
34
|
version:
|
35
|
-
description:
|
35
|
+
description: New-generation Ruby/GSL wrapper.
|
36
36
|
email:
|
37
37
|
- phreakuencies@gmail.com
|
38
38
|
executables: []
|
@@ -51,10 +51,18 @@ files:
|
|
51
51
|
- Rakefile
|
52
52
|
- ext/extconf.rb
|
53
53
|
- ext/gslng_extensions.cpp
|
54
|
-
- lib/
|
55
|
-
- lib/
|
56
|
-
- lib/
|
57
|
-
- lib/
|
54
|
+
- lib/gslng.rb
|
55
|
+
- lib/gslng/backend.rb
|
56
|
+
- lib/gslng/backend_components/error_handling.rb
|
57
|
+
- lib/gslng/backend_components/matrix.rb
|
58
|
+
- lib/gslng/backend_components/vector.rb
|
59
|
+
- lib/gslng/finalizer.rb
|
60
|
+
- lib/gslng/matrix.rb
|
61
|
+
- lib/gslng/matrix_view.rb
|
62
|
+
- lib/gslng/vector.rb
|
63
|
+
- lib/gslng/vector_view.rb
|
64
|
+
- test/benchmark.rb
|
65
|
+
- test/matrix_test.rb
|
58
66
|
- test/test_gsl.rb
|
59
67
|
- test/vector_test.rb
|
60
68
|
has_rdoc: true
|
@@ -86,6 +94,6 @@ rubyforge_project: ruby-gsl-ng
|
|
86
94
|
rubygems_version: 1.3.5
|
87
95
|
signing_key:
|
88
96
|
specification_version: 3
|
89
|
-
summary:
|
97
|
+
summary: New-generation Ruby/GSL wrapper.
|
90
98
|
test_files:
|
91
99
|
- test/test_gsl.rb
|
data/lib/gsl/finalizer.rb
DELETED
data/lib/gsl/vector.rb
DELETED
@@ -1,236 +0,0 @@
|
|
1
|
-
module GSL
|
2
|
-
# A fixed-size n-dimensional vector.
|
3
|
-
#
|
4
|
-
# =Examples
|
5
|
-
# Vector[1,2,3] + Vector[2,3,4] => Vector[3,5,7]
|
6
|
-
# Vector[1,2,3] + 0.5 => Vector[1.5,2.5,3.5]
|
7
|
-
# Same goes for *, /, and - operators. The are also self-modifying versions (#add, #mul, #div, #sub).
|
8
|
-
#
|
9
|
-
# Note also that operator ^ produces the #dot product:
|
10
|
-
# Vector[1,2,3] ^ Vector[2,3,4] => 20
|
11
|
-
#
|
12
|
-
# =Notes
|
13
|
-
# * This class includes Enumerable, but certain methods are redefined (like #max and #min)
|
14
|
-
# for fast versions that don't use #each. Calling #each (and therefore, any other Enumerable's method) is slower.
|
15
|
-
# * #each is implemented through calls to #[], which can be relatively slow (compared to direct C pointer access)
|
16
|
-
# for big Vectors. It would be possible to have a faster version that iterates on the C-side and calls a block for each
|
17
|
-
# element, but in that case it wouldn't be possible to expect a return value of any type. This complicates things for methods like
|
18
|
-
# #any? which expect a boolean value.
|
19
|
-
# * Some functions (like #sum, #dot, and others) use BLAS functions (through GSL's CBLAS interface).
|
20
|
-
#--
|
21
|
-
# TODO: add type coercions
|
22
|
-
#
|
23
|
-
class Vector
|
24
|
-
include Enumerable
|
25
|
-
|
26
|
-
attr_reader :ptr # :nodoc:
|
27
|
-
attr_reader :size # Vector size
|
28
|
-
|
29
|
-
# Create a Vector of size n. If zero is true, the vector is initialized with zeros.
|
30
|
-
# Otherwise, the vector will contain garbage.
|
31
|
-
# You can optionally pass a block, in which case #map_index! will be called with it (i.e.: it works like Array.new).
|
32
|
-
def initialize(n, zero = false)
|
33
|
-
if (zero) then @ptr = GSL::Backend::gsl_vector_calloc(n)
|
34
|
-
else @ptr = GSL::Backend::gsl_vector_alloc(n) end
|
35
|
-
GSL.set_finalizer(self, :gsl_vector_free, @ptr)
|
36
|
-
|
37
|
-
@size = n # TODO: extract from @ptr
|
38
|
-
|
39
|
-
if (block_given?) then self.map_index! {|i| yield(i)} end
|
40
|
-
end
|
41
|
-
|
42
|
-
def initialize_copy(other) #:nodoc:
|
43
|
-
ObjectSpace.undefine_finalizer(self) # TODO: ruby bug?
|
44
|
-
@ptr = GSL::Backend::gsl_vector_alloc(other.size)
|
45
|
-
GSL.set_finalizer(self, :gsl_vector_free, @ptr)
|
46
|
-
|
47
|
-
@size = other.size
|
48
|
-
GSL::Backend::gsl_vector_memcpy(@ptr, other.ptr)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Same as Vector.new(n, true)
|
52
|
-
def Vector.zero(n); Vector.new(n, true) end
|
53
|
-
|
54
|
-
# Create a vector from an Array
|
55
|
-
def Vector.from_array(array)
|
56
|
-
if (array.empty?) then raise "Can't create empty vector" end
|
57
|
-
Vector.new(array.size) {|i| array[i]}
|
58
|
-
end
|
59
|
-
|
60
|
-
# See #from_array
|
61
|
-
def Vector.[](*args)
|
62
|
-
Vector.from_array(args)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Generates a Vector of n random numbers between 0 and 1.
|
66
|
-
# NOTE: This simply uses Kernel::rand
|
67
|
-
def Vector.random(n); Vector.new(n).map!{|x| Kernel::rand} end
|
68
|
-
class << self; alias_method :rand, :random end
|
69
|
-
|
70
|
-
# Copy other's values into self
|
71
|
-
def copy(other); GSL::Backend::gsl_vector_memcpy(@ptr, other.ptr); return self end
|
72
|
-
|
73
|
-
# Set all values to v
|
74
|
-
def all!(v); GSL::Backend::gsl_vector_set_all(@ptr, v); return self end
|
75
|
-
alias_method :set!, :all!
|
76
|
-
|
77
|
-
# Set all values to zero
|
78
|
-
def zero!; GSL::Backend::gsl_vector_set_zero(@ptr); return self end
|
79
|
-
|
80
|
-
# Set all values to zero, except the i-th element, which is set to 1
|
81
|
-
def basis!(i); GSL::Backend::gsl_vector_set_basis(@ptr, i); return self end
|
82
|
-
|
83
|
-
# Add other to self
|
84
|
-
def add(other)
|
85
|
-
case other
|
86
|
-
when Numeric; GSL::Backend::gsl_vector_add_constant(@ptr, other.to_f)
|
87
|
-
when Vector; GSL::Backend::gsl_vector_add(@ptr, other.ptr)
|
88
|
-
else raise TypeError, "Unsupported type: #{other.class}" end
|
89
|
-
return self
|
90
|
-
end
|
91
|
-
|
92
|
-
# Substract other from self
|
93
|
-
def sub(other)
|
94
|
-
case other
|
95
|
-
when Numeric; GSL::Backend::gsl_vector_add_constant(@ptr, -other.to_f)
|
96
|
-
when Vector; GSL::Backend::gsl_vector_sub(@ptr, other.ptr)
|
97
|
-
else raise TypeError, "Unsupported type: #{other.class}" end
|
98
|
-
return self
|
99
|
-
end
|
100
|
-
|
101
|
-
# Multiply (element-by-element) other with self
|
102
|
-
def mul(other)
|
103
|
-
case other
|
104
|
-
when Numeric; GSL::Backend::gsl_blas_dscal(other.to_f, @ptr)
|
105
|
-
when Vector; GSL::Backend::gsl_vector_mul(@ptr, other.ptr)
|
106
|
-
else raise TypeError, "Unsupported type: #{other.class}" end
|
107
|
-
return self
|
108
|
-
end
|
109
|
-
|
110
|
-
# Divide (element-by-element) self by other
|
111
|
-
def div(other)
|
112
|
-
case other
|
113
|
-
when Numeric; GSL::Backend::gsl_blas_dscal(1.0 / other, @ptr)
|
114
|
-
when Vector; GSL::Backend::gsl_vector_div(@ptr, other.ptr)
|
115
|
-
else raise TypeError, "Unsupported type: #{other.class}" end
|
116
|
-
return self
|
117
|
-
end
|
118
|
-
|
119
|
-
def +(other); self.dup.add(other) end
|
120
|
-
def -(other); self.dup.sub(other) end
|
121
|
-
def *(other); self.dup.mul(other) end
|
122
|
-
def /(other); self.dup.div(other) end
|
123
|
-
|
124
|
-
# Reverse the order of elements
|
125
|
-
def reverse!; GSL::Backend::gsl_vector_reverse(@ptr); return self end
|
126
|
-
|
127
|
-
# Swap the i-th element with the j-th element
|
128
|
-
def swap(i,j); GSL::Backend::gsl_vector_swap_elements(@ptr, i, j); return self end
|
129
|
-
|
130
|
-
# Access the i-th element (throws exception if out-of-bounds)
|
131
|
-
def [](i); GSL::Backend::gsl_vector_get(@ptr, i) end
|
132
|
-
|
133
|
-
# set the i-th element (throws exception if out-of-bounds)
|
134
|
-
def []=(i, v); GSL::Backend::gsl_vector_set(@ptr, i, v.to_f) end
|
135
|
-
|
136
|
-
# if all elements are zero
|
137
|
-
def zero?; GSL::Backend::gsl_vector_isnull(@ptr) == 1 ? true : false end
|
138
|
-
|
139
|
-
# if all elements are strictly positive (>0)
|
140
|
-
def positive?; GSL::Backend::gsl_vector_ispos(@ptr) == 1 ? true : false end
|
141
|
-
|
142
|
-
#if all elements are strictly negative (<0)
|
143
|
-
def negative?; GSL::Backend::gsl_vector_isneg(@ptr) == 1 ? true : false end
|
144
|
-
|
145
|
-
# if all elements are non-negative (>=0)
|
146
|
-
def nonnegative?; GSL::Backend::gsl_vector_isnonneg(@ptr) == 1 ? true : false end
|
147
|
-
|
148
|
-
def max; GSL::Backend::gsl_vector_max(@ptr) end
|
149
|
-
|
150
|
-
def min; GSL::Backend::gsl_vector_min(@ptr) end
|
151
|
-
|
152
|
-
# Same as Array#minmax
|
153
|
-
def minmax
|
154
|
-
min = FFI::Buffer.new(:double)
|
155
|
-
max = FFI::Buffer.new(:double)
|
156
|
-
GSL::Backend::gsl_vector_minmax(@ptr, min, max)
|
157
|
-
return [min[0].get_float64(0),max[0].get_float64(0)]
|
158
|
-
end
|
159
|
-
|
160
|
-
# Same as #minmax, but returns the indices to the elements
|
161
|
-
def minmax_index
|
162
|
-
min = FFI::Buffer.new(:size_t)
|
163
|
-
max = FFI::Buffer.new(:size_t)
|
164
|
-
GSL::Backend::gsl_vector_minmax_index(@ptr, min, max)
|
165
|
-
#return [min[0].get_size_t(0),max[0].get_size_t(0)]
|
166
|
-
return [min[0].get_ulong(0),max[0].get_ulong(0)]
|
167
|
-
end
|
168
|
-
|
169
|
-
# Same as #min, but returns the index to the element
|
170
|
-
def min_index; GSL::Backend::gsl_vector_min_index(@ptr) end
|
171
|
-
|
172
|
-
# Same as #max, but returns the index to the element
|
173
|
-
def max_index; GSL::Backend::gsl_vector_max_index(@ptr) end
|
174
|
-
|
175
|
-
# Dot product between self and other (uses BLAS's ddot)
|
176
|
-
def dot(other)
|
177
|
-
out = FFI::MemoryPointer.new(:double)
|
178
|
-
GSL::Backend::gsl_blas_ddot(@ptr, other.ptr, out)
|
179
|
-
return out[0].get_double(0)
|
180
|
-
end
|
181
|
-
alias_method :^, :dot
|
182
|
-
|
183
|
-
# Norm 2 of the vector (uses BLAS's dnrm2)
|
184
|
-
def norm; GSL::Backend::gsl_blas_dnrm2(@ptr) end
|
185
|
-
alias_method :length, :norm
|
186
|
-
|
187
|
-
# Returns the sum of all elements (uses BLAS's dasum)
|
188
|
-
def sum; GSL::Backend::gsl_blas_dasum(@ptr) end
|
189
|
-
|
190
|
-
# Optimized version of: self += other * alpha (where alpha is a Numeric). Uses BLAS's daxpy.
|
191
|
-
def mul_add(other, alpha); GSL::Backend::gsl_blas_daxpy(alpha, other.ptr, @ptr); return self end
|
192
|
-
|
193
|
-
# Yields the block for each element in the Vector
|
194
|
-
def each # :yield: obj
|
195
|
-
@size.times {|i| yield(self[i])}
|
196
|
-
end
|
197
|
-
|
198
|
-
# Efficient map! implementation
|
199
|
-
def map!(&block); GSL::Backend::gsl_vector_map(@ptr, block); return self end
|
200
|
-
|
201
|
-
# Alternate version of #map!, in this case the block receives the index as a parameter.
|
202
|
-
def map_index!(&block); GSL::Backend::gsl_vector_map_index(@ptr, block); return self end
|
203
|
-
|
204
|
-
# See #map!. Returns a Vector.
|
205
|
-
def map(&block); self.dup.map!(block) end
|
206
|
-
|
207
|
-
def sort!; GSL::Backend::gsl_sort_vector(@ptr); return self end
|
208
|
-
def sort; self.dup.sort! end
|
209
|
-
|
210
|
-
def join(sep = $,)
|
211
|
-
s = "#{self[0]}"
|
212
|
-
(1..(@size-1)).each do |e|
|
213
|
-
s += sep + self[e].to_s
|
214
|
-
end
|
215
|
-
return s
|
216
|
-
end
|
217
|
-
|
218
|
-
def to_s
|
219
|
-
"[" + self.join(', ') + "]"
|
220
|
-
end
|
221
|
-
|
222
|
-
def to_a
|
223
|
-
Array.new(@size) {|i| self[i]}
|
224
|
-
end
|
225
|
-
|
226
|
-
# Element-by-element comparison (uses #each_with_index)
|
227
|
-
# Admits comparing to Array
|
228
|
-
def ==(other)
|
229
|
-
if (self.size != other.size) then return false end
|
230
|
-
self.each_with_index do |elem,i|
|
231
|
-
if (elem != other[i]) then return false end
|
232
|
-
end
|
233
|
-
return true
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|