pnmatrix 1.2.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 (111) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/binary_format.txt +53 -0
  3. data/ext/nmatrix/data/complex.h +388 -0
  4. data/ext/nmatrix/data/data.cpp +274 -0
  5. data/ext/nmatrix/data/data.h +651 -0
  6. data/ext/nmatrix/data/meta.h +64 -0
  7. data/ext/nmatrix/data/ruby_object.h +386 -0
  8. data/ext/nmatrix/extconf.rb +70 -0
  9. data/ext/nmatrix/math/asum.h +99 -0
  10. data/ext/nmatrix/math/cblas_enums.h +36 -0
  11. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  12. data/ext/nmatrix/math/gemm.h +241 -0
  13. data/ext/nmatrix/math/gemv.h +178 -0
  14. data/ext/nmatrix/math/getrf.h +255 -0
  15. data/ext/nmatrix/math/getrs.h +121 -0
  16. data/ext/nmatrix/math/imax.h +82 -0
  17. data/ext/nmatrix/math/laswp.h +165 -0
  18. data/ext/nmatrix/math/long_dtype.h +62 -0
  19. data/ext/nmatrix/math/magnitude.h +54 -0
  20. data/ext/nmatrix/math/math.h +751 -0
  21. data/ext/nmatrix/math/nrm2.h +165 -0
  22. data/ext/nmatrix/math/rot.h +117 -0
  23. data/ext/nmatrix/math/rotg.h +106 -0
  24. data/ext/nmatrix/math/scal.h +71 -0
  25. data/ext/nmatrix/math/trsm.h +336 -0
  26. data/ext/nmatrix/math/util.h +162 -0
  27. data/ext/nmatrix/math.cpp +1368 -0
  28. data/ext/nmatrix/nm_memory.h +60 -0
  29. data/ext/nmatrix/nmatrix.cpp +285 -0
  30. data/ext/nmatrix/nmatrix.h +476 -0
  31. data/ext/nmatrix/ruby_constants.cpp +151 -0
  32. data/ext/nmatrix/ruby_constants.h +106 -0
  33. data/ext/nmatrix/ruby_nmatrix.c +3130 -0
  34. data/ext/nmatrix/storage/common.cpp +77 -0
  35. data/ext/nmatrix/storage/common.h +183 -0
  36. data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
  37. data/ext/nmatrix/storage/dense/dense.h +129 -0
  38. data/ext/nmatrix/storage/list/list.cpp +1628 -0
  39. data/ext/nmatrix/storage/list/list.h +138 -0
  40. data/ext/nmatrix/storage/storage.cpp +730 -0
  41. data/ext/nmatrix/storage/storage.h +99 -0
  42. data/ext/nmatrix/storage/yale/class.h +1139 -0
  43. data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
  44. data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
  45. data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
  46. data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
  47. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
  48. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
  49. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  50. data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
  51. data/ext/nmatrix/storage/yale/yale.h +203 -0
  52. data/ext/nmatrix/types.h +55 -0
  53. data/ext/nmatrix/util/io.cpp +279 -0
  54. data/ext/nmatrix/util/io.h +115 -0
  55. data/ext/nmatrix/util/sl_list.cpp +627 -0
  56. data/ext/nmatrix/util/sl_list.h +144 -0
  57. data/ext/nmatrix/util/util.h +78 -0
  58. data/lib/nmatrix/blas.rb +378 -0
  59. data/lib/nmatrix/cruby/math.rb +744 -0
  60. data/lib/nmatrix/enumerate.rb +253 -0
  61. data/lib/nmatrix/homogeneous.rb +241 -0
  62. data/lib/nmatrix/io/fortran_format.rb +138 -0
  63. data/lib/nmatrix/io/harwell_boeing.rb +221 -0
  64. data/lib/nmatrix/io/market.rb +263 -0
  65. data/lib/nmatrix/io/point_cloud.rb +189 -0
  66. data/lib/nmatrix/jruby/decomposition.rb +24 -0
  67. data/lib/nmatrix/jruby/enumerable.rb +13 -0
  68. data/lib/nmatrix/jruby/error.rb +4 -0
  69. data/lib/nmatrix/jruby/math.rb +501 -0
  70. data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
  71. data/lib/nmatrix/jruby/operators.rb +283 -0
  72. data/lib/nmatrix/jruby/slice.rb +264 -0
  73. data/lib/nmatrix/lapack_core.rb +181 -0
  74. data/lib/nmatrix/lapack_plugin.rb +44 -0
  75. data/lib/nmatrix/math.rb +953 -0
  76. data/lib/nmatrix/mkmf.rb +100 -0
  77. data/lib/nmatrix/monkeys.rb +137 -0
  78. data/lib/nmatrix/nmatrix.rb +1172 -0
  79. data/lib/nmatrix/rspec.rb +75 -0
  80. data/lib/nmatrix/shortcuts.rb +1163 -0
  81. data/lib/nmatrix/version.rb +39 -0
  82. data/lib/nmatrix/yale_functions.rb +118 -0
  83. data/lib/nmatrix.rb +28 -0
  84. data/spec/00_nmatrix_spec.rb +892 -0
  85. data/spec/01_enum_spec.rb +196 -0
  86. data/spec/02_slice_spec.rb +407 -0
  87. data/spec/03_nmatrix_monkeys_spec.rb +80 -0
  88. data/spec/2x2_dense_double.mat +0 -0
  89. data/spec/4x4_sparse.mat +0 -0
  90. data/spec/4x5_dense.mat +0 -0
  91. data/spec/blas_spec.rb +215 -0
  92. data/spec/elementwise_spec.rb +311 -0
  93. data/spec/homogeneous_spec.rb +100 -0
  94. data/spec/io/fortran_format_spec.rb +88 -0
  95. data/spec/io/harwell_boeing_spec.rb +98 -0
  96. data/spec/io/test.rua +9 -0
  97. data/spec/io_spec.rb +159 -0
  98. data/spec/lapack_core_spec.rb +482 -0
  99. data/spec/leakcheck.rb +16 -0
  100. data/spec/math_spec.rb +1363 -0
  101. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  102. data/spec/nmatrix_yale_spec.rb +286 -0
  103. data/spec/rspec_monkeys.rb +56 -0
  104. data/spec/rspec_spec.rb +35 -0
  105. data/spec/shortcuts_spec.rb +474 -0
  106. data/spec/slice_set_spec.rb +162 -0
  107. data/spec/spec_helper.rb +172 -0
  108. data/spec/stat_spec.rb +214 -0
  109. data/spec/test.pcd +20 -0
  110. data/spec/utm5940.mtx +83844 -0
  111. metadata +295 -0
@@ -0,0 +1,1163 @@
1
+ #--
2
+ # = NMatrix
3
+ #
4
+ # A linear algebra library for scientific computation in Ruby.
5
+ # NMatrix is part of SciRuby.
6
+ #
7
+ # NMatrix was originally inspired by and derived from NArray, by
8
+ # Masahiro Tanaka: http://narray.rubyforge.org
9
+ #
10
+ # == Copyright Information
11
+ #
12
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
+ #
15
+ # Please see LICENSE.txt for additional copyright notices.
16
+ #
17
+ # == Contributing
18
+ #
19
+ # By contributing source code to SciRuby, you agree to be bound by
20
+ # our Contributor Agreement:
21
+ #
22
+ # * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
23
+ #
24
+ # == shortcuts.rb
25
+ #
26
+ # These are shortcuts for NMatrix and NVector creation, contributed by Daniel
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
+ #++
34
+
35
+ class NMatrix
36
+
37
+ # Methods for generating magic matrix.
38
+ module MagicHelpers
39
+ class << self
40
+ def odd_magic(nm, shape)
41
+ row = shape - 1
42
+ col = shape / 2
43
+ nm[row,col] = 1
44
+ (2..shape * shape).each do |index|
45
+ if nm[(row + 1) % shape,(col + 1) % shape] == 0
46
+ row = (row + 1) % shape
47
+ col = (col + 1) % shape
48
+ else
49
+ row = (row - 1 + shape) % shape
50
+ end
51
+ nm[row,col] = index
52
+ end
53
+ end
54
+
55
+ def doubly_even_magic(nm, shape)
56
+ mini_square_num = shape / 4
57
+ count = 1
58
+ inv_count = shape * shape
59
+ shape.times do |row|
60
+ shape.times do |col|
61
+ if col >= mini_square_num and col < shape - mini_square_num
62
+ if row >= mini_square_num and row < shape - mini_square_num
63
+ nm[row,col] = count
64
+ else
65
+ nm[row,col] = inv_count
66
+ end
67
+ elsif row < mini_square_num or row >= shape - mini_square_num
68
+ nm[row,col] = count
69
+ else
70
+ nm[row,col] = inv_count
71
+ end
72
+ count += 1
73
+ inv_count -= 1
74
+ end
75
+ end
76
+ end
77
+
78
+ def singly_even_magic(nm, shape)
79
+ half_shape = shape / 2
80
+ complementary_pair = (shape - 2) / 4
81
+ swap_col = NMatrix.new([shape])
82
+ index = 0
83
+ mini_magic = NMatrix.new([half_shape,half_shape], 0, dtype: nm.dtype)
84
+ odd_magic mini_magic, half_shape
85
+ half_shape.times do |row|
86
+ half_shape.times do |col|
87
+ nm[row,col] = mini_magic[row,col]
88
+ nm[row + half_shape,col + half_shape] = mini_magic[row,col] + half_shape * half_shape
89
+ nm[row,col + half_shape] = mini_magic[row,col] + 2 * half_shape * half_shape
90
+ nm[row + half_shape,col] = mini_magic[row,col] + 3 * half_shape * half_shape
91
+ end
92
+ end
93
+
94
+ (1..complementary_pair).each do |complementary_entry|
95
+ swap_col[index] = complementary_entry
96
+ index += 1
97
+ end
98
+
99
+ (shape - complementary_pair + 2..shape).each do |center|
100
+ swap_col[index] = center
101
+ index += 1
102
+ end
103
+
104
+ (1..half_shape).each do |row|
105
+ (1..index).each do |col|
106
+ temp = nm[row - 1,swap_col[col - 1] - 1]
107
+ nm[row - 1,swap_col[col - 1] - 1] = nm[row + half_shape - 1,swap_col[col - 1] - 1]
108
+ nm[row + half_shape - 1,swap_col[col - 1] - 1] = temp
109
+ end
110
+ end
111
+
112
+ temp = nm[complementary_pair,0]
113
+ nm[complementary_pair,0] = nm[complementary_pair + half_shape,0]
114
+ nm[complementary_pair + half_shape,0] = temp
115
+
116
+ temp = nm[complementary_pair + half_shape,complementary_pair]
117
+ nm[complementary_pair + half_shape,complementary_pair] = nm[complementary_pair,complementary_pair]
118
+ nm[complementary_pair,complementary_pair] = temp
119
+ end
120
+ end
121
+ end
122
+
123
+ # call-seq:
124
+ # m.dense? -> true or false
125
+ #
126
+ # Determine if +m+ is a dense matrix.
127
+ def dense?; return stype == :dense; end
128
+
129
+ # call-seq:
130
+ # m.yale? -> true or false
131
+ #
132
+ # Determine if +m+ is a Yale matrix.
133
+ def yale?; return stype == :yale; end
134
+
135
+ # call-seq:
136
+ # m.list? -> true or false
137
+ #
138
+ # Determine if +m+ is a list-of-lists matrix.
139
+ def list?; return stype == :list; end
140
+
141
+ class << self
142
+ # call-seq:
143
+ # NMatrix[Numeric, ..., Numeric, dtype: Symbol] -> NMatrix
144
+ # NMatrix[Array, dtype: Symbol] -> NMatrix
145
+ #
146
+ # The default value for +dtype+ is guessed from the first parameter. For example:
147
+ # NMatrix[1.0, 2.0].dtype # => :float64
148
+ #
149
+ # But this is just a *guess*. If the other values can't be converted to
150
+ # this dtype, a +TypeError+ will be raised.
151
+ #
152
+ # You can use the +N+ constant in this way:
153
+ # N = NMatrix
154
+ # N[1, 2, 3]
155
+ #
156
+ # NMatrix needs to have a succinct way to create a matrix by specifying the
157
+ # components directly. This is very useful for using it as an advanced
158
+ # calculator, it is useful for learning how to use, for testing language
159
+ # features and for developing algorithms.
160
+ #
161
+ # The NMatrix::[] method provides a way to create a matrix in a way that is compact and
162
+ # natural. The components are specified using Ruby array syntax. Optionally,
163
+ # one can specify a dtype as the last parameter (default is :float64).
164
+ #
165
+ # Examples:
166
+ #
167
+ # a = N[ 1,2,3,4 ] => 1 2 3 4
168
+ #
169
+ # a = N[ 1,2,3,4, :int32 ] => 1 2 3 4
170
+ #
171
+ # a = N[ [1,2,3], [3,4,5] ] => 1.0 2.0 3.0
172
+ # 3.0 4.0 5.0
173
+ #
174
+ # a = N[ 3,6,9 ].transpose => 3
175
+ # 6
176
+ # 9
177
+ #
178
+ # SYNTAX COMPARISON:
179
+ #
180
+ # MATLAB: a = [ [1 2 3] ; [4 5 6] ] or [ 1 2 3 ; 4 5 6 ]
181
+ # IDL: a = [ [1,2,3] , [4,5,6] ]
182
+ # NumPy: a = array( [1,2,3], [4,5,6] )
183
+ #
184
+ # SciRuby: a = NMatrix[ [1,2,3], [4,5,6] ]
185
+ # Ruby array: a = [ [1,2,3], [4,5,6] ]
186
+ def [](*params)
187
+ options = params.last.is_a?(Hash) ? params.pop : {}
188
+
189
+ # First find the dimensions of the array.
190
+ i = 0
191
+ shape = []
192
+ row = params
193
+ while row.is_a?(Array)
194
+ shape[i] = row.length
195
+ row = row[0]
196
+ i += 1
197
+ end
198
+
199
+ # A row vector should be stored as 1xN, not N
200
+ #shape.unshift(1) if shape.size == 1
201
+
202
+ # Then flatten the array.
203
+ NMatrix.new(shape, params.flatten, options)
204
+ end
205
+
206
+ #
207
+ # call-seq:
208
+ # zeros(shape) -> NMatrix
209
+ # zeros(shape, dtype: dtype) -> NMatrix
210
+ # zeros(shape, dtype: dtype, stype: stype) -> NMatrix
211
+ #
212
+ # Creates a new matrix of zeros with the dimensions supplied as
213
+ # parameters.
214
+ #
215
+ # * *Arguments* :
216
+ # - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
217
+ # - +dtype+ -> (optional) Default is +:float64+
218
+ # - +stype+ -> (optional) Default is +:dense+.
219
+ # * *Returns* :
220
+ # - NMatrix filled with zeros.
221
+ #
222
+ # Examples:
223
+ #
224
+ # NMatrix.zeros(2) # => 0.0 0.0
225
+ # 0.0 0.0
226
+ #
227
+ # NMatrix.zeros([2, 3], dtype: :int32) # => 0 0 0
228
+ # 0 0 0
229
+ #
230
+ # NMatrix.zeros([1, 5], dtype: :int32) # => 0 0 0 0 0
231
+ #
232
+ def zeros(shape, opts = {})
233
+ NMatrix.new(shape, 0, {:dtype => :float64}.merge(opts))
234
+ end
235
+ alias :zeroes :zeros
236
+
237
+ #
238
+ # call-seq:
239
+ # ones(shape) -> NMatrix
240
+ # ones(shape, dtype: dtype, stype: stype) -> NMatrix
241
+ #
242
+ # Creates a matrix filled with ones.
243
+ #
244
+ # * *Arguments* :
245
+ # - +shape+ -> Array (or integer for square matrix) specifying the shape.
246
+ # - +opts+ -> (optional) Hash of options from NMatrix#initialize
247
+ # * *Returns* :
248
+ # - NMatrix filled with ones.
249
+ #
250
+ # Examples:
251
+ #
252
+ # NMatrix.ones([1, 3]) # => 1.0 1.0 1.0
253
+ #
254
+ # NMatrix.ones([2, 3], dtype: :int32) # => 1 1 1
255
+ # 1 1 1
256
+ #
257
+ def ones(shape, opts={})
258
+ NMatrix.new(shape, 1, {:dtype => :float64, :default => 1}.merge(opts))
259
+ end
260
+
261
+ # call-seq:
262
+ # ones_like(nm) -> NMatrix
263
+ #
264
+ # Creates a new matrix of ones with the same dtype and shape as the
265
+ # provided matrix.
266
+ #
267
+ # @param [NMatrix] nm the nmatrix whose dtype and shape will be used
268
+ # @return [NMatrix] a new nmatrix filled with ones.
269
+ #
270
+ def ones_like(nm)
271
+ NMatrix.ones(nm.shape, dtype: nm.dtype, stype: nm.stype, capacity: nm.capacity, default: 1)
272
+ end
273
+
274
+ # call-seq:
275
+ # zeros_like(nm) -> NMatrix
276
+ #
277
+ # Creates a new matrix of zeros with the same stype, dtype, and shape
278
+ # as the provided matrix.
279
+ #
280
+ # @param [NMatrix] nm the nmatrix whose stype, dtype, and shape will be used
281
+ # @return [NMatrix] a new nmatrix filled with zeros.
282
+ #
283
+ def zeros_like(nm)
284
+ NMatrix.zeros(nm.shape, dtype: nm.dtype, stype: nm.stype, capacity: nm.capacity, default: 0)
285
+ end
286
+
287
+ #
288
+ # call-seq:
289
+ # eye(shape) -> NMatrix
290
+ # eye(shape, dtype: dtype) -> NMatrix
291
+ # eye(shape, stype: stype, dtype: dtype) -> NMatrix
292
+ #
293
+ # Creates an identity matrix (square matrix rank 2).
294
+ #
295
+ # * *Arguments* :
296
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
297
+ # - +dtype+ -> (optional) Default is +:float64+
298
+ # - +stype+ -> (optional) Default is +:dense+.
299
+ # * *Returns* :
300
+ # - An identity matrix.
301
+ #
302
+ # Examples:
303
+ #
304
+ # NMatrix.eye(3) # => 1.0 0.0 0.0
305
+ # 0.0 1.0 0.0
306
+ # 0.0 0.0 1.0
307
+ #
308
+ # NMatrix.eye(3, dtype: :int32) # => 1 0 0
309
+ # 0 1 0
310
+ # 0 0 1
311
+ #
312
+ # NMatrix.eye(2, dtype: :int32, stype: :yale) # => 1 0
313
+ # 0 1
314
+ #
315
+ def eye(shape, opts={})
316
+ # Fill the diagonal with 1's.
317
+ m = NMatrix.zeros(shape, {:dtype => :float64}.merge(opts))
318
+ (0...m.shape[0]).each do |i|
319
+ m[i, i] = 1
320
+ end
321
+
322
+ m
323
+ end
324
+ alias :identity :eye
325
+
326
+ #
327
+ # call-seq:
328
+ # hilbert(shape) -> NMatrix
329
+ # hilbert(shape, dtype: dtype) -> NMatrix
330
+ # hilbert(shape, stype: stype, dtype: dtype) -> NMatrix
331
+ #
332
+ # Creates an hilbert matrix (square matrix).
333
+ #
334
+ # * *Arguments* :
335
+ # - +size+ -> integer ( for square matrix) specifying the dimensions.
336
+ # - +dtype+ -> (optional) Default is +:float64+
337
+ # - +stype+ -> (optional) Default is +:dense+.
338
+ # * *Returns* :
339
+ # - A hilbert matrix.
340
+ #
341
+ # Examples:
342
+ #
343
+ # NMatrix.hilbert(3) # => 1.0 0.5 0.3333333333333333
344
+ # 0.5 0.3333333333333333 0.25
345
+ # 0.3333333333333333 0.25 0.2
346
+ #
347
+ def hilbert(shape, opts={})
348
+ m = NMatrix.new([shape,shape], {:dtype => :float64}.merge(opts))
349
+ 0.upto(shape - 1) do |i|
350
+ 0.upto(i) do |j|
351
+ m[i,j] = 1.0 / (j + i + 1)
352
+ m[j,i] = m[i,j] if i != j
353
+ end
354
+ end
355
+ m
356
+ end
357
+
358
+ #
359
+ # call-seq:
360
+ # inv_hilbert(shape) -> NMatrix
361
+ # inv_hilbert(shape, dtype: dtype) -> NMatrix
362
+ # inv_hilbert(shape, stype: stype, dtype: dtype) -> NMatrix
363
+ #
364
+ # Creates an inverse hilbert matrix (square matrix rank 2).
365
+ #
366
+ # * *Arguments* :
367
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
368
+ # - +dtype+ -> (optional) Default is +:float64+
369
+ # - +stype+ -> (optional) Default is +:dense+.
370
+ # * *Returns* :
371
+ # - A hilbert matrix.
372
+ #
373
+ # Examples:
374
+ # NMatrix.inv_hilbert(3) # => 9.0, -36.0, 30.0
375
+ # -36.0, 192.0, -180.0
376
+ # 30.0, -180.0, 180.0
377
+ #
378
+ #
379
+ def inv_hilbert(shape, opts={})
380
+ opts = {:dtype => :float64}.merge(opts)
381
+ m = NMatrix.new([shape,shape],opts)
382
+ combination = NMatrix.new([2*shape,2*shape],opts)
383
+ #combinations refers to the combination of n things taken k at a time
384
+ 0.upto(2*shape-1) do |i|
385
+ 0.upto(i) do |j|
386
+ if j != 0 and j != i
387
+ combination[i,j] = combination[i-1,j] + combination[i-1,j-1]
388
+ else
389
+ combination[i,j] = 1
390
+ end
391
+ end
392
+ end
393
+
394
+ 0.upto(shape-1) do |i|
395
+ 0.upto(i) do |j|
396
+ m[i,j] = combination[shape + j,shape - i - 1] * ((i+j)+1) * \
397
+ combination[shape + i,shape - j - 1] * (-1) ** ((i+j)) * \
398
+ combination[(i+j),i] * combination[(i+j),i]
399
+ m[j,i] = m[i,j] if i != j
400
+ end
401
+ end
402
+ m
403
+ end
404
+
405
+ #
406
+ # call-seq:
407
+ # diagonals(array) -> NMatrix
408
+ # diagonals(array, dtype: dtype, stype: stype) -> NMatrix
409
+ #
410
+ # Creates a matrix filled with specified diagonals.
411
+ #
412
+ # * *Arguments* :
413
+ # - +entries+ -> Array containing input values for diagonal matrix
414
+ # - +options+ -> (optional) Hash with options for NMatrix#initialize
415
+ # * *Returns* :
416
+ # - NMatrix filled with specified diagonal values.
417
+ #
418
+ # Examples:
419
+ #
420
+ # NMatrix.diagonal([1.0,2,3,4]) # => 1.0 0.0 0.0 0.0
421
+ # 0.0 2.0 0.0 0.0
422
+ # 0.0 0.0 3.0 0.0
423
+ # 0.0 0.0 0.0 4.0
424
+ #
425
+ # NMatrix.diagonal([1,2,3,4], dtype: :int32) # => 1 0 0 0
426
+ # 0 2 0 0
427
+ # 0 0 3 0
428
+ # 0 0 0 4
429
+ #
430
+ #
431
+ def diagonal(entries, opts={})
432
+ m = NMatrix.zeros(entries.size,
433
+ {:dtype => guess_dtype(entries[0]), :capacity => entries.size + 1}.merge(opts)
434
+ )
435
+ entries.each_with_index do |n, i|
436
+ m[i,i] = n
437
+ end
438
+ m
439
+ end
440
+ alias :diag :diagonal
441
+ alias :diagonals :diagonal
442
+
443
+ # Generate a block-diagonal NMatrix from the supplied 2D square matrices.
444
+ #
445
+ # * *Arguments*
446
+ # - +*params+ -> An array that collects all arguments passed to the method. The method
447
+ # can receive any number of arguments. Optionally, the last entry of +params+ is
448
+ # a hash of options from NMatrix#initialize. All other entries of +params+ are
449
+ # the blocks of the desired block-diagonal matrix. Each such matrix block can be
450
+ # supplied as a square 2D NMatrix object, or alternatively as an array of arrays
451
+ # (with dimensions corresponding to a square matrix), or alternatively as a number.
452
+ # * *Returns*
453
+ # - NMatrix of block-diagonal form filled with specified matrices
454
+ # as the blocks along the diagonal.
455
+ #
456
+ # * *Example*
457
+ #
458
+ # a = NMatrix.new([2,2], [1,2,3,4])
459
+ # b = NMatrix.new([1,1], [123], dtype: :float64)
460
+ # c = Array.new(2) { [[10,10], [10,10]] }
461
+ # d = Array[[1,2,3], [4,5,6], [7,8,9]]
462
+ # m = NMatrix.block_diagonal(a, b, *c, d, 10.0, 11, dtype: :int64, stype: :yale)
463
+ # =>
464
+ # [
465
+ # [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
466
+ # [3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
467
+ # [0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0]
468
+ # [0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0]
469
+ # [0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0]
470
+ # [0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0]
471
+ # [0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0]
472
+ # [0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0]
473
+ # [0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0]
474
+ # [0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0]
475
+ # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0]
476
+ # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11]
477
+ # ]
478
+ #
479
+ def block_diagonal(*params)
480
+ options = params.last.is_a?(Hash) ? params.pop : {}
481
+
482
+ params.each_index do |i|
483
+ params[i] = params[i].to_nm if params[i].is_a?(Array) # Convert Array to NMatrix
484
+ params[i] = NMatrix.new([1,1], [params[i]]) if params[i].is_a?(Numeric) # Convert number to NMatrix
485
+ end
486
+
487
+ block_sizes = [] #holds the size of each matrix block
488
+ params.each do |b|
489
+ unless b.is_a?(NMatrix)
490
+ raise(ArgumentError, "Only NMatrix or appropriate Array objects or single numbers allowed")
491
+ end
492
+ raise(ArgumentError, "Only 2D matrices or 2D arrays allowed") unless b.shape.size == 2
493
+ raise(ArgumentError, "Only square-shaped blocks allowed") unless b.shape[0] == b.shape[1]
494
+ block_sizes << b.shape[0]
495
+ end
496
+
497
+ block_diag_mat = NMatrix.zeros(block_sizes.inject(0,:+), options)
498
+ (0...params.length).each do |n|
499
+ # First determine the size and position of the n'th block in the block-diagonal matrix
500
+ block_size = block_sizes[n]
501
+ block_pos = block_sizes[0...n].inject(0,:+)
502
+ # populate the n'th block in the block-diagonal matrix
503
+ (0...block_size).each do |i|
504
+ (0...block_size).each do |j|
505
+ block_diag_mat[block_pos+i,block_pos+j] = params[n][i,j]
506
+ end
507
+ end
508
+ end
509
+
510
+ return block_diag_mat
511
+ end
512
+ alias :block_diag :block_diagonal
513
+
514
+ #
515
+ # call-seq:
516
+ # random(shape) -> NMatrix
517
+ #
518
+ # Creates a +:dense+ NMatrix with random numbers between 0 and 1 generated
519
+ # by +Random::rand+. The parameter is the dimension of the matrix.
520
+ #
521
+ # If you use an integer dtype, make sure to specify :scale as a parameter, or you'll
522
+ # only get a matrix of 0s.
523
+ #
524
+ # * *Arguments* :
525
+ # - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
526
+ # * *Returns* :
527
+ # - NMatrix filled with random values.
528
+ #
529
+ # Examples:
530
+ #
531
+ # NMatrix.random([2, 2]) # => 0.4859439730644226 0.1783195585012436
532
+ # 0.23193766176700592 0.4503345191478729
533
+ #
534
+ # NMatrix.random([2, 2], :dtype => :byte, :scale => 255) # => [ [252, 108] [44, 12] ]
535
+ #
536
+ def random(shape, opts={})
537
+ scale = opts.delete(:scale) || 1.0
538
+
539
+ if opts[:seed].nil?
540
+ rng = Random.new
541
+ else
542
+ rng = Random.new(opts[:seed])
543
+ end
544
+
545
+
546
+ random_values = []
547
+
548
+
549
+ # Construct the values of the final matrix based on the dimension.
550
+ if opts[:dtype] == :complex64 || opts[:dtype] == :complex128
551
+ NMatrix.size(shape).times { |i| random_values << Complex(rng.rand(scale), rng.rand(scale)) }
552
+ else
553
+ NMatrix.size(shape).times { |i| random_values << rng.rand(scale) }
554
+ end
555
+
556
+ NMatrix.new(shape, random_values, {:dtype => :float64, :stype => :dense}.merge(opts))
557
+ end
558
+ alias :rand :random
559
+
560
+ #
561
+ # call-seq:
562
+ # magic(shape) -> NMatrix
563
+ # magic(shape, dtype: dtype) -> NMatrix
564
+ #
565
+ # The parameter is the dimension of the matrix.
566
+ #
567
+ # Creates a +:dense+ NMatrix with the following properties:
568
+ # - An arrangement of the numbers from 1 to n^2 (n-squared) in the matrix, with each number occurring exactly once.
569
+ # - The sum of the entries of any row, any column, or any main diagonal is the same.
570
+ # - This sum must be n(n^2+1)/2.
571
+ #
572
+ # See: http://www.mathworks.com/help/matlab/ref/magic.html
573
+ #
574
+ # * *Arguments* :
575
+ # - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
576
+ # - +dtype+ -> (optional) Default is +:float64+
577
+ # * *Returns* :
578
+ # - NMatrix with the above given properties.
579
+ #
580
+ # Examples:
581
+ #
582
+ # NMatrix.magic(3) # => [ [4.0, 9.0, 2.0] [3.0, 5.0, 7.0] [8.0, 1.0, 6.0] ]
583
+ #
584
+ # NMatrix.magic(4, dtype :int32) # => [ [ 1, 15, 14, 4]
585
+ # [12, 6, 7, 9]
586
+ # [ 8, 10, 11, 5]
587
+ # [13, 3, 2, 16] ]
588
+ #
589
+ # NMatrix.magic(6,dtype: :int64) # => [ [31, 9, 2, 22, 27, 20]
590
+ # [ 3, 32, 7, 21, 23, 25]
591
+ # [35, 1, 6, 26, 19, 24]
592
+ # [ 4, 36, 29, 13, 18, 11]
593
+ # [30, 5, 34, 12, 14, 16]
594
+ # [ 8, 28, 33, 17, 10, 15] ]
595
+ #
596
+ def magic(shape, opts={})
597
+ raise(ArgumentError, "shape of two is not allowed") if shape == 2
598
+ nm = NMatrix.new([shape,shape], 0, {:dtype => :float64}.merge(opts))
599
+ if shape % 2 != 0
600
+ MagicHelpers.odd_magic nm, shape
601
+ elsif shape % 4 == 0
602
+ MagicHelpers.doubly_even_magic nm, shape
603
+ else
604
+ MagicHelpers.singly_even_magic nm, shape
605
+ end
606
+ nm
607
+ end
608
+
609
+ #
610
+ # call-seq:
611
+ # linspace(base, limit) -> 1x100 NMatrix
612
+ # linspace(base, limit, *shape) -> NMatrix
613
+ #
614
+ # Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ equally spaced from
615
+ # +base+ to +limit+, inclusive.
616
+ #
617
+ # See: http://www.mathworks.com/help/matlab/ref/linspace.html
618
+ #
619
+ # * *Arguments* :
620
+ # - +base+ -> The first value in the sequence.
621
+ # - +limit+ -> The last value in the sequence.
622
+ # - +shape+ -> Desired output shape. Default returns a 1x100 row vector.
623
+ # * *Returns* :
624
+ # - NMatrix with +:float64+ values.
625
+ #
626
+ # Examples :-
627
+ #
628
+ # NMatrix.linspace(1,Math::PI, 6)
629
+ # =>[1.0,
630
+ # 1.4283185005187988,
631
+ # 1.8566370010375977,
632
+ # 2.2849555015563965,
633
+ # 2.7132740020751953,
634
+ # 3.1415927410125732
635
+ # ]
636
+ #
637
+ # NMatrix.linspace(1,10, [3,2])
638
+ # =>[
639
+ # [ 1.0, 2.799999952316284]
640
+ # [4.599999904632568, 6.400000095367432]
641
+ # [8.199999809265137, 10.0]
642
+ # ]
643
+ #
644
+ def linspace(base, limit, shape = [100])
645
+
646
+ # Convert shape to array format
647
+ shape = [shape] if shape.is_a? Integer
648
+
649
+ #Calculate number of elements
650
+ count = shape.inject(:*)
651
+
652
+ # Linear spacing between elements calculated in step
653
+ # step = limit - base / (count - 1)
654
+ # [Result Sequence] = [0->N sequence] * step + [Base]
655
+ step = (limit - base) * (1.0 / (count - 1))
656
+ result = NMatrix.seq(shape, {:dtype => :float64}) * step
657
+ result += NMatrix.new(shape, base)
658
+ result
659
+ end
660
+
661
+ # call-seq:
662
+ # logspace(base, limit) -> 1x50 NMatrix with exponent_base = 10
663
+ # logspace(base, limit, shape , exponent_base:) -> NMatrix
664
+ # logspace(base, :pi, n) -> 1xn NMatrix with interval [10 ^ base, Math::PI]
665
+ #
666
+ # Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ logarithmically spaced from
667
+ # +exponent_base ^ base+ to +exponent_base ^ limit+, inclusive.
668
+ #
669
+ # See: http://www.mathworks.com/help/matlab/ref/logspace.html
670
+ #
671
+ # * *Arguments* :
672
+ # - +base+ -> exponent_base ** base is the first value in the sequence
673
+ # - +limit+ -> exponent_base ** limit is the last value in the sequence.
674
+ # - +shape+ -> Desired output shape. Default returns a 1x50 row vector.
675
+ # * *Returns* :
676
+ # - NMatrix with +:float64+ values.
677
+ #
678
+ # Examples :-
679
+ #
680
+ # NMatrix.logspace(1,:pi,7)
681
+ # =>[
682
+ # 10.0000,
683
+ # 8.2450,
684
+ # 6.7980,
685
+ # 5.6050,
686
+ # 4.6213,
687
+ # 3.8103,
688
+ # 3.1416
689
+ # ]
690
+ #
691
+ # NMatrix.logspace(1,2,[3,2])
692
+ # =>[
693
+ # [10.0, 15.8489]
694
+ # [25.1189, 39.8107]
695
+ # [63.0957, 100.0]
696
+ # ]
697
+ #
698
+ def logspace(base, limit, shape = [50], exponent_base: 10)
699
+
700
+ #Calculate limit for [10 ^ base ... Math::PI] if limit = :pi
701
+ limit = Math.log(Math::PI, exponent_base = 10) if limit == :pi
702
+ shape = [shape] if shape.is_a? Integer
703
+
704
+ #[base...limit] -> [exponent_base ** base ... exponent_base ** limit]
705
+ result = NMatrix.linspace(base, limit, shape)
706
+ result.map {|element| exponent_base ** element}
707
+ end
708
+
709
+ #
710
+ # call-seq:
711
+ # linspace(base, limit) -> 1x100 NMatrix
712
+ # linspace(base, limit, *shape) -> NMatrix
713
+ #
714
+ # Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ equally spaced from
715
+ # +base+ to +limit+, inclusive.
716
+ #
717
+ # See: http://www.mathworks.com/help/matlab/ref/linspace.html
718
+ #
719
+ # * *Arguments* :
720
+ # - +base+ -> The first value in the sequence.
721
+ # - +limit+ -> The last value in the sequence.
722
+ # - +shape+ -> Desired output shape. Default returns a 1x100 row vector.
723
+ # * *Returns* :
724
+ # - NMatrix with +:float64+ values.
725
+ #
726
+ # Examples :-
727
+ #
728
+ # NMatrix.linspace(1,Math::PI, 6)
729
+ # =>[1.0,
730
+ # 1.4283185005187988,
731
+ # 1.8566370010375977,
732
+ # 2.2849555015563965,
733
+ # 2.7132740020751953,
734
+ # 3.1415927410125732
735
+ # ]
736
+ #
737
+ # NMatrix.linspace(1,10, [3,2])
738
+ # =>[
739
+ # [ 1.0, 2.799999952316284]
740
+ # [4.599999904632568, 6.400000095367432]
741
+ # [8.199999809265137, 10.0]
742
+ # ]
743
+ #
744
+ def linspace(base, limit, shape = [100])
745
+
746
+ # Convert shape to array format
747
+ shape = [shape] if shape.is_a? Integer
748
+
749
+ #Calculate number of elements
750
+ count = shape.inject(:*)
751
+
752
+ # Linear spacing between elements calculated in step
753
+ # step = limit - base / (count - 1)
754
+ # [Result Sequence] = [0->N sequence] * step + [Base]
755
+ step = (limit - base) * (1.0 / (count - 1))
756
+ result = NMatrix.seq(shape, {:dtype => :float64}) * step
757
+ result += NMatrix.new(shape, base)
758
+ result
759
+ end
760
+
761
+ # call-seq:
762
+ # logspace(base, limit) -> 1x50 NMatrix with exponent_base = 10
763
+ # logspace(base, limit, shape , exponent_base:) -> NMatrix
764
+ # logspace(base, :pi, n) -> 1xn NMatrix with interval [10 ^ base, Math::PI]
765
+ #
766
+ # Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ logarithmically spaced from
767
+ # +exponent_base ^ base+ to +exponent_base ^ limit+, inclusive.
768
+ #
769
+ # See: http://www.mathworks.com/help/matlab/ref/logspace.html
770
+ #
771
+ # * *Arguments* :
772
+ # - +base+ -> exponent_base ** base is the first value in the sequence
773
+ # - +limit+ -> exponent_base ** limit is the last value in the sequence.
774
+ # - +shape+ -> Desired output shape. Default returns a 1x50 row vector.
775
+ # * *Returns* :
776
+ # - NMatrix with +:float64+ values.
777
+ #
778
+ # Examples :-
779
+ #
780
+ # NMatrix.logspace(1,:pi,7)
781
+ # =>[
782
+ # 10.0000,
783
+ # 8.2450,
784
+ # 6.7980,
785
+ # 5.6050,
786
+ # 4.6213,
787
+ # 3.8103,
788
+ # 3.1416
789
+ # ]
790
+ #
791
+ # NMatrix.logspace(1,2,[3,2])
792
+ # =>[
793
+ # [10.0, 15.8489]
794
+ # [25.1189, 39.8107]
795
+ # [63.0957, 100.0]
796
+ # ]
797
+ #
798
+ def logspace(base, limit, shape = [50], exponent_base: 10)
799
+
800
+ #Calculate limit for [10 ^ base ... Math::PI] if limit = :pi
801
+ limit = Math.log(Math::PI, exponent_base = 10) if limit == :pi
802
+ shape = [shape] if shape.is_a? Integer
803
+
804
+ #[base...limit] -> [exponent_base ** base ... exponent_base ** limit]
805
+ result = NMatrix.linspace(base, limit, shape)
806
+ result.map {|element| exponent_base ** element}
807
+ end
808
+
809
+ #
810
+ # call-seq:
811
+ # seq(shape) -> NMatrix
812
+ # seq(shape, options) -> NMatrix
813
+ # bindgen(shape) -> NMatrix of :byte
814
+ # indgen(shape) -> NMatrix of :int64
815
+ # findgen(shape) -> NMatrix of :float32
816
+ # dindgen(shape) -> NMatrix of :float64
817
+ # cindgen(shape) -> NMatrix of :complex64
818
+ # zindgen(shape) -> NMatrix of :complex128
819
+ # rbindgen(shape) -> NMatrix of :object
820
+ #
821
+ # Creates a matrix filled with a sequence of integers starting at zero.
822
+ #
823
+ # * *Arguments* :
824
+ # - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
825
+ # - +options+ -> (optional) Options permissible for NMatrix#initialize
826
+ # * *Returns* :
827
+ # - NMatrix filled with values 0 through +size+.
828
+ #
829
+ # Examples:
830
+ #
831
+ # NMatrix.seq(2) # => 0 1
832
+ # 2 3
833
+ #
834
+ # NMatrix.seq([3, 3], dtype: :float32) # => 0.0 1.0 2.0
835
+ # 3.0 4.0 5.0
836
+ # 6.0 7.0 8.0
837
+ #
838
+ def seq(shape, options={})
839
+
840
+ # Construct the values of the final matrix based on the dimension.
841
+ values = (0 ... NMatrix.size(shape)).to_a
842
+
843
+ # It'll produce :int32, except if a dtype is provided.
844
+ NMatrix.new(shape, values, {:stype => :dense}.merge(options))
845
+ end
846
+
847
+ {:bindgen => :byte, :indgen => :int64, :findgen => :float32, :dindgen => :float64,
848
+ :cindgen => :complex64, :zindgen => :complex128,
849
+ :rbindgen => :object}.each_pair do |meth, dtype|
850
+ define_method(meth) { |shape| NMatrix.seq(shape, :dtype => dtype) }
851
+ end
852
+ end
853
+ end
854
+
855
+ module NVector #:nodoc:
856
+
857
+ class << self
858
+ #
859
+ # call-seq:
860
+ # new(shape) -> NVector
861
+ # new(stype, shape) -> NVector
862
+ # new(shape, init) -> NVector
863
+ # new(:dense, shape, init) -> NVector
864
+ # new(:list, shape, init) -> NVector
865
+ # new(shape, init, dtype) -> NVector
866
+ # new(stype, shape, init, dtype) -> NVector
867
+ # new(stype, shape, dtype) -> NVector
868
+ #
869
+ # Creates a new NVector. See also NMatrix#initialize for a more detailed explanation of
870
+ # the arguments.
871
+ #
872
+ # * *Arguments* :
873
+ # - +stype+ -> (optional) Storage type of the vector (:list, :dense, :yale). Defaults to :dense.
874
+ # - +shape+ -> Shape of the vector. Accepts [n,1], [1,n], or n, where n is a Fixnum.
875
+ # - +init+ -> (optional) Yale: capacity; List: default value (0); Dense: initial value or values (uninitialized by default).
876
+ # - +dtype+ -> (optional if +init+ provided) Data type stored in the vector. For :dense and :list, can be inferred from +init+.
877
+ # * *Returns* :
878
+ # -
879
+ #
880
+ def new(*args)
881
+ stype = args[0].is_a?(Symbol) ? args.shift : :dense
882
+ shape = args[0].is_a?(Array) ? args.shift : [1,args.shift]
883
+
884
+ if shape.size != 2 || !shape.include?(1) || shape == [1,1]
885
+ raise(ArgumentError, "shape must be a Fixnum or an Array of positive Fixnums where exactly one value is 1")
886
+ end
887
+
888
+ warn "NVector is deprecated and not guaranteed to work any longer"
889
+
890
+ NMatrix.new(stype, shape, *args)
891
+ end
892
+
893
+ #
894
+ # call-seq:
895
+ # zeros(size) -> NMatrix
896
+ # zeros(size, dtype) -> NMatrix
897
+ #
898
+ # Creates a new vector of zeros with the dimensions supplied as
899
+ # parameters.
900
+ #
901
+ # * *Arguments* :
902
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
903
+ # - +dtype+ -> (optional) Default is +:float64+.
904
+ # * *Returns* :
905
+ # - NVector filled with zeros.
906
+ #
907
+ # Examples:
908
+ #
909
+ # NVector.zeros(2) # => 0.0
910
+ # 0.0
911
+ #
912
+ # NVector.zeros(3, :int32) # => 0
913
+ # 0
914
+ # 0
915
+ #
916
+ def zeros(size, dtype = :float64)
917
+ NMatrix.new([size,1], 0, dtype: dtype)
918
+ end
919
+ alias :zeroes :zeros
920
+
921
+ #
922
+ # call-seq:
923
+ # ones(size) -> NVector
924
+ # ones(size, dtype) -> NVector
925
+ #
926
+ # Creates a vector of ones with the dimensions supplied as
927
+ # parameters.
928
+ #
929
+ # * *Arguments* :
930
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
931
+ # - +dtype+ -> (optional) Default is +:float64+.
932
+ # * *Returns* :
933
+ # - NVector filled with ones.
934
+ #
935
+ # Examples:
936
+ #
937
+ # NVector.ones(2) # => 1.0
938
+ # 1.0
939
+ #
940
+ # NVector.ones(3, :int32) # => 1
941
+ # 1
942
+ # 1
943
+ #
944
+ def ones(size, dtype = :float64)
945
+ NMatrix.new([size,1], 1, dtype: dtype)
946
+ end
947
+
948
+ #
949
+ # call-seq:
950
+ # random(size) -> NVector
951
+ #
952
+ # Creates a vector with random numbers between 0 and 1 generated by
953
+ # +Random::rand+ with the dimensions supplied as parameters.
954
+ #
955
+ # * *Arguments* :
956
+ # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
957
+ # - +opts+ -> (optional) NMatrix#initialize options
958
+ # * *Returns* :
959
+ # - NVector filled with random numbers generated by the +Random+ class.
960
+ #
961
+ # Examples:
962
+ #
963
+ # NVector.rand(2) # => 0.4859439730644226
964
+ # 0.1783195585012436
965
+ #
966
+ def random(size, opts = {})
967
+ rng = Random.new
968
+
969
+ random_values = []
970
+ size.times { |i| random_values << rng.rand }
971
+
972
+ NMatrix.new([size,1], random_values, opts)
973
+ end
974
+
975
+ #
976
+ # call-seq:
977
+ # seq(n) -> NVector
978
+ # seq(n, dtype) -> NVector
979
+ #
980
+ # Creates a vector with a sequence of +n+ integers starting at zero. You
981
+ # can choose other types based on the dtype parameter.
982
+ #
983
+ # * *Arguments* :
984
+ # - +n+ -> Number of integers in the sequence.
985
+ # - +dtype+ -> (optional) Default is +:int64+.
986
+ # * *Returns* :
987
+ # - NVector filled with +n+ integers.
988
+ #
989
+ # Examples:
990
+ #
991
+ # NVector.seq(2) # => 0
992
+ # 1
993
+ #
994
+ # NVector.seq(3, :float32) # => 0.0
995
+ # 1.0
996
+ # 2.0
997
+ #
998
+ def seq(size, dtype = :int64)
999
+ values = (0 ... size).to_a
1000
+
1001
+ NMatrix.new([size,1], values, dtype: dtype)
1002
+ end
1003
+
1004
+ #
1005
+ # call-seq:
1006
+ # indgen(n) -> NVector
1007
+ #
1008
+ # Returns an integer NVector. Equivalent to <tt>seq(n, :int32)</tt>.
1009
+ #
1010
+ # * *Arguments* :
1011
+ # - +n+ -> Size of the sequence.
1012
+ # * *Returns* :
1013
+ # - NVector filled with +n+ integers of dtype +:int32+.
1014
+ #
1015
+ def indgen(n)
1016
+ NVector.seq(n, :int32)
1017
+ end
1018
+
1019
+ #
1020
+ # call-seq:
1021
+ # findgen(n) -> NVector
1022
+ #
1023
+ # Returns a float NVector. Equivalent to <tt>seq(n, :float32)</tt>.
1024
+ #
1025
+ # * *Arguments* :
1026
+ # - +n+ -> Size of the sequence.
1027
+ # * *Returns* :
1028
+ # - NVector filled with +n+ integers of dtype +:float32+.
1029
+ #
1030
+ def findgen(n)
1031
+ NVector.seq(n, :float32)
1032
+ end
1033
+
1034
+ #
1035
+ # call-seq:
1036
+ # bindgen(n) -> NVector
1037
+ #
1038
+ # Returns a byte NVector. Equivalent to <tt>seq(n, :byte)</tt>.
1039
+ #
1040
+ # * *Arguments* :
1041
+ # - +n+ -> Size of the sequence.
1042
+ # * *Returns* :
1043
+ # - NVector filled with +n+ integers of dtype +:byte+.
1044
+ #
1045
+ def bindgen(n)
1046
+ NVector.seq(n, :byte)
1047
+ end
1048
+
1049
+ #
1050
+ # call-seq:
1051
+ # cindgen(n) -> NVector
1052
+ #
1053
+ # Returns a complex NVector. Equivalent to <tt>seq(n, :complex64)</tt>.
1054
+ #
1055
+ # * *Arguments* :
1056
+ # - +n+ -> Size of the sequence.
1057
+ # * *Returns* :
1058
+ # - NVector filled with +n+ integers of dtype +:complex64+.
1059
+ #
1060
+ def cindgen(n)
1061
+ NVector.seq(n, :complex64)
1062
+ end
1063
+
1064
+ #
1065
+ # call-seq:
1066
+ # linspace(a, b) -> NVector
1067
+ # linspace(a, b, n) -> NVector
1068
+ #
1069
+ # Returns a NVector with +n+ values of dtype +:float64+ equally spaced from
1070
+ # +a+ to +b+, inclusive.
1071
+ #
1072
+ # See: http://www.mathworks.com/help/matlab/ref/linspace.html
1073
+ #
1074
+ # * *Arguments* :
1075
+ # - +a+ -> The first value in the sequence.
1076
+ # - +b+ -> The last value in the sequence.
1077
+ # - +n+ -> The number of elements. Default is 100.
1078
+ # * *Returns* :
1079
+ # - NVector with +n+ +:float64+ values.
1080
+ #
1081
+ # Example:
1082
+ # x = NVector.linspace(0, Math::PI, 1000)
1083
+ # x.pretty_print
1084
+ # [0.0
1085
+ # 0.0031447373909807737
1086
+ # 0.006289474781961547
1087
+ # ...
1088
+ # 3.135303178807831
1089
+ # 3.138447916198812
1090
+ # 3.141592653589793]
1091
+ # => nil
1092
+ #
1093
+ def linspace(a, b, n = 100)
1094
+ # Formula: seq(n) * step + a
1095
+
1096
+ # step = ((b - a) / (n - 1))
1097
+ step = (b - a) * (1.0 / (n - 1))
1098
+
1099
+ # dtype = :float64 is used to prevent integer coercion.
1100
+ result = NVector.seq(n, :float64) * NMatrix.new([n,1], step, dtype: :float64)
1101
+ result += NMatrix.new([n,1], a, dtype: :float64)
1102
+ result
1103
+ end
1104
+
1105
+ #
1106
+ # call-seq:
1107
+ # logspace(a, b) -> NVector
1108
+ # logspace(a, b, n) -> NVector
1109
+ #
1110
+ # Returns a NVector with +n+ values of dtype +:float64+ logarithmically
1111
+ # spaced from +10^a+ to +10^b+, inclusive.
1112
+ #
1113
+ # See: http://www.mathworks.com/help/matlab/ref/logspace.html
1114
+ #
1115
+ # * *Arguments* :
1116
+ # - +a+ -> The first value in the sequence.
1117
+ # - +b+ -> The last value in the sequence.
1118
+ # - +n+ -> The number of elements. Default is 100.
1119
+ # * *Returns* :
1120
+ # - NVector with +n+ +:float64+ values.
1121
+ #
1122
+ # Example:
1123
+ # x = NVector.logspace(0, Math::PI, 10)
1124
+ # x.pretty_print
1125
+ # [1.0
1126
+ # 2.2339109164570266
1127
+ # 4.990357982665873
1128
+ # 11.148015174505757
1129
+ # 24.903672795156997
1130
+ # 55.632586516975095
1131
+ # 124.27824233101062
1132
+ # 277.6265222213364
1133
+ # 620.1929186882427
1134
+ # 1385.4557313670107]
1135
+ # => nil
1136
+ #
1137
+ def logspace(a, b, n = 100)
1138
+ # Formula: 10^a, 10^(a + step), ..., 10^b, where step = ((b-a) / (n-1)).
1139
+
1140
+ result = NVector.linspace(a, b, n)
1141
+ result.each_stored_with_index { |element, i| result[i] = 10 ** element }
1142
+ result
1143
+ end
1144
+ end
1145
+ end
1146
+
1147
+
1148
+ # This constant is intended as a simple constructor for NMatrix meant for
1149
+ # experimenting.
1150
+ #
1151
+ # Examples:
1152
+ #
1153
+ # a = N[ 1,2,3,4 ] => 1 2 3 4
1154
+ #
1155
+ # a = N[ 1,2,3,4, :int32 ] => 1 2 3 4
1156
+ #
1157
+ # a = N[ [1,2,3], [3,4,5] ] => 1 2 3
1158
+ # 3 4 5
1159
+ #
1160
+ # a = N[ 3,6,9 ].transpose => 3
1161
+ # 6
1162
+ # 9
1163
+ N = NMatrix