Class Matrix
In: lib/backports/1.9.2/stdlib/matrix.rb
lib/backports/1.9.2/stdlib/matrix/eigenvalue_decomposition.rb
lib/backports/1.9.2/stdlib/matrix/lup_decomposition.rb
Parent: Object

The Matrix class represents a mathematical matrix. It provides methods for creating matrices, operating on them arithmetically and algebraically, and determining their mathematical properties (trace, rank, inverse, determinant).

Method Catalogue

To create a matrix:

To access Matrix elements/columns/rows/submatrices/properties:

Properties of a matrix:

  • diagonal?
  • empty?
  • hermitian?
  • lower_triangular?
  • normal?
  • orthogonal?
  • permutation?
  • real?
  • regular?
  • singular?
  • square?
  • symmetric?
  • unitary?
  • upper_triangular?
  • zero?

Matrix arithmetic:

Matrix functions:

Matrix decompositions:

Complex arithmetic:

Conversion to other data types:

String representations:

Methods

*   **   +   -   /   ==   []   []   []=   build   clone   coerce   collect   column   column_vector   column_vectors   columns   component   conj   conjugate   det   det_e   determinant   determinant_e   diagonal   diagonal?   each   each_with_index   eigen   eigensystem   element   elements_to_f   elements_to_i   elements_to_r   empty   empty?   eql?   find_index   hash   hermitian?   identity   imag   imaginary   index   inspect   inv   inverse   lower_triangular?   lup   lup_decomposition   map   minor   new   normal?   orthogonal?   permutation?   rank   rank_e   real   real?   rect   rectangular   regular?   round   row   row_size   row_vector   row_vectors   rows   scalar   set_component   set_element   singular?   square?   symmetric?   t   to_a   to_s   tr   trace   transpose   unitary?   upper_triangular?   zero   zero?  

Included Modules

Enumerable ExceptionForMatrix CoercionHelper

Classes and Modules

Class Matrix::EigenvalueDecomposition
Class Matrix::LUPDecomposition

Constants

SELECTORS = {:all => true, :diagonal => true, :off_diagonal => true, :lower => true, :strict_lower => true, :strict_upper => true, :upper => true}.freeze

External Aliases

identity -> unit
identity -> I

Attributes

column_size  [R]  Returns the number of columns.
rows  [R]  instance creations

Public Class methods

Creates a matrix where each argument is a row.

  Matrix[ [25, 93], [-1, 66] ]
     =>  25 93
         -1 66

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 142
142:   def Matrix.[](*rows)
143:     rows(rows, false)
144:   end

Creates a matrix of size row_size x column_size. It fills the values by calling the given block, passing the current row and column. Returns an enumerator if no block is given.

  m = Matrix.build(2, 4) {|row, col| col - row }
    => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
  m = Matrix.build(3) { rand }
    => a 3x3 matrix with random elements

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 187
187:   def Matrix.build(row_size, column_size = row_size)
188:     row_size = CoercionHelper.coerce_to_int(row_size)
189:     column_size = CoercionHelper.coerce_to_int(column_size)
190:     raise ArgumentError if row_size < 0 || column_size < 0
191:     return to_enum :build, row_size, column_size unless block_given?
192:     rows = Array.new(row_size) do |i|
193:       Array.new(column_size) do |j|
194:         yield i, j
195:       end
196:     end
197:     new rows, column_size
198:   end

Creates a single-column matrix where the values of that column are as given in column.

  Matrix.column_vector([4,5,6])
    => 4
       5
       6

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 272
272:   def Matrix.column_vector(column)
273:     column = convert_to_array(column)
274:     new [column].transpose, 1
275:   end

Creates a matrix using columns as an array of column vectors.

  Matrix.columns([[25, 93], [-1, 66]])
     =>  25 -1
         93 66

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 172
172:   def Matrix.columns(columns)
173:     rows(columns, false).transpose
174:   end

Creates a matrix where the diagonal elements are composed of values.

  Matrix.diagonal(9, 5, -3)
    =>  9  0  0
        0  5  0
        0  0 -3

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 207
207:   def Matrix.diagonal(*values)
208:     size = values.size
209:     rows = Array.new(size) {|j|
210:       row = Array.new(size, 0)
211:       row[j] = values[j]
212:       row
213:     }
214:     new rows
215:   end

Creates a empty matrix of row_size x column_size. At least one of row_size or column_size must be 0.

  m = Matrix.empty(2, 0)
  m == Matrix[ [], [] ]
    => true
  n = Matrix.empty(0, 3)
  n == Matrix.columns([ [], [], [] ])
    => true
  m * n
    => Matrix[[0, 0, 0], [0, 0, 0]]

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 290
290:   def Matrix.empty(row_size = 0, column_size = 0)
291:     Matrix.Raise ArgumentError, "One size must be 0" if column_size != 0 && row_size != 0
292:     Matrix.Raise ArgumentError, "Negative size" if column_size < 0 || row_size < 0
293: 
294:     new([[]]*row_size, column_size)
295:   end

Creates an n by n identity matrix.

  Matrix.identity(2)
    => 1 0
       0 1

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 234
234:   def Matrix.identity(n)
235:     scalar(n, 1)
236:   end

Matrix.new is private; use Matrix.rows, columns, [], etc… to create.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 300
300:   def initialize(rows, column_size = rows[0].size)
301:     # No checking is done at this point. rows must be an Array of Arrays.
302:     # column_size must be the size of the first row, if there is one,
303:     # otherwise it *must* be specified and can be any integer >= 0
304:     @rows = rows
305:     @column_size = column_size
306:   end

Creates a single-row matrix where the values of that row are as given in row.

  Matrix.row_vector([4,5,6])
    => 4 5 6

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 259
259:   def Matrix.row_vector(row)
260:     row = convert_to_array(row)
261:     new [row]
262:   end

Creates a matrix where rows is an array of arrays, each of which is a row of the matrix. If the optional argument copy is false, use the given arrays as the internal structure of the matrix without copying.

  Matrix.rows([[25, 93], [-1, 66]])
     =>  25 93
         -1 66

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 154
154:   def Matrix.rows(rows, copy = true)
155:     rows = convert_to_array(rows)
156:     rows.map! do |row|
157:       convert_to_array(row, copy)
158:     end
159:     size = (rows[0] || []).size
160:     rows.each do |row|
161:       Matrix.Raise ErrDimensionMismatch, "row size differs (#{row.size} should be #{size})" unless row.size == size
162:     end
163:     new rows, size
164:   end

Creates an n by n diagonal matrix where each diagonal element is value.

  Matrix.scalar(2, 5)
    => 5 0
       0 5

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 224
224:   def Matrix.scalar(n, value)
225:     diagonal(*Array.new(n, value))
226:   end

Creates a zero matrix.

  Matrix.zero(2)
    => 0 0
       0 0

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 248
248:   def Matrix.zero(row_size, column_size = row_size)
249:     rows = Array.new(row_size){Array.new(column_size, 0)}
250:     new rows, column_size
251:   end

Public Instance methods

Matrix multiplication.

  Matrix[[2,4], [6,8]] * Matrix.identity(2)
    => 2 4
       6 8

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 808
808:   def *(m) # m is matrix or vector or number
809:     case(m)
810:     when Numeric
811:       rows = @rows.collect {|row|
812:         row.collect {|e| e * m }
813:       }
814:       return new_matrix rows, column_size
815:     when Vector
816:       m = self.class.column_vector(m)
817:       r = self * m
818:       return r.column(0)
819:     when Matrix
820:       Matrix.Raise ErrDimensionMismatch if column_size != m.row_size
821: 
822:       rows = Array.new(row_size) {|i|
823:         Array.new(m.column_size) {|j|
824:           (0 ... column_size).inject(0) do |vij, k|
825:             vij + self[i, k] * m[k, j]
826:           end
827:         }
828:       }
829:       return new_matrix rows, m.column_size
830:     else
831:       return apply_through_coercion(m, __method__)
832:     end
833:   end

Matrix exponentiation. Equivalent to multiplying the matrix by itself N times. Non integer exponents will be handled by diagonalizing the matrix.

  Matrix[[7,6], [3,9]] ** 2
    => 67 96
       48 99

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 975
975:   def ** (other)
976:     case other
977:     when Integer
978:       x = self
979:       if other <= 0
980:         x = self.inverse
981:         return self.class.identity(self.column_size) if other == 0
982:         other = -other
983:       end
984:       z = nil
985:       loop do
986:         z = z ? z * x : x if other[0] == 1
987:         return z if (other >>= 1).zero?
988:         x *= x
989:       end
990:     when Numeric
991:       v, d, v_inv = eigensystem
992:       v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** other}) * v_inv
993:     else
994:       Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class
995:     end
996:   end

Matrix addition.

  Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
    =>  6  0
       -4 12

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 841
841:   def +(m)
842:     case m
843:     when Numeric
844:       Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class
845:     when Vector
846:       m = self.class.column_vector(m)
847:     when Matrix
848:     else
849:       return apply_through_coercion(m, __method__)
850:     end
851: 
852:     Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
853: 
854:     rows = Array.new(row_size) {|i|
855:       Array.new(column_size) {|j|
856:         self[i, j] + m[i, j]
857:       }
858:     }
859:     new_matrix rows, column_size
860:   end

Matrix subtraction.

  Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
    => -8  2
        8  1

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 868
868:   def -(m)
869:     case m
870:     when Numeric
871:       Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class
872:     when Vector
873:       m = self.class.column_vector(m)
874:     when Matrix
875:     else
876:       return apply_through_coercion(m, __method__)
877:     end
878: 
879:     Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
880: 
881:     rows = Array.new(row_size) {|i|
882:       Array.new(column_size) {|j|
883:         self[i, j] - m[i, j]
884:       }
885:     }
886:     new_matrix rows, column_size
887:   end

Matrix division (multiplication by the inverse).

  Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
    => -7  1
       -3 -6

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 895
895:   def /(other)
896:     case other
897:     when Numeric
898:       rows = @rows.collect {|row|
899:         row.collect {|e| e / other }
900:       }
901:       return new_matrix rows, column_size
902:     when Matrix
903:       return self * other.inverse
904:     else
905:       return apply_through_coercion(other, __method__)
906:     end
907:   end

Returns true if and only if the two matrices contain equal elements.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 770
770:   def ==(other)
771:     return false unless Matrix === other &&
772:                         column_size == other.column_size # necessary for empty matrices
773:     rows == other.rows
774:   end

Returns element (i,j) of the matrix. That is: row i, column j.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 316
316:   def [](i, j)
317:     @rows.fetch(i){return nil}[j]
318:   end

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 322
322:   def []=(i, j, v)
323:     @rows[i][j] = v
324:   end

Returns a clone of the matrix, so that the contents of each do not reference identical objects. There should be no good reason to do this since Matrices are immutable.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 787
787:   def clone
788:     new_matrix @rows.map(&:dup), column_size
789:   end

The coerce method provides support for Ruby type coercion. This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator. See also Numeric#coerce.

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1281
1281:   def coerce(other)
1282:     case other
1283:     when Numeric
1284:       return Scalar.new(other), self
1285:     else
1286:       raise TypeError, "#{self.class} can't be coerced into #{other.class}"
1287:     end
1288:   end

Returns a matrix that is the result of iteration of the given block over all elements of the matrix.

  Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
    => 1  4
       9 16

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 382
382:   def collect(&block) # :yield: e
383:     return to_enum(:collect) unless block_given?
384:     rows = @rows.collect{|row| row.collect(&block)}
385:     new_matrix rows, column_size
386:   end

Returns column vector number j of the matrix as a Vector (starting at 0 like an array). When a block is given, the elements of that vector are iterated.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 359
359:   def column(j) # :yield: e
360:     if block_given?
361:       return self if j >= column_size || j < -column_size
362:       row_size.times do |i|
363:         yield @rows[i][j]
364:       end
365:       self
366:     else
367:       return nil if j >= column_size || j < -column_size
368:       col = Array.new(row_size) {|i|
369:         @rows[i][j]
370:       }
371:       Vector.elements(col, false)
372:     end
373:   end

Returns an array of the column vectors of the matrix. See Vector.

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1302
1302:   def column_vectors
1303:     Array.new(column_size) {|i|
1304:       column(i)
1305:     }
1306:   end
component(i, j)

Alias for #[]

conj()

Alias for conjugate

Returns the conjugate of the matrix.

  Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
    => 1+2i   i  0
          1   2  3
  Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].conjugate
    => 1-2i  -i  0
          1   2  3

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1227
1227:   def conjugate
1228:     collect(&:conjugate)
1229:   end
det()

Alias for determinant

det_e()

Alias for determinant_e

Returns the determinant of the matrix.

Beware that using Float values can yield erroneous results because of their lack of precision. Consider using exact types like Rational or BigDecimal instead.

  Matrix[[7,6], [3,9]].determinant
    => 45

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1012
1012:   def determinant
1013:     Matrix.Raise ErrDimensionMismatch unless square?
1014:     m = @rows
1015:     case row_size
1016:       # Up to 4x4, give result using Laplacian expansion by minors.
1017:       # This will typically be faster, as well as giving good results
1018:       # in case of Floats
1019:     when 0
1020:       +1
1021:     when 1
1022:       + m[0][0]
1023:     when 2
1024:       + m[0][0] * m[1][1] - m[0][1] * m[1][0]
1025:     when 3
1026:       m0, m1, m2 = m
1027:       + m0[0] * m1[1] * m2[2] - m0[0] * m1[2] * m2[1] \
1028:       - m0[1] * m1[0] * m2[2] + m0[1] * m1[2] * m2[0] \
1029:       + m0[2] * m1[0] * m2[1] - m0[2] * m1[1] * m2[0]
1030:     when 4
1031:       m0, m1, m2, m3 = m
1032:       + m0[0] * m1[1] * m2[2] * m3[3] - m0[0] * m1[1] * m2[3] * m3[2] \
1033:       - m0[0] * m1[2] * m2[1] * m3[3] + m0[0] * m1[2] * m2[3] * m3[1] \
1034:       + m0[0] * m1[3] * m2[1] * m3[2] - m0[0] * m1[3] * m2[2] * m3[1] \
1035:       - m0[1] * m1[0] * m2[2] * m3[3] + m0[1] * m1[0] * m2[3] * m3[2] \
1036:       + m0[1] * m1[2] * m2[0] * m3[3] - m0[1] * m1[2] * m2[3] * m3[0] \
1037:       - m0[1] * m1[3] * m2[0] * m3[2] + m0[1] * m1[3] * m2[2] * m3[0] \
1038:       + m0[2] * m1[0] * m2[1] * m3[3] - m0[2] * m1[0] * m2[3] * m3[1] \
1039:       - m0[2] * m1[1] * m2[0] * m3[3] + m0[2] * m1[1] * m2[3] * m3[0] \
1040:       + m0[2] * m1[3] * m2[0] * m3[1] - m0[2] * m1[3] * m2[1] * m3[0] \
1041:       - m0[3] * m1[0] * m2[1] * m3[2] + m0[3] * m1[0] * m2[2] * m3[1] \
1042:       + m0[3] * m1[1] * m2[0] * m3[2] - m0[3] * m1[1] * m2[2] * m3[0] \
1043:       - m0[3] * m1[2] * m2[0] * m3[1] + m0[3] * m1[2] * m2[1] * m3[0]
1044:     else
1045:       # For bigger matrices, use an efficient and general algorithm.
1046:       # Currently, we use the Gauss-Bareiss algorithm
1047:       determinant_bareiss
1048:     end
1049:   end

deprecated; use Matrix#determinant

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1094
1094:   def determinant_e
1095:     warn "#{caller(1)[0]}: warning: Matrix#determinant_e is deprecated; use #determinant"
1096:     rank
1097:   end

Returns true is this is a diagonal matrix. Raises an error if matrix is not square.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 600
600:   def diagonal?
601:     Matrix.Raise ErrDimensionMismatch unless square?
602:     each(:off_diagonal).all?(&:zero?)
603:   end

Yields all elements of the matrix, starting with those of the first row, or returns an Enumerator is no block given. Elements can be restricted by passing an argument:

  • :all (default): yields all elements
  • :diagonal: yields only elements on the diagonal
  • :off_diagonal: yields all elements except on the diagonal
  • :lower: yields only elements on or below the diagonal
  • :strict_lower: yields only elements below the diagonal
  • :strict_upper: yields only elements above the diagonal
  • :upper: yields only elements on or above the diagonal

    Matrix[ [1,2], [3,4] ].each { |e| puts e }

      # => prints the numbers 1 to 4
    

    Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 405
405:   def each(which = :all) # :yield: e
406:     return to_enum :each, which unless block_given?
407:     last = column_size - 1
408:     case which
409:     when :all
410:       block = Proc.new
411:       @rows.each do |row|
412:         row.each(&block)
413:       end
414:     when :diagonal
415:       @rows.each_with_index do |row, row_index|
416:         yield row.fetch(row_index){return self}
417:       end
418:     when :off_diagonal
419:       @rows.each_with_index do |row, row_index|
420:         column_size.times do |col_index|
421:           yield row[col_index] unless row_index == col_index
422:         end
423:       end
424:     when :lower
425:       @rows.each_with_index do |row, row_index|
426:         0.upto([row_index, last].min) do |col_index|
427:           yield row[col_index]
428:         end
429:       end
430:     when :strict_lower
431:       @rows.each_with_index do |row, row_index|
432:         [row_index, column_size].min.times do |col_index|
433:           yield row[col_index]
434:         end
435:       end
436:     when :strict_upper
437:       @rows.each_with_index do |row, row_index|
438:         (row_index+1).upto(last) do |col_index|
439:           yield row[col_index]
440:         end
441:       end
442:     when :upper
443:       @rows.each_with_index do |row, row_index|
444:         row_index.upto(last) do |col_index|
445:           yield row[col_index]
446:         end
447:       end
448:     else
449:       Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
450:     end
451:     self
452:   end

Same as each, but the row index and column index in addition to the element

  Matrix[ [1,2], [3,4] ].each_with_index do |e, row, col|
    puts "#{e} at #{row}, #{col}"
  end
    # => Prints:
    #    1 at 0, 0
    #    2 at 0, 1
    #    3 at 1, 0
    #    4 at 1, 1

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 466
466:   def each_with_index(which = :all) # :yield: e, row, column
467:     return to_enum :each_with_index, which unless block_given?
468:     last = column_size - 1
469:     case which
470:     when :all
471:       @rows.each_with_index do |row, row_index|
472:         row.each_with_index do |e, col_index|
473:           yield e, row_index, col_index
474:         end
475:       end
476:     when :diagonal
477:       @rows.each_with_index do |row, row_index|
478:         yield row.fetch(row_index){return self}, row_index, row_index
479:       end
480:     when :off_diagonal
481:       @rows.each_with_index do |row, row_index|
482:         column_size.times do |col_index|
483:           yield row[col_index], row_index, col_index unless row_index == col_index
484:         end
485:       end
486:     when :lower
487:       @rows.each_with_index do |row, row_index|
488:         0.upto([row_index, last].min) do |col_index|
489:           yield row[col_index], row_index, col_index
490:         end
491:       end
492:     when :strict_lower
493:       @rows.each_with_index do |row, row_index|
494:         [row_index, column_size].min.times do |col_index|
495:           yield row[col_index], row_index, col_index
496:         end
497:       end
498:     when :strict_upper
499:       @rows.each_with_index do |row, row_index|
500:         (row_index+1).upto(last) do |col_index|
501:           yield row[col_index], row_index, col_index
502:         end
503:       end
504:     when :upper
505:       @rows.each_with_index do |row, row_index|
506:         row_index.upto(last) do |col_index|
507:           yield row[col_index], row_index, col_index
508:         end
509:       end
510:     else
511:       Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
512:     end
513:     self
514:   end
eigen()

Alias for eigensystem

Returns the Eigensystem of the matrix; see EigenvalueDecomposition.

  m = Matrix[[1, 2], [3, 4]]
  v, d, v_inv = m.eigensystem
  d.diagonal? # => true
  v.inv == v_inv # => true
  (v * d * v_inv).round(5) == m # => true

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1193
1193:   def eigensystem
1194:     EigenvalueDecomposition.new(self)
1195:   end
element(i, j)

Alias for #[]

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1315
1315:   def elements_to_f
1316:     warn "#{caller(1)[0]}: warning: Matrix#elements_to_f is deprecated, use map(&:to_f)"
1317:     map(&:to_f)
1318:   end

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1320
1320:   def elements_to_i
1321:     warn "#{caller(1)[0]}: warning: Matrix#elements_to_i is deprecated, use map(&:to_i)"
1322:     map(&:to_i)
1323:   end

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1325
1325:   def elements_to_r
1326:     warn "#{caller(1)[0]}: warning: Matrix#elements_to_r is deprecated, use map(&:to_r)"
1327:     map(&:to_r)
1328:   end

Returns true if this is an empty matrix, i.e. if the number of rows or the number of columns is 0.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 609
609:   def empty?
610:     column_size == 0 || row_size == 0
611:   end

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 776
776:   def eql?(other)
777:     return false unless Matrix === other &&
778:                         column_size == other.column_size # necessary for empty matrices
779:     rows.eql? other.rows
780:   end
find_index(*args)

Alias for index

Returns a hash-code for the matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 794
794:   def hash
795:     @rows.hash
796:   end

Returns true is this is an hermitian matrix. Raises an error if matrix is not square.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 619
619:   def hermitian?
620:     Matrix.Raise ErrDimensionMismatch unless square?
621:     each_with_index(:strict_upper).all? do |e, row, col|
622:       e == rows[col][row].conj
623:     end
624:   end
imag()

Alias for imaginary

Returns the imaginary part of the matrix.

  Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
    => 1+2i  i  0
          1  2  3
  Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
    =>   2i  i  0
          0  0  0

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1241
1241:   def imaginary
1242:     collect(&:imaginary)
1243:   end

The index method is specialized to return the index as [row, column] It also accepts an optional selector argument, see each for details.

  Matrix[ [1,2], [3,4] ].index(&:even?) # => [0, 1]
  Matrix[ [1,1], [1,1] ].index(1, :strict_lower) # => [1, 0]

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 529
529:   def index(*args)
530:     raise ArgumentError, "wrong number of arguments(#{args.size} for 0-2)" if args.size > 2
531:     which = (args.size == 2 || SELECTORS.include?(args.last)) ? args.pop : :all
532:     return to_enum :find_index, which, *args unless block_given? || args.size == 1
533:     if args.size == 1
534:       value = args.first
535:       each_with_index(which) do |e, row_index, col_index|
536:         return row_index, col_index if e == value
537:       end
538:     else
539:       each_with_index(which) do |e, row_index, col_index|
540:         return row_index, col_index if yield e
541:       end
542:     end
543:     nil
544:   end

Overrides Object#inspect

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1350
1350:   def inspect
1351:     if empty?
1352:       "#{self.class}.empty(#{row_size}, #{column_size})"
1353:     else
1354:       "#{self.class}#{@rows.inspect}"
1355:     end
1356:   end
inv()

Alias for inverse

Returns the inverse of the matrix.

  Matrix[[-1, -1], [0, -1]].inverse
    => -1  1
        0 -1

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 915
915:   def inverse
916:     Matrix.Raise ErrDimensionMismatch unless square?
917:     self.class.I(row_size).send(:inverse_from, self)
918:   end

Returns true is this is a lower triangular matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 629
629:   def lower_triangular?
630:     each(:strict_upper).all?(&:zero?)
631:   end

Returns the LUP decomposition of the matrix; see LUPDecomposition.

  a = Matrix[[1, 2], [3, 4]]
  l, u, p = a.lup
  l.lower_triangular? # => true
  u.upper_triangular? # => true
  p.permutation?      # => true
  l * u == a * p      # => true
  a.lup.solve([2, 5]) # => Vector[(1/1), (1/2)]

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1208
1208:   def lup
1209:     LUPDecomposition.new(self)
1210:   end
lup_decomposition()

Alias for lup

map()

Alias for collect

Returns a section of the matrix. The parameters are either:

  • start_row, nrows, start_col, ncols; OR
  • row_range, col_range
  Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
    => 9 0 0
       0 5 0

Like Array#[], negative indices count backward from the end of the row or column (-1 is the last element). Returns nil if the starting row or column is greater than row_size or column_size respectively.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 559
559:   def minor(*param)
560:     case param.size
561:     when 2
562:       row_range, col_range = param
563:       from_row = row_range.first
564:       from_row += row_size if from_row < 0
565:       to_row = row_range.end
566:       to_row += row_size if to_row < 0
567:       to_row += 1 unless row_range.exclude_end?
568:       size_row = to_row - from_row
569: 
570:       from_col = col_range.first
571:       from_col += column_size if from_col < 0
572:       to_col = col_range.end
573:       to_col += column_size if to_col < 0
574:       to_col += 1 unless col_range.exclude_end?
575:       size_col = to_col - from_col
576:     when 4
577:       from_row, size_row, from_col, size_col = param
578:       return nil if size_row < 0 || size_col < 0
579:       from_row += row_size if from_row < 0
580:       from_col += column_size if from_col < 0
581:     else
582:       Matrix.Raise ArgumentError, param.inspect
583:     end
584: 
585:     return nil if from_row > row_size || from_col > column_size || from_row < 0 || from_col < 0
586:     rows = @rows[from_row, size_row].collect{|row|
587:       row[from_col, size_col]
588:     }
589:     new_matrix rows, [column_size - from_col, size_col].min
590:   end

Returns true is this is a normal matrix. Raises an error if matrix is not square.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 637
637:   def normal?
638:     Matrix.Raise ErrDimensionMismatch unless square?
639:     rows.each_with_index do |row_i, i|
640:       rows.each_with_index do |row_j, j|
641:         s = 0
642:         rows.each_with_index do |row_k, k|
643:           s += row_i[k] * row_j[k].conj - row_k[i].conj * row_k[j]
644:         end
645:         return false unless s == 0
646:       end
647:     end
648:     true
649:   end

Returns true is this is an orthogonal matrix Raises an error if matrix is not square.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 655
655:   def orthogonal?
656:     Matrix.Raise ErrDimensionMismatch unless square?
657:     rows.each_with_index do |row, i|
658:       column_size.times do |j|
659:         s = 0
660:         row_size.times do |k|
661:           s += row[k] * rows[k][j]
662:         end
663:         return false unless s == (i == j ? 1 : 0)
664:       end
665:     end
666:     true
667:   end

Returns true is this is a permutation matrix Raises an error if matrix is not square.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 673
673:   def permutation?
674:     Matrix.Raise ErrDimensionMismatch unless square?
675:     cols = Array.new(column_size)
676:     rows.each_with_index do |row, i|
677:       found = false
678:       row.each_with_index do |e, j|
679:         if e == 1
680:           return false if found || cols[j]
681:           found = cols[j] = true
682:         elsif e != 0
683:           return false
684:         end
685:       end
686:       return false unless found
687:     end
688:     true
689:   end

Returns the rank of the matrix. Beware that using Float values can yield erroneous results because of their lack of precision. Consider using exact types like Rational or BigDecimal instead.

  Matrix[[7,6], [3,9]].rank
    => 2

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1109
1109:   def rank
1110:     # We currently use Bareiss' multistep integer-preserving gaussian elimination
1111:     # (see comments on determinant)
1112:     a = to_a
1113:     last_column = column_size - 1
1114:     last_row = row_size - 1
1115:     pivot_row = 0
1116:     previous_pivot = 1
1117:     0.upto(last_column) do |k|
1118:       switch_row = (pivot_row .. last_row).find {|row|
1119:         a[row][k] != 0
1120:       }
1121:       if switch_row
1122:         a[switch_row], a[pivot_row] = a[pivot_row], a[switch_row] unless pivot_row == switch_row
1123:         pivot = a[pivot_row][k]
1124:         (pivot_row+1).upto(last_row) do |i|
1125:            ai = a[i]
1126:            (k+1).upto(last_column) do |j|
1127:              ai[j] =  (pivot * ai[j] - ai[k] * a[pivot_row][j]) / previous_pivot
1128:            end
1129:          end
1130:         pivot_row += 1
1131:         previous_pivot = pivot
1132:       end
1133:     end
1134:     pivot_row
1135:   end

deprecated; use Matrix#rank

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1140
1140:   def rank_e
1141:     warn "#{caller(1)[0]}: warning: Matrix#rank_e is deprecated; use #rank"
1142:     rank
1143:   end

Returns the real part of the matrix.

  Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
    => 1+2i  i  0
          1  2  3
  Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real
    =>    1  0  0
          1  2  3

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1255
1255:   def real
1256:     collect(&:real)
1257:   end

Returns true if all entries of the matrix are real.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 694
694:   def real?
695:     all?(&:real?)
696:   end

Returns an array containing matrices corresponding to the real and imaginary parts of the matrix

m.rect == [m.real, m.imag] # ==> true for all matrices m

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1265
1265:   def rect
1266:     [real, imag]
1267:   end
rectangular()

Alias for rect

Returns true if this is a regular (i.e. non-singular) matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 701
701:   def regular?
702:     not singular?
703:   end

Returns a matrix with entries rounded to the given precision (see Float#round)

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1148
1148:   def round(ndigits=0)
1149:     map{|e| e.round(ndigits)}
1150:   end

Returns row vector number i of the matrix as a Vector (starting at 0 like an array). When a block is given, the elements of that vector are iterated.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 345
345:   def row(i, &block) # :yield: e
346:     if block_given?
347:       @rows.fetch(i){return self}.each(&block)
348:       self
349:     else
350:       Vector.elements(@rows.fetch(i){return nil})
351:     end
352:   end

Returns the number of rows.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 332
332:   def row_size
333:     @rows.size
334:   end

Returns an array of the row vectors of the matrix. See Vector.

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1293
1293:   def row_vectors
1294:     Array.new(row_size) {|i|
1295:       row(i)
1296:     }
1297:   end
set_component(i, j, v)

Alias for #[]=

set_element(i, j, v)

Alias for #[]=

Returns true is this is a singular matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 708
708:   def singular?
709:     determinant == 0
710:   end

Returns true is this is a square matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 715
715:   def square?
716:     column_size == row_size
717:   end

Returns true is this is a symmetric matrix. Raises an error if matrix is not square.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 723
723:   def symmetric?
724:     Matrix.Raise ErrDimensionMismatch unless square?
725:     each_with_index(:strict_upper) do |e, row, col|
726:       return false if e != rows[col][row]
727:     end
728:     true
729:   end
t()

Alias for transpose

Returns an array of arrays that describe the rows of the matrix.

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1311
1311:   def to_a
1312:     @rows.collect(&:dup)
1313:   end

Overrides Object#to_s

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1337
1337:   def to_s
1338:     if empty?
1339:       "#{self.class}.empty(#{row_size}, #{column_size})"
1340:     else
1341:       "#{self.class}[" + @rows.collect{|row|
1342:         "[" + row.collect{|e| e.to_s}.join(", ") + "]"
1343:       }.join(", ")+"]"
1344:     end
1345:   end
tr()

Alias for trace

Returns the trace (sum of diagonal elements) of the matrix.

  Matrix[[7,6], [3,9]].trace
    => 16

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1157
1157:   def trace
1158:     Matrix.Raise ErrDimensionMismatch unless square?
1159:     (0...column_size).inject(0) do |tr, i|
1160:       tr + @rows[i][i]
1161:     end
1162:   end

Returns the transpose of the matrix.

  Matrix[[1,2], [3,4], [5,6]]
    => 1 2
       3 4
       5 6
  Matrix[[1,2], [3,4], [5,6]].transpose
    => 1 3 5
       2 4 6

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1175
1175:   def transpose
1176:     return self.class.empty(column_size, 0) if row_size.zero?
1177:     new_matrix @rows.transpose, row_size
1178:   end

Returns true is this is a unitary matrix Raises an error if matrix is not square.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 735
735:   def unitary?
736:     Matrix.Raise ErrDimensionMismatch unless square?
737:     rows.each_with_index do |row, i|
738:       column_size.times do |j|
739:         s = 0
740:         row_size.times do |k|
741:           s += row[k].conj * rows[k][j]
742:         end
743:         return false unless s == (i == j ? 1 : 0)
744:       end
745:     end
746:     true
747:   end

Returns true is this is an upper triangular matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 752
752:   def upper_triangular?
753:     each(:strict_lower).all?(&:zero?)
754:   end

Returns true is this is a matrix with only zero elements

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 759
759:   def zero?
760:     all?(&:zero?)
761:   end

[Validate]