nmatrix 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/ext/nmatrix/data/data.cpp +9 -9
  3. data/ext/nmatrix/data/data.h +7 -8
  4. data/ext/nmatrix/data/ruby_object.h +1 -4
  5. data/ext/nmatrix/extconf.rb +9 -127
  6. data/ext/nmatrix/math.cpp +25 -25
  7. data/ext/nmatrix/math/asum.h +10 -31
  8. data/ext/nmatrix/math/cblas_templates_core.h +10 -10
  9. data/ext/nmatrix/math/getrf.h +2 -2
  10. data/ext/nmatrix/math/imax.h +12 -9
  11. data/ext/nmatrix/math/laswp.h +3 -3
  12. data/ext/nmatrix/math/long_dtype.h +16 -3
  13. data/ext/nmatrix/math/magnitude.h +54 -0
  14. data/ext/nmatrix/math/nrm2.h +19 -14
  15. data/ext/nmatrix/math/trsm.h +40 -36
  16. data/ext/nmatrix/math/util.h +14 -0
  17. data/ext/nmatrix/nmatrix.h +39 -1
  18. data/ext/nmatrix/ruby_nmatrix.c +45 -83
  19. data/ext/nmatrix/storage/common.h +9 -3
  20. data/ext/nmatrix/storage/dense/dense.cpp +4 -4
  21. data/ext/nmatrix/storage/list/list.cpp +2 -2
  22. data/ext/nmatrix/storage/yale/class.h +1 -1
  23. data/lib/nmatrix/blas.rb +103 -34
  24. data/lib/nmatrix/io/fortran_format.rb +8 -5
  25. data/lib/nmatrix/io/harwell_boeing.rb +11 -10
  26. data/lib/nmatrix/io/market.rb +9 -6
  27. data/lib/nmatrix/io/mat5_reader.rb +54 -29
  28. data/lib/nmatrix/io/mat_reader.rb +26 -14
  29. data/lib/nmatrix/io/point_cloud.rb +19 -11
  30. data/lib/nmatrix/math.rb +224 -5
  31. data/lib/nmatrix/mkmf.rb +103 -0
  32. data/lib/nmatrix/nmatrix.rb +20 -6
  33. data/lib/nmatrix/shortcuts.rb +415 -0
  34. data/lib/nmatrix/version.rb +1 -1
  35. data/spec/00_nmatrix_spec.rb +50 -1
  36. data/spec/02_slice_spec.rb +21 -21
  37. data/spec/blas_spec.rb +25 -3
  38. data/spec/math_spec.rb +233 -5
  39. data/spec/shortcuts_spec.rb +145 -5
  40. data/spec/spec_helper.rb +24 -1
  41. metadata +20 -4
@@ -551,7 +551,7 @@ void set(VALUE left, SLICE* slice, VALUE right) {
551
551
  v = reinterpret_cast<D*>(t->elements);
552
552
  v_size = nm_storage_count_max_elements(t);
553
553
 
554
- } else if (TYPE(right) == T_ARRAY) {
554
+ } else if (RB_TYPE_P(right, T_ARRAY)) {
555
555
  nm_register_nmatrix(nm_and_free.first);
556
556
  v_size = RARRAY_LEN(right);
557
557
  v = NM_ALLOC_N(D, v_size);
@@ -1016,7 +1016,7 @@ VALUE nm_list_map_merged_stored(VALUE left, VALUE right, VALUE init) {
1016
1016
  void* scalar_init = NULL;
1017
1017
 
1018
1018
  // right might be a scalar, in which case this is a scalar operation.
1019
- if (TYPE(right) != T_DATA || (RDATA(right)->dfree != (RUBY_DATA_FUNC)nm_delete && RDATA(right)->dfree != (RUBY_DATA_FUNC)nm_delete_ref)) {
1019
+ if (!IsNMatrixType(right)) {
1020
1020
  nm::dtype_t r_dtype = Upcast[NM_DTYPE(left)][nm_dtype_min(right)];
1021
1021
  scalar_init = rubyobj_to_cval(right, r_dtype); // make a copy of right
1022
1022
 
@@ -376,7 +376,7 @@ public:
376
376
  v = reinterpret_cast<D*>(s->elements);
377
377
  v_size = nm_storage_count_max_elements(s);
378
378
 
379
- } else if (TYPE(right) == T_ARRAY) {
379
+ } else if (RB_TYPE_P(right, T_ARRAY)) {
380
380
  v_size = RARRAY_LEN(right);
381
381
  v = NM_ALLOC_N(D, v_size);
382
382
  if (dtype() == nm::RUBYOBJ) {
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
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
12
+ # SciRuby is Copyright (c) 2010 - 2016, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2016, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -68,10 +68,19 @@ module NMatrix::BLAS
68
68
  # - +ArgumentError+ -> +c+ must be +nil+ or a dense matrix.
69
69
  # - +ArgumentError+ -> The dtype of the matrices must be equal.
70
70
  #
71
- def gemm(a, b, c = nil, alpha = 1.0, beta = 0.0, transpose_a = false, transpose_b = false, m = nil, n = nil, k = nil, lda = nil, ldb = nil, ldc = nil)
72
- raise(ArgumentError, 'Expected dense NMatrices as first two arguments.') unless a.is_a?(NMatrix) and b.is_a?(NMatrix) and a.stype == :dense and b.stype == :dense
73
- raise(ArgumentError, 'Expected nil or dense NMatrix as third argument.') unless c.nil? or (c.is_a?(NMatrix) and c.stype == :dense)
74
- raise(ArgumentError, 'NMatrix dtype mismatch.') unless a.dtype == b.dtype and (c ? a.dtype == c.dtype : true)
71
+ def gemm(a, b, c = nil, alpha = 1.0, beta = 0.0,
72
+ transpose_a = false, transpose_b = false, m = nil,
73
+ n = nil, k = nil, lda = nil, ldb = nil, ldc = nil)
74
+
75
+ raise(ArgumentError, 'Expected dense NMatrices as first two arguments.') \
76
+ unless a.is_a?(NMatrix) and b.is_a? \
77
+ (NMatrix) and a.stype == :dense and b.stype == :dense
78
+
79
+ raise(ArgumentError, 'Expected nil or dense NMatrix as third argument.') \
80
+ unless c.nil? or (c.is_a?(NMatrix) \
81
+ and c.stype == :dense)
82
+ raise(ArgumentError, 'NMatrix dtype mismatch.') \
83
+ unless a.dtype == b.dtype and (c ? a.dtype == c.dtype : true)
75
84
 
76
85
  # First, set m, n, and k, which depend on whether we're taking the
77
86
  # transpose of a and b.
@@ -108,7 +117,8 @@ module NMatrix::BLAS
108
117
  end
109
118
 
110
119
  # For argument descriptions, see: http://www.netlib.org/blas/dgemm.f
111
- ::NMatrix::BLAS.cblas_gemm(:row, transpose_a, transpose_b, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
120
+ ::NMatrix::BLAS.cblas_gemm(:row, transpose_a, transpose_b,
121
+ m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
112
122
 
113
123
  return c
114
124
  end
@@ -140,17 +150,27 @@ module NMatrix::BLAS
140
150
  # * *Raises* :
141
151
  # - ++ ->
142
152
  #
143
- def gemv(a, x, y = nil, alpha = 1.0, beta = 0.0, transpose_a = false, m = nil, n = nil, lda = nil, incx = nil, incy = nil)
144
- raise(ArgumentError, 'Expected dense NMatrices as first two arguments.') unless a.is_a?(NMatrix) and x.is_a?(NMatrix) and a.stype == :dense and x.stype == :dense
145
- raise(ArgumentError, 'Expected nil or dense NMatrix as third argument.') unless y.nil? or (y.is_a?(NMatrix) and y.stype == :dense)
146
- raise(ArgumentError, 'NMatrix dtype mismatch.') unless a.dtype == x.dtype and (y ? a.dtype == y.dtype : true)
153
+ def gemv(a, x, y = nil, alpha = 1.0, beta = 0.0,
154
+ transpose_a = false, m = nil, n = nil, lda = nil,
155
+ incx = nil, incy = nil)
156
+ raise(ArgumentError, 'Expected dense NMatrices as first two arguments.') \
157
+ unless a.is_a?(NMatrix) and x.is_a?(NMatrix) and \
158
+ a.stype == :dense and x.stype == :dense
159
+
160
+ raise(ArgumentError, 'Expected nil or dense NMatrix as third argument.') \
161
+ unless y.nil? or (y.is_a?(NMatrix) and y.stype == :dense)
162
+
163
+ raise(ArgumentError, 'NMatrix dtype mismatch.') \
164
+ unless a.dtype == x.dtype and (y ? a.dtype == y.dtype : true)
147
165
 
148
166
  m ||= transpose_a == :transpose ? a.shape[1] : a.shape[0]
149
167
  n ||= transpose_a == :transpose ? a.shape[0] : a.shape[1]
150
- raise(ArgumentError, "dimensions don't match") unless x.shape[0] == n && x.shape[1] == 1
168
+ raise(ArgumentError, "dimensions don't match") \
169
+ unless x.shape[0] == n && x.shape[1] == 1
151
170
 
152
171
  if y
153
- raise(ArgumentError, "dimensions don't match") unless y.shape[0] == m && y.shape[1] == 1
172
+ raise(ArgumentError, "dimensions don't match") \
173
+ unless y.shape[0] == m && y.shape[1] == 1
154
174
  else
155
175
  y = NMatrix.new([m,1], dtype: a.dtype)
156
176
  end
@@ -159,7 +179,8 @@ module NMatrix::BLAS
159
179
  incx ||= 1
160
180
  incy ||= 1
161
181
 
162
- ::NMatrix::BLAS.cblas_gemv(transpose_a, m, n, alpha, a, lda, x, incx, beta, y, incy)
182
+ ::NMatrix::BLAS.cblas_gemv(transpose_a, m, n,
183
+ alpha, a, lda, x, incx, beta, y, incy)
163
184
 
164
185
  return y
165
186
  end
@@ -178,18 +199,27 @@ module NMatrix::BLAS
178
199
  # - +incx+ -> stride of NMatrix +x+
179
200
  # - +incy+ -> stride of NMatrix +y+
180
201
  # - +n+ -> number of elements to consider in x and y
181
- # - +in_place+ -> true if it's okay to modify the supplied +x+ and +y+ parameters directly; false if not. Default is false.
202
+ # - +in_place+ -> true if it's okay to modify the supplied
203
+ # +x+ and +y+ parameters directly;
204
+ # false if not. Default is false.
182
205
  # * *Returns* :
183
206
  # - Array with the results, in the format [xx, yy]
184
207
  # * *Raises* :
185
208
  # - +ArgumentError+ -> Expected dense NMatrices as first two arguments.
186
209
  # - +ArgumentError+ -> NMatrix dtype mismatch.
187
- # - +ArgumentError+ -> Need to supply n for non-standard incx, incy values.
210
+ # - +ArgumentError+ -> Need to supply n for non-standard incx,
211
+ # incy values.
188
212
  #
189
213
  def rot(x, y, c, s, incx = 1, incy = 1, n = nil, in_place=false)
190
- 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
191
- raise(ArgumentError, 'NMatrix dtype mismatch.') unless x.dtype == y.dtype
192
- raise(ArgumentError, 'Need to supply n for non-standard incx, incy values') if n.nil? && incx != 1 && incx != -1 && incy != 1 && incy != -1
214
+ raise(ArgumentError, 'Expected dense NMatrices as first two arguments.') \
215
+ unless x.is_a?(NMatrix) and y.is_a?(NMatrix) \
216
+ and x.stype == :dense and y.stype == :dense
217
+
218
+ raise(ArgumentError, 'NMatrix dtype mismatch.') \
219
+ unless x.dtype == y.dtype
220
+
221
+ raise(ArgumentError, 'Need to supply n for non-standard incx, incy values') \
222
+ if n.nil? && incx != 1 && incx != -1 && incy != 1 && incy != -1
193
223
 
194
224
  n ||= [x.size/incx.abs, y.size/incy.abs].min
195
225
 
@@ -223,9 +253,11 @@ module NMatrix::BLAS
223
253
  # call-seq:
224
254
  # rotg(ab) -> [Numeric, Numeric]
225
255
  #
226
- # Apply givens plane rotation to the coordinates (a,b), returning the cosine and sine of the angle theta.
256
+ # Apply givens plane rotation to the coordinates (a,b),
257
+ # returning the cosine and sine of the angle theta.
227
258
  #
228
- # Since the givens rotation includes a square root, integers are disallowed.
259
+ # Since the givens rotation includes a square root,
260
+ # integers are disallowed.
229
261
  #
230
262
  # * *Arguments* :
231
263
  # - +ab+ -> NMatrix with two elements
@@ -235,7 +267,8 @@ module NMatrix::BLAS
235
267
  # - +ArgumentError+ -> Expected dense NMatrix of size 2
236
268
  #
237
269
  def rotg(ab)
238
- raise(ArgumentError, "Expected dense NMatrix of shape [2,1] or [1,2]") unless ab.is_a?(NMatrix) && ab.stype == :dense && ab.size == 2
270
+ raise(ArgumentError, "Expected dense NMatrix of shape [2,1] or [1,2]") \
271
+ unless ab.is_a?(NMatrix) && ab.stype == :dense && ab.size == 2
239
272
 
240
273
  ::NMatrix::BLAS.cblas_rotg(ab)
241
274
  end
@@ -245,10 +278,12 @@ module NMatrix::BLAS
245
278
  # call-seq:
246
279
  # asum(x, incx, n) -> Numeric
247
280
  #
248
- # Calculate the sum of absolute values of the entries of a vector +x+ of size +n+
281
+ # Calculate the sum of absolute values of the entries of a
282
+ # vector +x+ of size +n+
249
283
  #
250
284
  # * *Arguments* :
251
- # - +x+ -> an NMatrix (will also allow an NMatrix, but will treat it as if it's a vector )
285
+ # - +x+ -> an NMatrix (will also allow an NMatrix,
286
+ # but will treat it as if it's a vector )
252
287
  # - +incx+ -> the skip size (defaults to 1)
253
288
  # - +n+ -> the size of +x+ (defaults to +x.size / incx+)
254
289
  # * *Returns* :
@@ -259,9 +294,12 @@ module NMatrix::BLAS
259
294
  #
260
295
  def asum(x, incx = 1, n = nil)
261
296
  n ||= x.size / incx
262
- raise(ArgumentError, "Expected dense NMatrix for arg 0") unless x.is_a?(NMatrix)
263
- raise(RangeError, "n out of range") if n*incx > x.size || n*incx <= 0 || n <= 0
264
- ::NMatrix::BLAS.cblas_asum(n, x, incx)
297
+ raise(ArgumentError, "Expected dense NMatrix for arg 0") \
298
+ unless x.is_a?(NMatrix)
299
+
300
+ raise(RangeError, "n out of range") \
301
+ if n*incx > x.size || n*incx <= 0 || n <= 0
302
+ ::NMatrix::BLAS.cblas_asum(n, x, incx)
265
303
  end
266
304
 
267
305
  #
@@ -271,7 +309,8 @@ module NMatrix::BLAS
271
309
  # Calculate the 2-norm of a vector +x+ of size +n+
272
310
  #
273
311
  # * *Arguments* :
274
- # - +x+ -> an NMatrix (will also allow an NMatrix, but will treat it as if it's a vector )
312
+ # - +x+ -> an NMatrix (will also allow an
313
+ # NMatrix, but will treat it as if it's a vector )
275
314
  # - +incx+ -> the skip size (defaults to 1)
276
315
  # - +n+ -> the size of +x+ (defaults to +x.size / incx+)
277
316
  # * *Returns* :
@@ -282,24 +321,54 @@ module NMatrix::BLAS
282
321
  #
283
322
  def nrm2(x, incx = 1, n = nil)
284
323
  n ||= x.size / incx
285
- raise(ArgumentError, "Expected dense NMatrix for arg 0") unless x.is_a?(NMatrix)
286
- raise(RangeError, "n out of range") if n*incx > x.size || n*incx <= 0 || n <= 0
287
- ::NMatrix::BLAS.cblas_nrm2(n, x, incx)
324
+ raise(ArgumentError, "Expected dense NMatrix for arg 0") \
325
+ unless x.is_a?(NMatrix)
326
+
327
+ raise(RangeError, "n out of range") \
328
+ if n*incx > x.size || n*incx <= 0 || n <= 0
329
+ ::NMatrix::BLAS.cblas_nrm2(n, x, incx)
330
+ end
331
+
332
+ #
333
+ # call-seq:
334
+ # scal(alpha, vector, incx, n)
335
+ #
336
+ # Scale a matrix by a given scaling factor
337
+ #
338
+ # * *Arguments* :
339
+ # - +alpha+ -> a scaling factor
340
+ # - +vector+ -> an NMatrix
341
+ # - +incx+ -> the skip size (defaults to 1)
342
+ # - +n+ -> the size of +x+ (defaults to +x.size / incx+)
343
+ # * *Returns* :
344
+ # - The scaling result
345
+ # * *Raises* :
346
+ # - +ArgumentError+ -> Expected dense NMatrix for arg 0
347
+ # - +RangeError+ -> n out of range
348
+ #
349
+ def scal(alpha, vector, incx=1, n=nil)
350
+ n ||= vector.size / incx
351
+ raise(ArgumentError, "Expected dense NMatrix for arg 0") unless vector.is_a?(NMatrix)
352
+ raise(RangeError, "n out of range") if n*incx > vector.size || n*incx <= 0 || n <= 0
353
+ ::NMatrix::BLAS.cblas_scal(n, alpha, vector, incx)
288
354
  end
289
355
 
290
356
  # The following are functions that used to be implemented in C, but
291
357
  # now require nmatrix-atlas or nmatrix-lapcke to run properly, so we can just
292
358
  # implemented their stubs in Ruby.
293
359
  def cblas_trmm(order, side, uplo, trans_a, diag, m, n, alpha, a, lda, b, ldb)
294
- raise(NotImplementedError,"cblas_trmm requires either the nmatrix-lapacke or nmatrix-atlas gem")
360
+ raise(NotImplementedError,"cblas_trmm requires either the
361
+ nmatrix-lapacke or nmatrix-atlas gem")
295
362
  end
296
363
 
297
364
  def cblas_syrk(order, uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
298
- raise(NotImplementedError,"cblas_syrk requires either the nmatrix-lapacke or nmatrix-atlas gem")
365
+ raise(NotImplementedError,"cblas_syrk requires either the
366
+ nmatrix-lapacke or nmatrix-atlas gem")
299
367
  end
300
368
 
301
369
  def cblas_herk(order, uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
302
- raise(NotImplementedError,"cblas_herk requires either the nmatrix-lapacke or nmatrix-atlas gem")
370
+ raise(NotImplementedError,"cblas_herk requires either the
371
+ nmatrix-lapacke or nmatrix-atlas gem")
303
372
  end
304
373
  end
305
374
  end
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
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
12
+ # SciRuby is Copyright (c) 2010 - 2016, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2016, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -70,7 +70,8 @@ class NMatrix
70
70
  # * +:post_decimal_width+ - Width of the numerals after the decimal point.
71
71
  # * +:exponent_width+ - Width of exponent part of the number.
72
72
  def parse
73
- raise(IOError, "Left or right parentheses missing") if parentheses_missing? # change tests to handle 'raise' not return
73
+ raise(IOError, "Left or right parentheses missing") \
74
+ if parentheses_missing? # change tests to handle 'raise' not return
74
75
 
75
76
  @result = {}
76
77
  @string = @string[1..-2]
@@ -92,8 +93,10 @@ class NMatrix
92
93
  # Changing any of the following regular expressions can lead to disaster
93
94
  def valid_fortran_format?
94
95
  @mdata = @string.match(/\A(\d*)(I)(\d+)\z/) # check for integer format
95
- @mdata = @string.match(/\A(\d*)(F)(\d+)\.(\d+)\z/) if @mdata.nil? # check for floating point if not integer
96
- @mdata = @string.match(/\A(\d*)(E)(\d+)\.(\d+)(E)?(\d*)\z/) if @mdata.nil? # check for exponential format if not floating point
96
+ @mdata = @string.match(/\A(\d*)(F)(\d+)\.(\d+)\z/) \
97
+ if @mdata.nil? # check for floating point if not integer
98
+ @mdata = @string.match(/\A(\d*)(E)(\d+)\.(\d+)(E)?(\d*)\z/) \
99
+ if @mdata.nil? # check for exponential format if not floating point
97
100
 
98
101
  @mdata
99
102
  end
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
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
12
+ # SciRuby is Copyright (c) 2010 - 2016, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2016, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -48,14 +48,14 @@ class NMatrix
48
48
  # == Arguments
49
49
  #
50
50
  # * +file_path+ - Path of the Harwell Boeing file to load.
51
- # * +opts+ - Options for specifying whether you want the values and
52
- # header or only the header.
51
+ # * +opts+ - Options for specifying whether you want
52
+ # the values and header or only the header.
53
53
  #
54
54
  # == Options
55
55
  #
56
- # * +:header+ - If specified as *true*, will return only the header of the HB file.
57
- # Will return the NMatrix object and header as an array if
58
- # left blank.
56
+ # * +:header+ - If specified as *true*, will return only the header of
57
+ # the HB file.Will return the NMatrix object and
58
+ # header as an array if left blank.
59
59
  #
60
60
  # == Usage
61
61
  #
@@ -65,8 +65,8 @@ class NMatrix
65
65
  #
66
66
  # == Alternate Usage
67
67
  #
68
- # You can specify the file using NMatrix::IO::Reader.new("path/to/file") and
69
- # then call *header* or *values* on the resulting object.
68
+ # You can specify the file using NMatrix::IO::Reader.new("path/to/file")
69
+ # and then call *header* or *values* on the resulting object.
70
70
  def load file_path, opts={}
71
71
  hb_obj = NMatrix::IO::HarwellBoeing::Reader.new(file_path)
72
72
 
@@ -103,7 +103,8 @@ class NMatrix
103
103
  @header[:valcrd] = line[42...56].strip.to_i
104
104
  @header[:rhscrd] = line[56...70].strip.to_i
105
105
 
106
- raise(IOError, "Right hand sides not supported.") if @header[:rhscrd] > 0
106
+ raise(IOError, "Right hand sides not supported.") \
107
+ if @header[:rhscrd] > 0
107
108
 
108
109
  line = @file.gets
109
110
 
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
11
+ # SciRuby is Copyright (c) 2010 - 2016, Ruby Science Foundation
12
+ # NMatrix is Copyright (c) 2012 - 2016, John Woods and the Ruby Science Foundation
13
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -47,8 +47,9 @@ module NMatrix::IO::Market
47
47
  } #:nodoc:
48
48
 
49
49
  ENTRY_TYPE = {
50
- :byte => :integer, :int8 => :integer, :int16 => :integer, :int32 => :integer, :int64 => :integer,
51
- :float32 => :real, :float64 => :real, :complex64 => :complex, :complex128 => :complex
50
+ :byte => :integer, :int8 => :integer, :int16 => :integer,
51
+ :int32 => :integer, :int64 => :integer,:float32 => :real,
52
+ :float64 => :real, :complex64 => :complex, :complex128 => :complex
52
53
  } #:nodoc:
53
54
 
54
55
  class << self
@@ -68,7 +69,8 @@ module NMatrix::IO::Market
68
69
 
69
70
  header = f.gets
70
71
  header.chomp!
71
- raise(IOError, "expected type code line beginning with '%%MatrixMarket matrix'") if header !~ /^\%\%MatrixMarket\ matrix/
72
+ raise(IOError, "expected type code line beginning with '%%MatrixMarket matrix'") \
73
+ if header !~ /^\%\%MatrixMarket\ matrix/
72
74
 
73
75
  header = header.split
74
76
 
@@ -106,7 +108,8 @@ module NMatrix::IO::Market
106
108
  end
107
109
  entry_type = options[:pattern] ? :pattern : ENTRY_TYPE[matrix.dtype]
108
110
 
109
- raise(ArgumentError, "expected two-dimensional NMatrix") if matrix.dim != 2
111
+ raise(ArgumentError, "expected two-dimensional NMatrix") \
112
+ if matrix.dim != 2
110
113
 
111
114
  f = File.new(filename, 'w')
112
115
 
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
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
12
+ # SciRuby is Copyright (c) 2010 - 2016, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2016, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -63,7 +63,8 @@ module NMatrix::IO::Matlab
63
63
  end
64
64
 
65
65
  def padded_bytes
66
- @padded_bytes ||= content.size % 4 == 0 ? content.size : (content.size / 4 + 1) * 4
66
+ @padded_bytes ||= content.size % 4 == 0 ? \
67
+ content.size : (content.size / 4 + 1) * 4
67
68
  end
68
69
 
69
70
  def write_packed(packedio, options = {})
@@ -89,9 +90,10 @@ module NMatrix::IO::Matlab
89
90
  end
90
91
 
91
92
  MatrixDataStruct = Struct.new(
92
- :cells, :logical, :global, :complex, :nonzero_max,
93
- :matlab_class, :dimensions, :matlab_name, :real_part,
94
- :imaginary_part, :row_index, :column_index)
93
+ :cells, :logical, :global, :complex,
94
+ :nonzero_max,:matlab_class, :dimensions,
95
+ :matlab_name, :real_part,:imaginary_part,
96
+ :row_index, :column_index)
95
97
 
96
98
  class MatrixData < MatrixDataStruct #:nodoc:
97
99
  include Packable
@@ -196,16 +198,19 @@ module NMatrix::IO::Matlab
196
198
  imag_mdtype = self.imaginary_part.tag.data_type
197
199
 
198
200
  # Make sure we convert both mdtypes do the same dtype
199
- to_dtype ||= NMatrix.upcast(MatReader::MDTYPE_TO_DTYPE[real_mdtype], MatReader::MDTYPE_TO_DTYPE[imag_mdtype])
201
+ to_dtype ||= NMatrix.upcast(MatReader::MDTYPE_TO_DTYPE[real_mdtype], \
202
+ MatReader::MDTYPE_TO_DTYPE[imag_mdtype])
200
203
 
201
- # Let's make sure we don't try to send NMatrix complex integers. We need complex floating points.
204
+ # Let's make sure we don't try to send NMatrix complex integers.
205
+ # We need complex floating points.
202
206
  unless [:float32, :float64].include?(to_dtype)
203
207
  to_dtype = NMatrix.upcast(to_dtype, :float32)
204
208
  end
205
209
 
206
210
  STDERR.puts "imag: Requesting dtype #{to_dtype.inspect}"
207
211
  # Repack the imaginary part
208
- components[1] = ::NMatrix::IO::Matlab.repack( self.imaginary_part.data, imag_mdtype, :dtype => to_dtype )
212
+ components[1] = ::NMatrix::IO::Matlab.repack( self.imaginary_part.data, \
213
+ imag_mdtype, :dtype => to_dtype )
209
214
 
210
215
  else
211
216
 
@@ -221,10 +226,12 @@ module NMatrix::IO::Matlab
221
226
 
222
227
  # Repack the real part
223
228
  STDERR.puts "real: Requesting dtype #{to_dtype.inspect}"
224
- components[0] = ::NMatrix::IO::Matlab.repack( self.real_part.data, real_mdtype, :dtype => to_dtype )
229
+ components[0] = ::NMatrix::IO::Matlab.repack( \
230
+ self.real_part.data, real_mdtype, :dtype => to_dtype )
225
231
 
226
232
  # Merge the two parts if complex, or just return the real part.
227
- [self.complex ? ::NMatrix::IO::Matlab.complex_merge( components[0], components[1], to_dtype ) : components[0],
233
+ [self.complex ? ::NMatrix::IO::Matlab.complex_merge( \
234
+ components[0], components[1], to_dtype ) : components[0],
228
235
  to_dtype]
229
236
  end
230
237
 
@@ -233,8 +240,10 @@ module NMatrix::IO::Matlab
233
240
  # If data is already in the appropriate format, does not unpack or
234
241
  # repack, just returns directly.
235
242
  def repacked_indices
236
- repacked_row_indices = ::NMatrix::IO::Matlab.repack( self.row_index.data, :miINT32, :itype )
237
- repacked_col_indices = ::NMatrix::IO::Matlab.repack( self.column_index.data, :miINT32, :itype )
243
+ repacked_row_indices = ::NMatrix::IO::Matlab.repack( \
244
+ self.row_index.data, :miINT32, :itype )
245
+ repacked_col_indices = ::NMatrix::IO::Matlab.repack( \
246
+ self.column_index.data, :miINT32, :itype )
238
247
 
239
248
  [repacked_row_indices, repacked_col_indices]
240
249
  end
@@ -276,7 +285,8 @@ module NMatrix::IO::Matlab
276
285
  # MATLAB always uses :miINT32 for indices according to the spec
277
286
  ia_ja = repacked_indices
278
287
  data_str, repacked_dtype = repacked_data(dtype)
279
- NMatrix.new(:yale, self.dimensions.reverse, repacked_dtype, ia_ja[0], ia_ja[1], data_str, repacked_dtype)
288
+ NMatrix.new(:yale, self.dimensions.reverse, repacked_dtype, \
289
+ ia_ja[0], ia_ja[1], data_str, repacked_dtype)
280
290
 
281
291
  else
282
292
  # Call regular dense constructor.
@@ -298,7 +308,9 @@ module NMatrix::IO::Matlab
298
308
 
299
309
  begin
300
310
  name_tag_data = packedio.read([Element, options])
301
- self.matlab_name = name_tag_data.data.is_a?(Array) ? name_tag_data.data.collect { |i| i.chr }.join('') : name_tag_data.data.chr
311
+ self.matlab_name = name_tag_data.data.is_a?(Array) ? \
312
+ name_tag_data.data.collect { |i| i.chr }.join('') : \
313
+ name_tag_data.data.chr
302
314
 
303
315
  rescue ElementDataIOError => e
304
316
  STDERR.puts "ERROR: Failure while trying to read Matlab variable name: #{name_tag_data.inspect}"
@@ -315,10 +327,12 @@ module NMatrix::IO::Matlab
315
327
  self.cells = []
316
328
  STDERR.puts("Warning: Cell array does not yet support reading multiple dimensions") if dimensions.size > 2 || (dimensions[0] > 1 && dimensions[1] > 1)
317
329
  number_of_cells = dimensions.inject(1) { |prod,i| prod * i }
318
- number_of_cells.times { self.cells << packedio.read([Element, options]) }
330
+ number_of_cells.times { self.cells << \
331
+ packedio.read([Element, options]) }
319
332
 
320
333
  else
321
- read_opts = [RawElement, {:bytes => options[:bytes], :endian => :native}]
334
+ read_opts = [RawElement, {:bytes => options[:bytes], \
335
+ :endian => :native}]
322
336
 
323
337
  if self.matlab_class == :mxSPARSE
324
338
  self.column_index = packedio.read(read_opts)
@@ -331,7 +345,8 @@ module NMatrix::IO::Matlab
331
345
  end
332
346
 
333
347
  def ignore_padding(packedio, bytes)
334
- packedio.read([Integer, {:unsigned => true, :bytes => bytes}]) if bytes > 0
348
+ packedio.read([Integer, {:unsigned => true, \
349
+ :bytes => bytes}]) if bytes > 0
335
350
  end
336
351
  end
337
352
 
@@ -386,7 +401,8 @@ module NMatrix::IO::Matlab
386
401
  def each(&block)
387
402
  stream.each(Element, {:endian => byte_order}) do |element|
388
403
  if element.data.is_a?(Compressed)
389
- StringIO.new(element.data.content, 'rb').each(Element, {:endian => byte_order}) do |compressed_element|
404
+ StringIO.new(element.data.content, 'rb').each(Element, \
405
+ {:endian => byte_order}) do |compressed_element|
390
406
  yield compressed_element.data
391
407
  end
392
408
 
@@ -456,7 +472,8 @@ module NMatrix::IO::Matlab
456
472
  end
457
473
 
458
474
  def read_packed packedio, options
459
- self.raw_data_type = packedio.read([Integer, DATA_TYPE_OPTS.merge(options)])
475
+ self.raw_data_type = packedio.read([Integer, \
476
+ DATA_TYPE_OPTS.merge(options)])
460
477
 
461
478
  # Borrowed from a SciPy patch
462
479
  upper = self.raw_data_type >> 16
@@ -504,20 +521,23 @@ module NMatrix::IO::Matlab
504
521
  end
505
522
 
506
523
  def read_packed(packedio, options)
507
- raise(ArgumentError, 'Missing mandatory option :endian.') unless options.has_key?(:endian)
524
+ raise(ArgumentError, 'Missing mandatory option :endian.') \
525
+ unless options.has_key?(:endian)
508
526
 
509
527
  tag = packedio.read([Tag, {:endian => options[:endian]}])
510
528
  data_type = MDTYPE_UNPACK_ARGS[tag.data_type]
511
529
 
512
530
  self.tag = tag
513
531
 
514
- raise ElementDataIOError.new(tag, "Unrecognized Matlab type #{tag.raw_data_type}") if data_type.nil?
532
+ raise ElementDataIOError.new(tag, "Unrecognized Matlab type #{tag.raw_data_type}") \
533
+ if data_type.nil?
515
534
 
516
535
  if tag.bytes == 0
517
536
  self.data = []
518
537
 
519
538
  else
520
- number_of_reads = data_type[1].has_key?(:bytes) ? tag.bytes / data_type[1][:bytes] : 1
539
+ number_of_reads = data_type[1].has_key?(:bytes) ? \
540
+ tag.bytes / data_type[1][:bytes] : 1
521
541
  data_type[1].merge!({:endian => options[:endian]})
522
542
 
523
543
  if number_of_reads == 1
@@ -531,7 +551,8 @@ module NMatrix::IO::Matlab
531
551
  end
532
552
 
533
553
  begin
534
- ignore_padding(packedio, (tag.bytes + tag.size) % 8) unless [:miMATRIX, :miCOMPRESSED].include?(tag.data_type)
554
+ ignore_padding(packedio, (tag.bytes + tag.size) % 8) \
555
+ unless [:miMATRIX, :miCOMPRESSED].include?(tag.data_type)
535
556
 
536
557
  rescue EOFError
537
558
  STDERR.puts self.tag.inspect
@@ -545,7 +566,8 @@ module NMatrix::IO::Matlab
545
566
  #STDERR.puts "Ignored #{8 - bytes} on #{self.tag.data_type}"
546
567
  ignored = packedio.read(8 - bytes)
547
568
  ignored_unpacked = ignored.unpack("C*")
548
- raise(IOError, "Nonzero padding detected: #{ignored_unpacked}") if ignored_unpacked.any? { |i| i != 0 }
569
+ raise(IOError, "Nonzero padding detected: #{ignored_unpacked}") \
570
+ if ignored_unpacked.any? { |i| i != 0 }
549
571
  end
550
572
  end
551
573
 
@@ -558,13 +580,16 @@ module NMatrix::IO::Matlab
558
580
  # manually, or pass the raw string of bytes into NMatrix.
559
581
  class RawElement < Element #:nodoc:
560
582
  def read_packed(packedio, options)
561
- raise(ArgumentError, 'Missing mandatory option :endian.') unless options.has_key?(:endian)
583
+ raise(ArgumentError, 'Missing mandatory option :endian.') \
584
+ unless options.has_key?(:endian)
562
585
 
563
- self.tag = packedio.read([Tag, {:endian => options[:endian] }])
564
- self.data = packedio.read([String, {:endian => options[:endian], :bytes => tag.bytes }])
586
+ self.tag = packedio.read([Tag, {:endian => options[:endian]}])
587
+ self.data = packedio.read([String, {:endian => options[:endian], \
588
+ :bytes => tag.bytes }])
565
589
 
566
590
  begin
567
- ignore_padding(packedio, (tag.bytes + tag.size) % 8) unless [:miMATRIX, :miCOMPRESSED].include?(tag.data_type)
591
+ ignore_padding(packedio, (tag.bytes + tag.size) % 8) \
592
+ unless [:miMATRIX, :miCOMPRESSED].include?(tag.data_type)
568
593
 
569
594
  rescue EOFError
570
595
  STDERR.puts self.tag.inspect