nmatrix 0.1.0.rc5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/Gemfile +0 -2
  4. data/History.txt +39 -4
  5. data/LICENSE.txt +3 -1
  6. data/Manifest.txt +2 -0
  7. data/README.rdoc +6 -14
  8. data/Rakefile +4 -1
  9. data/ext/nmatrix/data/data.cpp +1 -1
  10. data/ext/nmatrix/data/data.h +2 -1
  11. data/ext/nmatrix/data/rational.h +230 -226
  12. data/ext/nmatrix/extconf.rb +7 -4
  13. data/ext/nmatrix/math.cpp +259 -172
  14. data/ext/nmatrix/math/getri.h +2 -2
  15. data/ext/nmatrix/math/math.h +1 -1
  16. data/ext/nmatrix/ruby_constants.cpp +0 -1
  17. data/ext/nmatrix/ruby_nmatrix.c +55 -32
  18. data/ext/nmatrix/storage/dense/dense.cpp +1 -0
  19. data/ext/nmatrix/storage/yale/yale.cpp +12 -14
  20. data/ext/nmatrix/ttable_helper.rb +0 -1
  21. data/lib/nmatrix.rb +5 -0
  22. data/lib/nmatrix/homogeneous.rb +98 -0
  23. data/lib/nmatrix/io/fortran_format.rb +135 -0
  24. data/lib/nmatrix/io/harwell_boeing.rb +220 -0
  25. data/lib/nmatrix/io/market.rb +18 -8
  26. data/lib/nmatrix/io/mat5_reader.rb +16 -111
  27. data/lib/nmatrix/io/mat_reader.rb +3 -5
  28. data/lib/nmatrix/io/point_cloud.rb +27 -28
  29. data/lib/nmatrix/lapack.rb +3 -1
  30. data/lib/nmatrix/math.rb +112 -43
  31. data/lib/nmatrix/monkeys.rb +67 -11
  32. data/lib/nmatrix/nmatrix.rb +56 -33
  33. data/lib/nmatrix/rspec.rb +2 -2
  34. data/lib/nmatrix/shortcuts.rb +42 -25
  35. data/lib/nmatrix/version.rb +4 -4
  36. data/nmatrix.gemspec +4 -3
  37. data/spec/03_nmatrix_monkeys_spec.rb +72 -0
  38. data/spec/blas_spec.rb +4 -0
  39. data/spec/homogeneous_spec.rb +12 -4
  40. data/spec/io/fortran_format_spec.rb +88 -0
  41. data/spec/io/harwell_boeing_spec.rb +98 -0
  42. data/spec/io/test.rua +9 -0
  43. data/spec/math_spec.rb +51 -9
  44. metadata +38 -9
@@ -0,0 +1,135 @@
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
+ # == io/matlab/fortran_format.rb
25
+ #
26
+ # A parser for making sense of FORTRAN formats.
27
+ # => Only handles R (real), F (float) and E (exponential) format codes.
28
+ #++
29
+
30
+ class NMatrix
31
+ module IO
32
+ module FortranFormat
33
+
34
+ # Class for reading strings in FORTRAN format for specifying attributes
35
+ # of numerical data in a file. Supports F (float), E (exponential) and
36
+ # R (real).
37
+ #
38
+ # == Usage
39
+ #
40
+ # p = NMatrix::IO::FortranFormat::Reader.new("(16I5)")
41
+ # v = p.parse
42
+ # puts v #=> { :format_code => "INT_ID",
43
+ # #=> :repeat => 16,
44
+ # #=> :field_width => 5 }
45
+ class Reader
46
+
47
+ # Accepts a string in FORTRAN format and initializes the
48
+ # NMatrix::IO::FortranFormat::Reader object for further parsing of the
49
+ # data.
50
+ #
51
+ # == Arguments
52
+ #
53
+ # * +string+ - FORTRAN format string to be parsed.
54
+ def initialize string
55
+ @string = string
56
+ end
57
+
58
+ # Parses the FORTRAN format string passed in initialize and returns
59
+ # a hash of the results.
60
+ #
61
+ # == Result Hash Format
62
+ #
63
+ # Take note that some of the below parameters may be absent in the hash
64
+ # depending on the type of string being parsed.
65
+ #
66
+ # * +:format_code+ - A string containing the format code of the read data.
67
+ # Can be "INT_ID", "FP_ID" or "EXP_ID"
68
+ # * +:repeat+ - Number of times this format will repeat in a line.
69
+ # * +:field_width+ - Width of the numerical part of the number.
70
+ # * +:post_decimal_width+ - Width of the numerals after the decimal point.
71
+ # * +:exponent_width+ - Width of exponent part of the number.
72
+ def parse
73
+ raise(IOError, "Left or right parentheses missing") if parentheses_missing? # change tests to handle 'raise' not return
74
+
75
+ @result = {}
76
+ @string = @string[1..-2]
77
+
78
+ if valid_fortran_format?
79
+ load_result
80
+ else
81
+ raise(IOError, "Invalid FORTRAN format specified. Only Integer, Float or Exponential acceptable.")
82
+ end
83
+
84
+ @result
85
+ end
86
+
87
+ private
88
+ def parentheses_missing?
89
+ true if @string[0] != '(' or @string[-1] != ')'
90
+ end
91
+
92
+ # Changing any of the following regular expressions can lead to disaster
93
+ def valid_fortran_format?
94
+ @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
97
+
98
+ @mdata
99
+ end
100
+
101
+ def load_result
102
+ if @mdata.to_a.include? "I"
103
+ create_integer_hash
104
+ elsif @mdata.to_a.include? "F"
105
+ create_float_hash
106
+ else
107
+ create_exp_hash
108
+ end
109
+ end
110
+
111
+ def create_integer_hash
112
+ @result[:format_code] = "INT_ID"
113
+ @result[:repeat] = @mdata[1].to_i if !@mdata[1].empty?
114
+ @result[:field_width] = @mdata[3].to_i
115
+ end
116
+
117
+ def create_float_hash
118
+ @result[:format_code] = "FP_ID"
119
+ @result[:repeat] = @mdata[1].to_i if !@mdata[1].empty?
120
+ @result[:field_width] = @mdata[3].to_i
121
+ @result[:post_decimal_width] = @mdata[4].to_i
122
+ end
123
+
124
+ def create_exp_hash
125
+ @result[:format_code] = "EXP_ID"
126
+ @result[:repeat] = @mdata[1].to_i if !@mdata[1].empty?
127
+ @result[:field_width] = @mdata[3].to_i
128
+ @result[:post_decimal_width] = @mdata[4].to_i
129
+ @result[:exponent_width] = @mdata[6].to_i if !@mdata[6].empty?
130
+ end
131
+ end
132
+
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,220 @@
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
+ # == io/matlab/harwell_boeing.rb
25
+ #
26
+ # Harwell Boeing file reader (and eventually writer too).
27
+ # => Supports only assembled, non-symmetric, real matrices
28
+ # => Data types supported are exponential, floating point and integer
29
+ # => Returned NMatrix is of type :float64
30
+ #++
31
+
32
+ require_relative './fortran_format.rb'
33
+
34
+ class NMatrix
35
+ module IO
36
+ module HarwellBoeing
37
+
38
+ class << self
39
+ # Loads the contents of a valid Harwell Boeing format file and
40
+ # returns an NMatrix object with the values of the file and optionally
41
+ # only the header info.
42
+ #
43
+ # Supports only assembled, non-symmetric, real matrices. File name must
44
+ # have matrix type as extension.
45
+ #
46
+ # Example - test_file.rua
47
+ #
48
+ # == Arguments
49
+ #
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.
53
+ #
54
+ # == Options
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.
59
+ #
60
+ # == Usage
61
+ #
62
+ # mat, head = NMatrix::IO::HarwellBoeing.load("test_file.rua")
63
+ #
64
+ # head = NMatrix::IO::HarwellBoeing.load("test_file.rua", {header: true})
65
+ #
66
+ # == Alternate Usage
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.
70
+ def load file_path, opts={}
71
+ hb_obj = NMatrix::IO::HarwellBoeing::Reader.new(file_path)
72
+
73
+ return hb_obj.header if opts[:header]
74
+
75
+ [hb_obj.values, hb_obj.header]
76
+ end
77
+ end
78
+
79
+ class Reader
80
+ def initialize file_name
81
+ raise(IOError, "Unsupported file format. Specify file as \
82
+ file_name.rua.") if !file_name.match(/.*\.[rR][uU][aA]/)
83
+
84
+ @file_name = file_name
85
+ @header = {}
86
+ @body = nil
87
+ end
88
+
89
+ def header
90
+ return @header if !@header.empty?
91
+ @file = File.open @file_name, "r"
92
+
93
+ line = @file.gets
94
+
95
+ @header[:title] = line[0...72].strip
96
+ @header[:key] = line[72...80].strip
97
+
98
+ line = @file.gets
99
+
100
+ @header[:totcrd] = line[0...14] .strip.to_i
101
+ @header[:ptrcrd] = line[14...28].strip.to_i
102
+ @header[:indcrd] = line[28...42].strip.to_i
103
+ @header[:valcrd] = line[42...56].strip.to_i
104
+ @header[:rhscrd] = line[56...70].strip.to_i
105
+
106
+ raise(IOError, "Right hand sides not supported.") if @header[:rhscrd] > 0
107
+
108
+ line = @file.gets
109
+
110
+ @header[:mxtype] = line[0...3]
111
+
112
+ raise(IOError, "Currently supports only real, assembled, unsymmetric \
113
+ matrices.") if !@header[:mxtype].match(/RUA/)
114
+
115
+ @header[:nrow] = line[13...28].strip.to_i
116
+ @header[:ncol] = line[28...42].strip.to_i
117
+ @header[:nnzero] = line[42...56].strip.to_i
118
+ @header[:neltvl] = line[56...70].strip.to_i
119
+
120
+ line = @file.gets
121
+
122
+ fortran_reader = NMatrix::IO::FortranFormat::Reader
123
+
124
+ @header[:ptrfmt] = fortran_reader.new(line[0...16].strip) .parse
125
+ @header[:indfmt] = fortran_reader.new(line[16...32].strip).parse
126
+ @header[:valfmt] = fortran_reader.new(line[32...52].strip).parse
127
+ @header[:rhsfmt] = fortran_reader.new(line[52...72].strip).parse
128
+
129
+ @header
130
+ end
131
+
132
+ def values
133
+ @header = header if @header.empty?
134
+ @file.lineno = 5 if @file.lineno != 5
135
+ @matrix = NMatrix.new([ @header[:nrow], @header[:ncol] ],
136
+ 0, dtype: :float64)
137
+
138
+ read_column_pointers
139
+ read_row_indices
140
+ read_values
141
+
142
+ @file.close
143
+
144
+ assemble_matrix
145
+
146
+ @matrix
147
+ end
148
+
149
+ private
150
+
151
+ def read_column_pointers
152
+ @col_ptrs = []
153
+ pointer_lines = @header[:ptrcrd]
154
+ pointers_per_line = @header[:ptrfmt][:repeat]
155
+ pointer_width = @header[:ptrfmt][:field_width]
156
+
157
+ @col_ptrs = read_numbers :to_i, pointer_lines, pointers_per_line,
158
+ pointer_width
159
+
160
+ @col_ptrs.map! {|c| c -= 1}
161
+ end
162
+
163
+ def read_row_indices
164
+ @row_indices = []
165
+ row_lines = @header[:indcrd]
166
+ indices_per_line = @header[:indfmt][:repeat]
167
+ row_width = @header[:indfmt][:field_width]
168
+
169
+ @row_indices = read_numbers :to_i, row_lines, indices_per_line,
170
+ row_width
171
+
172
+ @row_indices.map! {|r| r -= 1}
173
+ end
174
+
175
+ def read_values
176
+ @vals = []
177
+ value_lines = @header[:valcrd]
178
+ values_per_line = @header[:valfmt][:repeat]
179
+ value_width = @header[:valfmt][:field_width]
180
+
181
+ @vals = read_numbers :to_f, value_lines, values_per_line,
182
+ value_width
183
+ end
184
+
185
+ def read_numbers to_dtype, num_of_lines, numbers_per_line, number_width
186
+ data = []
187
+
188
+ num_of_lines.times do
189
+ line = @file.gets
190
+ index = 0
191
+
192
+ numbers_per_line.times do
193
+ delimiter = index + number_width
194
+
195
+ data << line[index...delimiter].strip.send(to_dtype)
196
+
197
+ break if line.length <= delimiter
198
+ index += number_width
199
+ end
200
+ end
201
+
202
+ data
203
+ end
204
+
205
+ def assemble_matrix
206
+ col = 0
207
+ @col_ptrs[0..-2].each_index do |index|
208
+ @col_ptrs[index].upto(@col_ptrs[index+1] - 1) do |row_ptr|
209
+ row = @row_indices[row_ptr]
210
+ @matrix[row, col] = @vals[row_ptr]
211
+ end
212
+
213
+ col += 1
214
+ end
215
+ end
216
+ end
217
+
218
+ end
219
+ end
220
+ end
@@ -26,30 +26,42 @@
26
26
  #
27
27
  #++
28
28
 
29
+ # Matrix Market is a repository of test data for use in studies of algorithms
30
+ # for numerical linear algebra. There are 3 file formats used:
31
+ #
32
+ # - Matrix Market Exchange Format.
33
+ # - Harwell-Boeing Exchange Format.
34
+ # - Coordinate Text File Format. (to be phased out)
35
+ #
36
+ # This module can load and save the first format. We might support
37
+ # Harwell-Boeing in the future.
38
+ #
39
+ # The MatrixMarket format is documented in:
40
+ # * http://math.nist.gov/MatrixMarket/formats.html
29
41
  module NMatrix::IO::Market
30
42
  CONVERTER_AND_DTYPE = {
31
43
  :real => [:to_f, :float64],
32
44
  :complex => [:to_c, :complex128],
33
45
  :integer => [:to_i, :int64],
34
46
  :pattern => [:to_i, :byte]
35
- }
47
+ } #:nodoc:
36
48
 
37
49
  ENTRY_TYPE = {
38
50
  :byte => :integer, :int8 => :integer, :int16 => :integer, :int32 => :integer, :int64 => :integer,
39
51
  :float32 => :real, :float64 => :real, :complex64 => :complex, :complex128 => :complex
40
- }
52
+ } #:nodoc:
41
53
 
42
54
  class << self
43
- #
55
+
44
56
  # call-seq:
45
- # load(filename) ->
57
+ # load(filename) -> NMatrix
58
+ #
59
+ # Load a MatrixMarket file. Requires a +filename+ as an argument.
46
60
  #
47
61
  # * *Arguments* :
48
62
  # - +filename+ -> String with the filename to be saved.
49
63
  # * *Raises* :
50
64
  # - +IOError+ -> expected type code line beginning with '%%MatrixMarket matrix'
51
- #
52
- # Load a MatrixMarket file. Requires a filename as an argument.
53
65
  def load(filename)
54
66
 
55
67
  f = File.new(filename, "r")
@@ -71,7 +83,6 @@ module NMatrix::IO::Market
71
83
  end
72
84
  end
73
85
 
74
- #
75
86
  # call-seq:
76
87
  # save(matrix, filename, options = {}) -> true
77
88
  #
@@ -85,7 +96,6 @@ module NMatrix::IO::Market
85
96
  # * *Raises* :
86
97
  # - +DataTypeError+ -> MatrixMarket does not support rational or Ruby objects.
87
98
  # - +ArgumentError+ -> Expected two-dimensional NMatrix.
88
- #
89
99
  def save(matrix, filename, options = {})
90
100
  options = {:pattern => false,
91
101
  :symmetry => :general}.merge(options)
@@ -30,27 +30,16 @@
30
30
  require_relative './mat_reader.rb'
31
31
 
32
32
  module NMatrix::IO::Matlab
33
- #
33
+
34
34
  # Reader (and eventual writer) for a version 5 .mat file.
35
- #
36
- class Mat5Reader < MatReader
35
+ class Mat5Reader < MatReader #:nodoc:
37
36
  attr_reader :file_header, :first_tag_field, :first_data_field
38
37
 
39
- class Compressed
38
+ class Compressed #:nodoc:
40
39
  include Packable
41
- # include TaggedDataEnumerable
42
40
 
43
41
  attr_reader :byte_order
44
42
 
45
- #
46
- # call-seq:
47
- # new(stream = nil, byte_order = nil, content_or_bytes = nil) -> Mat5Reader::Compressed
48
- #
49
- # * *Arguments* :
50
- # - ++ ->
51
- # * *Raises* :
52
- # - ++ ->
53
- #
54
43
  def initialize(stream = nil, byte_order = nil, content_or_bytes = nil)
55
44
  @stream = stream
56
45
  @byte_order = byte_order
@@ -60,69 +49,33 @@ module NMatrix::IO::Matlab
60
49
 
61
50
  elsif content_or_bytes.is_a?(Fixnum)
62
51
  @padded_bytes = content_or_bytes
63
- #else
64
- # raise ArgumentError, "Need a content string or a number of bytes; content_or_bytes is #{content_or_bytes.class.to_s}."
65
52
  end
66
53
  end
67
54
 
68
- #
69
- # call-seq:
70
- # compressed ->
71
- #
72
55
  def compressed
73
56
  require "zlib"
74
57
  # [2..-5] removes headers
75
58
  @compressed ||= Zlib::Deflate.deflate(content)
76
59
  end
77
60
 
78
- #
79
- # call-seq:
80
- # content ->
81
- #
82
61
  def content
83
62
  @content ||= extract
84
63
  end
85
64
 
86
- #
87
- # call-seq:
88
- # padded_bytes ->
89
- #
90
65
  def padded_bytes
91
66
  @padded_bytes ||= content.size % 4 == 0 ? content.size : (content.size / 4 + 1) * 4
92
67
  end
93
68
 
94
- #
95
- # call-seq:
96
- # write_packed(packedio, options = {}) ->
97
- #
98
- # * *Arguments* :
99
- # - ++ ->
100
- # * *Returns* :
101
- # -
102
- #
103
69
  def write_packed(packedio, options = {})
104
70
  packedio << [compressed, {:bytes => padded_bytes}.merge(options)]
105
71
  end
106
72
 
107
- #
108
- # call-seq:
109
- # read_packed(packedio, options = {}) ->
110
- #
111
- # * *Arguments* :
112
- # - ++ ->
113
- # * *Returns* :
114
- # -
115
- #
116
73
  def read_packed(packedio, options)
117
74
  @compressed = (packedio >> [String, options]).first
118
75
  content
119
76
  end
120
77
 
121
78
  protected
122
- #
123
- # call-seq:
124
- # extract ->
125
- #
126
79
  def extract
127
80
  require 'zlib'
128
81
 
@@ -140,26 +93,17 @@ module NMatrix::IO::Matlab
140
93
  :matlab_class, :dimensions, :matlab_name, :real_part,
141
94
  :imaginary_part, :row_index, :column_index)
142
95
 
143
- class MatrixData < MatrixDataStruct
96
+ class MatrixData < MatrixDataStruct #:nodoc:
144
97
  include Packable
145
98
 
146
- #
147
- # call-seq:
148
- # write_packed(packedio, options) ->
149
- #
150
- # * *Arguments* :
151
- # - ++ ->
152
- # * *Returns* :
153
- # -
154
- #
155
99
  def write_packed(packedio, options)
156
100
  raise NotImplementedError
157
101
  packedio << [info, {:bytes => padded_bytes}.merge(options)]
158
102
  end
159
103
 
160
- #
161
104
  # call-seq:
162
- # to_ruby -> NMatrix or Array
105
+ # to_ruby -> NMatrix
106
+ # to_ruby -> Array
163
107
  #
164
108
  # Figure out the appropriate Ruby type to convert to, and do it. There
165
109
  # are basically two possible types: +NMatrix+ and +Array+. This method
@@ -172,7 +116,6 @@ module NMatrix::IO::Matlab
172
116
  # appropriate stype (:yale or :dense, respectively).
173
117
  #
174
118
  # See also to_nm, which is responsible for NMatrix instantiation.
175
- #
176
119
  def to_ruby
177
120
  case matlab_class
178
121
  when :mxSPARSE then return to_nm
@@ -181,7 +124,6 @@ module NMatrix::IO::Matlab
181
124
  end
182
125
  end
183
126
 
184
- #
185
127
  # call-seq:
186
128
  # guess_dtype_from_mdtype -> Symbol
187
129
  #
@@ -189,7 +131,6 @@ module NMatrix::IO::Matlab
189
131
  #
190
132
  # TODO: Needs to be verified that unsigned MATLAB types are being
191
133
  # converted to the correct NMatrix signed dtypes.
192
- #
193
134
  def guess_dtype_from_mdtype
194
135
  dtype = MatReader::MDTYPE_TO_DTYPE[self.real_part.tag.data_type]
195
136
 
@@ -228,10 +169,6 @@ module NMatrix::IO::Matlab
228
169
 
229
170
  end
230
171
 
231
- #
232
- # call-seq:
233
- # repacked_data(to_dtype = nil) ->
234
- #
235
172
  # Unpacks and repacks data into the appropriate format for NMatrix.
236
173
  #
237
174
  # If data is already in the appropriate format, does not unpack or
@@ -291,15 +228,10 @@ module NMatrix::IO::Matlab
291
228
  to_dtype]
292
229
  end
293
230
 
294
- #
295
- # call-seq:
296
- # repacked_indices ->
297
- #
298
231
  # Unpacks and repacks index data into the appropriate format for NMatrix.
299
232
  #
300
233
  # If data is already in the appropriate format, does not unpack or
301
234
  # repack, just returns directly.
302
- #
303
235
  def repacked_indices
304
236
  repacked_row_indices = ::NMatrix::IO::Matlab.repack( self.row_index.data, :miINT32, :itype )
305
237
  repacked_col_indices = ::NMatrix::IO::Matlab.repack( self.column_index.data, :miINT32, :itype )
@@ -352,29 +284,17 @@ module NMatrix::IO::Matlab
352
284
  end
353
285
  end
354
286
 
355
- #
356
- # call-seq:
357
- # read_packed(packedio, options) ->
358
- #
359
- # * *Arguments* :
360
- # - ++ ->
361
- # * *Returns* :
362
- # -
363
- #
364
287
  def read_packed(packedio, options)
365
288
  flags_class, self.nonzero_max = packedio.read([Element, options]).data
366
289
 
367
290
  self.matlab_class = MatReader::MCLASSES[flags_class % 16]
368
- #STDERR.puts "Matrix class: #{self.matlab_class}"
369
291
 
370
292
  self.logical = (flags_class >> 8) % 2 == 1 ? true : false
371
293
  self.global = (flags_class >> 9) % 2 == 1 ? true : false
372
294
  self.complex = (flags_class >> 10) % 2 == 1 ? true : false
373
- #STDERR.puts "nzmax: #{self.nonzero_max}"
374
295
 
375
296
  dimensions_tag_data = packedio.read([Element, options])
376
297
  self.dimensions = dimensions_tag_data.data
377
- #STDERR.puts "dimensions: #{self.dimensions}"
378
298
 
379
299
  begin
380
300
  name_tag_data = packedio.read([Element, options])
@@ -390,7 +310,6 @@ module NMatrix::IO::Matlab
390
310
  raise(e)
391
311
  end
392
312
 
393
- #STDERR.puts [flags_class.to_s(2), self.complex, self.global, self.logical, nil, self.mclass, self.nonzero_max].join("\t")
394
313
  if self.matlab_class == :mxCELL
395
314
  # Read what may be a series of matrices
396
315
  self.cells = []
@@ -404,8 +323,6 @@ module NMatrix::IO::Matlab
404
323
  if self.matlab_class == :mxSPARSE
405
324
  self.column_index = packedio.read(read_opts)
406
325
  self.row_index = packedio.read(read_opts)
407
-
408
- # STDERR.puts "row and col indices: #{self.row_index.inspect}, #{self.column_index.inspect}"
409
326
  end
410
327
 
411
328
  self.real_part = packedio.read(read_opts)
@@ -413,15 +330,6 @@ module NMatrix::IO::Matlab
413
330
  end
414
331
  end
415
332
 
416
- #
417
- # call-seq:
418
- # ignore_padding(packedio, bytes) ->
419
- #
420
- # * *Arguments* :
421
- # - ++ ->
422
- # * *Returns* :
423
- # -
424
- #
425
333
  def ignore_padding(packedio, bytes)
426
334
  packedio.read([Integer, {:unsigned => true, :bytes => bytes}]) if bytes > 0
427
335
  end
@@ -433,7 +341,6 @@ module NMatrix::IO::Matlab
433
341
  :miCOMPRESSED => [Compressed, {}],
434
342
  :miMATRIX => [MatrixData, {}]
435
343
  })
436
- # include TaggedDataEnumerable
437
344
 
438
345
  FIRST_TAG_FIELD_POS = 128
439
346
 
@@ -441,6 +348,8 @@ module NMatrix::IO::Matlab
441
348
  # Instance Methods for Mat5Reader #
442
349
  ###################################
443
350
 
351
+ # call-seq:
352
+ # NMatrix::IO::Mat5Reader.new(stream, options = {}) -> NMatrix
444
353
  def initialize(stream, options = {})
445
354
  super(stream, options)
446
355
  @file_header = seek_and_read_file_header
@@ -492,11 +401,9 @@ module NMatrix::IO::Matlab
492
401
  self
493
402
  end
494
403
 
495
- ####################
496
- # Internal Classes #
497
- ####################
404
+ # Internal Classes.
498
405
 
499
- class Header < Struct.new(:desc, :data_offset, :version, :endian)
406
+ class Header < Struct.new(:desc, :data_offset, :version, :endian) #:nodoc:
500
407
 
501
408
  include Packable
502
409
 
@@ -506,7 +413,7 @@ module NMatrix::IO::Matlab
506
413
  VERSION_LENGTH = 2
507
414
  BYTE_ORDER_POS = 126
508
415
 
509
- ## TODO: TEST WRITE.
416
+ # TODO: TEST WRITE.
510
417
  def write_packed(packedio, options)
511
418
  packedio << [desc, {:bytes => DESC_LENGTH }] <<
512
419
  [data_offset, {:bytes => DATA_OFFSET_LENGTH }] <<
@@ -529,13 +436,13 @@ module NMatrix::IO::Matlab
529
436
  end
530
437
  end
531
438
 
532
- class Tag < Struct.new(:data_type, :raw_data_type, :bytes, :small)
439
+ class Tag < Struct.new(:data_type, :raw_data_type, :bytes, :small) #:nodoc:
533
440
  include Packable
534
441
 
535
442
  DATA_TYPE_OPTS = BYTES_OPTS = {:bytes => 4, :signed => false}
536
443
  LENGTH = DATA_TYPE_OPTS[:bytes] + BYTES_OPTS[:bytes]
537
444
 
538
- ## TODO: TEST WRITE.
445
+ # TODO: TEST WRITE.
539
446
  def write_packed packedio, options
540
447
  packedio << [data_type, DATA_TYPE_OPTS] << [bytes, BYTES_OPTS]
541
448
  end
@@ -575,7 +482,7 @@ module NMatrix::IO::Matlab
575
482
  end
576
483
 
577
484
 
578
- class ElementDataIOError < IOError
485
+ class ElementDataIOError < IOError #:nodoc:
579
486
  attr_reader :tag
580
487
 
581
488
  def initialize(tag = nil, msg = nil)
@@ -589,7 +496,7 @@ module NMatrix::IO::Matlab
589
496
  end
590
497
 
591
498
 
592
- class Element < Struct.new(:tag, :data)
499
+ class Element < Struct.new(:tag, :data) #:nodoc:
593
500
  include Packable
594
501
 
595
502
  def write_packed packedio, options
@@ -600,11 +507,9 @@ module NMatrix::IO::Matlab
600
507
  raise(ArgumentError, 'Missing mandatory option :endian.') unless options.has_key?(:endian)
601
508
 
602
509
  tag = packedio.read([Tag, {:endian => options[:endian]}])
603
- #STDERR.puts tag.inspect
604
510
  data_type = MDTYPE_UNPACK_ARGS[tag.data_type]
605
511
 
606
512
  self.tag = tag
607
- #STDERR.puts self.tag.inspect
608
513
 
609
514
  raise ElementDataIOError.new(tag, "Unrecognized Matlab type #{tag.raw_data_type}") if data_type.nil?
610
515
 
@@ -651,7 +556,7 @@ module NMatrix::IO::Matlab
651
556
 
652
557
  # Doesn't unpack the contents of the element, e.g., if we want to handle
653
558
  # manually, or pass the raw string of bytes into NMatrix.
654
- class RawElement < Element
559
+ class RawElement < Element #:nodoc:
655
560
  def read_packed(packedio, options)
656
561
  raise(ArgumentError, 'Missing mandatory option :endian.') unless options.has_key?(:endian)
657
562