nmatrix 0.0.3 → 0.0.4

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.
Files changed (63) hide show
  1. data/.gitignore +3 -0
  2. data/CONTRIBUTING.md +66 -0
  3. data/Gemfile +1 -1
  4. data/History.txt +68 -10
  5. data/LICENSE.txt +2 -2
  6. data/Manifest.txt +2 -0
  7. data/README.rdoc +90 -69
  8. data/Rakefile +18 -9
  9. data/ext/nmatrix/data/complex.h +7 -7
  10. data/ext/nmatrix/data/data.cpp +2 -7
  11. data/ext/nmatrix/data/data.h +7 -4
  12. data/ext/nmatrix/data/rational.h +2 -2
  13. data/ext/nmatrix/data/ruby_object.h +3 -10
  14. data/ext/nmatrix/extconf.rb +79 -54
  15. data/ext/nmatrix/new_extconf.rb +11 -12
  16. data/ext/nmatrix/nmatrix.cpp +94 -125
  17. data/ext/nmatrix/nmatrix.h +38 -17
  18. data/ext/nmatrix/ruby_constants.cpp +2 -15
  19. data/ext/nmatrix/ruby_constants.h +2 -14
  20. data/ext/nmatrix/storage/common.cpp +2 -2
  21. data/ext/nmatrix/storage/common.h +2 -2
  22. data/ext/nmatrix/storage/dense.cpp +206 -31
  23. data/ext/nmatrix/storage/dense.h +5 -2
  24. data/ext/nmatrix/storage/list.cpp +52 -4
  25. data/ext/nmatrix/storage/list.h +3 -2
  26. data/ext/nmatrix/storage/storage.cpp +6 -6
  27. data/ext/nmatrix/storage/storage.h +2 -2
  28. data/ext/nmatrix/storage/yale.cpp +202 -49
  29. data/ext/nmatrix/storage/yale.h +5 -4
  30. data/ext/nmatrix/ttable_helper.rb +108 -108
  31. data/ext/nmatrix/types.h +2 -15
  32. data/ext/nmatrix/util/io.cpp +2 -2
  33. data/ext/nmatrix/util/io.h +2 -2
  34. data/ext/nmatrix/util/lapack.h +2 -2
  35. data/ext/nmatrix/util/math.cpp +14 -14
  36. data/ext/nmatrix/util/math.h +2 -2
  37. data/ext/nmatrix/util/sl_list.cpp +2 -2
  38. data/ext/nmatrix/util/sl_list.h +2 -2
  39. data/ext/nmatrix/util/util.h +2 -2
  40. data/lib/nmatrix.rb +13 -35
  41. data/lib/nmatrix/blas.rb +182 -56
  42. data/lib/nmatrix/io/market.rb +38 -14
  43. data/lib/nmatrix/io/mat5_reader.rb +393 -278
  44. data/lib/nmatrix/io/mat_reader.rb +121 -107
  45. data/lib/nmatrix/lapack.rb +59 -14
  46. data/lib/nmatrix/monkeys.rb +32 -30
  47. data/lib/nmatrix/nmatrix.rb +204 -100
  48. data/lib/nmatrix/nvector.rb +166 -57
  49. data/lib/nmatrix/shortcuts.rb +364 -231
  50. data/lib/nmatrix/version.rb +8 -4
  51. data/nmatrix.gemspec +5 -3
  52. data/scripts/mac-brew-gcc.sh +1 -1
  53. data/spec/blas_spec.rb +80 -2
  54. data/spec/math_spec.rb +78 -32
  55. data/spec/nmatrix_list_spec.rb +55 -55
  56. data/spec/nmatrix_spec.rb +60 -117
  57. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  58. data/spec/nmatrix_yale_spec.rb +214 -198
  59. data/spec/nvector_spec.rb +58 -2
  60. data/spec/shortcuts_spec.rb +156 -32
  61. data/spec/slice_spec.rb +229 -178
  62. data/spec/spec_helper.rb +2 -2
  63. metadata +71 -21
@@ -1,3 +1,4 @@
1
+ #--
1
2
  # = NMatrix
2
3
  #
3
4
  # A linear algebra library for scientific computation in Ruby.
@@ -8,8 +9,8 @@
8
9
  #
9
10
  # == Copyright Information
10
11
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2013, Ruby Science Foundation
13
14
  #
14
15
  # Please see LICENSE.txt for additional copyright notices.
15
16
  #
@@ -23,30 +24,43 @@
23
24
  # == shortcuts.rb
24
25
  #
25
26
  # These are shortcuts for NMatrix and NVector creation, contributed by Daniel
26
- # Carrera (dcarrera@hush.com) and Carlos Agarie (carlos@onox.com.br).
27
+ # Carrera (dcarrera@hush.com) and Carlos Agarie (carlos.agarie@gmail.com).
28
+ #
29
+ # TODO Make all the shortcuts available through modules, allowing someone
30
+ # to include them to make "MATLAB-like" scripts.
31
+ #
32
+ # There are some questions to be answered before this can be done, tho.
33
+ #++
27
34
 
28
35
  class NMatrix
29
36
 
30
37
  class << self
31
- # zeros() or zeroes()
32
38
  #
33
- # Creates a new matrix of zeros with the dimensions supplied as
34
- # parameters. Optional parameters include:
39
+ # call-seq:
40
+ # zeros(size) -> NMatrix
41
+ # zeros(size, dtype) -> NMatrix
42
+ # zeros(stype, size, dtype) -> NMatrix
35
43
  #
36
- # * A storage type as the first parameter (default is :dense).
37
- # * A dtype as the last parameter (default is :float64).
44
+ # Creates a new matrix of zeros with the dimensions supplied as
45
+ # parameters.
46
+ #
47
+ # * *Arguments* :
48
+ # - +stype+ -> (optional) Default is +:dense+.
49
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
50
+ # - +dtype+ -> (optional) Default is +:float64+
51
+ # * *Returns* :
52
+ # - NMatrix filled with zeros.
38
53
  #
39
54
  # Examples:
40
55
  #
41
- # zeros(2) # => 0.0 0.0
42
- # 0.0 0.0
56
+ # NMatrix.zeros(2) # => 0.0 0.0
57
+ # 0.0 0.0
43
58
  #
44
- # zeros([2, 3], :int32) # => 0 0 0
45
- # 0 0 0
59
+ # NMatrix.zeros([2, 3], :int32) # => 0 0 0
60
+ # 0 0 0
46
61
  #
47
- # zeros(:list, [1, 5], :int32) # => 0 0 0 0 0
62
+ # NMatrix.zeros(:list, [1, 5], :int32) # => 0 0 0 0 0
48
63
  #
49
-
50
64
  def zeros(*params)
51
65
  dtype = params.last.is_a?(Symbol) ? params.pop : :float64
52
66
  stype = params.first.is_a?(Symbol) ? params.shift : :dense
@@ -54,23 +68,28 @@ class NMatrix
54
68
 
55
69
  NMatrix.new(stype, dim, 0, dtype)
56
70
  end
57
-
58
71
  alias :zeroes :zeros
59
72
 
60
- # ones()
61
73
  #
62
- # Creates a :dense matrix of ones with the dimensions supplied
63
- # as parameters. Optionaly, one can specify a dtype as the last
64
- # parameter (default is :float64).
74
+ # call-seq:
75
+ # ones(size) -> NMatrix
76
+ # ones(size, dtype) -> NMatrix
77
+ #
78
+ # Creates a matrix filled with ones.
79
+ #
80
+ # * *Arguments* :
81
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
82
+ # - +dtype+ -> (optional) Default is +:float64+
83
+ # * *Returns* :
84
+ # - NMatrix filled with ones.
65
85
  #
66
86
  # Examples:
67
87
  #
68
- # ones([1, 3]) # => 1.0 1.0 1.0
88
+ # NMatrix.ones([1, 3]) # => 1.0 1.0 1.0
69
89
  #
70
- # ones([2, 3], :int32) # => 1 1 1
71
- # 1 1 1
90
+ # NMatrix.ones([2, 3], :int32) # => 1 1 1
91
+ # 1 1 1
72
92
  #
73
-
74
93
  def ones(*params)
75
94
  dtype = params.last.is_a?(Symbol) ? params.pop : :float64
76
95
  dim = params.first
@@ -78,351 +97,467 @@ class NMatrix
78
97
  NMatrix.new(dim, 1, dtype)
79
98
  end
80
99
 
81
- # identity() or eye()
82
100
  #
83
- # Creates an identity matrix (square matrix rank 2) of the size
84
- # supplied as a parameter. Optional parameters include:
101
+ # call-seq:
102
+ # eye(size) -> NMatrix
103
+ # eye(size, dtype) -> NMatrix
104
+ # eye(stype, size, dtype) -> NMatrix
85
105
  #
86
- # * A storage type as the first parameter (default is :dense).
87
- # * A dtype as the last parameter (default is :float64).
106
+ # Creates an identity matrix (square matrix rank 2).
107
+ #
108
+ # * *Arguments* :
109
+ # - +stype+ -> (optional) Default is +:dense+.
110
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
111
+ # - +dtype+ -> (optional) Default is +:float64+
112
+ # * *Returns* :
113
+ # - NMatrix filled with zeros.
88
114
  #
89
115
  # Examples:
90
116
  #
91
- # eye(3) # => 1.0 0.0 0.0
92
- # 0.0 1.0 0.0
93
- # 0.0 0.0 1.0
117
+ # NMatrix.eye(3) # => 1.0 0.0 0.0
118
+ # 0.0 1.0 0.0
119
+ # 0.0 0.0 1.0
94
120
  #
95
- # eye(3, :int32) # => 1 0 0
96
- # 0 1 0
97
- # 0 0 1
121
+ # NMatrix.eye(3, :int32) # => 1 0 0
122
+ # 0 1 0
123
+ # 0 0 1
98
124
  #
99
- # eye(:yale, 2, :int32) # => 1 0
100
- # 0 1
125
+ # NMatrix.eye(:yale, 2, :int32) # => 1 0
126
+ # 0 1
101
127
  #
102
-
103
128
  def eye(*params)
104
129
  dtype = params.last.is_a?(Symbol) ? params.pop : :float64
105
130
  stype = params.first.is_a?(Symbol) ? params.shift : :dense
106
131
 
107
132
  dim = params.first
108
-
133
+
109
134
  # Fill the diagonal with 1's.
110
135
  m = NMatrix.zeros(stype, dim, dtype)
111
- (0 .. (dim - 1)).each do |i|
136
+ (0 .. (dim - 1)).each do |i|
112
137
  m[i, i] = 1
113
138
  end
114
-
139
+
115
140
  m
116
141
  end
117
-
118
142
  alias :identity :eye
119
-
120
- # random()
143
+
144
+ #
145
+ # call-seq:
146
+ # random(size) -> NMatrix
121
147
  #
122
- # Creates a :dense NMatrix with random numbers between 0 and 1 generated
123
- # by Random::rand. The parameter is the dimension of the matrix.
148
+ # Creates a +:dense+ NMatrix with random numbers between 0 and 1 generated
149
+ # by +Random::rand+. The parameter is the dimension of the matrix.
150
+ #
151
+ # * *Arguments* :
152
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
153
+ # * *Returns* :
154
+ # - NMatrix filled with zeros.
124
155
  #
125
156
  # Examples:
126
157
  #
127
- # rand([2, 2]) # => 0.4859439730644226 0.1783195585012436
128
- # 0.23193766176700592 0.4503345191478729
158
+ # NMatrix.random([2, 2]) # => 0.4859439730644226 0.1783195585012436
159
+ # 0.23193766176700592 0.4503345191478729
129
160
  #
130
-
131
- def random(*params)
132
- dim = params.first
161
+ def random(size)
133
162
  rng = Random.new
134
163
 
135
- # Must provide the dimension as an Integer for a square matrix or as an
136
- # array, e.g. [2, 4, 7].
137
- unless dim.is_a?(Integer) || dim.is_a?(Array)
138
- raise ArgumentError, "random() accepts only integers or arrays as \
139
- dimension."
140
- end
141
-
142
164
  random_values = []
143
-
165
+
144
166
  # Construct the values of the final matrix based on the dimension.
145
- if dim.is_a?(Integer)
146
- (dim * dim - 1).times { |i| random_values << rng.rand }
167
+ if size.is_a?(Integer)
168
+ (size * size - 1).times { |i| random_values << rng.rand }
147
169
  else
148
170
  # Dimensions given by an array. Get the product of the array elements
149
171
  # and generate this number of random values.
150
- dim.reduce(1, :*).times { |i| random_values << rng.rand }
172
+ size.reduce(1, :*).times { |i| random_values << rng.rand }
151
173
  end
152
174
 
153
- NMatrix.new(:dense, dim, random_values, :float64)
175
+ NMatrix.new(:dense, size, random_values, :float64)
154
176
  end
155
177
 
156
- # seq()
157
178
  #
158
- # Creates a :dense NMatrix with a sequence of integers starting at
159
- # zero until the matrix is filled. The parameters to the method
160
- # are the dimensions of the matrix. Optionaly, one can specify a
161
- # dtype as the last parameter (default is :float64).
179
+ # call-seq:
180
+ # seq(size) -> NMatrix
181
+ # seq(size, dtype) -> NMatrix
182
+ #
183
+ # Creates a matrix filled with a sequence of integers starting at zero.
184
+ #
185
+ # * *Arguments* :
186
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
187
+ # - +dtype+ -> (optional) Default is +:float64+
188
+ # * *Returns* :
189
+ # - NMatrix filled with zeros.
162
190
  #
163
191
  # Examples:
164
192
  #
165
- # seq(2) # => 0 1
193
+ # NMatrix.seq(2) # => 0 1
166
194
  # 2 3
167
195
  #
168
- # seq([3, 3], :float32) # => 0.0 1.0 2.0
169
- # 3.0 4.0 5.0
170
- # 6.0 7.0 8.0
196
+ # NMatrix.seq([3, 3], :float32) # => 0.0 1.0 2.0
197
+ # 3.0 4.0 5.0
198
+ # 6.0 7.0 8.0
171
199
  #
172
-
173
200
  def seq(*params)
174
201
  dtype = params.last.is_a?(Symbol) ? params.pop : nil
175
- dim = params.first
176
-
202
+ size = params.first
203
+
177
204
  # Must provide the dimension as an Integer for a square matrix or as an
178
205
  # 2 element array, e.g. [2,4].
179
- unless dim.is_a?(Integer) || (dim.is_a?(Array) && dim.size < 3)
206
+ unless size.is_a?(Integer) || (size.is_a?(Array) && size.size < 3)
180
207
  raise ArgumentError, "seq() accepts only integers or 2-element arrays \
181
208
  as dimension."
182
209
  end
183
-
210
+
184
211
  # Construct the values of the final matrix based on the dimension.
185
- if dim.is_a?(Integer)
186
- values = (0 .. (dim * dim - 1)).to_a
212
+ if size.is_a?(Integer)
213
+ values = (0 .. (size * size - 1)).to_a
187
214
  else
188
215
  # Dimensions given by a 2 element array.
189
- values = (0 .. (dim.first * dim.last - 1)).to_a
216
+ values = (0 .. (size.first * size.last - 1)).to_a
190
217
  end
191
-
218
+
192
219
  # It'll produce :int32, except if a dtype is provided.
193
- NMatrix.new(:dense, dim, values, dtype)
220
+ NMatrix.new(:dense, size, values, dtype)
194
221
  end
195
222
 
196
- #########################################
197
- # FUNCTIONS FOR MATLAB AND IDL REFUGEES #
198
- #########################################
199
-
200
223
  #
201
- # These are functions that replicate existing functionality, but
202
- # would probably be appreciated by MATLAB or IDL users.
224
+ # call-seq:
225
+ # indgen(size) -> NMatrix
226
+ #
227
+ # Returns an integer NMatrix. Equivalent to <tt>seq(n, :int32)</tt>.
203
228
  #
229
+ # * *Arguments* :
230
+ # - +size+ -> Size of the sequence.
231
+ # * *Returns* :
232
+ # - NMatrix with dtype +:int32+.
233
+ #
234
+ def indgen(size)
235
+ NMatrix.seq(size, :int32)
236
+ end
204
237
 
205
- # indgen() , findgen() , bindgen() , cindgen()
206
238
  #
207
- # These IDL functions are similar to seq() but less flexible.
208
- # They produce one-dimensional vectors:
239
+ # call-seq:
240
+ # findgen(size) -> NMatrix
209
241
  #
210
- # indgen -- Integer vector -- seq(n, :int32)
211
- # findgen -- Float vector -- seq(n, :float32)
212
- # bindgen -- Byte vector -- seq(n, :byte)
213
- # cindgen -- Complex vector -- seq(n, :complex64)
242
+ # Returns a float NMatrix. Equivalent to <tt>seq(n, :float32)</tt>.
214
243
  #
215
-
216
- def indgen(n)
217
- NMatrix.seq(n, :int32)
244
+ # * *Arguments* :
245
+ # - +size+ -> Size of the sequence.
246
+ # * *Returns* :
247
+ # - NMatrix with dtype +:float32+.
248
+ #
249
+ def findgen(size)
250
+ NMatrix.seq(size, :float32)
218
251
  end
219
252
 
220
- def findgen(n)
221
- NMatrix.seq(n, :float32)
253
+ #
254
+ # call-seq:
255
+ # bindgen(size) -> NMatrix
256
+ #
257
+ # Returns a byte NMatrix. Equivalent to <tt>seq(n, :byte)</tt>.
258
+ #
259
+ # * *Arguments* :
260
+ # - +size+ -> Size of the sequence.
261
+ # * *Returns* :
262
+ # - NMatrix with dtype +:byte+.
263
+ #
264
+ def bindgen(size)
265
+ NMatrix.seq(size, :byte)
222
266
  end
223
267
 
224
- def bindgen(n)
225
- NMatrix.seq(n, :byte)
268
+ #
269
+ # call-seq:
270
+ # cindgen(size) -> NMatrix
271
+ #
272
+ # Returns an complex NMatrix. Equivalent to <tt>seq(n, :complex64)</tt>.
273
+ #
274
+ # * *Arguments* :
275
+ # - +size+ -> Size of the sequence.
276
+ # * *Returns* :
277
+ # - NMatrix with dtype +:complex64+.
278
+ #
279
+ def cindgen(size)
280
+ NMatrix.seq(size, :complex64)
226
281
  end
227
282
 
228
- def cindgen(n)
229
- NMatrix.seq(n, :complex64)
230
- end
231
-
232
283
  end
233
284
 
234
285
  #
235
- # These shortcuts are to be called directly from a NMatrix object, i.e.:
286
+ # call-seq:
287
+ # column(column_number) -> NMatrix
288
+ # column(column_number, get_by) -> NMatrix
236
289
  #
237
- # >> m = NMatrix.random(3)
238
- # >> m.column(2)
239
- #
240
-
241
- # column()
290
+ # Returns the column specified. Uses slicing by copy as default.
242
291
  #
243
- # Returns the column specified. The second parameter defaults to
244
- # :copy, which returns a copy of the selected column, but it can be
245
- # specified as :reference, which will return a reference to it.
292
+ # * *Arguments* :
293
+ # - +column_number+ -> Integer.
294
+ # - +get_by+ -> Type of slicing to use, +:copy+ or +:reference+.
295
+ # * *Returns* :
296
+ # - A NMatrix representing the requested column as a column vector.
246
297
  #
247
298
  # Examples:
248
299
  #
249
300
  # m = NMatrix.new(2, [1, 4, 9, 14], :int32) # => 1 4
250
301
  # 9 14
251
- #
302
+ #
252
303
  # m.column(1) # => 4
253
304
  # 14
254
305
  #
255
-
256
306
  def column(column_number, get_by = :copy)
257
307
  unless [:copy, :reference].include?(get_by)
258
308
  raise ArgumentError, "column() 2nd parameter must be :copy or :reference"
259
309
  end
260
-
310
+
261
311
  if get_by == :copy
262
312
  self.slice(0 ... self.shape[0], column_number)
263
313
  else # by reference
264
314
  self[0 ... self.shape[0], column_number]
265
315
  end
266
316
  end
317
+
318
+ alias :col :column
319
+
320
+ #
321
+ # call-seq:
322
+ # row(row_number) -> NMatrix
323
+ # row(row_number, get_by) -> NMatrix
324
+ #
325
+ # * *Arguments* :
326
+ # - +row_number+ -> Integer.
327
+ # - +get_by+ -> Type of slicing to use, +:copy+ or +:reference+.
328
+ # * *Returns* :
329
+ # - A NMatrix representing the requested row .
330
+ #
331
+ def row(row_number, get_by = :copy)
332
+ unless [:copy, :reference].include?(get_by)
333
+ raise ArgumentError, "row() 2nd parameter must be :copy or :reference"
334
+ end
335
+
336
+ if get_by == :copy
337
+ self.slice(row_number, 0 ... self.shape[1])
338
+ else # by reference
339
+ self[row_number, 0 ... self.shape[1]]
340
+ end
341
+ end
267
342
  end
268
343
 
269
344
  class NVector < NMatrix
270
-
345
+
271
346
  class << self
272
- # zeros() or zeroes()
273
347
  #
274
- # Creates a new matrix of zeros with the dimensions supplied as
275
- # parameters. Optional parameters include:
348
+ # call-seq:
349
+ # zeros(size) -> NMatrix
350
+ # zeros(size, dtype) -> NMatrix
351
+ #
352
+ # Creates a new matrix of zeros with the dimensions supplied as
353
+ # parameters.
276
354
  #
277
- # * A storage type as the first parameter (default is :dense).
278
- # * A dtype as the last parameter (default is :float64).
355
+ # * *Arguments* :
356
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
357
+ # - +dtype+ -> (optional) Default is +:float64+.
358
+ # * *Returns* :
359
+ # - NVector filled with zeros.
279
360
  #
280
361
  # Examples:
281
362
  #
282
- # zeros(2) # => 0.0 0.0
363
+ # NVector.zeros(2) # => 0.0
364
+ # 0.0
283
365
  #
284
- # zeros(3, :int32) # => 0 0 0
366
+ # NVector.zeros(3, :int32) # => 0
367
+ # 0
368
+ # 0
285
369
  #
286
-
287
- def zeros(*params)
288
- dtype = params.last.is_a?(Symbol) ? params.pop : :float64
289
- dim = params.first
290
-
291
- NVector.new(dim, 0, dtype)
370
+ def zeros(size, dtype = :float64)
371
+ NVector.new(size, 0, dtype)
292
372
  end
293
-
294
373
  alias :zeroes :zeros
295
374
 
296
- # ones()
297
375
  #
298
- # Creates a :dense matrix of ones with the dimensions supplied
299
- # as parameters. Optionaly, one can specify a dtype as the last
300
- # parameter (default is :float64).
376
+ # call-seq:
377
+ # ones(size) -> NVector
378
+ # ones(size, dtype) -> NVector
379
+ #
380
+ # Creates a vector of ones with the dimensions supplied as
381
+ # parameters.
382
+ #
383
+ # * *Arguments* :
384
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
385
+ # - +dtype+ -> (optional) Default is +:float64+.
386
+ # * *Returns* :
387
+ # - NVector filled with ones.
301
388
  #
302
389
  # Examples:
303
390
  #
304
- # ones(3) # => 1.0 1.0 1.0
391
+ # NVector.ones(2) # => 1.0
392
+ # 1.0
305
393
  #
306
- # ones(2, :int32) # => 1 1
394
+ # NVector.ones(3, :int32) # => 1
395
+ # 1
396
+ # 1
307
397
  #
308
-
309
- def ones(*params)
310
- dtype = params.last.is_a?(Symbol) ? params.pop : :float64
311
- dim = params.first
312
-
313
- NVector.new(dim, 1, dtype)
398
+ def ones(size, dtype = :float64)
399
+ NVector.new(size, 1, dtype)
314
400
  end
315
-
316
- # random()
401
+
402
+ #
403
+ # call-seq:
404
+ # random(size) -> NVector
317
405
  #
318
- # Creates a :dense NMatrix with random numbers between 0 and 1 generated
319
- # by Random::rand. The parameter is the dimension of the matrix.
406
+ # Creates a vector with random numbers between 0 and 1 generated by
407
+ # +Random::rand+ with the dimensions supplied as parameters.
408
+ #
409
+ # * *Arguments* :
410
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
411
+ # - +dtype+ -> (optional) Default is +:float64+.
412
+ # * *Returns* :
413
+ # - NVector filled with random numbers generated by the +Random+ class.
320
414
  #
321
415
  # Examples:
322
416
  #
323
- # rand(2) # => 0.4859439730644226 0.1783195585012436
417
+ # NVector.rand(2) # => 0.4859439730644226
418
+ # 0.1783195585012436
324
419
  #
325
-
326
- def random(*params)
420
+ def random(size)
327
421
  rng = Random.new
328
- dim = params.first
329
422
 
330
423
  random_values = []
331
- dim.times { |i| random_values << rng.rand }
332
-
333
- NVector.new(dim, random_values, :float64)
424
+ size.times { |i| random_values << rng.rand }
425
+
426
+ NVector.new(size, random_values, :float64)
334
427
  end
335
428
 
336
- # seq()
337
429
  #
338
- # Creates a :dense NMatrix with a sequence of integers starting at
339
- # zero until the matrix is filled. The parameters to the method
340
- # are the dimensions of the matrix. Optionaly, one can specify a
341
- # dtype as the last parameter (default is :float64).
430
+ # call-seq:
431
+ # seq(n) -> NVector
432
+ # seq(n, dtype) -> NVector
433
+ #
434
+ # Creates a vector with a sequence of +n+ integers starting at zero. You
435
+ # can choose other types based on the dtype parameter.
436
+ #
437
+ # * *Arguments* :
438
+ # - +n+ -> Number of integers in the sequence.
439
+ # - +dtype+ -> (optional) Default is +:int64+.
440
+ # * *Returns* :
441
+ # - NVector filled with +n+ integers.
342
442
  #
343
443
  # Examples:
344
444
  #
345
- # seq(2) # => 0 1
445
+ # NVector.seq(2) # => 0
446
+ # 1
346
447
  #
347
- # seq(3, :float32) # => 0.0 1.0 2.0
448
+ # NVector.seq(3, :float32) # => 0.0
449
+ # 1.0
450
+ # 2.0
348
451
  #
349
-
350
- def seq(*params)
351
- dtype = params.last.is_a?(Symbol) ? params.pop : nil
352
- dim = params.first
353
-
354
- unless dim.is_a?(Integer)
355
- raise ArgumentError, "NVector::seq() only accepts integers as \
356
- dimension."
452
+ def seq(n, dtype = :int64)
453
+ unless n.is_a?(Integer)
454
+ raise ArgumentError, "NVector::seq() only accepts integers as size."
357
455
  end
358
-
359
- values = (0 .. (dim - 1)).to_a
360
-
361
- NVector.new(dim, values, dtype)
362
- end
363
456
 
364
- #########################################
365
- # FUNCTIONS FOR MATLAB AND IDL REFUGEES #
366
- #########################################
457
+ values = (0 ... n).to_a
367
458
 
368
- #
369
- # These are functions that replicate existing functionality, but
370
- # would probably be appreciated by MATLAB or IDL users.
371
- #
459
+ NVector.new(n, values, dtype)
460
+ end
372
461
 
373
- # indgen() , findgen() , bindgen() , cindgen()
374
462
  #
375
- # These IDL functions are similar to seq() but less flexible.
376
- # They produce one-dimensional vectors:
463
+ # call-seq:
464
+ # indgen(n) -> NVector
377
465
  #
378
- # indgen -- Integer vector -- seq(n, :int32)
379
- # findgen -- Float vector -- seq(n, :float32)
380
- # bindgen -- Byte vector -- seq(n, :byte)
381
- # cindgen -- Complex vector -- seq(n, :complex64)
466
+ # Returns an integer NVector. Equivalent to <tt>seq(n, :int32)</tt>.
467
+ #
468
+ # * *Arguments* :
469
+ # - +n+ -> Size of the sequence.
470
+ # * *Returns* :
471
+ # - NVector filled with +n+ integers of dtype +:int32+.
382
472
  #
383
-
384
473
  def indgen(n)
385
474
  NVector.seq(n, :int32)
386
475
  end
387
476
 
477
+ #
478
+ # call-seq:
479
+ # findgen(n) -> NVector
480
+ #
481
+ # Returns a float NVector. Equivalent to <tt>seq(n, :float32)</tt>.
482
+ #
483
+ # * *Arguments* :
484
+ # - +n+ -> Size of the sequence.
485
+ # * *Returns* :
486
+ # - NVector filled with +n+ integers of dtype +:float32+.
487
+ #
388
488
  def findgen(n)
389
489
  NVector.seq(n, :float32)
390
490
  end
391
491
 
492
+ #
493
+ # call-seq:
494
+ # bindgen(n) -> NVector
495
+ #
496
+ # Returns a byte NVector. Equivalent to <tt>seq(n, :byte)</tt>.
497
+ #
498
+ # * *Arguments* :
499
+ # - +n+ -> Size of the sequence.
500
+ # * *Returns* :
501
+ # - NVector filled with +n+ integers of dtype +:byte+.
502
+ #
392
503
  def bindgen(n)
393
504
  NVector.seq(n, :byte)
394
505
  end
395
506
 
507
+ #
508
+ # call-seq:
509
+ # cindgen(n) -> NVector
510
+ #
511
+ # Returns a complex NVector. Equivalent to <tt>seq(n, :complex64)</tt>.
512
+ #
513
+ # * *Arguments* :
514
+ # - +n+ -> Size of the sequence.
515
+ # * *Returns* :
516
+ # - NVector filled with +n+ integers of dtype +:complex64+.
517
+ #
396
518
  def cindgen(n)
397
519
  NVector.seq(n, :complex64)
398
520
  end
399
-
400
- # linspace()
521
+
401
522
  #
402
- # This MATLAB function somewhat resembles seq(), but it differs
403
- # enough that is likely to be legitimately useful to non-MATLAB
404
- # refugees. This function takes three parameter, the last one
405
- # being an integer.
523
+ # call-seq:
524
+ # linspace(a, b) -> NVector
525
+ # linspace(a, b, n) -> NVector
406
526
  #
407
- # linspace( a, b, n )
527
+ # Returns a NVector with +n+ values of dtype +:float64+ equally spaced from
528
+ # +a+ to +b+, inclusive.
408
529
  #
409
- # This returns a vector with n values equally spaced from a to b,
410
- # inclusive.
411
- #
412
- # Following the MATLAB implementation, if n isn't provided it's
413
- # assumed to be 100.
530
+ # Following the MATLAB implementation, if n isn't provided it's assumed to
531
+ # be 100.
414
532
  #
415
- # Ex: x = linspace(0, pi, 1000)
416
- # y = sin(x)
533
+ # * *Arguments* :
534
+ # - +a+ -> The first value in the sequence.
535
+ # - +b+ -> The last value in the sequence.
536
+ # - +n+ -> The number of elements.
537
+ # * *Returns* :
538
+ # - n-by-1 NMatrix with +n+ +:float64+ values.
539
+ #
540
+ # Example:
541
+ # x = NVector.linspace(0, Math::PI, 1000)
542
+ # => #<NMatrix:0x007f83921992f0shape:[1000,1] dtype:float64 stype:dense>
543
+ #
544
+ # x.pp
545
+ # [0.0]
546
+ # [0.0031447373909807737]
547
+ # [0.006289474781961547]
548
+ # ...
549
+ # [3.135303178807831]
550
+ # [3.138447916198812]
551
+ # [3.141592653589793]
552
+ # => nil
417
553
  #
418
-
419
554
  def linspace(a, b, n = 100)
420
555
  # See: http://www.mathworks.com/help/matlab/ref/linspace.html
421
556
  # Formula: seq(n) * step + a
422
-
557
+
423
558
  # step = ((b - a) / (n - 1))
424
559
  step = (b - a) * (1.0 / (n - 1))
425
-
560
+
426
561
  # dtype = :float64 is used to prevent integer coercion.
427
562
  result = NVector.seq(n, :float64) * NVector.new(n, step, :float64)
428
563
  result += NVector.new(n, a, :float64)
@@ -431,36 +566,39 @@ dimension."
431
566
  end
432
567
  end
433
568
 
434
- # NMatrix needs to have a succinct way to create a matrix by specifying
435
- # the components directly. This is very usefeul for using NMatrix as an
436
- # advanced calculator, it is useful for learning NMatrix and it is also
437
- # useful for testing language features or developing algorithms.
569
+ # NMatrix needs to have a succinct way to create a matrix by specifying the
570
+ # components directly. This is very useful for using it as an advanced
571
+ # calculator, it is useful for learning how to use, for testing language
572
+ # features and for developing algorithms.
438
573
  #
439
- # The N[] function provides a way to create a matrix in a way that is
440
- # very short and very natural, simply by specifying the components in
441
- # the traditional Ruby array syntax. Optionally, one can specify a
442
- # dtype as the last parameter (default is :float64).
574
+ # The N class provides a way to create a matrix in a way that is compact and
575
+ # natural. The components are specified using Ruby array syntax. Optionally,
576
+ # one can specify a dtype as the last parameter (default is :float64).
443
577
  #
444
- # a = N[ 1,2,3,4 ] => 1.0 2.0 3.0 4.0
578
+ # Examples:
445
579
  #
446
- # a = N[ 1,2,3,4, :int32 ] => 1 2 3 4
580
+ # a = N[ 1,2,3,4 ] => 1.0 2.0 3.0 4.0
447
581
  #
448
- # a = N[ [1,2,3], [3,4,5] ] => 1.0 2.0 3.0
449
- # 3.0 4.0 5.0
582
+ # a = N[ 1,2,3,4, :int32 ] => 1 2 3 4
450
583
  #
584
+ # a = N[ [1,2,3], [3,4,5] ] => 1.0 2.0 3.0
585
+ # 3.0 4.0 5.0
451
586
  #
452
587
  # SYNTAX COMPARISON:
453
588
  #
454
- # MATLAB: a = [ [1 2 3] ; [4 5 6] ] or [ 1 2 3 ; 4 5 6 ]
455
- # IDL: a = [ [1,2,3] , [4,5,6] ]
456
- # NumPy: a = array( [1,2,3], [4,5,6] )
589
+ # MATLAB: a = [ [1 2 3] ; [4 5 6] ] or [ 1 2 3 ; 4 5 6 ]
590
+ # IDL: a = [ [1,2,3] , [4,5,6] ]
591
+ # NumPy: a = array( [1,2,3], [4,5,6] )
457
592
  #
458
- # SciRuby: a = N[ [1,2,3], [4,5,6] ]
459
- # Ruby array: a = [ [1,2,3], [4,5,6] ]
593
+ # SciRuby: a = N[ [1,2,3], [4,5,6] ]
594
+ # Ruby array: a = [ [1,2,3], [4,5,6] ]
460
595
  #
461
-
462
596
  class N
463
597
  class << self
598
+ #
599
+ # call-seq:
600
+ # N[array-of-arrays, dtype = nil]
601
+ #
464
602
  def [](*params)
465
603
  dtype = params.last.is_a?(Symbol) ? params.pop : nil
466
604
 
@@ -470,7 +608,7 @@ class N
470
608
  foo = params
471
609
  while foo.is_a?(Array)
472
610
  dim[i] = foo.length
473
- foo = foo[0]
611
+ foo = foo[0]
474
612
  i += 1
475
613
  end
476
614
 
@@ -479,8 +617,3 @@ class N
479
617
  end
480
618
  end
481
619
  end
482
-
483
- # TODO Make all the shortcuts available through modules, allowing someone
484
- # to include them to make "MATLAB-like" scripts.
485
- #
486
- # There are some questions to be answered before this can be done, tho.