ruby-gsl-ng 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ module GSLng
2
+ backend.instance_eval do
3
+ # memory handling
4
+ attach_function :gsl_rng_alloc, [ :pointer ], :pointer
5
+ attach_function :gsl_rng_free, [ :pointer ], :void
6
+
7
+ # RNG types
8
+ algorithms = %w(mt19937 ranlxs0 ranlxs1 ranlxs2 ranlxd1 ranlxd2 ranlux ranlux389 cmrg mrg taus taus2 gfsr4)
9
+ algorithms.each do |alg|
10
+ attach_variable :"gsl_rng_#{alg}", :pointer
11
+ end
12
+
13
+ # Uniform
14
+ attach_function :gsl_ran_flat, [ :pointer, :double, :double ], :double
15
+ attach_function :gsl_ran_flat_pdf, [ :double, :double, :double ], :double
16
+
17
+ # Gaussian
18
+ attach_function :gsl_ran_gaussian, [ :pointer, :double ], :double
19
+ attach_function :gsl_ran_gaussian_ziggurat, [ :pointer, :double ], :double
20
+ attach_function :gsl_ran_gaussian_ratio_method, [ :pointer, :double ], :double
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ module GSLng
2
+ backend.instance_eval do
3
+ # trigonometric
4
+ attach_function :gsl_sf_angle_restrict_symm, [ :double ], :double
5
+ attach_function :gsl_sf_angle_restrict_pos, [ :double ], :double
6
+ end
7
+ end
@@ -1,75 +1,63 @@
1
- module GSLng
2
- backend.instance_eval do
3
- # memory handling
4
- attach_function :gsl_vector_alloc, [ :size_t ], :pointer
5
- attach_function :gsl_vector_calloc, [ :size_t ], :pointer
6
- attach_function :gsl_vector_free, [ :pointer ], :void
7
-
8
- # initializing
9
- attach_function :gsl_vector_set_all, [ :pointer, :double ], :void
10
- attach_function :gsl_vector_set_zero, [ :pointer ], :void
11
- attach_function :gsl_vector_set_basis, [ :pointer, :size_t ], :int
12
-
13
- # operations
14
- attach_function :gsl_vector_add, [ :pointer, :pointer ], :int
15
- attach_function :gsl_vector_sub, [ :pointer, :pointer ], :int
16
- attach_function :gsl_vector_mul, [ :pointer, :pointer ], :int
17
- attach_function :gsl_vector_div, [ :pointer, :pointer ], :int
18
- attach_function :gsl_vector_scale, [ :pointer, :double ], :int
19
- attach_function :gsl_vector_add_constant, [ :pointer, :double ], :int
20
-
21
- # element access
22
- attach_function :gsl_vector_get, [ :pointer, :size_t ], :double
23
- attach_function :gsl_vector_set, [ :pointer, :size_t, :double ], :void
24
-
25
- # properties
26
- attach_function :gsl_vector_isnull, [ :pointer ], :int
27
- attach_function :gsl_vector_ispos, [ :pointer ], :int
28
- attach_function :gsl_vector_isneg, [ :pointer ], :int
29
- attach_function :gsl_vector_isnonneg, [ :pointer ], :int
30
-
31
- # max and min
32
- attach_function :gsl_vector_max, [ :pointer ], :double
33
- attach_function :gsl_vector_min, [ :pointer ], :double
34
- attach_function :gsl_vector_minmax, [ :pointer, :buffer_out, :buffer_out ], :void
35
- attach_function :gsl_vector_max_index, [ :pointer ], :size_t
36
- attach_function :gsl_vector_min_index, [ :pointer ], :size_t
37
- attach_function :gsl_vector_minmax_index, [ :pointer, :buffer_out, :buffer_out ], :void
38
-
39
- # copying
40
- attach_function :gsl_vector_memcpy, [ :pointer, :pointer ], :int
41
-
42
- # exchanging elements
43
- attach_function :gsl_vector_swap_elements, [ :pointer, :size_t, :size_t ], :int
44
- attach_function :gsl_vector_reverse, [ :pointer ], :int
45
-
46
- # BLAS functions
47
- attach_function :gsl_blas_ddot, [ :pointer, :pointer, :buffer_out ], :int
48
- attach_function :gsl_blas_dnrm2, [ :pointer ], :double
49
- attach_function :gsl_blas_dasum, [ :pointer ], :double
50
- #attach_function :gsl_blas_idamax, [ :pointer ], clbas_index??
51
- #attach_function :gsl_blas_dcopy, use this instead of memcpy?
52
- attach_function :gsl_blas_daxpy, [ :double, :pointer, :pointer ], :int
53
- attach_function :gsl_blas_dscal, [ :double, :pointer ], :void
54
-
55
- # views
56
- attach_function :gsl_vector_subvector2, [ :pointer, :size_t, :size_t ], :pointer
57
- attach_function :gsl_vector_subvector_with_stride2, [ :pointer, :size_t, :size_t, :size_t ], :pointer
58
-
59
- # From local extension
60
- callback :gsl_vector_callback, [ :double ], :double
61
- attach_function :gsl_vector_map, [ :pointer, :gsl_vector_callback ], :void
62
-
63
- callback :gsl_vector_index_callback, [ :size_t ], :double
64
- attach_function :gsl_vector_map_index, [ :pointer, :gsl_vector_index_callback ], :void
65
-
66
- callback :gsl_vector_each_callback, [ :double ], :void
67
- attach_function :gsl_vector_each, [ :pointer, :gsl_vector_each_callback ], :void
68
-
69
- callback :gsl_vector_each_with_index_callback, [ :double, :size_t ], :void
70
- attach_function :gsl_vector_each_with_index, [ :pointer, :gsl_vector_each_with_index_callback ], :void
71
-
72
- # Sorting
73
- attach_function :gsl_sort_vector, [ :pointer ], :void
74
- end
75
- end
1
+ module GSLng
2
+ backend.instance_eval do
3
+ # memory handling
4
+ attach_function :gsl_vector_alloc, [ :size_t ], :pointer
5
+ attach_function :gsl_vector_calloc, [ :size_t ], :pointer
6
+ attach_function :gsl_vector_free, [ :pointer ], :void
7
+
8
+ # initializing
9
+ attach_function :gsl_vector_set_all, [ :pointer, :double ], :void
10
+ attach_function :gsl_vector_set_zero, [ :pointer ], :void
11
+ attach_function :gsl_vector_set_basis, [ :pointer, :size_t ], :int
12
+
13
+ # operations
14
+ attach_function :gsl_vector_add, [ :pointer, :pointer ], :int
15
+ attach_function :gsl_vector_sub, [ :pointer, :pointer ], :int
16
+ attach_function :gsl_vector_mul, [ :pointer, :pointer ], :int
17
+ attach_function :gsl_vector_div, [ :pointer, :pointer ], :int
18
+ attach_function :gsl_vector_scale, [ :pointer, :double ], :int
19
+ attach_function :gsl_vector_add_constant, [ :pointer, :double ], :int
20
+
21
+ # element access
22
+ attach_function :gsl_vector_get, [ :pointer, :size_t ], :double
23
+ attach_function :gsl_vector_set, [ :pointer, :size_t, :double ], :void
24
+
25
+ # properties
26
+ attach_function :gsl_vector_isnull, [ :pointer ], :int
27
+ attach_function :gsl_vector_ispos, [ :pointer ], :int
28
+ attach_function :gsl_vector_isneg, [ :pointer ], :int
29
+ attach_function :gsl_vector_isnonneg, [ :pointer ], :int
30
+
31
+ # max and min
32
+ attach_function :gsl_vector_max, [ :pointer ], :double
33
+ attach_function :gsl_vector_min, [ :pointer ], :double
34
+ attach_function :gsl_vector_minmax, [ :pointer, :buffer_out, :buffer_out ], :void
35
+ attach_function :gsl_vector_max_index, [ :pointer ], :size_t
36
+ attach_function :gsl_vector_min_index, [ :pointer ], :size_t
37
+ attach_function :gsl_vector_minmax_index, [ :pointer, :buffer_out, :buffer_out ], :void
38
+
39
+ # copying
40
+ attach_function :gsl_vector_memcpy, [ :pointer, :pointer ], :int
41
+
42
+ # exchanging elements
43
+ attach_function :gsl_vector_swap_elements, [ :pointer, :size_t, :size_t ], :int
44
+ attach_function :gsl_vector_reverse, [ :pointer ], :int
45
+
46
+ # BLAS functions
47
+ attach_function :gsl_blas_ddot, [ :pointer, :pointer, :buffer_out ], :int
48
+ attach_function :gsl_blas_dnrm2, [ :pointer ], :double
49
+ attach_function :gsl_blas_dasum, [ :pointer ], :double
50
+ #attach_function :gsl_blas_idamax, [ :pointer ], clbas_index??
51
+ #attach_function :gsl_blas_dcopy, use this instead of memcpy?
52
+ attach_function :gsl_blas_daxpy, [ :double, :pointer, :pointer ], :int
53
+ attach_function :gsl_blas_dscal, [ :double, :pointer ], :void
54
+
55
+ # Sorting
56
+ attach_function :gsl_sort_vector, [ :pointer ], :void
57
+
58
+ # From local extension
59
+ # views
60
+ attach_function :gsl_vector_subvector2, [ :pointer, :size_t, :size_t ], :pointer
61
+ attach_function :gsl_vector_subvector_with_stride2, [ :pointer, :size_t, :size_t, :size_t ], :pointer
62
+ end
63
+ end
@@ -1,5 +1,9 @@
1
1
  module GSLng
2
- def GSLng.set_finalizer(obj, func, ptr) # @private
3
- ObjectSpace.define_finalizer(obj, lambda {|id| GSLng.backend.send(func, ptr)})
2
+ def GSLng.define_finalizer(obj, func, ptr) # @private
3
+ ObjectSpace.define_finalizer(obj, self.get_finalizer(func, ptr))
4
+ end
5
+
6
+ def GSLng.get_finalizer(func, ptr) # @private
7
+ lambda {|id| GSLng.backend.send(func, ptr)}
4
8
  end
5
9
  end
data/lib/gslng/matrix.rb CHANGED
@@ -2,75 +2,82 @@ module GSLng
2
2
  # A fixed-size MxN matrix.
3
3
  #
4
4
  # =Notes
5
- # See Vector notes. Everything applies with the following differences/additions:
6
- # * The * operator performs actual matrix-matrix and matrix-vector products. To perform element-by-element
7
- # multiplication use the ^ operator (or multiply method) instead. The rest of the operators work element-by-element.
8
- # * Operators can handle matrix-matrix, matrix-vector and matrix-scalar (also in reversed order). See #coerce.
9
- # * The [] and []= operators can handle a "wildcard" value for any dimension, just like MATLAB's colon (:).
5
+ # See Vector notes. Everything applies with the following *differences/additions*:
6
+ # * The {#*} operator performs actual matrix-matrix and matrix-vector products. To perform element-by-element
7
+ # multiplication use the {#^} operator (or {#multiply} method) instead. The rest of the operators work element-by-element.
8
+ # * Operators can handle matrix-matrix, matrix-vector and matrix-scalar (also in reversed order). See {#coerce}.
9
+ # * The {#[]} and {#[]=} operators can handle a "wildcard" value for any dimension, just like MATLAB's colon (:).
10
10
  class Matrix
11
- attr_reader :m, :n, :ptr
11
+ attr_reader :m, :n
12
+ attr_reader :ptr # @private
12
13
 
13
- alias_method :height, :m
14
- alias_method :width, :n
15
- alias_method :rows, :m
16
- alias_method :columns, :n
14
+ alias_method :height, :m
15
+ alias_method :width, :n
16
+ alias_method :rows, :m
17
+ alias_method :columns, :n
17
18
 
18
- # Returns [ #rows, #columns ]
19
- def size; [ @m, @n ] end
19
+ # Shorthand for [{#rows},{#columns}]
20
+ def size; [ @m, @n ] end
20
21
 
21
22
  #--------------------- constructors -------------------------#
22
23
 
23
- # Create a Matrix of m-by-n (rows and columns). If zero is true, the Matrix is initialized with zeros.
24
+ # Create a Matrix of m-by-n (rows and columns). If zero is true, the Matrix is initialized with zeros.
24
25
  # Otherwise, the Matrix will contain garbage.
25
- # You can optionally pass a block, in which case #map_index! will be called with it (i.e.: it works like Array.new).
26
+ # You can optionally pass a block, in which case {#map_index!} will be called with it (i.e.: it works like Array.new).
26
27
  def initialize(m, n, zero = false)
27
28
  @ptr = (zero ? GSLng.backend::gsl_matrix_calloc(m, n) : GSLng.backend::gsl_matrix_alloc(m, n))
28
- GSLng.set_finalizer(self, :gsl_matrix_free, @ptr)
29
+ GSLng.define_finalizer(self, :gsl_matrix_free, @ptr)
29
30
 
30
31
  @m,@n = m,n
31
- if (block_given?) then self.map_index!(Proc.new) end
32
+ if (block_given?) then self.map_index!(Proc.new) end
32
33
  end
33
34
 
34
35
  def initialize_copy(other) # @private
35
36
  ObjectSpace.undefine_finalizer(self) # TODO: ruby bug?
36
37
  @ptr = GSLng.backend::gsl_matrix_alloc(other.m, other.n)
37
- GSLng.set_finalizer(self, :gsl_matrix_free, @ptr)
38
+ GSLng.define_finalizer(self, :gsl_matrix_free, @ptr)
38
39
 
39
40
  @m,@n = other.size
40
41
  GSLng.backend::gsl_matrix_memcpy(@ptr, other.ptr)
41
42
  end
42
43
 
43
- # Same as Matrix.new(m, n, true)
44
- def Matrix.zero(m, n); Matrix.new(m, n, true) end
45
-
46
- # Create a matrix from an Array
47
- # If array is unidimensional, a row Matrix is created. If it is multidimensional, each sub-array
48
- # corresponds to a row of the resulting Matrix. Also, _array_ can be an Array of Ranges, in which case
49
- # each Range will correspond to a row.
50
- def Matrix.from_array(array)
51
- if (array.empty?) then raise "Can't create empty matrix" end
52
-
53
- if (Numeric === array[0]) then
54
- Matrix.new(1, array.size) {|i,j| array[j]}
44
+ # Same as Matrix.new(m, n, true)
45
+ def Matrix.zero(m, n); Matrix.new(m, n, true) end
46
+
47
+ # Create a matrix from an Array
48
+ # @see Matrix::[]
49
+ def Matrix.from_array(array)
50
+ if (array.empty?) then raise "Can't create empty matrix" end
51
+
52
+ if (Numeric === array[0])
53
+ m = Matrix.new(1, array.size)
54
+ GSLng.backend.gsl_matrix_from_array(m.ptr.to_i, [ array ])
55
+ return m
56
+ elsif (Array === array[0])
57
+ m = Matrix.new(array.size, array[0].size)
58
+ GSLng.backend.gsl_matrix_from_array(m.ptr.to_i, array)
59
+ return m
55
60
  else
56
61
  Matrix.new(array.size, array[0].to_a.size) {|i,j| array[i].to_a[j]}
57
62
  end
58
- end
63
+ end
59
64
 
60
- # Create a Matrix from an Array of Arrays/Ranges (see #from_array). For example:
61
- # Matrix[[1,2],[3,4]]
62
- # Matrix[1,2,3]
63
- # Matrix[[1..2],[5..10]]
64
- def Matrix.[](*args)
65
+ # Create a Matrix from an Array/Array of Arrays/Range
66
+ # @example
67
+ # Matrix[[1,2],[3,4]] => [1.0 2.0; 3.0 4.0]:Matrix
68
+ # Matrix[1,2,3] => [1.0 2.0 3.0]:Matrix
69
+ # Matrix[[1..3],[5..7]] => [1.0 2.0 3.0; 5.0 6.0 7.0]:Matrix
70
+ # @see Matrix::from_array
71
+ def Matrix.[](*args)
65
72
  Matrix.from_array(args)
66
- end
73
+ end
67
74
 
68
75
  # Generates a Matrix of m by n, of random numbers between 0 and 1.
69
- # NOTE: This simply uses Kernel::rand
76
+ # NOTE: This simply uses {Kernel::rand}
70
77
  def Matrix.random(m, n)
71
- Matrix.new(m, n).map!{|x| Kernel::rand}
78
+ Matrix.new(m, n).map!{|x| Kernel::rand}
72
79
  end
73
- class << self; alias_method :rand, :random end
80
+ class << self; alias_method :rand, :random end
74
81
 
75
82
  #--------------------- setting values -------------------------#
76
83
 
@@ -87,139 +94,159 @@ module GSLng
87
94
 
88
95
  #--------------------- set/get -------------------------#
89
96
 
90
- # Access the element (i,j), which means (row,column). *NOTE*: throws exception if out-of-bounds.
91
- # If either i or j are :* or :all, it serves as a wildcard for that dimension, returning all rows or columns,
92
- # respectively.
97
+ # Access the element (i,j), which means (row,column).
98
+ # Symbols :* or :all can be used as wildcards for both dimensions.
99
+ # @example If +m = Matrix[[1,2],[3,4]]+
100
+ # m[0,0] => 1.0
101
+ # m[0,:*] => [1.0, 2.0]:Matrix
102
+ # m[:*,0] => [1.0, 3.0]:Matrix
103
+ # m[:*,:*] => [1.0, 2.0; 3.0, 4.0]:Matrix
104
+ # @raise [RuntimeError] if out-of-bounds
105
+ # @return [Numeric,Matrix] the element/sub-matrix
93
106
  def [](i, j = :*)
94
- if (Symbol === i && Symbol === j) then return self
95
- elsif (Symbol === i)
96
- col = Vector.new(@m)
97
- GSLng.backend::gsl_matrix_get_col(col.ptr, @ptr, j)
98
- return col
99
- elsif (Symbol === j)
100
- row = Vector.new(@n)
101
- GSLng.backend::gsl_matrix_get_row(row.ptr, @ptr, i)
102
- return row
103
- else
104
- GSLng.backend::gsl_matrix_get(@ptr, i, j)
105
- end
106
- end
107
-
108
- # Set the element (i,j), which means (row,column). *NOTE*: throws exception if out-of-bounds.
109
- # Same indexing options as #[].
110
- # _value_ can be a single Numeric, a Vector or a Matrix, depending on the indexing.
107
+ if (Symbol === i && Symbol === j) then return self
108
+ elsif (Symbol === i)
109
+ col = Vector.new(@m)
110
+ GSLng.backend::gsl_matrix_get_col(col.ptr, @ptr, j)
111
+ return col.to_matrix
112
+ elsif (Symbol === j)
113
+ row = Vector.new(@n)
114
+ GSLng.backend::gsl_matrix_get_row(row.ptr, @ptr, i)
115
+ return row.to_matrix
116
+ else
117
+ GSLng.backend::gsl_matrix_get(@ptr, i, j)
118
+ end
119
+ end
120
+
121
+ # Set the element (i,j), which means (row,column).
122
+ # @param [Numeric,Vector,Matrix] value depends on indexing
123
+ # @raise [RuntimeError] if out-of-bounds
124
+ # @see #[]
111
125
  def []=(i, j, value)
112
- if (Symbol === i && Symbol === j) then
113
- if (Numeric === value) then self.fill!(value)
126
+ if (Symbol === i && Symbol === j) then
127
+ if (Numeric === value) then self.fill!(value)
114
128
  else
115
129
  x,y = self.coerce(value)
116
130
  GSLng.backend::gsl_matrix_memcpy(@ptr, x.ptr)
117
131
  end
118
- elsif (Symbol === i)
119
- col = Vector.new(@m)
132
+ elsif (Symbol === i)
133
+ col = Vector.new(@m)
120
134
  x,y = col.coerce(value)
121
- GSLng.backend::gsl_matrix_set_col(@ptr, j, x.ptr)
122
- return col
123
- elsif (Symbol === j)
124
- row = Vector.new(@n)
135
+ GSLng.backend::gsl_matrix_set_col(@ptr, j, x.ptr)
136
+ return col
137
+ elsif (Symbol === j)
138
+ row = Vector.new(@n)
125
139
  x,y = row.coerce(value)
126
- GSLng.backend::gsl_matrix_set_row(@ptr, i, x.ptr)
127
- return row
128
- else
129
- GSLng.backend::gsl_matrix_set(@ptr, i, j, value)
130
- end
140
+ GSLng.backend::gsl_matrix_set_row(@ptr, i, x.ptr)
141
+ return row
142
+ else
143
+ GSLng.backend::gsl_matrix_set(@ptr, i, j, value)
144
+ end
131
145
 
132
- return self
133
- end
146
+ return self
147
+ end
134
148
 
135
149
  #--------------------- view -------------------------#
136
150
 
137
- # Create a Matrix::View from this Matrix.
138
- # If either _m_ or _n_ are nil, they're computed from _x_, _y_ and the Matrix's #size
151
+ # Create a {Matrix::View} from this Matrix.
152
+ # If either _m_ or _n_ are nil, they're computed from _x_, _y_ and the Matrix's {#size}
153
+ # @return [Matrix::View]
139
154
  def view(x = 0, y = 0, m = nil, n = nil)
140
155
  View.new(self, x, y, (m or @m - x), (n or @n - y))
141
156
  end
142
157
  alias_method :submatrix_view, :view
143
158
 
144
- # Shorthand for submatrix_view(..).to_matrix.
159
+ # Shorthand for #submatrix_view(..).to_matrix.
160
+ # @return [Matrix]
145
161
  def submatrix(*args); self.submatrix_view(*args).to_matrix end
146
162
 
147
- # Creates a Matrix::View for the i-th column
163
+ # Creates a {Matrix::View} for the i-th column
164
+ # @return [Matrix::View]
148
165
  def column_view(i, offset = 0, size = nil); self.view(offset, i, (size or (@m - offset)), 1) end
149
166
 
150
- # Analogous to #submatrix
167
+ # Analogous to {#submatrix}
168
+ # @return [Matrix]
151
169
  def column(*args); self.column_view(*args).to_matrix end
152
170
 
153
- # Creates a Matrix::View for the i-th row
171
+ # Creates a {Matrix::View} for the i-th row
172
+ # @return [Matrix::View]
154
173
  def row_view(i, offset = 0, size = nil); self.view(i, offset, 1, (size or (@n - offset))) end
155
174
 
156
- # Same as #row_view, but returns a Vector::View
175
+ # Analogous to {#submatrix}
176
+ # @return [Matrix]
177
+ def row(*args); self.row_view(*args).to_matrix end
178
+
179
+ # Same as {#row_view}, but returns a {Vector::View}
180
+ # @return [Vector::View]
157
181
  def row_vecview(i, offset = 0, size = nil)
158
182
  size = (@n - offset) if size.nil?
159
183
  ptr = GSLng.backend.gsl_matrix_row_view(self.ptr, i, offset, size)
160
184
  Vector::View.new(ptr, self, offset, size)
161
185
  end
162
186
 
163
- # Same as #column_view, but returns a Vector::View
187
+ # Same as {#column_view}, but returns a {Vector::View}
188
+ # @return [Vector::View]
164
189
  def column_vecview(i, offset = 0, size = nil)
165
190
  size = (@m - offset) if size.nil?
166
191
  ptr = GSLng.backend.gsl_matrix_column_view(self.ptr, i, offset, size)
167
192
  Vector::View.new(ptr, self, offset, size)
168
193
  end
169
194
 
170
- # Analogous to #submatrix
171
- def row(*args); self.row_view(*args).to_matrix end
172
-
195
+
173
196
  #--------------------- operators -------------------------#
174
197
 
175
198
  # Add other to self
199
+ # @return [Matrix] self
176
200
  def add!(other)
177
201
  case other
178
202
  when Numeric; GSLng.backend::gsl_matrix_add_constant(self.ptr, other.to_f)
179
203
  when Matrix; GSLng.backend::gsl_matrix_add(self.ptr, other.ptr)
180
204
  else
181
- x,y = other.coerce(self)
182
- x.add!(y)
183
- end
184
- return self
205
+ x,y = other.coerce(self)
206
+ x.add!(y)
207
+ end
208
+ return self
185
209
  end
186
210
 
187
211
  # Substract other from self
212
+ # @return [Matrix] self
188
213
  def substract!(other)
189
214
  case other
190
215
  when Numeric; GSLng.backend::gsl_matrix_add_constant(self.ptr, -other.to_f)
191
216
  when Matrix; GSLng.backend::gsl_matrix_sub(self.ptr, other.ptr)
192
217
  else
193
- x,y = other.coerce(self)
194
- x.substract!(y)
195
- end
196
- return self
218
+ x,y = other.coerce(self)
219
+ x.substract!(y)
220
+ end
221
+ return self
197
222
  end
198
223
  alias_method :sub!, :substract!
199
224
 
200
225
  # Multiply (element-by-element) other with self
226
+ # @return [Matrix] self
201
227
  def multiply!(other)
202
228
  case other
203
229
  when Numeric; GSLng.backend::gsl_matrix_scale(self.ptr, other.to_f)
204
230
  when Matrix; GSLng.backend::gsl_matrix_mul_elements(self.ptr, other.ptr)
205
231
  else
206
- x,y = other.coerce(self)
207
- x.multiply!(y)
208
- end
209
- return self
232
+ x,y = other.coerce(self)
233
+ x.multiply!(y)
234
+ end
235
+ return self
210
236
  end
211
237
  alias_method :mul!, :multiply!
212
238
 
213
239
  # Divide (element-by-element) self by other
240
+ # @return [Matrix] self
214
241
  def divide!(other)
215
242
  case other
216
243
  when Numeric; GSLng.backend::gsl_matrix_scale(self.ptr, 1.0 / other)
217
244
  when Matrix; GSLng.backend::gsl_matrix_div_elements(self.ptr, other.ptr)
218
245
  else
219
- x,y = other.coerce(self)
220
- x.divide!(y)
221
- end
222
- return self
246
+ x,y = other.coerce(self)
247
+ x.divide!(y)
248
+ end
249
+ return self
223
250
  end
224
251
  alias_method :div!, :divide!
225
252
 
@@ -237,8 +264,10 @@ module GSLng
237
264
  alias_method :multiply, :^
238
265
  alias_method :mul, :^
239
266
 
240
- # Matrix Product. self#n should equal other#m (or other#size, if a Vector).
241
- # TODO: some cases could be optimized when doing Matrix-Matrix, by using dgemv
267
+ # Matrix Product. self.n should equal other.m (or other.size, if a Vector).
268
+ # @example
269
+ # Matrix[[1,2],[2,3]] * 2 => [2.0 4.0; 4.0 6.0]:Matrix
270
+ # @todo some cases could be optimized when doing Matrix-Matrix, by using dgemv
242
271
  def *(other)
243
272
  case other
244
273
  when Numeric
@@ -265,7 +294,10 @@ module GSLng
265
294
  # Returns the transpose of self, in a new matrix
266
295
  def transpose; matrix = Matrix.new(@n, @m); GSLng.backend::gsl_matrix_transpose_memcpy(matrix.ptr, self.ptr); return matrix end
267
296
 
297
+ # Swap the i-th and j-th columnos
268
298
  def swap_columns(i, j); GSLng.backend::gsl_matrix_swap_columns(self.ptr, i, j); return self end
299
+
300
+ # Swap the i-th and j-th rows
269
301
  def swap_rows(i, j); GSLng.backend::gsl_matrix_swap_rows(self.ptr, i, j); return self end
270
302
 
271
303
  # Swap the i-th row with the j-th column. The Matrix must be square.
@@ -281,7 +313,7 @@ module GSLng
281
313
 
282
314
  #if all elements are strictly negative (<0)
283
315
  def negative?; GSLng.backend::gsl_matrix_isneg(@ptr) == 1 ? true : false end
284
-
316
+
285
317
  # if all elements are non-negative (>=0)
286
318
  def nonnegative?; GSLng.backend::gsl_matrix_isnonneg(@ptr) == 1 ? true : false end
287
319
 
@@ -296,7 +328,7 @@ module GSLng
296
328
  # Minimum element of the Matrix
297
329
  def min; GSLng.backend::gsl_matrix_min(self.ptr) end
298
330
 
299
- # Same as Array#minmax
331
+ # Same as {Array#minmax}
300
332
  def minmax
301
333
  min = FFI::Buffer.new(:double)
302
334
  max = FFI::Buffer.new(:double)
@@ -304,7 +336,7 @@ module GSLng
304
336
  return [min[0].get_float64(0),max[0].get_float64(0)]
305
337
  end
306
338
 
307
- # Same as #minmax, but returns the indices to the i-th and j-th min, and i-th and j-th max.
339
+ # Same as {#minmax}, but returns the indices to the i-th and j-th min, and i-th and j-th max.
308
340
  def minmax_index
309
341
  i_min = FFI::Buffer.new(:size_t)
310
342
  j_min = FFI::Buffer.new(:size_t)
@@ -312,10 +344,10 @@ module GSLng
312
344
  j_max = FFI::Buffer.new(:size_t)
313
345
  GSLng.backend::gsl_matrix_minmax_index(self.ptr, i_min, j_min, i_max, j_max)
314
346
  #return [min[0].get_size_t(0),max[0].get_size_t(0)]
315
- return [i_min[0].get_ulong(0),j_min[0].get_ulong(0),i_max[0].get_ulong(0),j_max[0].get_ulong(0)]
347
+ return [i_min[0].get_ulong(0),j_min[0].get_ulong(0),i_max[0].get_ulong(0),j_max[0].get_ulong(0)]
316
348
  end
317
349
 
318
- # Same as #min, but returns the indices to the i-th and j-th minimum elements
350
+ # Same as {#min}, but returns the indices to the i-th and j-th minimum elements
319
351
  def min_index
320
352
  i_min = FFI::Buffer.new(:size_t)
321
353
  j_min = FFI::Buffer.new(:size_t)
@@ -323,7 +355,7 @@ module GSLng
323
355
  return [i_min[0].get_ulong(0), j_min[0].get_ulong(0)]
324
356
  end
325
357
 
326
- # Same as #max, but returns the indices to the i-th and j-th maximum elements
358
+ # Same as {#max}, but returns the indices to the i-th and j-th maximum elements
327
359
  def max_index
328
360
  i_max = FFI::Buffer.new(:size_t)
329
361
  j_max = FFI::Buffer.new(:size_t)
@@ -334,54 +366,80 @@ module GSLng
334
366
  #--------------------- block handling -------------------------#
335
367
 
336
368
  # Yields the specified block for each element going row-by-row
337
- def each # :yields: elem
369
+ # @yield [elem]
370
+ def each
338
371
  @m.times {|i| @n.times {|j| yield(self[i,j]) } }
339
372
  end
340
373
 
341
374
  # Yields the specified block for each element going row-by-row
342
- def each_with_index # :yields: elem, i, j
375
+ # @yield [elem, i, j]
376
+ def each_with_index
343
377
  @m.times {|i| @n.times {|j| yield(self[i,j], i, j) } }
344
378
  end
345
379
 
346
- # Same as #each, but faster. The catch is that this method returns nothing.
347
- def fast_each(block = Proc.new) #:yield: elem
348
- GSLng.backend::gsl_matrix_each(self.ptr, block)
380
+ # Calls the block on each element of the matrix
381
+ # @yield [elem]
382
+ # @return [void]
383
+ def each(block = Proc.new)
384
+ GSLng.backend::gsl_matrix_each(self.ptr.to_i, &block)
349
385
  end
350
-
351
- # Yields the block for each row *view* (Matrix::View).
386
+
387
+ # @see #each
388
+ # @yield [elem,i,j]
389
+ def each_with_index(block = Proc.new)
390
+ GSLng.backend::gsl_matrix_each_with_index(self.ptr.to_i, &block)
391
+ end
392
+
393
+ # Yields the block for each row *view* ({Matrix::View}).
394
+ # @yield [view]
352
395
  def each_row; self.rows.times {|i| yield(row_view(i))} end
353
396
 
354
- # Same as #each_row, but yields Vector::View's
397
+ # Same as {#each_row}, but yields {Vector::View}'s
398
+ # @yield [vector_view]
355
399
  def each_vec_row; self.rows.times {|i| yield(row_vecview(i))} end
356
400
 
357
- # Same as #each_column, but yields Vector::View's
401
+ # Same as #each_column, but yields {Vector::View}'s
402
+ # @yield [vector_view]
358
403
  def each_vec_column; self.columns.times {|i| yield(column_vecview(i))} end
359
404
 
360
- # Yields the block for each column *view* (Matrix::View).
405
+ # Yields the block for each column *view* ({Matrix::View}).
406
+ # @yield [view]
361
407
  def each_column; self.columns.times {|i| yield(column_view(i))} end
362
408
 
363
- # Efficient map! implementation
364
- def map!(block = Proc.new); GSLng.backend::gsl_matrix_map(@ptr, block); return self end
409
+ # Efficient {#map!} implementation
410
+ # @yield [elem]
411
+ def map!(block = Proc.new); GSLng.backend::gsl_matrix_map!(@ptr.to_i, &block); return self end
412
+
413
+ # Alternate version of {#map!}, in this case the block receives the index (row, column) as a parameter.
414
+ # @yield [i,j]
415
+ def map_index!(block = Proc.new); GSLng.backend::gsl_matrix_map_index!(@ptr.to_i, &block); return self end
365
416
 
366
- # Alternate version of #map!, in this case the block receives the index as a parameter.
367
- def map_index!(block = Proc.new); GSLng.backend::gsl_matrix_map_index(@ptr, block); return self end
417
+ # Similar to {#map_index!}, in this case it receives both the element and the index to it
418
+ # @yield [elem,i,j]
419
+ def map_with_index!(block = Proc.new); GSLng.backend::gsl_matrix_map_with_index!(@ptr.to_i, &block); return self end
368
420
 
369
- # See #map!. Returns a Matrix.
370
- def map(block = Proc.new); self.dup.map!(block) end
421
+ # @see #map!
422
+ # @return [Matrix]
423
+ # @yield [elem]
424
+ def map(block = Proc.new); self.dup.map!(block) end
371
425
 
372
426
  #--------------------- conversions -------------------------#
373
427
 
374
- # Same as Array#join, for example:
428
+ # Same as {Array#join}
429
+ # @example
375
430
  # Matrix[[1,2],[2,3]].join => "1.0 2.0 2.0 3.0"
376
431
  def join(sep = $,)
377
- s = ''
378
- GSLng.backend::gsl_matrix_each(@ptr, lambda {|e| s += (s.empty?() ? e.to_s : "#{sep}#{e}")})
379
- return s
380
- end
432
+ s = ''
433
+ self.each do |e|
434
+ s += (s.empty?() ? e.to_s : "#{sep}#{e}")
435
+ end
436
+ return s
437
+ end
381
438
 
382
- # Converts the matrix to a String, separating each element with a space and each row with a ';' and a newline:
439
+ # Converts the matrix to a String, separating each element with a space and each row with a ';' and a newline.
440
+ # @example
383
441
  # Matrix[[1,2],[2,3]] => "[1.0 2.0;\n 2.0 3.0]"
384
- def to_s
442
+ def to_s
385
443
  s = '['
386
444
  @m.times do |i|
387
445
  s += ' ' unless i == 0
@@ -392,7 +450,14 @@ module GSLng
392
450
  end
393
451
 
394
452
  return s
395
- end
453
+ end
454
+
455
+ # Converts the matrix to an Array (of Arrays).
456
+ # @example
457
+ # Matrix[[1,2],[2,3]] => [[1.0,2.0],[2.0,3.0]]
458
+ def to_a
459
+ GSLng.backend.gsl_matrix_to_a(self.ptr.to_i)
460
+ end
396
461
 
397
462
  def inspect # @private
398
463
  "#{self}:Matrix"
@@ -400,7 +465,7 @@ module GSLng
400
465
 
401
466
  # Coerces _other_ to be of Matrix class.
402
467
  # If _other_ is a scalar (Numeric) a Matrix filled with _other_ values is created.
403
- # Vectors are coerced using Vector#to_matrix (which results in a row matrix).
468
+ # Vectors are coerced using {Vector#to_matrix} (which results in a row matrix).
404
469
  def coerce(other)
405
470
  case other
406
471
  when Matrix