nmatrix 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -8
  3. data/.rspec +1 -1
  4. data/.travis.yml +12 -0
  5. data/CONTRIBUTING.md +27 -12
  6. data/Gemfile +1 -0
  7. data/History.txt +38 -0
  8. data/Manifest.txt +15 -15
  9. data/README.rdoc +7 -6
  10. data/Rakefile +40 -5
  11. data/ext/nmatrix/data/data.cpp +2 -37
  12. data/ext/nmatrix/data/data.h +19 -121
  13. data/ext/nmatrix/data/meta.h +70 -0
  14. data/ext/nmatrix/extconf.rb +40 -12
  15. data/ext/nmatrix/math/math.h +13 -103
  16. data/ext/nmatrix/nmatrix.cpp +10 -2018
  17. data/ext/nmatrix/nmatrix.h +16 -13
  18. data/ext/nmatrix/ruby_constants.cpp +12 -1
  19. data/ext/nmatrix/ruby_constants.h +7 -1
  20. data/ext/nmatrix/ruby_nmatrix.c +2169 -0
  21. data/ext/nmatrix/storage/dense.cpp +123 -14
  22. data/ext/nmatrix/storage/dense.h +10 -4
  23. data/ext/nmatrix/storage/list.cpp +265 -48
  24. data/ext/nmatrix/storage/list.h +6 -9
  25. data/ext/nmatrix/storage/storage.cpp +44 -54
  26. data/ext/nmatrix/storage/storage.h +2 -2
  27. data/ext/nmatrix/storage/yale/class.h +1070 -0
  28. data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
  29. data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
  30. data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
  31. data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
  32. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +167 -0
  33. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
  34. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  35. data/ext/nmatrix/storage/yale/yale.cpp +1785 -0
  36. data/ext/nmatrix/storage/{yale.h → yale/yale.h} +23 -55
  37. data/ext/nmatrix/types.h +2 -0
  38. data/ext/nmatrix/util/io.cpp +27 -45
  39. data/ext/nmatrix/util/io.h +0 -2
  40. data/ext/nmatrix/util/sl_list.cpp +169 -28
  41. data/ext/nmatrix/util/sl_list.h +9 -3
  42. data/lib/nmatrix/blas.rb +20 -20
  43. data/lib/nmatrix/enumerate.rb +1 -1
  44. data/lib/nmatrix/io/mat5_reader.rb +8 -14
  45. data/lib/nmatrix/lapack.rb +3 -3
  46. data/lib/nmatrix/math.rb +3 -3
  47. data/lib/nmatrix/nmatrix.rb +19 -5
  48. data/lib/nmatrix/nvector.rb +2 -0
  49. data/lib/nmatrix/shortcuts.rb +90 -125
  50. data/lib/nmatrix/version.rb +1 -1
  51. data/nmatrix.gemspec +7 -8
  52. data/spec/{nmatrix_spec.rb → 00_nmatrix_spec.rb} +45 -208
  53. data/spec/01_enum_spec.rb +184 -0
  54. data/spec/{slice_spec.rb → 02_slice_spec.rb} +55 -39
  55. data/spec/blas_spec.rb +22 -54
  56. data/spec/elementwise_spec.rb +9 -8
  57. data/spec/io_spec.rb +6 -4
  58. data/spec/lapack_spec.rb +26 -26
  59. data/spec/math_spec.rb +9 -5
  60. data/spec/nmatrix_yale_spec.rb +29 -61
  61. data/spec/shortcuts_spec.rb +34 -22
  62. data/spec/slice_set_spec.rb +157 -0
  63. data/spec/spec_helper.rb +42 -2
  64. data/spec/stat_spec.rb +192 -0
  65. metadata +52 -55
  66. data/ext/nmatrix/storage/yale.cpp +0 -2284
  67. data/spec/nmatrix_list_spec.rb +0 -113
  68. data/spec/nvector_spec.rb +0 -112
@@ -78,10 +78,15 @@ void mark(LIST* list, size_t recursions);
78
78
  ///////////////
79
79
 
80
80
  NODE* insert(LIST* list, bool replace, size_t key, void* val);
81
- NODE* insert_with_copy(LIST *list, size_t key, void *val, size_t size);
81
+ NODE* insert_copy(LIST *list, bool replace, size_t key, void *val, size_t size);
82
+ NODE* insert_first_node(LIST* list, size_t key, void* val, size_t val_size);
83
+ NODE* insert_first_list(LIST* list, size_t key, LIST* l);
82
84
  NODE* insert_after(NODE* node, size_t key, void* val);
85
+ NODE* replace_insert_after(NODE* node, size_t key, void* val, bool copy, size_t copy_size);
83
86
  void* remove(LIST* list, size_t key);
84
- bool remove_recursive(LIST* list, const size_t* coords, const size_t* offset, size_t r, const size_t& dim, void* rm);
87
+ void* remove_by_node(LIST* list, NODE* prev, NODE* rm);
88
+ bool remove_recursive(LIST* list, const size_t* coords, const size_t* offset, const size_t* lengths, size_t r, const size_t& dim);
89
+ bool node_is_within_slice(NODE* n, size_t coord, size_t len);
85
90
 
86
91
  template <typename Type>
87
92
  inline NODE* insert_helper(LIST* list, NODE* node, size_t key, Type val) {
@@ -116,7 +121,8 @@ inline NODE* insert_helper(LIST* list, NODE* node, size_t key, Type* ptr) {
116
121
  /////////////
117
122
 
118
123
  NODE* find(LIST* list, size_t key);
119
- NODE* find_preceding_from(NODE* prev, size_t key);
124
+ NODE* find_preceding_from_node(NODE* prev, size_t key);
125
+ NODE* find_preceding_from_list(LIST* l, size_t key);
120
126
  NODE* find_nearest(LIST* list, size_t key);
121
127
  NODE* find_nearest_from(NODE* prev, size_t key);
122
128
 
@@ -85,7 +85,7 @@ module NMatrix::BLAS
85
85
  end
86
86
 
87
87
  n ||= transpose_b ? b.shape[0] : b.shape[1]
88
- c = NMatrix.new([m, n], a.dtype)
88
+ c = NMatrix.new([m, n], dtype: a.dtype)
89
89
  end
90
90
 
91
91
  # I think these are independent of whether or not a transpose occurs.
@@ -107,9 +107,9 @@ module NMatrix::BLAS
107
107
 
108
108
  #
109
109
  # call-seq:
110
- # gemv(a, x) -> NVector
111
- # gemv(a, x, y) -> NVector
112
- # gemv(a, x, y, alpha, beta) -> NVector
110
+ # gemv(a, x) -> NMatrix
111
+ # gemv(a, x, y) -> NMatrix
112
+ # gemv(a, x, y, alpha, beta) -> NMatrix
113
113
  #
114
114
  # Implements matrix-vector product via
115
115
  # y = (alpha * A * x) + (beta * y)
@@ -150,7 +150,7 @@ module NMatrix::BLAS
150
150
  beta = Complex(0.0, 0.0) if beta == 0.0
151
151
  end
152
152
 
153
- y ||= NMatrix.new([m, n], a.dtype)
153
+ y ||= NMatrix.new([m, n], dtype: a.dtype)
154
154
 
155
155
  ::NMatrix::BLAS.cblas_gemv(transpose_a, m, n, alpha, a, lda, x, incx, beta, y, incy)
156
156
 
@@ -159,29 +159,29 @@ module NMatrix::BLAS
159
159
 
160
160
  #
161
161
  # call-seq:
162
- # rot(x, y, c, s) -> [NVector, NVector]
162
+ # rot(x, y, c, s) -> [NMatrix, NMatrix]
163
163
  #
164
164
  # Apply plane rotation.
165
165
  #
166
166
  # * *Arguments* :
167
- # - +x+ -> NVector
168
- # - +y+ -> NVector
167
+ # - +x+ -> NMatrix
168
+ # - +y+ -> NMatrix
169
169
  # - +c+ -> cosine of the angle of rotation
170
170
  # - +s+ -> sine of the angle of rotation
171
- # - +incx+ -> stride of NVector +x+
172
- # - +incy+ -> stride of NVector +y+
171
+ # - +incx+ -> stride of NMatrix +x+
172
+ # - +incy+ -> stride of NMatrix +y+
173
173
  # - +n+ -> number of elements to consider in x and y
174
174
  # - +in_place+ -> true if it's okay to modify the supplied +x+ and +y+ parameters directly; false if not. Default is false.
175
175
  # * *Returns* :
176
176
  # - Array with the results, in the format [xx, yy]
177
177
  # * *Raises* :
178
- # - +ArgumentError+ -> Expected dense NVectors as first two arguments.
178
+ # - +ArgumentError+ -> Expected dense NMatrices as first two arguments.
179
179
  # - +ArgumentError+ -> NMatrix dtype mismatch.
180
180
  # - +ArgumentError+ -> Need to supply n for non-standard incx, incy values.
181
181
  #
182
182
  def rot(x, y, c, s, incx = 1, incy = 1, n = nil, in_place=false)
183
- raise(ArgumentError, 'Expected dense NMatrices as first two arguments.') unless x.is_a?(NMatrix) and y.is_a?(NMatrix) and x.stype == :dense and y.stype == :dense
184
- raise(ArgumentError, 'NMatrix dtype mismatch.') unless x.dtype == y.dtype
183
+ raise(ArgumentError, 'Expected dense NMatrices as first two arguments.') unless x.is_a?(NMatrix) and y.is_a?(NMatrix) and x.stype == :dense and y.stype == :dense
184
+ raise(ArgumentError, 'NMatrix dtype mismatch.') unless x.dtype == y.dtype
185
185
  raise(ArgumentError, 'Need to supply n for non-standard incx, incy values') if n.nil? && incx != 1 && incx != -1 && incy != 1 && incy != -1
186
186
 
187
187
  n ||= [x.size/incx.abs, y.size/incy.abs].min
@@ -202,7 +202,7 @@ module NMatrix::BLAS
202
202
 
203
203
  #
204
204
  # call-seq:
205
- # rot!(x, y, c, s) -> [NVector, NVector]
205
+ # rot!(x, y, c, s) -> [NMatrix, NMatrix]
206
206
  #
207
207
  # Apply plane rotation directly to +x+ and +y+.
208
208
  #
@@ -221,11 +221,11 @@ module NMatrix::BLAS
221
221
  # Since the givens rotation includes a square root, integers and rationals are disallowed.
222
222
  #
223
223
  # * *Arguments* :
224
- # - +ab+ -> NVector with two elements
224
+ # - +ab+ -> NMatrix with two elements
225
225
  # * *Returns* :
226
226
  # - Array with the results, in the format [cos(theta), sin(theta)]
227
227
  # * *Raises* :
228
- # - +ArgumentError+ -> Expected dense NVector of size 2
228
+ # - +ArgumentError+ -> Expected dense NMatrix of size 2
229
229
  #
230
230
  def rotg(ab)
231
231
  raise(ArgumentError, "Expected dense NMatrix of shape [2,1] or [1,2]") unless ab.is_a?(NMatrix) && ab.stype == :dense && ab.size == 2
@@ -241,13 +241,13 @@ module NMatrix::BLAS
241
241
  # Calculate the sum of absolute values of the entries of a vector +x+ of size +n+
242
242
  #
243
243
  # * *Arguments* :
244
- # - +x+ -> an NVector (will also allow an NMatrix, but will treat it as if it's a vector )
244
+ # - +x+ -> an NMatrix (will also allow an NMatrix, but will treat it as if it's a vector )
245
245
  # - +incx+ -> the skip size (defaults to 1)
246
246
  # - +n+ -> the size of +x+ (defaults to +x.size / incx+)
247
247
  # * *Returns* :
248
248
  # - The sum
249
249
  # * *Raises* :
250
- # - +ArgumentError+ -> Expected dense NVector (or NMatrix on rare occasions) for arg 0
250
+ # - +ArgumentError+ -> Expected dense NMatrix for arg 0
251
251
  # - +RangeError+ -> n out of range
252
252
  #
253
253
  def asum(x, incx = 1, n = nil)
@@ -264,13 +264,13 @@ module NMatrix::BLAS
264
264
  # Calculate the 2-norm of a vector +x+ of size +n+
265
265
  #
266
266
  # * *Arguments* :
267
- # - +x+ -> an NVector (will also allow an NMatrix, but will treat it as if it's a vector )
267
+ # - +x+ -> an NMatrix (will also allow an NMatrix, but will treat it as if it's a vector )
268
268
  # - +incx+ -> the skip size (defaults to 1)
269
269
  # - +n+ -> the size of +x+ (defaults to +x.size / incx+)
270
270
  # * *Returns* :
271
271
  # - The 2-norm
272
272
  # * *Raises* :
273
- # - +ArgumentError+ -> Expected dense NVector (or NMatrix on rare occasions) for arg 0
273
+ # - +ArgumentError+ -> Expected dense NMatrix for arg 0
274
274
  # - +RangeError+ -> n out of range
275
275
  #
276
276
  def nrm2(x, incx = 1, n = nil)
@@ -215,7 +215,7 @@ class NMatrix
215
215
  first_as_acc = false
216
216
 
217
217
  if initial then
218
- acc = NMatrix.new(new_shape, initial, dtype || self.dtype)
218
+ acc = NMatrix.new(new_shape, initial, :dtype => dtype || self.dtype)
219
219
  else
220
220
  each_rank(dimen) do |sub_mat|
221
221
  acc = (sub_mat.is_a?(NMatrix) and !dtype.nil? and dtype != self.dtype) ? sub_mat.cast(self.stype, dtype) : sub_mat
@@ -293,19 +293,16 @@ module NMatrix::IO::Matlab
293
293
 
294
294
  #
295
295
  # call-seq:
296
- # repacked_indices(to_itype) ->
296
+ # repacked_indices ->
297
297
  #
298
298
  # Unpacks and repacks index data into the appropriate format for NMatrix.
299
299
  #
300
300
  # If data is already in the appropriate format, does not unpack or
301
301
  # repack, just returns directly.
302
302
  #
303
- def repacked_indices(to_itype)
304
- return [row_index.data, column_index.data] if to_itype == :uint32 # No need to re-pack -- already correct
305
-
306
- STDERR.puts "indices: Requesting itype #{to_itype.inspect}"
307
- repacked_row_indices = ::NMatrix::IO::Matlab.repack( self.row_index.data, :miINT32, :itype => to_itype )
308
- repacked_col_indices = ::NMatrix::IO::Matlab.repack( self.column_index.data, :miINT32, :itype => to_itype )
303
+ def repacked_indices
304
+ repacked_row_indices = ::NMatrix::IO::Matlab.repack( self.row_index.data, :miINT32, :itype )
305
+ repacked_col_indices = ::NMatrix::IO::Matlab.repack( self.column_index.data, :miINT32, :itype )
309
306
 
310
307
  [repacked_row_indices, repacked_col_indices]
311
308
  end
@@ -341,14 +338,11 @@ module NMatrix::IO::Matlab
341
338
  when :mxSPARSE
342
339
  raise(NotImplementedError, "expected .mat row indices to be of type :miINT32") unless row_index.tag.data_type == :miINT32
343
340
  raise(NotImplementedError, "expected .mat column indices to be of type :miINT32") unless column_index.tag.data_type == :miINT32
344
-
345
- to_itype = NMatrix.itype_by_shape(dimensions)
346
-
347
341
  #require 'pry'
348
342
  #binding.pry
349
343
 
350
344
  # MATLAB always uses :miINT32 for indices according to the spec
351
- ia_ja = repacked_indices(to_itype)
345
+ ia_ja = repacked_indices
352
346
  data_str, repacked_dtype = repacked_data(dtype)
353
347
  NMatrix.new(:yale, self.dimensions.reverse, repacked_dtype, ia_ja[0], ia_ja[1], data_str, repacked_dtype)
354
348
 
@@ -443,9 +437,9 @@ module NMatrix::IO::Matlab
443
437
 
444
438
  FIRST_TAG_FIELD_POS = 128
445
439
 
446
- ####################
447
- # Instance Methods #
448
- ####################
440
+ ###################################
441
+ # Instance Methods for Mat5Reader #
442
+ ###################################
449
443
 
450
444
  def initialize(stream, options = {})
451
445
  super(stream, options)
@@ -151,9 +151,9 @@ class NMatrix
151
151
  # Build up the u and vt matrices
152
152
  m, n = matrix.shape
153
153
  dtype = matrix.dtype
154
- s_matrix = NMatrix.new([1,matrix.shape.min], dtype)
155
- u_matrix = NMatrix.new([m,m], dtype)
156
- v_matrix = NMatrix.new([n,n], dtype)
154
+ s_matrix = NMatrix.new([1,matrix.shape.min], dtype: dtype)
155
+ u_matrix = NMatrix.new([m,m], dtype: dtype)
156
+ v_matrix = NMatrix.new([n,n], dtype: dtype)
157
157
  # test this
158
158
  s = gesvd(type, matrix, s_matrix, u_matrix, v_matrix)
159
159
 
@@ -99,9 +99,9 @@ class NMatrix
99
99
 
100
100
  def alloc_svd_result
101
101
  [
102
- NMatrix.new(:dense, self.shape[0], self.dtype),
103
- NMatrix.new(:dense, [self.shape[0],1], self.dtype),
104
- NMatrix.new(:dense, self.shape[1], self.dtype)
102
+ NMatrix.new(self.shape[0], dtype: self.dtype),
103
+ NMatrix.new([self.shape[0],1], dtype: self.dtype),
104
+ NMatrix.new(self.shape[1], dtype: self.dtype)
105
105
  ]
106
106
  end
107
107
 
@@ -65,6 +65,13 @@ class NMatrix
65
65
  def load_file(file_path)
66
66
  NMatrix::IO::Mat5Reader.new(File.open(file_path, 'rb')).to_ruby
67
67
  end
68
+
69
+ #
70
+ # Calculate the size of an NMatrix of a given shape.
71
+ def size(shape)
72
+ shape = [shape,shape] unless shape.is_a?(Array)
73
+ (0...shape.size).inject(1) { |x,i| x * shape[i] }
74
+ end
68
75
  end
69
76
 
70
77
  # TODO: Make this actually pretty.
@@ -76,7 +83,7 @@ class NMatrix
76
83
  longest = Array.new(self.shape[1], 0)
77
84
  self.each_column.with_index do |col, j|
78
85
  col.each do |elem|
79
- elem_len = elem.to_s.size
86
+ elem_len = elem.inspect.size
80
87
  longest[j] = elem_len if longest[j] < elem_len
81
88
  end
82
89
  end
@@ -87,7 +94,7 @@ class NMatrix
87
94
  q.group(0, "\n [\n", " ]\n") do
88
95
  layer.each_row.with_index do |row,i|
89
96
  q.group(0, " [", "]\n") do
90
- q.seplist(self[i,0...self.shape[1],k].to_flat_array, lambda { q.text ", "}, :each_with_index) { |v,j| q.text v.to_s.rjust(longest[j]) }
97
+ q.seplist(self[i,0...self.shape[1],k].to_flat_array, lambda { q.text ", "}, :each_with_index) { |v,j| q.text v.inspect.rjust(longest[j]) }
91
98
  end
92
99
  end
93
100
  end
@@ -97,7 +104,7 @@ class NMatrix
97
104
  q.group(0, "\n[\n", "]") do
98
105
  self.each_row.with_index do |row,i|
99
106
  q.group(1, " [", "]") do
100
- q.seplist(self.dim > 2 ? row.to_a[0] : row.to_a, lambda { q.text ", " }, :each_with_index) { |v,j| q.text v.to_s.rjust(longest[j]) }
107
+ q.seplist(self.dim > 2 ? row.to_a[0] : row.to_a, lambda { q.text ", " }, :each_with_index) { |v,j| q.text v.inspect.rjust(longest[j]) }
101
108
  end
102
109
  q.breakable
103
110
  end
@@ -258,8 +265,7 @@ class NMatrix
258
265
  # Returns the total size of the NMatrix based on its shape.
259
266
  #
260
267
  def size
261
- s = self.shape
262
- (0...self.dimensions).inject(1) { |x,i| x * s[i] }
268
+ NMatrix.size(self.shape)
263
269
  end
264
270
 
265
271
 
@@ -455,6 +461,7 @@ class NMatrix
455
461
  #def __list_elementwise_add__ rhs
456
462
  # self.__list_map_merged_stored__(rhs){ |l,r| l+r }.cast(self.stype, NMatrix.upcast(self.dtype, rhs.dtype))
457
463
  #end
464
+ protected
458
465
 
459
466
  def inspect_helper #:nodoc:
460
467
  ary = []
@@ -486,6 +493,13 @@ class NMatrix
486
493
  end
487
494
  ary
488
495
  end
496
+
497
+
498
+ # NMatrix constructor helper for sparse matrices. Uses multi-slice-setting to initialize a matrix
499
+ # with a given array of initial values.
500
+ def __sparse_initial_set__(ary) #:nodoc:
501
+ self[0...self.shape[0],0...self.shape[1]] = ary
502
+ end
489
503
  end
490
504
 
491
505
  require_relative './shortcuts.rb'
@@ -61,6 +61,8 @@ class NVector < NMatrix
61
61
  raise(ArgumentError, "shape must be a Fixnum or an Array of positive Fixnums where exactly one value is 1")
62
62
  end
63
63
 
64
+ warn "NVector is deprecated"
65
+
64
66
  super(stype, shape, *args)
65
67
  end
66
68
 
@@ -70,7 +70,7 @@ class NMatrix
70
70
  #
71
71
  # a = NMatrix[ 1,2,3,4 ] => 1.0 2.0 3.0 4.0
72
72
  #
73
- # a = NMatrix[ 1,2,3,4, :int32 ] => 1 2 3 4
73
+ # a = NMatrix[ 1,2,3,4, dtype: :int32 ] => 1 2 3 4
74
74
  #
75
75
  # a = NMatrix[ [1,2,3], [3,4,5] ] => 1.0 2.0 3.0
76
76
  # 3.0 4.0 5.0
@@ -85,7 +85,7 @@ class NMatrix
85
85
  # Ruby array: a = [ [1,2,3], [4,5,6] ]
86
86
  #
87
87
  def [](*params)
88
- dtype = params.last.is_a?(Symbol) ? params.pop : nil
88
+ options = params.last.is_a?(Hash) ? params.pop : {}
89
89
 
90
90
  # First find the dimensions of the array.
91
91
  i = 0
@@ -101,22 +101,22 @@ class NMatrix
101
101
  #shape.unshift(1) if shape.size == 1
102
102
 
103
103
  # Then flatten the array.
104
- NMatrix.new(shape, params.flatten, dtype)
104
+ NMatrix.new(shape, params.flatten, options)
105
105
  end
106
106
 
107
107
  #
108
108
  # call-seq:
109
- # zeros(size) -> NMatrix
110
- # zeros(size, dtype) -> NMatrix
111
- # zeros(stype, size, dtype) -> NMatrix
109
+ # zeros(shape) -> NMatrix
110
+ # zeros(shape, dtype: dtype) -> NMatrix
111
+ # zeros(shape, dtype: dtype, stype: stype) -> NMatrix
112
112
  #
113
113
  # Creates a new matrix of zeros with the dimensions supplied as
114
114
  # parameters.
115
115
  #
116
116
  # * *Arguments* :
117
- # - +stype+ -> (optional) Default is +:dense+.
118
- # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
117
+ # - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
119
118
  # - +dtype+ -> (optional) Default is +:float64+
119
+ # - +stype+ -> (optional) Default is +:dense+.
120
120
  # * *Returns* :
121
121
  # - NMatrix filled with zeros.
122
122
  #
@@ -125,30 +125,26 @@ class NMatrix
125
125
  # NMatrix.zeros(2) # => 0.0 0.0
126
126
  # 0.0 0.0
127
127
  #
128
- # NMatrix.zeros([2, 3], :int32) # => 0 0 0
129
- # 0 0 0
128
+ # NMatrix.zeros([2, 3], dtype: :int32) # => 0 0 0
129
+ # 0 0 0
130
130
  #
131
- # NMatrix.zeros(:list, [1, 5], :int32) # => 0 0 0 0 0
131
+ # NMatrix.zeros([1, 5], dtype: :int32) # => 0 0 0 0 0
132
132
  #
133
- def zeros(*params)
134
- dtype = params.last.is_a?(Symbol) ? params.pop : :float64
135
- stype = params.first.is_a?(Symbol) ? params.shift : :dense
136
- dim = params.first
137
-
138
- NMatrix.new(stype, dim, 0, dtype)
133
+ def zeros(shape, opts = {})
134
+ NMatrix.new(shape, 0, {:dtype => :float64}.merge(opts))
139
135
  end
140
136
  alias :zeroes :zeros
141
137
 
142
138
  #
143
139
  # call-seq:
144
- # ones(size) -> NMatrix
145
- # ones(size, dtype) -> NMatrix
140
+ # ones(shape) -> NMatrix
141
+ # ones(shape, dtype: dtype, stype: stype) -> NMatrix
146
142
  #
147
143
  # Creates a matrix filled with ones.
148
144
  #
149
145
  # * *Arguments* :
150
- # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
151
- # - +dtype+ -> (optional) Default is +:float64+
146
+ # - +shape+ -> Array (or integer for square matrix) specifying the shape.
147
+ # - +opts+ -> (optional) Hash of options from NMatrix#initialize
152
148
  # * *Returns* :
153
149
  # - NMatrix filled with ones.
154
150
  #
@@ -156,14 +152,11 @@ class NMatrix
156
152
  #
157
153
  # NMatrix.ones([1, 3]) # => 1.0 1.0 1.0
158
154
  #
159
- # NMatrix.ones([2, 3], :int32) # => 1 1 1
160
- # 1 1 1
155
+ # NMatrix.ones([2, 3], dtype: :int32) # => 1 1 1
156
+ # 1 1 1
161
157
  #
162
- def ones(*params)
163
- dtype = params.last.is_a?(Symbol) ? params.pop : :float64
164
- dim = params.first
165
-
166
- NMatrix.new(dim, 1, dtype)
158
+ def ones(shape, opts={})
159
+ NMatrix.new(shape, 1, {:dtype => :float64, :default => 1}.merge(opts))
167
160
  end
168
161
 
169
162
  ##
@@ -177,7 +170,7 @@ class NMatrix
177
170
  # @return [NMatrix] a new nmatrix filled with ones.
178
171
  #
179
172
  def ones_like(nm)
180
- NMatrix.ones(nm.shape, nm.dtype)
173
+ NMatrix.ones(nm.shape, dtype: nm.dtype, stype: nm.stype, capacity: nm.capacity, default: 1)
181
174
  end
182
175
 
183
176
  ##
@@ -191,23 +184,23 @@ class NMatrix
191
184
  # @return [NMatrix] a new nmatrix filled with zeros.
192
185
  #
193
186
  def zeros_like(nm)
194
- NMatrix.zeros(nm.stype, nm.shape, nm.dtype)
187
+ NMatrix.zeros(nm.shape, dtype: nm.dtype, stype: nm.stype, capacity: nm.capacity, default: 0)
195
188
  end
196
189
 
197
190
  #
198
191
  # call-seq:
199
- # eye(size) -> NMatrix
200
- # eye(size, dtype) -> NMatrix
201
- # eye(stype, size, dtype) -> NMatrix
192
+ # eye(shape) -> NMatrix
193
+ # eye(shape, dtype: dtype) -> NMatrix
194
+ # eye(shape, stype: stype, dtype: dtype) -> NMatrix
202
195
  #
203
196
  # Creates an identity matrix (square matrix rank 2).
204
197
  #
205
198
  # * *Arguments* :
206
- # - +stype+ -> (optional) Default is +:dense+.
207
199
  # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
208
200
  # - +dtype+ -> (optional) Default is +:float64+
201
+ # - +stype+ -> (optional) Default is +:dense+.
209
202
  # * *Returns* :
210
- # - NMatrix filled with zeros.
203
+ # - An identity matrix.
211
204
  #
212
205
  # Examples:
213
206
  #
@@ -215,22 +208,17 @@ class NMatrix
215
208
  # 0.0 1.0 0.0
216
209
  # 0.0 0.0 1.0
217
210
  #
218
- # NMatrix.eye(3, :int32) # => 1 0 0
219
- # 0 1 0
220
- # 0 0 1
211
+ # NMatrix.eye(3, dtype: :int32) # => 1 0 0
212
+ # 0 1 0
213
+ # 0 0 1
221
214
  #
222
- # NMatrix.eye(:yale, 2, :int32) # => 1 0
223
- # 0 1
215
+ # NMatrix.eye(2, dtype: :int32, stype: :yale) # => 1 0
216
+ # 0 1
224
217
  #
225
- def eye(*params)
226
- dtype = params.last.is_a?(Symbol) ? params.pop : :float64
227
- stype = params.first.is_a?(Symbol) ? params.shift : :dense
228
-
229
- dim = params.first
230
-
218
+ def eye(shape, opts={})
231
219
  # Fill the diagonal with 1's.
232
- m = NMatrix.zeros(stype, dim, dtype)
233
- (0...dim).each do |i|
220
+ m = NMatrix.zeros(shape, {:dtype => :float64}.merge(opts))
221
+ (0...m.shape[0]).each do |i|
234
222
  m[i, i] = 1
235
223
  end
236
224
 
@@ -240,16 +228,13 @@ class NMatrix
240
228
  #
241
229
  # call-seq:
242
230
  # diagonals(array) -> NMatrix
243
- # diagonals(stype, array, dtype) -> NMatrix
244
- # diagonals(array, dtype) -> NMatrix
245
- # diagonals(stype, array) -> NMatrix
231
+ # diagonals(array, dtype: dtype, stype: stype) -> NMatrix
246
232
  #
247
233
  # Creates a matrix filled with specified diagonals.
248
234
  #
249
235
  # * *Arguments* :
250
- # - +stype+ -> (optional) Storage type for the matrix (default is :dense)
251
236
  # - +entries+ -> Array containing input values for diagonal matrix
252
- # - +dtype+ -> (optional) Default is based on values in supplied Array
237
+ # - +options+ -> (optional) Hash with options for NMatrix#initialize
253
238
  # * *Returns* :
254
239
  # - NMatrix filled with specified diagonal values.
255
240
  #
@@ -260,19 +245,17 @@ class NMatrix
260
245
  # 0.0 0.0 3.0 0.0
261
246
  # 0.0 0.0 0.0 4.0
262
247
  #
263
- # NMatrix.diagonal(:dense, [1,2,3,4], :int32) # => 1 0 0 0
264
- # 0 2 0 0
265
- # 0 0 3 0
266
- # 0 0 0 4
248
+ # NMatrix.diagonal([1,2,3,4], dtype: :int32) # => 1 0 0 0
249
+ # 0 2 0 0
250
+ # 0 0 3 0
251
+ # 0 0 0 4
267
252
  #
268
253
  #
269
- def diagonal(*params)
270
- dtype = params.last.is_a?(Symbol) ? params.pop : nil
271
- stype = params.first.is_a?(Symbol) ? params.shift : :dense
272
- ary = params.shift
273
-
274
- m = NMatrix.zeros(stype, ary.length, dtype || guess_dtype(ary[0]))
275
- ary.each_with_index do |n, i|
254
+ def diagonal(entries, opts={})
255
+ m = NMatrix.zeros(entries.size,
256
+ {:dtype => guess_dtype(entries[0]), :capacity => entries.size + 1}.merge(opts)
257
+ )
258
+ entries.each_with_index do |n, i|
276
259
  m[i,i] = n
277
260
  end
278
261
  m
@@ -282,141 +265,121 @@ class NMatrix
282
265
 
283
266
  #
284
267
  # call-seq:
285
- # random(size) -> NMatrix
268
+ # random(shape) -> NMatrix
286
269
  #
287
270
  # Creates a +:dense+ NMatrix with random numbers between 0 and 1 generated
288
271
  # by +Random::rand+. The parameter is the dimension of the matrix.
289
272
  #
290
273
  # * *Arguments* :
291
- # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
274
+ # - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
292
275
  # * *Returns* :
293
- # - NMatrix filled with zeros.
276
+ # - NMatrix filled with random values.
294
277
  #
295
278
  # Examples:
296
279
  #
297
280
  # NMatrix.random([2, 2]) # => 0.4859439730644226 0.1783195585012436
298
281
  # 0.23193766176700592 0.4503345191478729
299
282
  #
300
- def random(size)
283
+ def random(shape, opts={})
301
284
  rng = Random.new
302
285
 
303
286
  random_values = []
304
287
 
305
288
  # Construct the values of the final matrix based on the dimension.
306
- if size.is_a?(Integer)
307
- (size * size - 1).times { |i| random_values << rng.rand }
308
- else
309
- # Dimensions given by an array. Get the product of the array elements
310
- # and generate this number of random values.
311
- size.reduce(1, :*).times { |i| random_values << rng.rand }
312
- end
289
+ NMatrix.size(shape).times { |i| random_values << rng.rand }
313
290
 
314
- NMatrix.new(:dense, size, random_values, :float64)
291
+ NMatrix.new(shape, random_values, {:dtype => :float64, :stype => :dense}.merge(opts))
315
292
  end
316
293
 
317
294
  #
318
295
  # call-seq:
319
- # seq(size) -> NMatrix
320
- # seq(size, dtype) -> NMatrix
296
+ # seq(shape) -> NMatrix
297
+ # seq(shape, options) -> NMatrix
321
298
  #
322
299
  # Creates a matrix filled with a sequence of integers starting at zero.
323
300
  #
324
301
  # * *Arguments* :
325
- # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
326
- # - +dtype+ -> (optional) Default is +:float64+
302
+ # - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
303
+ # - +options+ -> (optional) Options permissible for NMatrix#initialize
327
304
  # * *Returns* :
328
- # - NMatrix filled with zeros.
305
+ # - NMatrix filled with values 0 through +size+.
329
306
  #
330
307
  # Examples:
331
308
  #
332
309
  # NMatrix.seq(2) # => 0 1
333
310
  # 2 3
334
311
  #
335
- # NMatrix.seq([3, 3], :float32) # => 0.0 1.0 2.0
312
+ # NMatrix.seq([3, 3], dtype: :float32) # => 0.0 1.0 2.0
336
313
  # 3.0 4.0 5.0
337
314
  # 6.0 7.0 8.0
338
315
  #
339
- def seq(*params)
340
- dtype = params.last.is_a?(Symbol) ? params.pop : nil
341
- size = params.first
342
-
343
- # Must provide the dimension as an Integer for a square matrix or as an
344
- # 2 element array, e.g. [2,4].
345
- unless size.is_a?(Integer) || (size.is_a?(Array) && size.size < 3)
346
- raise ArgumentError, "seq() accepts only integers or 2-element arrays \
347
- as dimension."
348
- end
316
+ def seq(shape, options={})
349
317
 
350
318
  # Construct the values of the final matrix based on the dimension.
351
- if size.is_a?(Integer)
352
- values = (0 .. (size * size - 1)).to_a
353
- else
354
- # Dimensions given by a 2 element array.
355
- values = (0 .. (size.first * size.last - 1)).to_a
356
- end
319
+ values = (0 ... NMatrix.size(shape)).to_a
357
320
 
358
321
  # It'll produce :int32, except if a dtype is provided.
359
- NMatrix.new(:dense, size, values, dtype)
322
+ NMatrix.new(shape, values, {:stype => :dense}.merge(options))
360
323
  end
361
324
 
362
325
  #
363
326
  # call-seq:
364
327
  # indgen(size) -> NMatrix
365
328
  #
366
- # Returns an integer NMatrix. Equivalent to <tt>seq(n, :int32)</tt>.
329
+ # Returns an integer NMatrix. Equivalent to <tt>seq(n, dtype: :int32)</tt>.
367
330
  #
368
331
  # * *Arguments* :
369
- # - +size+ -> Size of the sequence.
332
+ # - +shape+ -> Shape of the sequence.
370
333
  # * *Returns* :
371
334
  # - NMatrix with dtype +:int32+.
372
335
  #
373
- def indgen(size)
374
- NMatrix.seq(size, :int32)
336
+ def indgen(shape)
337
+ NMatrix.seq(shape, dtype: :int32)
375
338
  end
376
339
 
377
340
  #
378
341
  # call-seq:
379
- # findgen(size) -> NMatrix
342
+ # findgen(shape) -> NMatrix
380
343
  #
381
- # Returns a float NMatrix. Equivalent to <tt>seq(n, :float32)</tt>.
344
+ # Returns a float NMatrix. Equivalent to <tt>seq(n, dtype: :float32)</tt>.
382
345
  #
383
346
  # * *Arguments* :
384
- # - +size+ -> Size of the sequence.
347
+ # - +shape+ -> Shape of the sequence.
385
348
  # * *Returns* :
386
349
  # - NMatrix with dtype +:float32+.
387
350
  #
388
- def findgen(size)
389
- NMatrix.seq(size, :float32)
351
+ def findgen(shape)
352
+ NMatrix.seq(shape, dtype: :float32)
390
353
  end
391
354
 
392
355
  #
393
356
  # call-seq:
394
357
  # bindgen(size) -> NMatrix
395
358
  #
396
- # Returns a byte NMatrix. Equivalent to <tt>seq(n, :byte)</tt>.
359
+ # Returns a byte NMatrix. Equivalent to <tt>seq(n, dtype: :byte)</tt>.
397
360
  #
398
361
  # * *Arguments* :
399
- # - +size+ -> Size of the sequence.
362
+ # - +size+ -> Shape of the sequence.
400
363
  # * *Returns* :
401
364
  # - NMatrix with dtype +:byte+.
402
365
  #
403
- def bindgen(size)
404
- NMatrix.seq(size, :byte)
366
+ def bindgen(shape)
367
+ NMatrix.seq(shape, dtype: :byte)
405
368
  end
406
369
 
407
370
  #
408
371
  # call-seq:
409
- # cindgen(size) -> NMatrix
372
+ # cindgen(shape) -> NMatrix
410
373
  #
411
- # Returns an complex NMatrix. Equivalent to <tt>seq(n, :complex64)</tt>.
374
+ # Returns a complex NMatrix. Equivalent to <tt>seq(n, dtype: :complex64)</tt>.
412
375
  #
413
376
  # * *Arguments* :
414
- # - +size+ -> Size of the sequence.
377
+ # - +shape+ -> Shape of the sequence.
415
378
  # * *Returns* :
416
379
  # - NMatrix with dtype +:complex64+.
417
380
  #
418
- def cindgen(size)
419
- NMatrix.seq(size, :complex64)
381
+ def cindgen(shape)
382
+ NMatrix.seq(shape, dtype: :complex64)
420
383
  end
421
384
 
422
385
  end
@@ -455,6 +418,8 @@ module NVector
455
418
  raise(ArgumentError, "shape must be a Fixnum or an Array of positive Fixnums where exactly one value is 1")
456
419
  end
457
420
 
421
+ warn "NVector is deprecated and not guaranteed to work any longer"
422
+
458
423
  NMatrix.new(stype, shape, *args)
459
424
  end
460
425
 
@@ -482,7 +447,7 @@ module NVector
482
447
  # 0
483
448
  #
484
449
  def zeros(size, dtype = :float64)
485
- NVector.new(size, 0, dtype)
450
+ NMatrix.new([size,1], 0, dtype: dtype)
486
451
  end
487
452
  alias :zeroes :zeros
488
453
 
@@ -510,7 +475,7 @@ module NVector
510
475
  # 1
511
476
  #
512
477
  def ones(size, dtype = :float64)
513
- NVector.new(size, 1, dtype)
478
+ NMatrix.new([size,1], 1, dtype: dtype)
514
479
  end
515
480
 
516
481
  #
@@ -522,7 +487,7 @@ module NVector
522
487
  #
523
488
  # * *Arguments* :
524
489
  # - +size+ -> Array (or integer for square matrix) specifying the dimensions.
525
- # - +dtype+ -> (optional) Default is +:float64+.
490
+ # - +opts+ -> (optional) NMatrix#initialize options
526
491
  # * *Returns* :
527
492
  # - NVector filled with random numbers generated by the +Random+ class.
528
493
  #
@@ -531,13 +496,13 @@ module NVector
531
496
  # NVector.rand(2) # => 0.4859439730644226
532
497
  # 0.1783195585012436
533
498
  #
534
- def random(size)
499
+ def random(size, opts = {})
535
500
  rng = Random.new
536
501
 
537
502
  random_values = []
538
503
  size.times { |i| random_values << rng.rand }
539
504
 
540
- NVector.new(size, random_values, :float64)
505
+ NMatrix.new([size,1], random_values, opts)
541
506
  end
542
507
 
543
508
  #
@@ -566,7 +531,7 @@ module NVector
566
531
  def seq(size, dtype = :int64)
567
532
  values = (0 ... size).to_a
568
533
 
569
- NVector.new(size, values, dtype)
534
+ NMatrix.new([size,1], values, dtype: dtype)
570
535
  end
571
536
 
572
537
  #
@@ -665,8 +630,8 @@ module NVector
665
630
  step = (b - a) * (1.0 / (n - 1))
666
631
 
667
632
  # dtype = :float64 is used to prevent integer coercion.
668
- result = NVector.seq(n, :float64) * NVector.new(n, step, :float64)
669
- result += NVector.new(n, a, :float64)
633
+ result = NVector.seq(n, :float64) * NMatrix.new([n,1], step, dtype: :float64)
634
+ result += NMatrix.new([n,1], a, dtype: :float64)
670
635
  result
671
636
  end
672
637