ruby-gsl-ng 0.2.2 → 0.2.3

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.
@@ -9,16 +9,17 @@ module GSLng
9
9
  class View < Matrix
10
10
  attr_reader :owner # The Matrix owning the data this View uses
11
11
 
12
- # Create a MatrixView of the sub-matrix starting at (x,y), of size (m,n)
12
+ # Create a Matrix::View of the sub-matrix starting at (x,y), of size (m,n)
13
13
  def initialize(owner, x, y, m, n) # @private
14
14
  @owner = owner
15
15
  @m,@n = m,n
16
16
  @ptr = GSLng.backend::gsl_matrix_submatrix2(owner.ptr, x, y, m, n)
17
- GSLng.set_finalizer(self, :gsl_matrix_free, @ptr)
17
+ GSLng.define_finalizer(self, :gsl_matrix_free, @ptr)
18
18
  end
19
19
 
20
20
  # Returns a Matrix (*NOT* a View) copied from this view. In other words,
21
21
  # you'll get a Matrix which you can modify without modifying #owner elements.
22
+ # @return [Matrix]
22
23
  def dup
23
24
  matrix = Matrix.new(@m, @n)
24
25
  GSLng.backend::gsl_matrix_memcpy(matrix.ptr, @ptr)
@@ -0,0 +1,34 @@
1
+ module GSLng
2
+ class RNG
3
+ class Gaussian < RNG
4
+ attr_reader :ptr # @private
5
+
6
+ attr_reader :mu, :sigma
7
+
8
+ # Creates a new Gaussian distribution
9
+ # @param [Float] mu mean
10
+ # @param [Float] sigma standard deviation
11
+ # @param [Symbol] sample_method The method to use to sample numbers. Can be either :boxmuller, :ziggurat or :ratio_method
12
+ # @param generator_type (see GSLng::RNG#initialize)
13
+ # @see http://www.gnu.org/software/gsl/manual/html_node/The-Gaussian-Distribution.html
14
+ def initialize(mu = 0, sigma = 1, sample_method = :boxmuller, generator_type = nil)
15
+ super(generator_type)
16
+ @mu,@sigma = mu,sigma
17
+
18
+ case sample_method
19
+ when :boxmuller; @function = :gsl_ran_gaussian
20
+ when :ziggurat; @function = :gsl_ran_gaussian_ziggurat
21
+ when :ratio_method; @function = :gsl_ran_ratio_method
22
+ else raise "Unsupported method"
23
+ end
24
+ end
25
+
26
+ # Obtain a sample from this distribution
27
+ # @return [Float]
28
+ def sample
29
+ GSLng.backend.send(@function, self.ptr, @sigma) + @mu
30
+ end
31
+ alias_method :get, :sample
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ module GSLng
2
+ # Random Number Generator class
3
+ # @abstract You should use any of the descendant classes which implement the {#sample} method.
4
+ class RNG
5
+ # Create a Generator of the given type
6
+ # @param [Symbol] generator_type the algorithm to use (without the +gsl_rng+ prefix). Default is :mt19937.
7
+ # @see http://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html
8
+ def initialize(generator_type = nil)
9
+ @type = generator_type
10
+ if (@type.nil?) then @type = :mt19937 end # update comment above if changed
11
+
12
+ type = GSLng.backend.send(:"gsl_rng_#{@type}")
13
+ @ptr = GSLng.backend.gsl_rng_alloc(type)
14
+ GSLng.define_finalizer(self, :gsl_rng_free, @ptr)
15
+ end
16
+
17
+ def initialize_copy
18
+ ObjectSpace.undefine_finalizer(self)
19
+ type = GSLng.backend.send(:"gsl_rng_#{@type}")
20
+ @ptr = GSLng.backend.gsl_rng_alloc(type)
21
+ GSLng.define_finalizer(self, :gsl_rng_free, @ptr)
22
+ end
23
+ end
24
+ end
25
+
26
+ require 'gslng/rng/gaussian'
27
+ require 'gslng/rng/uniform'
@@ -0,0 +1,23 @@
1
+ module GSLng
2
+ class RNG
3
+ class Uniform < RNG
4
+ attr_reader :ptr # @private
5
+
6
+ # Creates a new Uniform distribution with values in [min,max)
7
+ # @param [Float] min
8
+ # @param [Float] max
9
+ # @param generator_type (see GSLng::RNG#initialize)
10
+ def initialize(min, max, generator_type = nil)
11
+ super(generator_type)
12
+ @min,@max = min,max
13
+ end
14
+
15
+ # Obtain a sample from this distribution
16
+ # @return [Float]
17
+ def sample
18
+ GSLng.backend.gsl_ran_flat(self.ptr, @min, @max)
19
+ end
20
+ alias_method :get, :sample
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ module GSLng
2
+ # A group of several different special functions.
3
+ #
4
+ # =Notes
5
+ # You can use this module simply by acessing its functions. Optionally, you can also extend the +Math+ standard module
6
+ # with these methods by doing:
7
+ # Math.extend(GSLng::Special)
8
+ #
9
+ module Special
10
+ extend self # allow this module to be used as such, and as a mixin
11
+
12
+ # Restrict the given angle to the interval (-pi,pi]
13
+ def angle_restrict_symm(theta)
14
+ GSLng.backend.gsl_sf_angle_restrict_symm(theta)
15
+ end
16
+
17
+ # Restrict the given angle to the interval (0,2pi]
18
+ def angle_restrict_pos(theta)
19
+ GSLng.backend.gsl_sf_angle_restrict_pos(theta)
20
+ end
21
+ end
22
+ end
data/lib/gslng/vector.rb CHANGED
@@ -2,31 +2,31 @@ module GSLng
2
2
  # A fixed-size n-dimensional vector.
3
3
  #
4
4
  # =Notes
5
- # * #each is implemented through calls to #[], which can be relatively slow (compared to direct C pointer access)
6
- # for big Vectors. There's a faster version (#fast_each) that can be used when there's not return value expected from the #each call.
7
- # * Since this class includes Enumerable, and Enumerable's methods call #each, certain methods are redefined (like #max and #min)
8
- # so they use #fast_each instead. Thus, any other Enumerable's method not defined here will be slower.
9
- # * Some functions (like #sum, #dot, and others) use BLAS functions (through GSLng's CBLAS interface).
10
- # * In contrary to Array, operators [] and []= will raise an exception when accessing out-of-bounds elements.
11
- # * Operator * multiplies two vectors element-by-element. To perform a dot product use the ^ operator instead (or the #dot method).
12
- # * Operands are coerced to vectors so you can do vector + scalar, etc. (see #coerce)
5
+ # * {#each}, {#map} and similar methods are implemented with C versions which should be fast.
6
+ # * {#map} returns a Vector, not an Array. Use {#map_array} for that.
7
+ # * While this class includes Enumerable, certain methods are redefined (like {#max} and {#min})
8
+ # so they use internal GSL methods.
9
+ # * Some functions (like {#sum}, {#dot}, and others) use BLAS functions (through GSLng's CBLAS interface).
10
+ # * In contrary to Array, operators {#[]} and {#[]=} will raise an exception when accessing out-of-bounds elements.
11
+ # * Operator {#*} multiplies two vectors element-by-element. To perform a dot product use the {#^} operator instead (or the {#dot} alias).
12
+ # * Operands are coerced to vectors so you can do vector + scalar, etc. (see {#coerce})
13
13
  #
14
14
  class Vector
15
15
  include Enumerable
16
-
17
- attr_reader :ptr # @private
18
- attr_reader :size # Vector size
16
+
17
+ attr_reader :size
18
+ attr_reader :ptr # @private
19
19
 
20
20
  #--------------------- constructors -------------------------#
21
21
 
22
22
  # Create a Vector of size n. If zero is true, the vector is initialized with zeros.
23
23
  # Otherwise, the vector will contain garbage.
24
- # You can optionally pass a block, in which case #map_index! will be called with it (i.e.: it works like Array.new).
24
+ # You can optionally pass a block, in which case {#map_index!} will be called with it (i.e.: it works like {Array.new}).
25
25
  def initialize(n, zero = false)
26
26
  @size = n
27
27
  @ptr = (zero ? GSLng.backend::gsl_vector_calloc(n) : GSLng.backend::gsl_vector_alloc(n))
28
- GSLng.set_finalizer(self, :gsl_vector_free, @ptr)
29
- if (block_given?) then self.map_index!(Proc.new) end
28
+ GSLng.define_finalizer(self, :gsl_vector_free, @ptr)
29
+ if (block_given?) then self.map_index!(Proc.new) end
30
30
  end
31
31
 
32
32
  def initialize_copy(other) # @private
@@ -34,41 +34,45 @@ module GSLng
34
34
 
35
35
  @size = other.size
36
36
  @ptr = GSLng.backend::gsl_vector_alloc(other.size)
37
- GSLng.set_finalizer(self, :gsl_vector_free, @ptr)
37
+ GSLng.define_finalizer(self, :gsl_vector_free, @ptr)
38
38
 
39
39
  GSLng.backend::gsl_vector_memcpy(@ptr, other.ptr)
40
40
  end
41
41
 
42
- # Same as Vector.new(n, true)
43
- def Vector.zero(n); Vector.new(n, true) end
42
+ # Same as Vector.new(n, true)
43
+ def Vector.zero(n); Vector.new(n, true) end
44
44
 
45
- # Create a vector from an Array.
46
- def Vector.from_array(array)
47
- if (array.empty?) then raise "Can't create empty vector" end
48
- Vector.new(array.size) {|i| array[i]}
49
- end
45
+ # Create a vector from an Array.
46
+ def Vector.from_array(array)
47
+ if (array.empty?) then raise "Can't create empty vector" end
48
+ v = Vector.new(array.size)
49
+ GSLng.backend.gsl_vector_from_array(v.ptr.to_i, array)
50
+ return v
51
+ end
50
52
 
51
- # Creates a Vector from an Array (see #from_array) or a Range. For example:
52
- # Vector[1,2,3]
53
- # Vector[1..3]
54
- def Vector.[](*args)
53
+ # Creates a Vector from an Array or a Range
54
+ # @see Vector::from_array
55
+ # @example
56
+ # Vector[1,2,3]
57
+ # Vector[1..3]
58
+ def Vector.[](*args)
55
59
  array = (args.size == 1 && Range === args[0] ? args[0].to_a : args)
56
- Vector.from_array(array)
57
- end
60
+ Vector.from_array(array)
61
+ end
58
62
 
59
63
  # Generates a Vector of n random numbers between 0 and 1.
60
- # NOTE: This simply uses Kernel::rand
64
+ # NOTE: This simply uses {Kernel::rand}
61
65
  def Vector.random(n)
62
- Vector.new(n).map!{|x| Kernel::rand}
66
+ Vector.new(n).map!{|x| Kernel::rand}
63
67
  end
64
- class << self; alias_method :rand, :random end
68
+ class << self; alias_method :rand, :random end
65
69
 
66
70
  #--------------------- setting values -------------------------#
67
71
 
68
72
  # Set all values to v
69
73
  def all!(v); GSLng.backend::gsl_vector_set_all(self.ptr, v); return self end
70
- alias_method :set!, :all!
71
- alias_method :fill!, :all!
74
+ alias_method :set!, :all!
75
+ alias_method :fill!, :all!
72
76
 
73
77
  # Set all values to zero
74
78
  def zero!; GSLng.backend::gsl_vector_set_zero(self.ptr); return self end
@@ -79,53 +83,57 @@ module GSLng
79
83
  #--------------------- operators -------------------------#
80
84
 
81
85
  # Add (element-by-element) other to self
86
+ # @return [Vector] self
82
87
  def add!(other)
83
88
  case other
84
89
  when Numeric; GSLng.backend::gsl_vector_add_constant(self.ptr, other.to_f)
85
90
  when Vector; GSLng.backend::gsl_vector_add(self.ptr, other.ptr)
86
91
  else
87
- x,y = other.coerce(self)
88
- x.add!(y)
89
- end
90
- return self
92
+ x,y = other.coerce(self)
93
+ x.add!(y)
94
+ end
95
+ return self
91
96
  end
92
97
 
93
98
  # Substract (element-by-element) other from self
99
+ # @return [Vector] self
94
100
  def substract!(other)
95
101
  case other
96
102
  when Numeric; GSLng.backend::gsl_vector_add_constant(self.ptr, -other.to_f)
97
103
  when Vector; GSLng.backend::gsl_vector_sub(self.ptr, other.ptr)
98
104
  else
99
- x,y = other.coerce(self)
100
- x.sub!(y)
101
- end
102
- return self
105
+ x,y = other.coerce(self)
106
+ x.sub!(y)
107
+ end
108
+ return self
103
109
  end
104
110
  alias_method :sub!, :substract!
105
111
 
106
112
  # Multiply (element-by-element) other with self
113
+ # @return [Vector] self
107
114
  def multiply!(other)
108
115
  case other
109
116
  when Numeric; GSLng.backend::gsl_blas_dscal(other.to_f, self.ptr)
110
117
  when Vector; GSLng.backend::gsl_vector_mul(self.ptr, other.ptr)
111
118
  else
112
- x,y = other.coerce(self)
113
- x.mul!(y)
114
- end
115
- return self
119
+ x,y = other.coerce(self)
120
+ x.mul!(y)
121
+ end
122
+ return self
116
123
  end
117
124
  alias_method :mul!, :multiply!
118
125
 
119
126
  # Divide (element-by-element) self by other
127
+ # @return [Vector] self
120
128
  def divide!(other)
121
129
  case other
122
130
  when Numeric; GSLng.backend::gsl_blas_dscal(1.0 / other, self.ptr)
123
131
  when Vector; GSLng.backend::gsl_vector_div(self.ptr, other.ptr)
124
132
  else
125
- x,y = other.coerce(self)
126
- x.div!(y)
127
- end
128
- return self
133
+ x,y = other.coerce(self)
134
+ x.div!(y)
135
+ end
136
+ return self
129
137
  end
130
138
  alias_method :div!, :divide!
131
139
 
@@ -136,14 +144,17 @@ module GSLng
136
144
  def -(other); self.dup.sub!(other) end
137
145
 
138
146
  # Element-by-element product
147
+ # @example
148
+ # Vector[1,2,3] * 2 => [2.0, 4.0, 6.0]:Vector
149
+ # Vector[1,2,3] * Vector[0,1,2] => [0.0, 2.0, 6.0]:Vector
139
150
  def *(other)
140
151
  case other
141
152
  when Numeric; self.dup.mul!(other)
142
153
  when Vector; self.dup.mul!(other)
143
154
  else
144
- x,y = other.coerce(self)
145
- x * y
146
- end
155
+ x,y = other.coerce(self)
156
+ x * y
157
+ end
147
158
  end
148
159
 
149
160
  # Element-by-element division
@@ -155,6 +166,9 @@ module GSLng
155
166
  #--------------------- other math -------------------------#
156
167
 
157
168
  # Dot product between self and other (uses BLAS's ddot)
169
+ # @return [Float]
170
+ # @example
171
+ # Vector[1,2,3] ^ Vector[0,1,2] => 8.0
158
172
  def dot(other)
159
173
  out = FFI::Buffer.new(:double)
160
174
  GSLng.backend::gsl_blas_ddot(self.ptr, other.ptr, out)
@@ -180,29 +194,54 @@ module GSLng
180
194
  # Swap the i-th element with the j-th element
181
195
  def swap(i,j); GSLng.backend::gsl_vector_swap_elements(self.ptr, i, j); return self end
182
196
 
183
- def sort!; GSLng.backend::gsl_sort_vector(self.ptr); return self end
184
- def sort; self.dup.sort! end
197
+ def sort!; GSLng.backend::gsl_sort_vector(self.ptr); return self end
198
+ def sort; self.dup.sort! end
185
199
 
186
200
  # Copy other's values into self
187
201
  def copy(other); GSLng.backend::gsl_vector_memcpy(self.ptr, other.ptr); return self end
188
202
 
203
+ # Wraps self into the interval [min,max) by adding or substracting (max-min) to each component as necessary.
204
+ # Note that wrapping is done only with a single addition/substraction.
205
+ # @param [Vector,Numeric] min
206
+ # @param [Vector,Numeric] max
207
+ # @return [Vector] a vector of values -1, 1 or 0, if (max-min) was substracted, added to the coordinate,
208
+ # or not modified, respectively.
209
+ # @example Assuming that +v = Vector[-8,2,8]+
210
+ # v.wrap(0, 5) => [1.0 0.0 -1.0]:Vector
211
+ # v => [-3.0 2.0 3.0]:Vector
212
+ def wrap!(min, max)
213
+ min,other = self.coerce(min)
214
+ max,other = self.coerce(max)
215
+ delta = Vector.new(self.size)
216
+ range = max - min
217
+
218
+ self.map_index! do |i|
219
+ if (self[i] < min[i]) then delta[i] = 1; self[i] + range[i]
220
+ elsif (self[i] >= max[i]) then delta[i] = -1; self[i] - range[i]
221
+ else delta[i] = 0; self[i] end
222
+ end
223
+ return delta
224
+ end
225
+
189
226
  #--------------------- set/get -------------------------#
190
227
 
191
- # Access the i-th element (*NOTE*: throws exception if out-of-bounds).
192
- # If _index_ is negative, it counts from the end (-1 is the last element).
193
- # TODO: support ranges
228
+ # Access the i-th element.
229
+ # If _index_ is negative, it counts from the end (-1 is the last element).
230
+ # @raise [RuntimeError] if out-of-bounds
231
+ # @todo support ranges
194
232
  def [](index)
195
- GSLng.backend::gsl_vector_get(self.ptr, (index < 0 ? @size + index : index))
233
+ GSLng.backend::gsl_vector_get(self.ptr, (index < 0 ? @size + index : index))
196
234
  end
197
235
 
198
- # Set the i-th element (*NOTE*: throws exception if out-of-bounds).
199
- # If _index_ is negative, it counts from the end (-1 is the last element).
200
- # TODO: support ranges
236
+ # Set the i-th element.
237
+ # If _index_ is negative, it counts from the end (-1 is the last element).
238
+ # @raise [RuntimeError] if out-of-bounds
239
+ # @todo support ranges
201
240
  def []=(index, value)
202
- GSLng.backend::gsl_vector_set(self.ptr, (index < 0 ? @size + index : index), value.to_f)
241
+ GSLng.backend::gsl_vector_set(self.ptr, (index < 0 ? @size + index : index), value.to_f)
203
242
  end
204
243
 
205
- # Create a Vector::View from this Vector.
244
+ # Create a {Vector::View} from this Vector.
206
245
  # If _size_ is nil, it is computed automatically from _offset_ and _stride_
207
246
  def view(offset = 0, size = nil, stride = 1)
208
247
  if (stride <= 0) then raise 'stride must be positive' end
@@ -223,15 +262,24 @@ module GSLng
223
262
  def subvector(*args); subvector_view(*args).to_vector end
224
263
 
225
264
  #------------ utility methods for 2D,3D and 4D vectors -----------#
265
+
266
+ # Same as Vector#[0]
226
267
  def x; GSLng.backend::gsl_vector_get(self.ptr, 0) end
268
+ # Same as Vector#[1]
227
269
  def y; GSLng.backend::gsl_vector_get(self.ptr, 1) end
228
- def z; GSLng.backend::gsl_vector_get(self.ptr, 2) end
229
- def w; GSLng.backend::gsl_vector_get(self.ptr, 3) end
270
+ # Same as Vector#[2]
271
+ def z; GSLng.backend::gsl_vector_get(self.ptr, 2) end
272
+ # Same as Vector#[3]
273
+ def w; GSLng.backend::gsl_vector_get(self.ptr, 3) end
230
274
 
275
+ # Same as Vector#[0]=
231
276
  def x=(v); GSLng.backend::gsl_vector_set(self.ptr, 0, v.to_f) end
277
+ # Same as Vector#[1]=
232
278
  def y=(v); GSLng.backend::gsl_vector_set(self.ptr, 1, v.to_f) end
279
+ # Same as Vector#[2]=
233
280
  def z=(v); GSLng.backend::gsl_vector_set(self.ptr, 2, v.to_f) end
234
- def w=(v); GSLng.backend::gsl_vector_set(self.ptr, 3, v.to_f) end
281
+ # Same as Vector#[3]=
282
+ def w=(v); GSLng.backend::gsl_vector_set(self.ptr, 3, v.to_f) end
235
283
 
236
284
  #--------------------- predicate methods -------------------------#
237
285
 
@@ -243,10 +291,22 @@ module GSLng
243
291
 
244
292
  #if all elements are strictly negative (<0)
245
293
  def negative?; GSLng.backend::gsl_vector_isneg(self.ptr) == 1 ? true : false end
246
-
294
+
247
295
  # if all elements are non-negative (>=0)
248
296
  def nonnegative?; GSLng.backend::gsl_vector_isnonneg(self.ptr) == 1 ? true : false end
249
297
 
298
+ # If each element of self is less than other's elements
299
+ def <(other); (other - self).positive? end
300
+
301
+ # If each element of self is greater than other's elements
302
+ def >(other); (other - self).negative? end
303
+
304
+ # If each element of self is less-or-equal than other's elements
305
+ def <=(other); (other - self).nonnegative? end
306
+
307
+ # If each element of self is less-or-equal than other's elements
308
+ def >=(other); (self - other).nonnegative? end
309
+
250
310
  #--------------------- min/max -------------------------#
251
311
 
252
312
  # Return maximum element of vector
@@ -255,7 +315,7 @@ module GSLng
255
315
  # Return minimum element of vector
256
316
  def min; GSLng.backend::gsl_vector_min(self.ptr) end
257
317
 
258
- # Same as Array#minmax
318
+ # Same as {Array#minmax}
259
319
  def minmax
260
320
  min = FFI::Buffer.new(:double)
261
321
  max = FFI::Buffer.new(:double)
@@ -263,87 +323,97 @@ module GSLng
263
323
  return [min[0].get_float64(0),max[0].get_float64(0)]
264
324
  end
265
325
 
266
- # Same as #minmax, but returns the indices to the elements
326
+ # Same as {#minmax}, but returns the indices to the elements
267
327
  def minmax_index
268
328
  min = FFI::Buffer.new(:size_t)
269
329
  max = FFI::Buffer.new(:size_t)
270
330
  GSLng.backend::gsl_vector_minmax_index(self.ptr, min, max)
271
331
  #return [min[0].get_size_t(0),max[0].get_size_t(0)]
272
- return [min[0].get_ulong(0),max[0].get_ulong(0)]
332
+ return [min[0].get_ulong(0),max[0].get_ulong(0)]
273
333
  end
274
334
 
275
- # Same as #min, but returns the index to the element
335
+ # Same as {#min}, but returns the index to the element
276
336
  def min_index; GSLng.backend::gsl_vector_min_index(self.ptr) end
277
337
 
278
- # Same as #max, but returns the index to the element
338
+ # Same as {#max}, but returns the index to the element
279
339
  def max_index; GSLng.backend::gsl_vector_max_index(self.ptr) end
280
340
 
281
341
  #--------------------- block handling -------------------------#
282
-
283
- # Yields the block for each element in the Vector
284
- def each # :yield: obj
285
- @size.times {|i| yield(self[i])}
286
- end
287
-
288
- # Same as #each, but faster. The catch is that this method returns nothing.
289
- def fast_each(block = Proc.new) #:yield: obj
290
- GSLng.backend::gsl_vector_each(self.ptr, block)
342
+
343
+ # Same as {#each}, but faster. The catch is that this method returns nothing.
344
+ # @yield [elem]
345
+ def each(block = Proc.new)
346
+ GSLng.backend::gsl_vector_each(self.ptr.to_i, &block)
291
347
  end
292
348
 
293
- def fast_each_with_index(block = Proc.new) #:yield: obj,i
294
- GSLng.backend::gsl_vector_each_with_index(self.ptr, block)
349
+ # @see #each
350
+ # @yield [elem,i]
351
+ def each_with_index(block = Proc.new)
352
+ GSLng.backend::gsl_vector_each_with_index(self.ptr.to_i, &block)
295
353
  end
296
354
 
297
- # Efficient map! implementation
298
- def map!(block = Proc.new); GSLng.backend::gsl_vector_map(self.ptr, block); return self end
355
+ # Efficient {#map!} implementation.
356
+ def map!(block = Proc.new); GSLng.backend::gsl_vector_map!(self.ptr.to_i, &block); return self end
299
357
 
300
- # Alternate version of #map!, in this case the block receives the index as a parameter.
301
- def map_index!(block = Proc.new); GSLng.backend::gsl_vector_map_index(self.ptr, block); return self end
358
+ # Similar to {#map!}, but passes the index to the element instead.
359
+ # @yield [i]
360
+ def map_index!(block = Proc.new); GSLng.backend::gsl_vector_map_index!(self.ptr.to_i, &block); return self end
302
361
 
303
- # See #map!. Returns a Vector.
304
- def map(block = Proc.new); self.dup.map!(block) end
362
+ # @return [Vector]
363
+ # @see map_index!
364
+ # @yield [i]
365
+ def map_index(block = Proc.new); self.dup.map_index!(block) end
305
366
 
306
- # Same as #map but returns an Array
307
- def map_array(block = Proc.new) ary = []; self.fast_each {|elem| ary << block.call(elem)}; return ary end
367
+ alias_method :map_array, :map
368
+
369
+ # @return [Vector]
370
+ # @yield [elem]
371
+ def map(block = Proc.new); self.dup.map!(block) end
308
372
 
309
373
  #--------------------- conversions -------------------------#
310
374
 
311
- # Same as Array#join
312
- def join(sep = $,)
313
- s = ''
314
- GSLng.backend::gsl_vector_each(self.ptr, lambda {|e| s += (s.empty?() ? e.to_s : "#{sep}#{e}")})
315
- return s
316
- end
375
+ # @see Array#join
376
+ # @return [String]
377
+ def join(sep = $,)
378
+ s = ''
379
+ self.each do |e|
380
+ s += (s.empty?() ? e.to_s : "#{sep}#{e}")
381
+ end
382
+ return s
383
+ end
317
384
 
318
- # Coerces _other_ to be a Vector. If _other_ is a scalar (a Numeric) a vector of the same size as self
319
- # will be created with all values set to _other_.
320
- def coerce(other)
385
+ # Coerces _other_ to be a Vector.
386
+ # @example
387
+ # Vector[1,2].coerce(5) => [[5.0, 5.0]:Vector, [1.0, 2.0]:Vector]
388
+ def coerce(other)
321
389
  case other
322
- when Vector
323
- [ other, self ]
324
- when Numeric
325
- [ Vector.new(@size).set!(other), self ]
326
- else
327
- raise TypeError, "Can't coerce #{other.class} into #{self.class}"
328
- end
329
- end
330
-
331
- # Convert to String (same format as Array#to_s):
390
+ when Vector
391
+ [ other, self ]
392
+ when Numeric
393
+ [ Vector.new(@size).set!(other), self ]
394
+ else
395
+ raise TypeError, "Can't coerce #{other.class} into #{self.class}"
396
+ end
397
+ end
398
+
399
+ # @return [String] same format as {Array#to_s}
400
+ # @example
332
401
  # Vector[1,2,3].to_s => "[1.0, 2.0, 3.0]"
333
- def to_s
334
- "[" + self.join(', ') + "]"
335
- end
402
+ def to_s
403
+ "[" + self.join(', ') + "]"
404
+ end
336
405
 
337
406
  def inspect # @private
338
407
  "#{self}:Vector"
339
408
  end
340
409
 
341
- # Convert to Array
342
- def to_a
343
- Array.new(@size) {|i| self[i]}
344
- end
410
+ # @return [Array]
411
+ def to_a
412
+ GSLng.backend.gsl_vector_to_a(self.ptr.to_i)
413
+ end
345
414
 
346
415
  # Create a row matrix from this vector
416
+ # @return [Matrix]
347
417
  def to_matrix
348
418
  m = Matrix.new(1, @size)
349
419
  GSLng.backend::gsl_matrix_set_row(m.ptr, 0, self.ptr)
@@ -352,6 +422,7 @@ module GSLng
352
422
  alias_method :to_row, :to_matrix
353
423
 
354
424
  # Create a column matrix from this vector
425
+ # @return [Matrix]
355
426
  def transpose
356
427
  m = Matrix.new(@size, 1)
357
428
  GSLng.backend::gsl_matrix_set_col(m.ptr, 0, self.ptr)
@@ -361,13 +432,13 @@ module GSLng
361
432
 
362
433
  #--------------------- equality -------------------------#
363
434
 
364
- # Element-by-element comparison. Admits comparing to Array.
365
- def ==(other)
366
- if (self.size != other.size) then return false end
367
- self.fast_each_with_index do |elem,i|
368
- if (elem != other[i]) then return false end
369
- end
370
- return true
371
- end
435
+ # Element-by-element comparison. Admits comparing to Array.
436
+ def ==(other)
437
+ if (self.size != other.size) then return false end
438
+ self.each_with_index do |elem,i|
439
+ if (elem != other[i]) then return false end
440
+ end
441
+ return true
442
+ end
372
443
  end
373
444
  end