In Files

  • matrix.rb
  • matrix/eigenvalue_decomposition.rb
  • matrix/lup_decomposition.rb
  • matrix/version.rb

Matrix

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

frozen_string_literal: false

frozen_string_literal: false

frozen_string_literal: true

Constants

VERSION

Attributes

rows[R]

instance creations

Public Class Methods

I(n) click to toggle source
Alias for: identity
[](*rows) click to toggle source

Creates a matrix where each argument is a row.

Matrix[ [25, 93], [-1, 66] ]
#   =>  25 93
#       -1 66
 
               # File matrix.rb, line 77
def Matrix.[](*rows)
  rows(rows, false)
end
            
build(row_count, column_count = row_count) click to toggle source

Creates a matrix of size row_count x column_count. 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
 
               # File matrix.rb, line 122
def Matrix.build(row_count, column_count = row_count)
  row_count = CoercionHelper.coerce_to_int(row_count)
  column_count = CoercionHelper.coerce_to_int(column_count)
  raise ArgumentError if row_count < 0 || column_count < 0
  return to_enum :build, row_count, column_count unless block_given?
  rows = Array.new(row_count) do |i|
    Array.new(column_count) do |j|
      yield i, j
    end
  end
  new rows, column_count
end
            
column_vector(column) click to toggle source

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
 
               # File matrix.rb, line 208
def Matrix.column_vector(column)
  column = convert_to_array(column)
  new [column].transpose, 1
end
            
columns(columns) click to toggle source

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

Matrix.columns([[25, 93], [-1, 66]])
#   =>  25 -1
#       93 66
 
               # File matrix.rb, line 107
def Matrix.columns(columns)
  rows(columns, false).transpose
end
            
combine(*matrices) { |*elements| ... } click to toggle source

Create a matrix by combining matrices entrywise, using the given block

x = Matrix[[6, 6], [4, 4]]
y = Matrix[[1, 2], [3, 4]]
Matrix.combine(x, y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
 
               # File matrix.rb, line 287
def Matrix.combine(*matrices)
  return to_enum(__method__, *matrices) unless block_given?

  return Matrix.empty if matrices.empty?
  matrices.map!(&CoercionHelper.method(:coerce_to_matrix))
  x = matrices.first
  matrices.each do |m|
    raise ErrDimensionMismatch unless x.row_count == m.row_count && x.column_count == m.column_count
  end

  rows = Array.new(x.row_count) do |i|
    Array.new(x.column_count) do |j|
      yield matrices.map{|m| m[i,j]}
    end
  end
  new rows, x.column_count
end
            
diagonal(*values) click to toggle source

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
 
               # File matrix.rb, line 142
def Matrix.diagonal(*values)
  size = values.size
  return Matrix.empty if size == 0
  rows = Array.new(size) {|j|
    row = Array.new(size, 0)
    row[j] = values[j]
    row
  }
  new rows
end
            
empty(row_count = 0, column_count = 0) click to toggle source

Creates a empty matrix of row_count x column_count. At least one of row_count or column_count 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]]
 
               # File matrix.rb, line 226
def Matrix.empty(row_count = 0, column_count = 0)
  raise ArgumentError, "One size must be 0" if column_count != 0 && row_count != 0
  raise ArgumentError, "Negative size" if column_count < 0 || row_count < 0

  new([[]]*row_count, column_count)
end
            
hstack(x, *matrices) click to toggle source

Create a matrix by stacking matrices horizontally

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
Matrix.hstack(x, y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]]
 
               # File matrix.rb, line 261
def Matrix.hstack(x, *matrices)
  x = CoercionHelper.coerce_to_matrix(x)
  result = x.send(:rows).map(&:dup)
  total_column_count = x.column_count
  matrices.each do |m|
    m = CoercionHelper.coerce_to_matrix(m)
    if m.row_count != x.row_count
      raise ErrDimensionMismatch, "The given matrices must have #{x.row_count} rows, but one has #{m.row_count}"
    end
    result.each_with_index do |row, i|
      row.concat m.send(:rows)[i]
    end
    total_column_count += m.column_count
  end
  new result, total_column_count
end
            
identity(n) click to toggle source

Creates an n by n identity matrix.

Matrix.identity(2)
#  => 1 0
#     0 1
 
               # File matrix.rb, line 170
def Matrix.identity(n)
  scalar(n, 1)
end
            
Also aliased as: unit, I
new(rows, column_count = rows[0].size) click to toggle source

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

 
               # File matrix.rb, line 321
def initialize(rows, column_count = rows[0].size)
  # No checking is done at this point. rows must be an Array of Arrays.
  # column_count must be the size of the first row, if there is one,
  # otherwise it *must* be specified and can be any integer >= 0
  @rows = rows
  @column_count = column_count
end
            
row_vector(row) click to toggle source

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
 
               # File matrix.rb, line 195
def Matrix.row_vector(row)
  row = convert_to_array(row)
  new [row]
end
            
rows(rows, copy = true) click to toggle source

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
 
               # File matrix.rb, line 89
def Matrix.rows(rows, copy = true)
  rows = convert_to_array(rows, copy)
  rows.map! do |row|
    convert_to_array(row, copy)
  end
  size = (rows[0] || []).size
  rows.each do |row|
    raise ErrDimensionMismatch, "row size differs (#{row.size} should be #{size})" unless row.size == size
  end
  new rows, size
end
            
scalar(n, value) click to toggle source

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

Matrix.scalar(2, 5)
#  => 5 0
#     0 5
 
               # File matrix.rb, line 160
def Matrix.scalar(n, value)
  diagonal(*Array.new(n, value))
end
            
unit(n) click to toggle source
Alias for: identity
vstack(x, *matrices) click to toggle source

Create a matrix by stacking matrices vertically

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
Matrix.vstack(x, y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]]
 
               # File matrix.rb, line 240
def Matrix.vstack(x, *matrices)
  x = CoercionHelper.coerce_to_matrix(x)
  result = x.send(:rows).map(&:dup)
  matrices.each do |m|
    m = CoercionHelper.coerce_to_matrix(m)
    if m.column_count != x.column_count
      raise ErrDimensionMismatch, "The given matrices must have #{x.column_count} columns, but one has #{m.column_count}"
    end
    result.concat(m.send(:rows))
  end
  new result, x.column_count
end
            
zero(row_count, column_count = row_count) click to toggle source

Creates a zero matrix.

Matrix.zero(2)
#  => 0 0
#     0 0
 
               # File matrix.rb, line 184
def Matrix.zero(row_count, column_count = row_count)
  rows = Array.new(row_count){Array.new(column_count, 0)}
  new rows, column_count
end
            

Public Instance Methods

combine(*other_matrices) { |*elements| ... } click to toggle source

Creates new matrix by combining with other_matrices entrywise, using the given block.

x = Matrix[[6, 6], [4, 4]]
y = Matrix[[1, 2], [3, 4]]
x.combine(y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
 
               # File matrix.rb, line 314
def combine(*matrices, &block)
  Matrix.combine(self, *matrices, &block)
end