Bug #1532 ยป a_matrix_creation.diff

View differences:

lib/matrix.rb
35 35
`# arithmetically and algebraically, and determining their mathematical properties (trace, rank,`
36 36
`# inverse, determinant).`
37 37
`#`
38
`# Note that although matrices should theoretically be rectangular, this is not`
39
`# enforced by the class.`
38
`# Note that matrices must be rectangular, otherwise an ErrDimensionMismatch is raised.`
40 39
`#`
41
`# Also note that the determinant of integer matrices may be incorrectly calculated unless you`
40
`# Also note that the determinant of integer matrices may be approximated unless you`
42 41
`# also <tt>require 'mathn'</tt>.  This may be fixed in the future.`
43 42
`#`
44 43
`# == Method Catalogue`
......
108 107

109 108
`  # instance creations`
110 109
`  private_class_method :new`
110
`  attr_reader :rows`
111
`  protected :rows`
111 112

112 113
`  #`
113 114
`  # Creates a matrix where each argument is a row.`
......
116 117
`  #          -1 66`
117 118
`  #`
118 119
`  def Matrix.[](*rows)`
119
`    new(:init_rows, rows, false)`
120
`    Matrix.rows(rows, false)`
120 121
`  end`
121 122

122 123
`  #`
......
128 129
`  #          -1 66`
129 130
`  #`
130 131
`  def Matrix.rows(rows, copy = true)`
131
`    new(:init_rows, rows, copy)`
132
`    rows = Matrix.convert_to_array(rows)`
133
`    rows.map! do |row|`
134
`      Matrix.convert_to_array(row, copy)`
135
`    end`
136
`    size = (rows[0] || []).size`
137
`    rows.each do |row|`
138
`      Matrix.Raise ErrDimensionMismatch, "element size differs (#{row.size} should be #{size})" unless row.size == size`
139
`    end`
140
`    new rows`
132 141
`  end`
133 142

134 143
`  #`
......
138 147
`  #          93 66`
139 148
`  #`
140 149
`  def Matrix.columns(columns)`
141
`    rows = (0 ... columns[0].size).collect {|i|`
142
`      (0 ... columns.size).collect {|j|`
143
`        columns[j][i]`
144
`      }`
145
`    }`
146
`    Matrix.rows(rows, false)`
150
`    Matrix.rows(columns, false).transpose`
147 151
`  end`
148 152

149 153
`  #`
......
160 164
`      row[j] = values[j]`
161 165
`      row`
162 166
`    }`
163
`    rows(rows, false)`
167
`    new rows`
164 168
`  end`
165 169

166 170
`  #`
......
205 209
`  #     => 4 5 6`
206 210
`  #`
207 211
`  def Matrix.row_vector(row)`
208
`    case row`
209
`    when Vector`
210
`      Matrix.rows([row.to_a], false)`
211
`    when Array`
212
`      Matrix.rows([row.dup], false)`
213
`    else`
214
`      Matrix.rows([[row]], false)`
215
`    end`
212
`    row = Matrix.convert_to_array(row)`
213
`    new [row]`
216 214
`  end`
217 215

218 216
`  #`
......
224 222
`  #        6`
225 223
`  #`
226 224
`  def Matrix.column_vector(column)`
227
`    case column`
228
`    when Vector`
229
`      Matrix.columns([column.to_a])`
230
`    when Array`
231
`      Matrix.columns([column])`
232
`    else`
233
`      Matrix.columns([[column]])`
234
`    end`
225
`    column = Matrix.convert_to_array(column)`
226
`    new [column].transpose`
235 227
`  end`
236 228

237 229
`  #`
238
`  # This method is used by the other methods that create matrices, and is of no`
239
`  # use to general users.`
230
`  # Matrix.new is private; use Matrix.rows, columns, [], etc... to create.`
240 231
`  #`
241
`  def initialize(init_method, *argv)`
242
`    self.send(init_method, *argv)`
232
`  def initialize(rows)`
233
`    # No checking is done at this point. rows must be an Array of Arrays.`
234
`    @rows = rows`
243 235
`  end`
244 236

245
`  def init_rows(rows, copy)`
246
`    if copy`
247
`      @rows = rows.collect{|row| row.dup}`
248
`    else`
249
`      @rows = rows`
250
`    end`
251
`    self`
237
`  def new(rows) # :nodoc:`
238
`    Matrix.send(:new, rows) # bypass privacy of Matrix.new`
252 239
`  end`
253
`  private :init_rows`
240
`  private :new`
254 241

255 242
`  #`
256 243
`  # Returns element (+i+,+j+) of the matrix.  That is: row +i+, column +j+.`
......
276 263
`  end`
277 264

278 265
`  #`
279
`  # Returns the number of columns.  Note that it is possible to construct a`
280
`  # matrix with uneven columns (e.g. Matrix[ [1,2,3], [4,5] ]), but this is`
281
`  # mathematically unsound.  This method uses the first row to determine the`
282
`  # result.`
266
`  # Returns the number of columns.`
283 267
`  #`
284 268
`  def column_size`
285 269
`    @rows[0].size`
......
324 308
`  #`
325 309
`  def collect(&block) # :yield: e`
326 310
`    rows = @rows.collect{|row| row.collect(&block)}`
327
`    Matrix.rows(rows, false)`
311
`    new(rows)`
328 312
`  end`
329 313
`  alias map collect`
330 314

......
355 339
`    rows = @rows[from_row, size_row].collect{|row|`
356 340
`      row[from_col, size_col]`
357 341
`    }`
358
`    Matrix.rows(rows, false)`
342
`    new(rows)`
359 343
`  end`
360 344

361 345
`  #--`
......
377 361
`  end`
378 362

379 363
`  #`
380
`  # Returns +true+ is this is a square matrix.  See note in column_size about this`
381
`  # being unreliable, though.`
364
`  # Returns +true+ is this is a square matrix.`
382 365
`  #`
383 366
`  def square?`
384 367
`    column_size == row_size`
......
417 400
`  #`
418 401
`  # Returns a clone of the matrix, so that the contents of each do not reference`
419 402
`  # identical objects.`
403
`  # There should be no good reason to do this since Matrices are immutable.`
420 404
`  #`
421 405
`  def clone`
422
`    Matrix.rows(@rows)`
406
`    new(@rows.map{|row| row.dup})`
423 407
`  end`
424 408

425 409
`  #`
......
447 431
`          e * m`
448 432
`        }`
449 433
`      }`
450
`      return Matrix.rows(rows, false)`
434
`      return new(rows)`
451 435
`    when Vector`
452 436
`      m = Matrix.column_vector(m)`
453 437
`      r = self * m`
......
462 446
`          end`
463 447
`        }`
464 448
`      }`
465
`      return Matrix.rows(rows, false)`
449
`      return new(rows)`
466 450
`    else`
467 451
`      x, y = m.coerce(self)`
468 452
`      return x * y`
......
494 478
`        self[i, j] + m[i, j]`
495 479
`      }`
496 480
`    }`
497
`    Matrix.rows(rows, false)`
481
`    new(rows)`
498 482
`  end`
499 483

500 484
`  #`
......
522 506
`        self[i, j] - m[i, j]`
523 507
`      }`
524 508
`    }`
525
`    Matrix.rows(rows, false)`
509
`    new(rows)`
526 510
`  end`
527 511

528 512
`  #`
......
539 523
`          e / other`
540 524
`        }`
541 525
`      }`
542
`      return Matrix.rows(rows, false)`
526
`      return new(rows)`
543 527
`    when Matrix`
544 528
`      return self * other.inverse`
545 529
`    else`
......
838 822
`  #        2 4 6`
839 823
`  #`
840 824
`  def transpose`
841
`    Matrix.columns(@rows)`
825
`    new @rows.transpose`
842 826
`  end`
843 827
`  alias t transpose`
844 828

......
915 899
`    "Matrix"+@rows.inspect`
916 900
`  end`
917 901

902
`  #`
903
`  # Converts the obj to an Array. If copy is set to true`
904
`  # a copy of obj will be made if necessary.`
905
`  #`
906
`  def Matrix.convert_to_array(obj, copy = false)`
907
`    case obj`
908
`    when Array`
909
`      copy ? obj.dup : obj`
910
`    when Vector`
911
`      obj.to_a`
912
`    else`
913
`      begin`
914
`        converted = obj.to_ary`
915
`      rescue Exception => e`
916
`        raise TypeError, "can't convert #{obj.class} into an Array (#{e.message})"`
917
`      end`
918
`      raise TypeError, "#{obj.class}#to_ary should return an Array" unless converted.is_a? Array`
919
`      converted`
920
`    end`
921
`  end`
922

918 923
`  # Private CLASS`
919 924

920 925
`  class Scalar < Numeric # :nodoc:`