nmatrix 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +3 -0
  2. data/CONTRIBUTING.md +66 -0
  3. data/Gemfile +1 -1
  4. data/History.txt +68 -10
  5. data/LICENSE.txt +2 -2
  6. data/Manifest.txt +2 -0
  7. data/README.rdoc +90 -69
  8. data/Rakefile +18 -9
  9. data/ext/nmatrix/data/complex.h +7 -7
  10. data/ext/nmatrix/data/data.cpp +2 -7
  11. data/ext/nmatrix/data/data.h +7 -4
  12. data/ext/nmatrix/data/rational.h +2 -2
  13. data/ext/nmatrix/data/ruby_object.h +3 -10
  14. data/ext/nmatrix/extconf.rb +79 -54
  15. data/ext/nmatrix/new_extconf.rb +11 -12
  16. data/ext/nmatrix/nmatrix.cpp +94 -125
  17. data/ext/nmatrix/nmatrix.h +38 -17
  18. data/ext/nmatrix/ruby_constants.cpp +2 -15
  19. data/ext/nmatrix/ruby_constants.h +2 -14
  20. data/ext/nmatrix/storage/common.cpp +2 -2
  21. data/ext/nmatrix/storage/common.h +2 -2
  22. data/ext/nmatrix/storage/dense.cpp +206 -31
  23. data/ext/nmatrix/storage/dense.h +5 -2
  24. data/ext/nmatrix/storage/list.cpp +52 -4
  25. data/ext/nmatrix/storage/list.h +3 -2
  26. data/ext/nmatrix/storage/storage.cpp +6 -6
  27. data/ext/nmatrix/storage/storage.h +2 -2
  28. data/ext/nmatrix/storage/yale.cpp +202 -49
  29. data/ext/nmatrix/storage/yale.h +5 -4
  30. data/ext/nmatrix/ttable_helper.rb +108 -108
  31. data/ext/nmatrix/types.h +2 -15
  32. data/ext/nmatrix/util/io.cpp +2 -2
  33. data/ext/nmatrix/util/io.h +2 -2
  34. data/ext/nmatrix/util/lapack.h +2 -2
  35. data/ext/nmatrix/util/math.cpp +14 -14
  36. data/ext/nmatrix/util/math.h +2 -2
  37. data/ext/nmatrix/util/sl_list.cpp +2 -2
  38. data/ext/nmatrix/util/sl_list.h +2 -2
  39. data/ext/nmatrix/util/util.h +2 -2
  40. data/lib/nmatrix.rb +13 -35
  41. data/lib/nmatrix/blas.rb +182 -56
  42. data/lib/nmatrix/io/market.rb +38 -14
  43. data/lib/nmatrix/io/mat5_reader.rb +393 -278
  44. data/lib/nmatrix/io/mat_reader.rb +121 -107
  45. data/lib/nmatrix/lapack.rb +59 -14
  46. data/lib/nmatrix/monkeys.rb +32 -30
  47. data/lib/nmatrix/nmatrix.rb +204 -100
  48. data/lib/nmatrix/nvector.rb +166 -57
  49. data/lib/nmatrix/shortcuts.rb +364 -231
  50. data/lib/nmatrix/version.rb +8 -4
  51. data/nmatrix.gemspec +5 -3
  52. data/scripts/mac-brew-gcc.sh +1 -1
  53. data/spec/blas_spec.rb +80 -2
  54. data/spec/math_spec.rb +78 -32
  55. data/spec/nmatrix_list_spec.rb +55 -55
  56. data/spec/nmatrix_spec.rb +60 -117
  57. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  58. data/spec/nmatrix_yale_spec.rb +214 -198
  59. data/spec/nvector_spec.rb +58 -2
  60. data/spec/shortcuts_spec.rb +156 -32
  61. data/spec/slice_spec.rb +229 -178
  62. data/spec/spec_helper.rb +2 -2
  63. metadata +71 -21
@@ -1,3 +1,4 @@
1
+ #--
1
2
  # = NMatrix
2
3
  #
3
4
  # A linear algebra library for scientific computation in Ruby.
@@ -8,8 +9,8 @@
8
9
  #
9
10
  # == Copyright Information
10
11
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2013, Ruby Science Foundation
13
14
  #
14
15
  # Please see LICENSE.txt for additional copyright notices.
15
16
  #
@@ -24,20 +25,15 @@
24
25
  #
25
26
  # This file adds a few additional pieces of functionality (e.g., inspect,
26
27
  # pretty_print).
27
-
28
- ############
29
- # Requires #
30
- ############
28
+ #++
31
29
 
32
30
  require_relative './shortcuts.rb'
33
-
34
- #######################
35
- # Classes and Modules #
36
- #######################
31
+ require_relative './lapack.rb'
37
32
 
38
33
  class NMatrix
39
- # Read and write extensions for NMatrix. These are only loaded when needed.
40
- module IO
34
+ # Read and write extensions for NMatrix. These are only loaded when needed.
35
+ #
36
+ module IO
41
37
  module Matlab
42
38
  class << self
43
39
  def load_mat file_path
@@ -54,10 +50,9 @@ class NMatrix
54
50
  autoload :Market, 'nmatrix/io/market'
55
51
  end
56
52
 
57
-
58
- # TODO: Make this actually pretty.
59
- def pretty_print(q = nil)
60
- if dim != 2 || (dim == 2 && shape[1] > 10) # FIXME: Come up with a better way of restricting the display
53
+ # TODO: Make this actually pretty.
54
+ def pretty_print(q = nil) #:nodoc:
55
+ if dim != 2 || (dim == 2 && shape[1] > 10) # FIXME: Come up with a better way of restricting the display
61
56
  inspect
62
57
  else
63
58
 
@@ -65,17 +60,17 @@ class NMatrix
65
60
  ary = []
66
61
  (0...shape[1]).each do |j|
67
62
  o = begin
68
- self[i, j]
69
- rescue ArgumentError
70
- nil
71
- end
63
+ self[i, j]
64
+ rescue ArgumentError
65
+ nil
66
+ end
72
67
  ary << (o.nil? ? 'nil' : o)
73
68
  end
74
69
  ary.inspect
75
70
  end
76
71
 
77
72
  if q.nil?
78
- puts arr.join("\n")
73
+ puts "[" + arr.join("\n") + "]"
79
74
  else
80
75
  q.group(1, "", "\n") do
81
76
  q.seplist(arr, lambda { q.text " " }, :each) { |v| q.text v.to_s }
@@ -83,21 +78,64 @@ class NMatrix
83
78
  end
84
79
 
85
80
  end
86
- end
87
- alias :pp :pretty_print
81
+ end
82
+ alias :pp :pretty_print
88
83
 
89
- # These shortcuts use #shape to return the number of rows and columns.
84
+ #
85
+ # call-seq:
86
+ # rows -> Integer
87
+ #
88
+ # This shortcut use #shape to return the number of rows (the first dimension)
89
+ # of the matrix.
90
+ #
90
91
  def rows
91
92
  shape[0]
92
93
  end
93
-
94
+
95
+ #
96
+ # call-seq:
97
+ # cols -> Integer
98
+ #
99
+ # This shortcut use #shape to return the number of columns (the second
100
+ # dimension) of the matrix.
101
+ #
94
102
  def cols
95
103
  shape[1]
96
104
  end
97
105
 
98
- # Use LAPACK to calculate the inverse of the matrix (in-place). Only works on dense matrices.
106
+ #
107
+ # call-seq:
108
+ # to_hash -> Hash
109
+ #
110
+ # Create a Ruby Hash from an NMatrix.
111
+ #
112
+ def to_hash
113
+ if stype == :yale
114
+ h = {}
115
+ each_stored_with_indices do |val,i,j|
116
+ next if val == 0 # Don't bother storing the diagonal zero values -- only non-zeros.
117
+ if h.has_key?(i)
118
+ h[i][j] = val
119
+ else
120
+ h[i] = {j => val}
121
+ end
122
+ end
123
+ h
124
+ else # dense and list should use a C internal functions.
125
+ to_hash_c
126
+ end
127
+ end
128
+ alias :to_h :to_hash
129
+
130
+ #
131
+ # call-seq:
132
+ # invert! -> NMatrix
133
+ #
134
+ # Use LAPACK to calculate the inverse of the matrix (in-place). Only works on
135
+ # dense matrices.
99
136
  #
100
137
  # Note: If you don't have LAPACK, e.g., on a Mac, this may not work yet.
138
+ #
101
139
  def invert!
102
140
  # Get the pivot array; factor the matrix
103
141
  pivot = self.getrf!
@@ -108,33 +146,64 @@ class NMatrix
108
146
  self
109
147
  end
110
148
 
111
- # Make a copy of the matrix, then invert it (requires LAPACK). Returns a dense matrix.
149
+ #
150
+ # call-seq:
151
+ # invert -> NMatrix
152
+ #
153
+ # Make a copy of the matrix, then invert it (requires LAPACK).
154
+ #
155
+ # * *Returns* :
156
+ # - A dense NMatrix.
157
+ #
112
158
  def invert
113
159
  self.cast(:dense, self.dtype).invert!
114
160
  end
115
-
116
161
  alias :inverse :invert
117
162
 
118
- # Calls clapack_getrf and returns the pivot array (dense only).
163
+ #
164
+ # call-seq:
165
+ # getrf! -> NMatrix
166
+ #
167
+ # LU factorization of a general M-by-N matrix +A+ using partial pivoting with
168
+ # row interchanges. Only works in dense matrices.
169
+ #
170
+ # * *Returns* :
171
+ # - The IPIV vector. The L and U matrices are stored in A.
172
+ # * *Raises* :
173
+ # - +StorageTypeError+ -> ATLAS functions only work on dense matrices.
174
+ #
119
175
  def getrf!
120
176
  raise(StorageTypeError, "ATLAS functions only work on dense matrices") unless self.stype == :dense
121
177
  NMatrix::LAPACK::clapack_getrf(:row, self.shape[0], self.shape[1], self, self.shape[0])
122
178
  end
123
179
 
124
- # Calculate the determinant by way of LU decomposition. This is accomplished using
125
- # clapack_getrf, and then by summing the diagonal elements. There is a risk of
126
- # underflow/overflow.
127
180
  #
128
- # There are probably also more efficient ways to calculate the determinant. This method
129
- # requires making a copy of the matrix, since clapack_getrf modifies its input.
181
+ # call-seq:
182
+ # det -> determinant
183
+ #
184
+ # Calculate the determinant by way of LU decomposition. This is accomplished
185
+ # using clapack_getrf, and then by summing the diagonal elements. There is a
186
+ # risk of underflow/overflow.
187
+ #
188
+ # There are probably also more efficient ways to calculate the determinant.
189
+ # This method requires making a copy of the matrix, since clapack_getrf
190
+ # modifies its input.
191
+ #
192
+ # For smaller matrices, you may be able to use +#det_exact+.
130
193
  #
131
- # For smaller matrices, you may be able to use det_exact.
194
+ # This function is guaranteed to return the same type of data in the matrix
195
+ # upon which it is called.
196
+ # In other words, if you call it on a rational matrix, you'll get a rational
197
+ # number back.
132
198
  #
133
- # This function is guaranteed to return the same type of data in the matrix upon which it is called.
134
- # In other words, if you call it on a rational matrix, you'll get a rational number back.
199
+ # Integer matrices are converted to rational matrices for the purposes of
200
+ # performing the calculation, as xGETRF can't work on integer matrices.
201
+ #
202
+ # * *Returns* :
203
+ # - The determinant of the matrix. It's the same type as the matrix's dtype.
204
+ # * *Raises* :
205
+ # - +NotImplementedError+ -> Must be used in 2D matrices.
135
206
  #
136
- # Integer matrices are converted to rational matrices for the purposes of performing the calculation,
137
- # as xGETRF can't work on integer matrices.
138
207
  def det
139
208
  raise(NotImplementedError, "determinant can be calculated only for 2D matrices") unless self.dim == 2
140
209
 
@@ -142,7 +211,8 @@ class NMatrix
142
211
  new_dtype = [:byte,:int8,:int16,:int32,:int64].include?(self.dtype) ? :rational128 : self.dtype
143
212
  copy = self.cast(:dense, new_dtype)
144
213
 
145
- # Need to know the number of permutations. We'll add up the diagonals of the factorized matrix.
214
+ # Need to know the number of permutations. We'll add up the diagonals of
215
+ # the factorized matrix.
146
216
  pivot = copy.getrf!
147
217
 
148
218
  prod = pivot.size % 2 == 1 ? -1 : 1 # odd permutations => negative
@@ -154,72 +224,106 @@ class NMatrix
154
224
  new_dtype != self.dtype ? prod.to_i : prod
155
225
  end
156
226
 
227
+ #
228
+ # call-seq:
229
+ # complex_conjugate -> NMatrix
230
+ # complex_conjugate(new_stype) -> NMatrix
231
+ #
232
+ # Get the complex conjugate of this matrix. See also complex_conjugate! for
233
+ # an in-place operation (provided the dtype is already +:complex64+ or
234
+ # +:complex128+).
235
+ #
236
+ # Doesn't work on list matrices, but you can optionally pass in the stype you
237
+ # want to cast to if you're dealing with a list matrix.
238
+ #
239
+ # * *Arguments* :
240
+ # - +new_stype+ -> stype for the new matrix.
241
+ # * *Returns* :
242
+ # - If the original NMatrix isn't complex, the result is a +:complex128+ NMatrix. Otherwise, it's the original dtype.
243
+ #
244
+ def complex_conjugate(new_stype = self.stype)
245
+ self.cast(new_stype, NMatrix::upcast(dtype, :complex64)).complex_conjugate!
246
+ end
247
+
248
+ #
249
+ # call-seq:
250
+ # conjugate_transpose -> NMatrix
251
+ #
252
+ # Calculate the conjugate transpose of a matrix. If your dtype is already
253
+ # complex, this should only require one copy (for the transpose).
254
+ #
255
+ # * *Returns* :
256
+ # - The conjugate transpose of the matrix as a copy.
257
+ #
258
+ def conjugate_transpose
259
+ self.transpose.complex_conjugate!
260
+ end
261
+
262
+ #
263
+ # call-seq:
264
+ # hermitian? -> Boolean
265
+ #
266
+ # A hermitian matrix is a complex square matrix that is equal to its
267
+ # conjugate transpose. (http://en.wikipedia.org/wiki/Hermitian_matrix)
268
+ #
269
+ # * *Returns* :
270
+ # - True if +self+ is a hermitian matrix, nil otherwise.
271
+ #
272
+ def hermitian?
273
+ return false if self.dim != 2 or self.shape[0] != self.shape[1]
274
+
275
+ if [:complex64, :complex128].include?(self.dtype)
276
+ # TODO: Write much faster Hermitian test in C
277
+ self.eql?(self.conjugate_transpose)
278
+ else
279
+ symmetric?
280
+ end
281
+ end
282
+
283
+ def inspect #:nodoc:
284
+ original_inspect = super()
285
+ original_inspect = original_inspect[0...original_inspect.size-1]
286
+ original_inspect + " " + inspect_helper.join(" ") + ">"
287
+ end
288
+
289
+ def __yale_ary__to_s(sym) #:nodoc:
290
+ ary = self.send("__yale_#{sym.to_s}__".to_sym)
157
291
 
158
- # Get the complex conjugate of this matrix. See also complex_conjugate! for
159
- # an in-place operation (provided the dtype is already :complex64 or
160
- # :complex128).
161
- #
162
- # Does not work on list matrices, but you can optionally pass in the type you
163
- # want to cast to if you're dealing with a list matrix.
164
- def complex_conjugate(new_stype = self.stype)
165
- self.cast(new_stype, NMatrix::upcast(dtype, :complex64)).complex_conjugate!
166
- end
167
-
168
- # Calculate the conjugate transpose of a matrix. If your dtype is already
169
- # complex, this should only require one copy (for the transpose).
170
- def conjugate_transpose
171
- self.transpose.complex_conjugate!
172
- end
173
-
174
- def hermitian?
175
- return false if self.dim != 2 or self.shape[0] != self.shape[1]
176
-
177
- if [:complex64, :complex128].include?(self.dtype)
178
- # TODO: Write much faster Hermitian test in C
179
- self.eql?(self.conjugate_transpose)
180
- else
181
- symmetric?
182
- end
183
- end
184
-
185
- def inspect
186
- original_inspect = super()
187
- original_inspect = original_inspect[0...original_inspect.size-1]
188
- original_inspect + inspect_helper.join(" ") + ">"
189
- end
190
-
191
- def __yale_ary__to_s(sym)
192
- ary = self.send("__yale_#{sym.to_s}__".to_sym)
193
-
194
- '[' + ary.collect { |a| a ? a : 'nil'}.join(',') + ']'
195
- end
196
-
197
- class << self
198
- def load_file(file_path)
199
- NMatrix::IO::Mat5Reader.new(File.open(file_path, 'rb')).to_ruby
200
- end
201
-
202
- end
203
-
204
- protected
205
- def inspect_helper
206
- ary = []
207
- ary << "shape:[#{shape.join(',')}]" << "dtype:#{dtype}" << "stype:#{stype}"
208
-
209
- if stype == :yale
210
- ary << "capacity:#{capacity}"
292
+ '[' + ary.collect { |a| a ? a : 'nil'}.join(',') + ']'
293
+ end
294
+
295
+ class << self
296
+ #
297
+ # call-seq:
298
+ # load_file(path) -> Mat5Reader
299
+ #
300
+ # * *Arguments* :
301
+ # - +path+ -> The path to a version 5 .mat file.
302
+ # * *Returns* :
303
+ # - A Mat5Reader object.
304
+ #
305
+ def load_file(file_path)
306
+ NMatrix::IO::Mat5Reader.new(File.open(file_path, 'rb')).to_ruby
307
+ end
308
+ end
309
+
310
+ protected
311
+ def inspect_helper #:nodoc:
312
+ ary = []
313
+ ary << "shape:[#{shape.join(',')}]" << "dtype:#{dtype}" << "stype:#{stype}"
314
+
315
+ if stype == :yale
316
+ ary << "capacity:#{capacity}"
211
317
 
212
318
  # These are enabled by the DEBUG_YALE compiler flag in extconf.rb.
213
319
  if respond_to?(:__yale_a__)
214
320
  ary << "ija:#{__yale_ary__to_s(:ija)}" << "ia:#{__yale_ary__to_s(:ia)}" <<
215
- "ja:#{__yale_ary__to_s(:ja)}" << "a:#{__yale_ary__to_s(:a)}" << "d:#{__yale_ary__to_s(:d)}" <<
216
- "lu:#{__yale_ary__to_s(:lu)}" << "yale_size:#{__yale_size__}"
321
+ "ja:#{__yale_ary__to_s(:ja)}" << "a:#{__yale_ary__to_s(:a)}" << "d:#{__yale_ary__to_s(:d)}" <<
322
+ "lu:#{__yale_ary__to_s(:lu)}" << "yale_size:#{__yale_size__}"
217
323
  end
218
324
 
219
- end
325
+ end
220
326
 
221
- ary
222
- end
327
+ ary
328
+ end
223
329
  end
224
-
225
- require_relative "./lapack.rb"
@@ -1,3 +1,4 @@
1
+ #--
1
2
  # = NMatrix
2
3
  #
3
4
  # A linear algebra library for scientific computation in Ruby.
@@ -8,8 +9,8 @@
8
9
  #
9
10
  # == Copyright Information
10
11
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2013, Ruby Science Foundation
13
14
  #
14
15
  # Please see LICENSE.txt for additional copyright notices.
15
16
  #
@@ -23,81 +24,189 @@
23
24
  # == nmatrix.rb
24
25
  #
25
26
  # This file defines the NVector class.
26
-
27
- ############
28
- # Requires #
29
- ############
30
-
31
-
32
- #######################
33
- # Classes and Modules #
34
- #######################
27
+ #++
35
28
 
36
29
  # This is a specific type of NMatrix in which only one dimension is not 1.
37
30
  # Although it is stored as a dim-2, n x 1, matrix, it acts as a dim-1 vector
38
31
  # of size n. If the @orientation flag is set to :row, it is stored as 1 x n
39
32
  # instead of n x 1.
40
33
  class NVector < NMatrix
41
- def initialize(length, *args)
42
- super(:dense, [length, 1], *args)
34
+ #
35
+ # call-seq:
36
+ # new(length) -> NVector
37
+ # new(length, values) -> NVector
38
+ # new(length, values, dtype) -> NVector
39
+ #
40
+ # Creates a new NVector.
41
+ #
42
+ # * *Arguments* :
43
+ # - +length+ -> Size of the vector.
44
+ # - +values+ -> (optional) Initial values of the vector. Default is 0.
45
+ # - +dtype+ -> (optional) Default is a guess from the +values+.
46
+ # * *Returns* :
47
+ # -
48
+ #
49
+ def initialize(length, *args)
50
+ super(:dense, [length, 1], *args)
43
51
  orientation
44
52
  end
45
53
 
46
- # Orientation defaults to column (e.g., [3,1] is a column of length 3). It
47
- # may also be row, e.g., for [1,5].
48
- def orientation
49
- @orientation ||= :column
50
- end
54
+ #
55
+ # call-seq:
56
+ # orientation -> Symbol
57
+ #
58
+ # Orientation defaults to column (e.g., [3,1] is a column of length 3). It
59
+ # may also be row, e.g., for [1,5].
60
+ #
61
+ def orientation
62
+ @orientation ||= :column
63
+ end
51
64
 
52
- def transpose
53
- t = super()
65
+ #
66
+ # call-seq:
67
+ # transpose -> NVector
68
+ #
69
+ # Returns a transposed copy of the vector.
70
+ #
71
+ # * *Returns* :
72
+ # - NVector containing the transposed vector.
73
+ #
74
+ def transpose
75
+ t = super()
54
76
  t.flip!
55
- end
77
+ end
56
78
 
57
- def transpose!
58
- super()
59
- self.flip!
60
- end
79
+ #
80
+ # call-seq:
81
+ # transpose! -> NVector
82
+ #
83
+ # Transpose the vector in-place.
84
+ #
85
+ # * *Returns* :
86
+ # - NVector containing the transposed vector.
87
+ #
88
+ def transpose!
89
+ super()
90
+ self.flip!
91
+ end
61
92
 
62
- def multiply(m)
63
- t = super(m)
93
+ #
94
+ # call-seq:
95
+ # multiply(m) ->
96
+ #
97
+ # ...
98
+ #
99
+ # * *Arguments* :
100
+ # - ++ ->
101
+ # * *Returns* :
102
+ # -
103
+ #
104
+ def multiply(m)
105
+ t = super(m)
64
106
  t.flip!
65
- end
107
+ end
108
+
109
+ #
110
+ # call-seq:
111
+ # multiply!(m) ->
112
+ #
113
+ # ...
114
+ #
115
+ # * *Arguments* :
116
+ # - ++ ->
117
+ # * *Returns* :
118
+ # -
119
+ #
120
+ def multiply!(m)
121
+ super().flip!
122
+ end
66
123
 
67
- def multiply!(m)
68
- super().flip!
69
- end
124
+ #
125
+ # call-seq:
126
+ # vector[index] -> element
127
+ # vector[range] -> NVector
128
+ #
129
+ # Retrieves an element or return a slice.
130
+ #
131
+ # Examples:
132
+ #
133
+ # u = NVector.new(3, [10, 20, 30])
134
+ # u[0] # => 10
135
+ # u[0] + u[1] # => 30
136
+ # u[0 .. 1].shape # => [2, 1]
137
+ #
138
+ def [](i)
139
+ case @orientation
140
+ when :column; super(i, 0)
141
+ when :row; super(0, i)
142
+ end
143
+ end
70
144
 
71
- def [](i)
72
- case @orientation
73
- when :column; super(i, 0)
74
- when :row; super(0, i)
75
- end
145
+ #
146
+ # call-seq:
147
+ # vector[index] = obj -> obj
148
+ #
149
+ # Stores +value+ at position +index+.
150
+ #
151
+ def []=(i, val)
152
+ case @orientation
153
+ when :column; super(i, 0, val)
154
+ when :row; super(0, i, val)
155
+ end
76
156
  end
77
157
 
78
- def []=(i, val)
79
- case @orientation
80
- when :column; super(i, 0, val)
81
- when :row; super(0, i, val)
82
- end
83
- end
158
+ #
159
+ # call-seq:
160
+ # dim -> 1
161
+ #
162
+ # Returns the dimension of a vector, which is 1.
163
+ #
164
+ def dim; 1; end
165
+
166
+ # shorthand for the dominant shape component
167
+ def size
168
+ shape[0] > 1 ? shape[0] : shape[1]
169
+ end
84
170
 
85
- def dim; 1; end
171
+ # TODO: Make this actually pretty.
172
+ def pretty_print(q = nil) #:nodoc:
173
+ dim = @orientation == :row ? 1 : 0
86
174
 
87
- # TODO: Make this actually pretty.
88
- def pretty_print
89
- dim = @orientation == :row ? 1 : 0
90
-
91
- puts (0...shape[dim]).inject(Array.new) { |a, i| a << self[i] }.join(' ')
92
- end
175
+ arr = (0...shape[dim]).inject(Array.new){ |a, i| a << self[i] }
176
+
177
+ if q.nil?
178
+ puts "[" + arr.join("\n") + "]"
179
+ else
180
+ q.group(1, "", "\n") do
181
+ q.seplist(arr, lambda { q.text " " }, :each) { |v| q.text v.to_s }
182
+ end
183
+ end
184
+ end
185
+
186
+ def inspect #:nodoc:
187
+ original_inspect = super()
188
+ original_inspect = original_inspect[0...original_inspect.size-1]
189
+ original_inspect.gsub("@orientation=:#{self.orientation}", "orientation:#{self.orientation}") + ">"
190
+ end
93
191
 
94
192
  protected
95
- def inspect_helper
96
- super() << "orientation:#{self.orientation}"
97
- end
98
-
99
- def flip_orientation!
100
- returning(self) { @orientation = @orientation == :row ? :column : :row }
101
- end
102
- alias :flip! :flip_orientation!
193
+ # def inspect_helper #:nodoc:
194
+ # x = (super() << "orientation:#{self.orientation}") #.gsub(" @orientation=:#{self.orientation}", "")
195
+ # binding.pry
196
+ # x
197
+ # end
198
+
199
+ #
200
+ # call-seq:
201
+ # flip_orientation! -> NVector
202
+ #
203
+ # Flip the orientation of the vector.
204
+ #
205
+ # * *Returns* :
206
+ # - NVector with orientation changed.
207
+ #
208
+ def flip_orientation!
209
+ returning(self) { @orientation = @orientation == :row ? :column : :row }
210
+ end
211
+ alias :flip! :flip_orientation!
103
212
  end