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 unless const_defined?(:SELECTORS)

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 140
140:   def Matrix.[](*rows)
141:     rows(rows, false)
142:   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 185
185:   def Matrix.build(row_size, column_size = row_size)
186:     row_size = CoercionHelper.coerce_to_int(row_size)
187:     column_size = CoercionHelper.coerce_to_int(column_size)
188:     raise ArgumentError if row_size < 0 || column_size < 0
189:     return to_enum :build, row_size, column_size unless block_given?
190:     rows = Array.new(row_size) do |i|
191:       Array.new(column_size) do |j|
192:         yield i, j
193:       end
194:     end
195:     new rows, column_size
196:   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 270
270:   def Matrix.column_vector(column)
271:     column = convert_to_array(column)
272:     new [column].transpose, 1
273:   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 170
170:   def Matrix.columns(columns)
171:     rows(columns, false).transpose
172:   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 205
205:   def Matrix.diagonal(*values)
206:     size = values.size
207:     rows = Array.new(size) {|j|
208:       row = Array.new(size, 0)
209:       row[j] = values[j]
210:       row
211:     }
212:     new rows
213:   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 288
288:   def Matrix.empty(row_size = 0, column_size = 0)
289:     Matrix.Raise ArgumentError, "One size must be 0" if column_size != 0 && row_size != 0
290:     Matrix.Raise ArgumentError, "Negative size" if column_size < 0 || row_size < 0
291: 
292:     new([[]]*row_size, column_size)
293:   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 232
232:   def Matrix.identity(n)
233:     scalar(n, 1)
234:   end

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

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 298
298:   def initialize(rows, column_size = rows[0].size)
299:     # No checking is done at this point. rows must be an Array of Arrays.
300:     # column_size must be the size of the first row, if there is one,
301:     # otherwise it *must* be specified and can be any integer >= 0
302:     @rows = rows
303:     @column_size = column_size
304:   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 257
257:   def Matrix.row_vector(row)
258:     row = convert_to_array(row)
259:     new [row]
260:   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 152
152:   def Matrix.rows(rows, copy = true)
153:     rows = convert_to_array(rows)
154:     rows.map! do |row|
155:       convert_to_array(row, copy)
156:     end
157:     size = (rows[0] || []).size
158:     rows.each do |row|
159:       Matrix.Raise ErrDimensionMismatch, "row size differs (#{row.size} should be #{size})" unless row.size == size
160:     end
161:     new rows, size
162:   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 222
222:   def Matrix.scalar(n, value)
223:     diagonal(*Array.new(n, value))
224:   end

Creates a zero matrix.

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

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 246
246:   def Matrix.zero(row_size, column_size = row_size)
247:     rows = Array.new(row_size){Array.new(column_size, 0)}
248:     new rows, column_size
249:   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 806
806:   def *(m) # m is matrix or vector or number
807:     case(m)
808:     when Numeric
809:       rows = @rows.collect {|row|
810:         row.collect {|e| e * m }
811:       }
812:       return new_matrix rows, column_size
813:     when Vector
814:       m = self.class.column_vector(m)
815:       r = self * m
816:       return r.column(0)
817:     when Matrix
818:       Matrix.Raise ErrDimensionMismatch if column_size != m.row_size
819: 
820:       rows = Array.new(row_size) {|i|
821:         Array.new(m.column_size) {|j|
822:           (0 ... column_size).inject(0) do |vij, k|
823:             vij + self[i, k] * m[k, j]
824:           end
825:         }
826:       }
827:       return new_matrix rows, m.column_size
828:     else
829:       return apply_through_coercion(m, __method__)
830:     end
831:   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 973
973:   def ** (other)
974:     case other
975:     when Integer
976:       x = self
977:       if other <= 0
978:         x = self.inverse
979:         return self.class.identity(self.column_size) if other == 0
980:         other = -other
981:       end
982:       z = nil
983:       loop do
984:         z = z ? z * x : x if other[0] == 1
985:         return z if (other >>= 1).zero?
986:         x *= x
987:       end
988:     when Numeric
989:       v, d, v_inv = eigensystem
990:       v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** other}) * v_inv
991:     else
992:       Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class
993:     end
994:   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 839
839:   def +(m)
840:     case m
841:     when Numeric
842:       Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class
843:     when Vector
844:       m = self.class.column_vector(m)
845:     when Matrix
846:     else
847:       return apply_through_coercion(m, __method__)
848:     end
849: 
850:     Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
851: 
852:     rows = Array.new(row_size) {|i|
853:       Array.new(column_size) {|j|
854:         self[i, j] + m[i, j]
855:       }
856:     }
857:     new_matrix rows, column_size
858:   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 866
866:   def -(m)
867:     case m
868:     when Numeric
869:       Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class
870:     when Vector
871:       m = self.class.column_vector(m)
872:     when Matrix
873:     else
874:       return apply_through_coercion(m, __method__)
875:     end
876: 
877:     Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
878: 
879:     rows = Array.new(row_size) {|i|
880:       Array.new(column_size) {|j|
881:         self[i, j] - m[i, j]
882:       }
883:     }
884:     new_matrix rows, column_size
885:   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 893
893:   def /(other)
894:     case other
895:     when Numeric
896:       rows = @rows.collect {|row|
897:         row.collect {|e| e / other }
898:       }
899:       return new_matrix rows, column_size
900:     when Matrix
901:       return self * other.inverse
902:     else
903:       return apply_through_coercion(other, __method__)
904:     end
905:   end

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

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 768
768:   def ==(other)
769:     return false unless Matrix === other &&
770:                         column_size == other.column_size # necessary for empty matrices
771:     rows == other.rows
772:   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 314
314:   def [](i, j)
315:     @rows.fetch(i){return nil}[j]
316:   end

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 320
320:   def []=(i, j, v)
321:     @rows[i][j] = v
322:   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 785
785:   def clone
786:     new_matrix @rows.map(&:dup), column_size
787:   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 1279
1279:   def coerce(other)
1280:     case other
1281:     when Numeric
1282:       return Scalar.new(other), self
1283:     else
1284:       raise TypeError, "#{self.class} can't be coerced into #{other.class}"
1285:     end
1286:   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 380
380:   def collect(&block) # :yield: e
381:     return to_enum(:collect) unless block_given?
382:     rows = @rows.collect{|row| row.collect(&block)}
383:     new_matrix rows, column_size
384:   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 357
357:   def column(j) # :yield: e
358:     if block_given?
359:       return self if j >= column_size || j < -column_size
360:       row_size.times do |i|
361:         yield @rows[i][j]
362:       end
363:       self
364:     else
365:       return nil if j >= column_size || j < -column_size
366:       col = Array.new(row_size) {|i|
367:         @rows[i][j]
368:       }
369:       Vector.elements(col, false)
370:     end
371:   end

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

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1300
1300:   def column_vectors
1301:     Array.new(column_size) {|i|
1302:       column(i)
1303:     }
1304:   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 1225
1225:   def conjugate
1226:     collect(&:conjugate)
1227:   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 1010
1010:   def determinant
1011:     Matrix.Raise ErrDimensionMismatch unless square?
1012:     m = @rows
1013:     case row_size
1014:       # Up to 4x4, give result using Laplacian expansion by minors.
1015:       # This will typically be faster, as well as giving good results
1016:       # in case of Floats
1017:     when 0
1018:       +1
1019:     when 1
1020:       + m[0][0]
1021:     when 2
1022:       + m[0][0] * m[1][1] - m[0][1] * m[1][0]
1023:     when 3
1024:       m0, m1, m2 = m
1025:       + m0[0] * m1[1] * m2[2] - m0[0] * m1[2] * m2[1] \
1026:       - m0[1] * m1[0] * m2[2] + m0[1] * m1[2] * m2[0] \
1027:       + m0[2] * m1[0] * m2[1] - m0[2] * m1[1] * m2[0]
1028:     when 4
1029:       m0, m1, m2, m3 = m
1030:       + m0[0] * m1[1] * m2[2] * m3[3] - m0[0] * m1[1] * m2[3] * m3[2] \
1031:       - m0[0] * m1[2] * m2[1] * m3[3] + m0[0] * m1[2] * m2[3] * m3[1] \
1032:       + m0[0] * m1[3] * m2[1] * m3[2] - m0[0] * m1[3] * m2[2] * m3[1] \
1033:       - m0[1] * m1[0] * m2[2] * m3[3] + m0[1] * m1[0] * m2[3] * m3[2] \
1034:       + m0[1] * m1[2] * m2[0] * m3[3] - m0[1] * m1[2] * m2[3] * m3[0] \
1035:       - m0[1] * m1[3] * m2[0] * m3[2] + m0[1] * m1[3] * m2[2] * m3[0] \
1036:       + m0[2] * m1[0] * m2[1] * m3[3] - m0[2] * m1[0] * m2[3] * m3[1] \
1037:       - m0[2] * m1[1] * m2[0] * m3[3] + m0[2] * m1[1] * m2[3] * m3[0] \
1038:       + m0[2] * m1[3] * m2[0] * m3[1] - m0[2] * m1[3] * m2[1] * m3[0] \
1039:       - m0[3] * m1[0] * m2[1] * m3[2] + m0[3] * m1[0] * m2[2] * m3[1] \
1040:       + m0[3] * m1[1] * m2[0] * m3[2] - m0[3] * m1[1] * m2[2] * m3[0] \
1041:       - m0[3] * m1[2] * m2[0] * m3[1] + m0[3] * m1[2] * m2[1] * m3[0]
1042:     else
1043:       # For bigger matrices, use an efficient and general algorithm.
1044:       # Currently, we use the Gauss-Bareiss algorithm
1045:       determinant_bareiss
1046:     end
1047:   end

deprecated; use Matrix#determinant

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1092
1092:   def determinant_e
1093:     warn "#{caller(1)[0]}: warning: Matrix#determinant_e is deprecated; use #determinant"
1094:     rank
1095:   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 598
598:   def diagonal?
599:     Matrix.Raise ErrDimensionMismatch unless square?
600:     each(:off_diagonal).all?(&:zero?)
601:   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 403
403:   def each(which = :all) # :yield: e
404:     return to_enum :each, which unless block_given?
405:     last = column_size - 1
406:     case which
407:     when :all
408:       block = Proc.new
409:       @rows.each do |row|
410:         row.each(&block)
411:       end
412:     when :diagonal
413:       @rows.each_with_index do |row, row_index|
414:         yield row.fetch(row_index){return self}
415:       end
416:     when :off_diagonal
417:       @rows.each_with_index do |row, row_index|
418:         column_size.times do |col_index|
419:           yield row[col_index] unless row_index == col_index
420:         end
421:       end
422:     when :lower
423:       @rows.each_with_index do |row, row_index|
424:         0.upto([row_index, last].min) do |col_index|
425:           yield row[col_index]
426:         end
427:       end
428:     when :strict_lower
429:       @rows.each_with_index do |row, row_index|
430:         [row_index, column_size].min.times do |col_index|
431:           yield row[col_index]
432:         end
433:       end
434:     when :strict_upper
435:       @rows.each_with_index do |row, row_index|
436:         (row_index+1).upto(last) do |col_index|
437:           yield row[col_index]
438:         end
439:       end
440:     when :upper
441:       @rows.each_with_index do |row, row_index|
442:         row_index.upto(last) do |col_index|
443:           yield row[col_index]
444:         end
445:       end
446:     else
447:       Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
448:     end
449:     self
450:   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 464
464:   def each_with_index(which = :all) # :yield: e, row, column
465:     return to_enum :each_with_index, which unless block_given?
466:     last = column_size - 1
467:     case which
468:     when :all
469:       @rows.each_with_index do |row, row_index|
470:         row.each_with_index do |e, col_index|
471:           yield e, row_index, col_index
472:         end
473:       end
474:     when :diagonal
475:       @rows.each_with_index do |row, row_index|
476:         yield row.fetch(row_index){return self}, row_index, row_index
477:       end
478:     when :off_diagonal
479:       @rows.each_with_index do |row, row_index|
480:         column_size.times do |col_index|
481:           yield row[col_index], row_index, col_index unless row_index == col_index
482:         end
483:       end
484:     when :lower
485:       @rows.each_with_index do |row, row_index|
486:         0.upto([row_index, last].min) do |col_index|
487:           yield row[col_index], row_index, col_index
488:         end
489:       end
490:     when :strict_lower
491:       @rows.each_with_index do |row, row_index|
492:         [row_index, column_size].min.times do |col_index|
493:           yield row[col_index], row_index, col_index
494:         end
495:       end
496:     when :strict_upper
497:       @rows.each_with_index do |row, row_index|
498:         (row_index+1).upto(last) do |col_index|
499:           yield row[col_index], row_index, col_index
500:         end
501:       end
502:     when :upper
503:       @rows.each_with_index do |row, row_index|
504:         row_index.upto(last) do |col_index|
505:           yield row[col_index], row_index, col_index
506:         end
507:       end
508:     else
509:       Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
510:     end
511:     self
512:   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 1191
1191:   def eigensystem
1192:     EigenvalueDecomposition.new(self)
1193:   end
element(i, j)

Alias for #[]

[Source]

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

[Source]

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

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1323
1323:   def elements_to_r
1324:     warn "#{caller(1)[0]}: warning: Matrix#elements_to_r is deprecated, use map(&:to_r)"
1325:     map(&:to_r)
1326:   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 607
607:   def empty?
608:     column_size == 0 || row_size == 0
609:   end

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 774
774:   def eql?(other)
775:     return false unless Matrix === other &&
776:                         column_size == other.column_size # necessary for empty matrices
777:     rows.eql? other.rows
778:   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 792
792:   def hash
793:     @rows.hash
794:   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 617
617:   def hermitian?
618:     Matrix.Raise ErrDimensionMismatch unless square?
619:     each_with_index(:strict_upper).all? do |e, row, col|
620:       e == rows[col][row].conj
621:     end
622:   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 1239
1239:   def imaginary
1240:     collect(&:imaginary)
1241:   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 527
527:   def index(*args)
528:     raise ArgumentError, "wrong number of arguments(#{args.size} for 0-2)" if args.size > 2
529:     which = (args.size == 2 || SELECTORS.include?(args.last)) ? args.pop : :all
530:     return to_enum :find_index, which, *args unless block_given? || args.size == 1
531:     if args.size == 1
532:       value = args.first
533:       each_with_index(which) do |e, row_index, col_index|
534:         return row_index, col_index if e == value
535:       end
536:     else
537:       each_with_index(which) do |e, row_index, col_index|
538:         return row_index, col_index if yield e
539:       end
540:     end
541:     nil
542:   end

Overrides Object#inspect

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1348
1348:   def inspect
1349:     if empty?
1350:       "#{self.class}.empty(#{row_size}, #{column_size})"
1351:     else
1352:       "#{self.class}#{@rows.inspect}"
1353:     end
1354:   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 913
913:   def inverse
914:     Matrix.Raise ErrDimensionMismatch unless square?
915:     self.class.I(row_size).send(:inverse_from, self)
916:   end

Returns true is this is a lower triangular matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 627
627:   def lower_triangular?
628:     each(:strict_upper).all?(&:zero?)
629:   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 1206
1206:   def lup
1207:     LUPDecomposition.new(self)
1208:   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 557
557:   def minor(*param)
558:     case param.size
559:     when 2
560:       row_range, col_range = param
561:       from_row = row_range.first
562:       from_row += row_size if from_row < 0
563:       to_row = row_range.end
564:       to_row += row_size if to_row < 0
565:       to_row += 1 unless row_range.exclude_end?
566:       size_row = to_row - from_row
567: 
568:       from_col = col_range.first
569:       from_col += column_size if from_col < 0
570:       to_col = col_range.end
571:       to_col += column_size if to_col < 0
572:       to_col += 1 unless col_range.exclude_end?
573:       size_col = to_col - from_col
574:     when 4
575:       from_row, size_row, from_col, size_col = param
576:       return nil if size_row < 0 || size_col < 0
577:       from_row += row_size if from_row < 0
578:       from_col += column_size if from_col < 0
579:     else
580:       Matrix.Raise ArgumentError, param.inspect
581:     end
582: 
583:     return nil if from_row > row_size || from_col > column_size || from_row < 0 || from_col < 0
584:     rows = @rows[from_row, size_row].collect{|row|
585:       row[from_col, size_col]
586:     }
587:     new_matrix rows, [column_size - from_col, size_col].min
588:   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 635
635:   def normal?
636:     Matrix.Raise ErrDimensionMismatch unless square?
637:     rows.each_with_index do |row_i, i|
638:       rows.each_with_index do |row_j, j|
639:         s = 0
640:         rows.each_with_index do |row_k, k|
641:           s += row_i[k] * row_j[k].conj - row_k[i].conj * row_k[j]
642:         end
643:         return false unless s == 0
644:       end
645:     end
646:     true
647:   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 653
653:   def orthogonal?
654:     Matrix.Raise ErrDimensionMismatch unless square?
655:     rows.each_with_index do |row, i|
656:       column_size.times do |j|
657:         s = 0
658:         row_size.times do |k|
659:           s += row[k] * rows[k][j]
660:         end
661:         return false unless s == (i == j ? 1 : 0)
662:       end
663:     end
664:     true
665:   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 671
671:   def permutation?
672:     Matrix.Raise ErrDimensionMismatch unless square?
673:     cols = Array.new(column_size)
674:     rows.each_with_index do |row, i|
675:       found = false
676:       row.each_with_index do |e, j|
677:         if e == 1
678:           return false if found || cols[j]
679:           found = cols[j] = true
680:         elsif e != 0
681:           return false
682:         end
683:       end
684:       return false unless found
685:     end
686:     true
687:   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 1107
1107:   def rank
1108:     # We currently use Bareiss' multistep integer-preserving gaussian elimination
1109:     # (see comments on determinant)
1110:     a = to_a
1111:     last_column = column_size - 1
1112:     last_row = row_size - 1
1113:     pivot_row = 0
1114:     previous_pivot = 1
1115:     0.upto(last_column) do |k|
1116:       switch_row = (pivot_row .. last_row).find {|row|
1117:         a[row][k] != 0
1118:       }
1119:       if switch_row
1120:         a[switch_row], a[pivot_row] = a[pivot_row], a[switch_row] unless pivot_row == switch_row
1121:         pivot = a[pivot_row][k]
1122:         (pivot_row+1).upto(last_row) do |i|
1123:            ai = a[i]
1124:            (k+1).upto(last_column) do |j|
1125:              ai[j] =  (pivot * ai[j] - ai[k] * a[pivot_row][j]) / previous_pivot
1126:            end
1127:          end
1128:         pivot_row += 1
1129:         previous_pivot = pivot
1130:       end
1131:     end
1132:     pivot_row
1133:   end

deprecated; use Matrix#rank

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1138
1138:   def rank_e
1139:     warn "#{caller(1)[0]}: warning: Matrix#rank_e is deprecated; use #rank"
1140:     rank
1141:   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 1253
1253:   def real
1254:     collect(&:real)
1255:   end

Returns true if all entries of the matrix are real.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 692
692:   def real?
693:     all?(&:real?)
694:   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 1263
1263:   def rect
1264:     [real, imag]
1265:   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 699
699:   def regular?
700:     not singular?
701:   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 1146
1146:   def round(ndigits=0)
1147:     map{|e| e.round(ndigits)}
1148:   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 343
343:   def row(i, &block) # :yield: e
344:     if block_given?
345:       @rows.fetch(i){return self}.each(&block)
346:       self
347:     else
348:       Vector.elements(@rows.fetch(i){return nil})
349:     end
350:   end

Returns the number of rows.

[Source]

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

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

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1291
1291:   def row_vectors
1292:     Array.new(row_size) {|i|
1293:       row(i)
1294:     }
1295:   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 706
706:   def singular?
707:     determinant == 0
708:   end

Returns true is this is a square matrix.

[Source]

     # File lib/backports/1.9.2/stdlib/matrix.rb, line 713
713:   def square?
714:     column_size == row_size
715:   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 721
721:   def symmetric?
722:     Matrix.Raise ErrDimensionMismatch unless square?
723:     each_with_index(:strict_upper) do |e, row, col|
724:       return false if e != rows[col][row]
725:     end
726:     true
727:   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 1309
1309:   def to_a
1310:     @rows.collect(&:dup)
1311:   end

Overrides Object#to_s

[Source]

      # File lib/backports/1.9.2/stdlib/matrix.rb, line 1335
1335:   def to_s
1336:     if empty?
1337:       "#{self.class}.empty(#{row_size}, #{column_size})"
1338:     else
1339:       "#{self.class}[" + @rows.collect{|row|
1340:         "[" + row.collect{|e| e.to_s}.join(", ") + "]"
1341:       }.join(", ")+"]"
1342:     end
1343:   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 1155
1155:   def trace
1156:     Matrix.Raise ErrDimensionMismatch unless square?
1157:     (0...column_size).inject(0) do |tr, i|
1158:       tr + @rows[i][i]
1159:     end
1160:   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 1173
1173:   def transpose
1174:     return self.class.empty(column_size, 0) if row_size.zero?
1175:     new_matrix @rows.transpose, row_size
1176:   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 733
733:   def unitary?
734:     Matrix.Raise ErrDimensionMismatch unless square?
735:     rows.each_with_index do |row, i|
736:       column_size.times do |j|
737:         s = 0
738:         row_size.times do |k|
739:           s += row[k].conj * rows[k][j]
740:         end
741:         return false unless s == (i == j ? 1 : 0)
742:       end
743:     end
744:     true
745:   end

Returns true is this is an upper triangular matrix.

[Source]

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

Returns true is this is a matrix with only zero elements

[Source]

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

[Validate]