class Apatite::Matrix(T)
- Apatite::Matrix(T)
- Reference
- Object
Included Modules
- Comparable(Apatite::Matrix(T))
- Enumerable(Apatite::Vector(T))
- Indexable(Apatite::Vector(T))
Defined in:
apatite/matrix.crapatite/matrix/eigenvalue_decomposition.cr
apatite/matrix/lup_decomposition.cr
Constant Summary
-
SELECTORS =
{all: true, diagonal: true, off_diagonal: true, lower: true, strict_lower: true, strict_upper: true, upper: true}
Constructors
-
.new(pull : JSON::PullParser)
Creates a new
Matrix
instance from aJSON::PullParser
. - .new(pull : JSON::PullParser, &)
Class Method Summary
-
.[](*rows)
Creates a matrix where each argument is a row.
-
.build(row_count, column_count = row_count, &block : Int32, Int32 -> T)
Creates a matrix of size +row_count+ x +column_count+.
-
.column_vector(column)
Creates a single-column matrix where the values of that column are as given in
#column
. -
.columns(columns)
Creates a matrix using +columns+ as an array of column vectors.
-
.combine(*matrices, &)
Create a matrix by combining matrices entrywise, using the given block
-
.diagonal(values : Indexable(T), dummy = nil)
Creates a matrix where the diagonal elements are composed of
values
. -
.diagonal(*values : T)
ditto
-
.empty(row_count = 0, column_count = 0)
Creates a empty matrix of
#row_count
x#column_count
. -
.hstack(x, *matrices)
Create a matrix by stacking matrices horizontally
-
.identity(n)
Creates an
n
byn
identity matrix. -
.row_vector(row)
Creates a single-row matrix where the values of that row are as given in
#row
. -
.rows(rows : Indexable(Indexable(T)), copy = true)
Creates a matrix where +rows+ is an array of arrays, each of which is a row of the matrix.
-
.scalar(n, value : T)
Creates an +n+ by +n+ diagonal matrix where each diagonal element is
value
. -
.unit(n : T)
ditto
-
.vstack(x, *matrices)
Create a matrix by stacking matrices vertically
-
.zero(row_count, column_count = row_count)
Creates a zero matrix.
Instance Method Summary
-
#*(other)
Matrix multiplication
-
#**(other)
Matrix exponentiation.
-
#+(other : Matrix | Indexable)
Matrix addition
-
#-(other : Matrix | Indexable)
Matrix subtraction
-
#/(other)
Matrix division (multiplication by the inverse).
-
#<=>(other : Matrix)
The comparison operator.
-
#==(other : Matrix)
Equality operator
-
#[](i, j)
Returns element (
i
,j
) of the matrix. -
#[](i)
Returns row
i
of the matrix as an Array. -
#[]=(i, j, v : T)
Set the value at index (
i
,j
). -
#[]?(i, j)
Returns element (
i
,j
) of the matrix. -
#[]?(i)
Returns row
i
of the matrix as an Array. -
#adjugate
Returns the adjugate of the matrix.
-
#clone
Returns a clone of the matrix, so that the contents of each do not reference identical objects.
-
#coerce(klass)
Attempt to coerce the elements in the matrix to another type.
-
#cofactor(row, column)
Returns the (row, column) cofactor which is obtained by multiplying the first minor by (-1)**(row + column).
-
#column(j)
Returns column vector
j
of the Matrix as a Vector (starting at 0). -
#column(j, &block : T -> )
Returns a block which yields every item in column
j
of the Matrix. -
#column?(j)
Returns column vector
j
of the Matrix as a Vector (starting at 0). -
#column_count : Int32
Returns the number of columns.
-
#column_vectors
Returns an array of the column vectors of the matrix.
-
#combine(*matrices, &block)
ditto
-
#conj
Returns the conjugate of the matrix.
-
#determinant
Returns the determinant of the matrix.
-
#diagonal?
Returns
true
if this is a diagonal matrix. -
#each(which = :all, &block : T -> )
Yields all elements of the matrix, starting with those of the first row, or returns an Enumerator if no block given.
-
#each_with_index(which = :all, &block : T, Int32, Int32 -> )
Same as #each, but yields the row index and column index in addition to the element
-
#eigensystem
Returns the Eigensystem of the matrix See
EigenvalueDecomposition
. -
#empty?
Returns true if this matrix is empty.
-
#first_minor(row, column)
Returns the submatrix obtained by deleting the specified row and column.
-
#hadamard_product(m)
Hadamard product
-
#hermitian?
Returns
true
if this is an hermitian matrix. -
#hstack(*matrices)
Returns a new matrix resulting by stacking horizontally the receiver with the given matrices
-
#imag
Returns the imaginary part of the matrix.
-
#index(i, selector = :all)
The index method is specialized to return the index as {row, column} It also accepts an optional
selector
argument, see#each
for details. -
#index(selector = :all, &block : T -> Bool)
Returns the index as {row, column}, using
&block
to filter the result. -
#inverse
Returns the inverse of the matrix.
-
#laplace_expansion(*, row = nil, column = nil)
Returns the Laplace expansion along given row or column.
-
#lower_triangular?
Returns true if this matrix is a lower triangular matrix.
-
#lup
Returns the LUP decomposition of the matrix See +LUPDecomposition+.
-
#map(&block : T -> T)
Returns a Matrix that is the result of iteration of the given block over all elements in the matrix.
-
#map_with_index(&block : T, Int32, Int32 -> U) forall U
Same as #map, but yields the row index and column index in addition to the element
-
#minor(from_row : Int, nrows : Int, from_col : Int, ncols : Int)
Returns a section of the Matrix.
-
#minor(row_range : Range, col_range : Range)
Returns a section of the Matrix.
-
#normal?
Returns
true
if this is a normal matrix. -
#orthogonal?
Returns
true
if this is an orthogonal matrix -
#permutation?
Returns
true
if this is a permutation matrix - #pretty_print(pp) : Nil
-
#rank
Returns the rank of the matrix.
-
#real
Returns the real part of the matrix.
-
#real?
Returns
true
if this matrix contains real numbers, i.e. -
#rect
Returns an array containing matrices corresponding to the real and imaginary parts of the matrix
-
#regular?
Returns
true
if this is a regular (i.e. -
#round(n = 0)
Returns a matrix with entries rounded to the given precision (see
Float#round
) -
#row(i)
Returns row vector number
i
of the Matrix as a Vector (starting at 0 like a good boy). -
#row(i, &block : Vector -> )
Returns a block which yields every Vector in the row (starting at 0).
-
#row?(i)
Returns row vector number
i
of the Matrix as a Vector (starting at 0 like a good boy). -
#row_count
Returns the number of rows.
-
#row_vectors
Returns an array of the row vectors of the matrix.
-
#singular?
Returns
true
if this is a singular matrix. -
#size
Return the row and column size as a
Tuple(Int32, Int32)
-
#square?
Returns
true
if this is a square matrix. -
#swap_columns(col1, col2)
Swaps
col1
andcol2
-
#swap_rows(row1, row2)
Swaps
row1
androw2
-
#symmetric?
Returns +true+ if this is a symmetric matrix.
-
#t
ditto
-
#to_a
Returns an array of arrays that describe the rows of the matrix.
-
#to_json(json : JSON::Builder)
Convert the matrix to a json array
-
#to_matrix
Just in case
- #to_s(io)
-
#tr
ditto
-
#trace
Returns the trace (sum of diagonal elements) of the matrix.
-
#transpose
Returns the transpose of the matrix.
-
#unitary?
Returns
true
if this is a unitary matrix -
#unsafe_fetch(index : Int)
Returns the element at the given index, without doing any bounds check.
-
#upper_triangular?
Returns true if this matrix is a upper triangular matrix.
-
#vstack(*matrices)
Returns a new matrix resulting by stacking vertically the receiver with the given matrices
-
#zero?
Returns
true
if this is a matrix with only zero elements
Constructor Detail
Creates a new Matrix
instance from a JSON::PullParser
.
Defaults to a Float64 matrix.
Class Method Detail
Creates a matrix where each argument is a row.
Matrix[[25, 93], [-1, 66]]
# => [ 25, 93,
# -1, 66 ]
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
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 ]
Creates a matrix using +columns+ as an array of column vectors.
Matrix.columns([[25, 93], [-1, 66]])
# => [ 25, -1,
# 93, 66 ]
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]]
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 ]
Creates a empty matrix of #row_count
x #column_count
.
At least one of #row_count
or #column_count
must be 0.
m = Matrix(Int32).empty(2, 0)
m == Matrix[ [], [] ]
# => true
n = Matrix(Int32).empty(0, 3)
m * n
# => Matrix[[0, 0, 0], [0, 0, 0]]
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]]
Creates an n
by n
identity matrix.
NOTE An explicit type is required since it cannot be inferred.
Matrix(Int32).identity(2)
# => [ 1, 0,
# 0, 1 ]
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 ]
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 ]
Creates an +n+ by +n+ diagonal matrix where each diagonal element is
value
.
Matrix.scalar(2, 5)
# => [ 5, 0,
# 0, 5 ]
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]]
Creates a zero matrix. Note that a type definition is required.
Matrix(Int32).zero(2)
# => [ 0, 0,
# 0, 0 ]
Instance Method Detail
Matrix multiplication
Matrix[[2, 4], [6, 8]] * Matrix.identity(2)
# => [ 2, 4,
# 6, 8 ]
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 ]
Matrix addition
Matrix.scalar(2, 5) + Matrix[[1, 0], [-4, 7]]
# => [ 6, 0,
# -4, 1 ]
Matrix subtraction
Matrix[[1, 5], [4, 2]] - Matrix[[9, 3], [-4, 1]]
# => [-8, 2,
# 8, 1 ]
Matrix division (multiplication by the inverse).
Matrix[[7, 6], [3, 9]] / Matrix[[2, 9], [3, 1]]
# => [ -7, 1,
# -3, -6 ]
The comparison operator. Returns 0
if the two objects are equal,
a negative number if this object is considered less than other,
a positive number if this object is considered greater than other,
or nil
if the two objects are not comparable.
Subclasses define this method to provide class-specific ordering.
The comparison operator is usually used to sort values:
# Sort in a descending way:
[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]
# Sort in an ascending way:
[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]
Returns element (i
, j
) of the matrix. That is: row i
, column j
.
Raises if either index is not found.
Returns element (i
, j
) of the matrix. That is: row i
, column j
.
Returns nil if either index is not found.
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.
Returns the (row, column) cofactor which is obtained by multiplying the first minor by (-1)**(row + column).
Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
# => -108
Returns column vector j
of the Matrix as a Vector (starting at 0).
Raises if the column doesn't exist.
Returns column vector j
of the Matrix as a Vector (starting at 0).
Returns nil if the column doesn't exist.
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]].conj
# => 1-2i -i 0
# 1 2 3
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
Yields all elements of the matrix, starting with those of the first row, or returns an Enumerator if 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]
Same as #each, but yields 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
Returns the Eigensystem of the matrix
See EigenvalueDecomposition
.
NOTE Not working yet
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
Returns the submatrix obtained by deleting the specified row and column.
Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
# => [ 9, 0, 0,
# 0, 0, 0,
# 0, 0, 4 ]
Hadamard product
Matrix[[1, 2], [3, 4]].hadamard_product Matrix[[1, 2], [3, 2]]
# => [ 1, 4,
# 9, 8 ]
Returns a new matrix resulting by stacking horizontally the receiver with the given matrices
x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.hstack(y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]]
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]].imag
# => [ 2i, i, 0,
# 0, 0, 0 ]
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, 1], [1, 1]].index(1, :strict_lower)
# => {1, 0}
Returns the index as {row, column}, using &block
to filter the
result. It also accepts an optional selector
argument, see
#each
for details.
Matrix[[1, 2], [3, 4]].index(&.even?)
# => {0, 1}
Returns the inverse of the matrix.
NOTE Always returns a Float64
regardless of T
s type. To coerce
back into an Int
, use #coerce
.
Matrix[[-1, -1], [0, -1]].inverse
# => [ -1.0, 1.0,
# 0.0, -1.0 ]
Returns the Laplace expansion along given row or column.
Matrix[[7, 6], [3, 9]].laplace_expansion(column: 1)
# => 45
Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0)
# => Vector[3, -2]
Returns the LUP decomposition of the matrix See +LUPDecomposition+.
NOTE Not working yet
a = Matrix[[1, 2], [3, 4]]
l, u, p = a.lup
l.lower_triangular? # => true
u.upper_triangular? # => true
p.permutation? # => true
l * u == p * a # => true
a.lup.solve([2, 5]) # => Vector[(1/1), (1/2)]
Returns a Matrix that is the result of iteration of the given block over all elements in the matrix.
Same as #map, but yields the row index and column index in addition to the element
matrix = Matrix[[1, 2], [3, 4]].map_with_index do |e, row, col|
e*row + col
end
matrix == Matrix[[0, 1], [3, 5]] # => true
Returns a section of the Matrix.
Matrix.diagonal(9, 5, -3).minor(0, 2, 0, 3)
# => [ 9, 0, 0,
# 0, 5, 0 ]
Returns a section of the Matrix.
Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
# => [ 9, 0, 0,
# 0, 5, 0 ]
Returns true
if this is a normal matrix.
Matrix[[1, 1, 0], [0, 1, 1], [1, 0, 1]].normal?
# => true
Returns true
if this is an orthogonal matrix
Matrix[[1, 0], [0, 1]].orthogonal?
# => true
Returns true
if this is a permutation matrix
Matrix[[1, 0], [0, 1]].permutation?
# => true
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
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 ]
Returns true
if this matrix contains real numbers,
i.e. not Complex
.
require "complex"
Matrix[[Complex.new(1, 0)], [Complex.new(0, 1)]].real?
# => false
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
Returns row vector number i
of the Matrix as a Vector (starting
at 0 like a good boy). Raises if the row doesn't exist.
Returns a block which yields every Vector in the row (starting at 0).
Returns row vector number i
of the Matrix as a Vector (starting
at 0 like a good boy). Returns nil if the row doesn't exist.
Returns +true+ if this is a symmetric matrix. Raises an error if matrix is not square.
Returns the trace (sum of diagonal elements) of the matrix.
Matrix[[7, 6], [3, 9]].trace
# => 16
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 ]
Returns the element at the given index, without doing any bounds check.
Indexable
makes sure to invoke this method with index in 0...size
,
so converting negative indices to positive ones is not needed here.
Clients never invoke this method directly. Instead, they access
elements with #[](index)
and #[]?(index)
.
This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.
Returns a new matrix resulting by stacking vertically the receiver with the given matrices
x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.vstack(y)
# => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]]