LA::Matrix(T)
Inherits LA::LapackHelper / Enumerable / Reference / Object
class that provide all utility matrix functions
Class methods
Create row from start_val...end_val with step of delta between
Create a block diagonal matrix from provided matrices
Given the inputs A, B and C, the output will have these matrices arranged on the diagonal:
Example:
m = Mat.block_diag(a, b, c)
m will have following structure:
[[a, 0, 0],
[0, b, 0],
[0, 0, c]]
Construct a Circulant matrix
c - first column of matrix
Example:
a = circulant([1, 2, 3])
a.to_aa # => [[1, 3, 2],[2, 1, 3],[3, 2, 1]])
Behaviour copied from scipy
Create a companion matrix associated with the polynomial whose coefficients are given in a
Behaviour copied from scipy
Example:
Mat.companion([1, -10, 31, -30]) # =>
# LA::GeneralMatrix(Float64) (3x3, None):
# [10.0, -31.0, 30.0]
# [1.0, 0.0, 0.0]
# [0.0, 1.0, 0.0]
Returns diagonal matrix of given size with all diagonal elements equal to value
Returns diagonal matrix of given size with diagonal elements taken from array values
Returns diagonal matrix of given size with diagonal elements equal to block value
Returns a symmetric Fiedler matrix
Given an sequence of numbers values, Fiedler matrices have the structure f[i, j] = (values[i] - values[j]).abs, and hence zero diagonals and nonnegative entries.
A Fiedler matrix has a dominant positive eigenvalue and other eigenvalues are negative.
Behaviour copied from scipy
Example:
Mat.fiedler([1, 4, 12, 45, 77]) # =>
# LA::GeneralMatrix(Float64) (5x5, Symmetric | Hermitian):
# [0.0, 3.0, 11.0, 44.0, 76.0]
# [3.0, 0.0, 8.0, 41.0, 73.0]
# [11.0, 8.0, 0.0, 33.0, 65.0]
# [44.0, 41.0, 33.0, 0.0, 32.0]
# [76.0, 73.0, 65.0, 32.0, 0.0]
Converts a string of given format to matrix Example:
str = "( 1,2,3 | 4,5,6 | 7,8,9 )"
LA::GMat.from_custom(str, "(", ",", "|", ")")
Converts a string of given format to matrix Example:
str = "( 1,2,3 | 4,5,6 | 7,8,9 )"
LA::GMat.from_custom(IO::Memory.new(str), prefix: "(", columns_separator: ",", rows_separator: "|", postfix: ")")
Converts a string from matlab format to matrix Example:
str = "[1,2,3; 4,5,6; 7,8,9]"
LA::GMat.from_matlab(str)
Constructs an n-by-n Hadamard matrix, n must be power of 2
Behaviour copied from scipy
Example:
Mat.hadamard(4) # =>
# LA::GeneralMatrix(Float64) (4x4, Symmetric | Hermitian):
# [1.0, 1.0, 1.0, 1.0]
# [1.0, -1.0, 1.0, -1.0]
# [1.0, 1.0, -1.0, -1.0]
# [1.0, -1.0, -1.0, 1.0]
Create a Hankel matrix
The Hankel matrix has constant anti-diagonals, with column as its first column and row as its last row.
If `row is nil, then row with elements equal to zero is assumed.
Behaviour copied from scipy
Examples:
a = Mat.hankel([1, 17, 99])
a.to_aa # => [
# [ 1, 17, 99],
# [17, 99, 0],
# [99, 0, 0]]
a = Mat.hankel([1, 2, 3, 4], [4, 7, 7, 8, 9])
a.to_aa # => [
# [1, 2, 3, 4, 7],
# [2, 3, 4, 7, 7],
# [3, 4, 7, 7, 8],
# [4, 7, 7, 8, 9]]
Create an Helmert matrix of order n
If full is true the (n x n) matrix will be returned.
Otherwise the submatrix that does not include the first row will be returned
Behaviour copied from scipy
Example:
Mat.helmert(5, full: true) # =>
# LA::GeneralMatrix(Float64) (5x5, Orthogonal):
# [0.4472135954999579, 0.4472135954999579, 0.4472135954999579, 0.4472135954999579, 0.4472135954999579]
# [0.7071067811865476, -0.7071067811865476, 0.0, 0.0, 0.0]
# [0.408248290463863, 0.408248290463863, -0.816496580927726, 0.0, 0.0]
# [0.28867513459481287, 0.28867513459481287, 0.28867513459481287, -0.8660254037844386, 0.0]
# [0.22360679774997896, 0.22360679774997896, 0.22360679774997896, 0.22360679774997896, -0.8944271909999159]
Create a Hilbert matrix of order n.
Returns the n by n matrix with entries h[i,j] = 1 / (i + j + 1).
Behaviour copied from scipy
Example:
Mat.hilbert(3) # =>
# LA::GeneralMatrix(Float64) (3x3, Symmetric | Hermitian | PositiveDefinite):
# [1.0, 0.5, 0.3333333333333333]
# [0.5, 0.3333333333333333, 0.25]
# [0.3333333333333333, 0.25, 0.2]
Compute the inverse of the Hilbert matrix of order n.
The entries in the inverse of a Hilbert matrix are integers.
Behaviour copied from scipy
Example:
Mat.invhilbert(4) # => LA::GeneralMatrix(Float64) (4x4, Symmetric | Hermitian | PositiveDefinite):
# [16.0, -120.0, 240.0, -140.0]
# [-120.0, 1200.0, -2700.0, 1680.0]
# [240.0, -2700.0, 6480.0, -4200.0]
# [-140.0, 1680.0, -4200.0, 2800.0]
Mat.invhilbert(16)[7, 7] # => 4.247509952853739e+19
Returns the inverse of the n x n Pascal matrix
The Pascal matrix is a matrix containing the binomial coefficients as its elements.
kind : see PascalKind
Behaviour copied from scipy
Example:
Mat.invpascal(4) # =>
# LA::GeneralMatrix(Float64) (5x5, Symmetric | Hermitian | PositiveDefinite):
# [5.0, -10.0, 10.0, -5.0, 1.0]
# [-10.0, 30.0, -35.0, 19.0, -4.0]
# [10.0, -35.0, 46.0, -27.0, 6.0]
# [-5.0, 19.0, -27.0, 17.0, -4.0]
# [1.0, -4.0, 6.0, -4.0, 1.0]
Mat.invpascal(5, PascalKind::Lower) # =>
# LA::GeneralMatrix(Float64) (5x5, LowerTriangular):
# [1.0, 0.0, 0.0, 0.0, 0.0]
# [-1.0, 1.0, 0.0, 0.0, 0.0]
# [1.0, -2.0, 1.0, 0.0, 0.0]
# [-1.0, 3.0, -3.0, 1.0, 0.0]
# [1.0, -4.0, 6.0, -4.0, 1.0]
Returns kroneker product of matrices
Resulting matrix size is {a.nrows*b.nrows, a.ncolumns*b.ncolumns}
Create a Leslie matrix
Given the length n array of fecundity coefficients f and the length n-1 array of survival coefficients s, return the associated Leslie matrix.
Behaviour copied from scipy
Example:
Mat.leslie([0.1, 2.0, 1.0, 0.1], [0.2, 0.8, 0.7]) # =>
# LA::GeneralMatrix(Float64) (4x4, None):
# [0.1, 2.0, 1.0, 0.1]
# [0.2, 0.0, 0.0, 0.0]
# [0.0, 0.8, 0.0, 0.0]
# [0.0, 0.0, 0.7, 0.0]
Loads a matrix from CSV (comma separated values) file Example:
LA::GMat.rand(30, 30).save_csv("./test.csv")
a = LA::GMat.load_csv("./test.csv")
Returns the n x n Pascal matrix.
The Pascal matrix is a matrix containing the binomial coefficients as its elements.
kind : see PascalKind
Behaviour copied from scipy
Example:
Mat.pascal(4) # =>
# LA::GeneralMatrix(Float64) (4x4, Symmetric | Hermitian | PositiveDefinite):
# [1.0, 1.0, 1.0, 1.0]
# [1.0, 2.0, 3.0, 4.0]
# [1.0, 3.0, 6.0, 10.0]
# [1.0, 4.0, 10.0, 20.0]
Mat.pascal(4, PascalKind::Lower) # =>
# LA::GeneralMatrix(Float64) (4x4, LowerTriangular):
# [1.0, 0.0, 0.0, 0.0]
# [1.0, 1.0, 0.0, 0.0]
# [1.0, 2.0, 1.0, 0.0]
# [1.0, 3.0, 3.0, 1.0]
Generate matrix of given size with elements randomly distributed from range 0.0..1.0
Create a Toeplitz matrix
column - first column of matrix
row - first row of matrix (if nil, it is assumed that row = column.map(&.conj))
Behaviour copied from scipy
Example:
MatComplex.toeplitz([1, 2, 3], [1, 4, 5, 6]) # =>
# LA::GeneralMatrix(Float64) (3x4, None):
# [1.0, 4.0, 5.0, 6.0]
# [2.0, 1.0, 4.0, 5.0]
# [3.0, 2.0, 1.0, 4.0]
MatComplex.toeplitz([1.0, 2 + 3.i, 4 - 1.i]) # =>
# LA::GeneralMatrix(Complex) (3x3, Hermitian):
# [1.0 + 0.0i, 2.0 - 3.0i, 4.0 + 1.0i]
# [2.0 + 3.0i, 1.0 + 0.0i, 2.0 - 3.0i]
# [4.0 - 1.0i, 2.0 + 3.0i, 1.0 + 0.0i]
Construct (nrows, ncolumns) matrix filled with ones at and below the kth diagonal.
The matrix has A[i,j] == 1 for j <= i + k
k - Number of subdiagonal below which matrix is filled with ones. k = 0 is the main diagonal, k < 0 subdiagonal and k > 0 superdiagonal.
Behaviour copied from scipy
Example:
Mat.tri(3, 5, 2).to_aa # => [[
# [1, 1, 1, 0, 0],
# [1, 1, 1, 1, 0],
# [1, 1, 1, 1, 1]]
Mat.tri(3, 5, -1).to_aa # => [[
# [0, 0, 0, 0, 0],
# [1, 0, 0, 0, 0],
# [1, 1, 0, 0, 0]]
Instance methods
Matrix product to given m
Raises ArgumentError if inner dimensions do not match
This method automatically calls optimal function depending on MatrixFlags.
If one of the matrix is square and triangular - trmm is called
If one of the matrix is symmetric\hermitian - symm/hemm is called
Otherwise - gemm is called
Raises the square matrix to the integer power other
Implementation taken from https://github.com/Exilor/matrix/
Returns element-wise sum
This method raises if another matrix doesn't have same size
Returns element-wise substract
This method raises if another matrix doesn't have same size
Compare with another matrix
Returns True only if all element are exactly equal.
Use #almost_eq If you need approximate equality
Return element of matrix on row i and column j
If i or j negative they are counted from end of matrix
If i>=nrows or j>=ncolumns exception is raised
Use #unsafe_fetch if you need to skip these checks
Return submatrix over given ranges.
See SubMatrix(T) for details on submatrices
Example:
m = GMat32.new([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
m1 = m[1..3, 2..3] # => [[7.0, 8.0], [11.0, 12.0], [15.0, 16.0]]
m2 = m[..3, 2] # => [[3.0], [7.0], [11.0], [15.0]]
Return submatrix over given ranges.
See SubMatrix(T) for details on submatrices
Example:
m = GMat32.new([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
m1 = m[1..3, 2..3] # => [[7.0, 8.0], [11.0, 12.0], [15.0, 16.0]]
m2 = m[..3, 2] # => [[3.0], [7.0], [11.0], [15.0]]
Return submatrix over given ranges.
See SubMatrix(T) for details on submatrices
Example:
m = GMat32.new([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
m1 = m[1..3, 2..3] # => [[7.0, 8.0], [11.0, 12.0], [15.0, 16.0]]
m2 = m[..3, 2] # => [[3.0], [7.0], [11.0], [15.0]]
Assign element of matrix on row i and column j
If i or j negative they are counted from end of matrix
If i>=nrows or j>=ncolumns exception is raised
Use #unsafe_set if you need to skip these checks
Note this method reset all matrix flags
Assign value to a given submatrix
value can be a scalar or a matrix of same size as affected submatrix
Assign value to a given submatrix
value can be a scalar or a matrix of same size as affected submatrix
Assign value to a given submatrix
value can be a scalar or a matrix of same size as affected submatrix
Perform inplace addition with matrix m multiplied to scalar k
a.add!(k, b) is equal to a = a + k * b, but faster as no new matrix is allocated
Performs inplace addition with matrix m
a.add!(b) is equal to a = a + b, but faster as no new matrix is allocated
performs c = alphaab + beta*c (BLAS routines gemm/symm/hemm)
Approximately compare with other matrix
Returns true if all elements are within eps from corresponding elements of other matrix
Approximately compare with other matrix
Returns true if all elements are within eps from corresponding elements of other matrix
Uses #tolerance as an eps by default
Directly set or reset matrix flag without check
See MatrixFlags for description of flags
Returns concatenation with another matrix by Axis::Rows (horizontal) or Axis::Columns (vertical)
Converts complex matrix to real one if all imaginary parts are less then eps, returns nil otherwise
Returns just matrix if it is already real
Reset matrix flags to None
Usually is done automatically,
but this method could be needed if internal content was changed using to_unsafe
Returns conjurgate transposed matrix
result is same as #transpose for real matrices
Calculates determinant for a square matrix
if overwrite_a is true, a will be overriden in process of calculation
Uses getrf LAPACK routine
Detect if given aflags are true or flase for a matrix with tolerance eps
Update flags property
See MatrixFlags for description of matrix flags
Returns self for method chaining
Detect if given aflags are true or flase for a matrix with tolerance eps
Update flags property
See MatrixFlags for description of matrix flags
Returns True if all given flags are set
Returns Indexable(T) that allow iterating over k-th diagonal of matrix
Example:
m = GMat32.new([[-1, 2, 3, 4],
[5, -6, 7, 8],
[9, 10, -11, 12]])
m.diag(0).to_a.should eq [-1, -6, -11]
m.diag(1).to_a.should eq [2, 7, 12]
m.diag(2).to_a.should eq [3, 8]
m.diag(3).to_a.should eq [4]
expect_raises(ArgumentError) { m.diag(4) }
m.diag(-1).to_a.should eq [5, 10]
m.diag(-2).to_a.should eq [9]
expect_raises(ArgumentError) { m.diag(-3) }
expect_raises(ArgumentError) { m.diag(-4) }
Yields every element of matrix
all argument controls whether to yield all or non-empty elements for banded\sparse matrices
Example:
m.each { |v| raise "negative element found" if v < 0 }
Yields every index
all argument controls whether to yield all or non-empty elements for banded\sparse matrices
Example:
m.each_index { |i, j| m[i, j] = -m[i, j] }
For every element of matrix that is below main diagonal it yields a block with value and with corresponding row and column
This method is useful for symmetric matrices and similar cases
include_diagonal argument controls whether to include elements on main diagonal
all argument controls whether to yield all or non-empty elements for banded\sparse matrices
For every element of matrix that is above main diagonal it yields a block with value and with corresponding row and column
This method is useful for symmetric matrices and similar cases
include_diagonal argument controls whether to include elements on main diagonal
all argument controls whether to yield all or non-empty elements for banded\sparse matrices
Yields every element of matrix with corresponding row and column
all argument controls whether to yield all or non-empty elements for banded\sparse matrices
Example:
m.each_with_index { |v, i, j| m2[i, j] = v }
generalized eigenvalues problem
Computes matrix exponential
It exploits triangularity (if any) of A. if schur_fact is true, function uses an initial transformation to Schur form.
Reference: A. H. Al-Mohy and N. J. Higham, A New Scaling and Squaring Algorithm for the Matrix Exponential, SIAM J. Matrix Anal. Appl. 31(3): 970-989, 2009. Awad H. Al-Mohy and Nicholas J. Higham, April 20, 2010.
Converts matrix to string for inspection
Output looks like:
GeneralMatrix(Float64) (10x10, MatrixFlags::None)
[1, 2, 3, .... 10]
[11, 12, 13, .... 20]
...
[91, 92, 93, .... 100]
Calculate matrix inversion inplace
Method selects optimal algorithm depending on MatrixFlags
transpose returned if matrix is orthogonal
trtri is used if matrix is triangular
potrf, potri are used if matrix is positive definite
hetrf, hetri are used if matrix is hermitian
sytrf, sytri are used if matrix is symmetric
getrf, getri are used otherwise
Compute pivoted LU decomposition of a matrix
If you call p,l,u = a.lu for a matrix m*n a then
pwill be m*m permutation matrixlwill be m*k lower triangular matrix with unit diagonal. K = min(M, N)uwill be k*n upper triangular matrix(p*l*u)will be equal toa(within calculation tolerance)
if overwrite_a is true, a will be overriden in process of calculation
Uses getrf LAPACK routine
Compute pivoted LU decomposition of a matrix and returns it in a compact form, useful for solving linear equation systems.
Uses getrf LAPACK routine
Compute pivoted LU decomposition of a matrix and returns it in a compact form, useful for solving linear equation systems.
Overrides source matrix in a process of calculation
Uses getrf LAPACK routine
returns matrix norm
kind defines type of norm
Uses LAPACK routines lantr, lanhe, lansy, lange depending on matrix flags
Calculate Moore–Penrose inverse of a matrix
https://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_inverse Implemented using an svd decomposition
determine effective rank either by SVD method or QR-factorization with pivoting
if overwrite_a is true, a will be overriden in process of calculation
QR method is faster, but could fail to determine rank in some cases
Return matrix repeated arows times by vertical and acolumns times by horizontal
Save a matrix to CSV (comma separated values) file Example:
LA::GMat.rand(30, 30).save_csv("./test.csv")
a = LA::GMat.load_csv("./test.csv")
Solves matrix equation self*x = b and returns x
Method returns matrix of same size as b
Matrix must be square, number of rows must match b
if overwrite_a is true, a will be overriden in process of calculation
if overwrite_b is true, b will be overriden in process of calculation
Uses LAPACK routines trtrs, posv, hesv, sysv, gesv depending on matrix flags
Calculates singular value decomposition for a matrix
If you call u,s,vt = a.svd for a matrix m*n a then
uwill be m*m matrixswill be Array(T) with size equal to{m, n}.minvtwill be n*n matrix(u*Mat.diag(a.nrows, a.ncolumns, s)*vt)will be equal toa(within calculation tolerance)
if overwrite_a is true, a will be overriden in process of calculation
Uses gesdd LAPACK routine
Calculates array of singular values for a matrix
if overwrite_a is true, a will be overriden in process of calculation
Uses gesdd LAPACK routine
to_custom(io, "[", ",", "],[", "]") Converts a matrix to string with custom format. Example:
a = LA::GMat[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
str = String.build do |io|
a.to_custom(io, prefix: "(", columns_separator: ",", rows_separator: "|", postfix: ")")
end
str # => "(1,2,3|4,5,6|7,8,9)"
to_custom(io, "[", ",", "],[", "]") Converts a matrix to string with custom format. Example:
a = LA::GMat[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
str = a.to_custom(prefix: "(", columns_separator: ",", rows_separator: "|", postfix: ")")
str # => "(1,2,3|4,5,6|7,8,9)"
Converts a matrix to matlab format string Example:
LA::GMat[[1, 2, 3], [4, 5, 6], [7, 8, 9]].to_matlab # => "[1,2,3; 4,5,6; 7,8,9]"
Converts matrix to string, with linefeeds before and after matrix:
Output looks like:
[1, 2, 3, .... 10]
[11, 12, 13, .... 20]
...
[91, 92, 93, .... 100]
Returns pointer to underlying data
Storage format depends of matrix type This method raises at runtime if matrix doesn't have raw pointer
Returns estimated tolerance of equality\inequality
This value is used by default in #almost_eq compare
performs b = alphaab or b = alphaba (BLAS routine trmm)
a must be a square triangular GeneralMatrix(T)
if left is true, alpha*a*b is calculated, otherwise alpha*b*a
Same as tril in scipy - returns lower triangular or trapezoidal part of matrix
Returns a matrix with all elements above k-th diagonal zeroed
Same as triu in scipy - returns upper triangular or trapezoidal part of matrix
Returns a matrix with all elements below k-th diagonal zeroed
Macros
Complex utility macros that simplifies calling certain LAPACK functions It substitute first letter, allocate workareas, raise exception if return value is negative Check source to see supported functions Example:
# Calling *geev to calculate eigenvalues
lapack(geev, 'N'.ord.to_u8, 'N'.ord.to_u8, nrows, a, nrows,
vals.to_unsafe.as(LibCBLAS::ComplexDouble*),
Pointer(LibCBLAS::ComplexDouble).null, nrows,
Pointer(LibCBLAS::ComplexDouble).null, nrows, worksize: [2*nrows])
Note that it should be called only from methods of Matrix or its descendants
Utility macros that simplifies calling certain LAPACK functions
Arguments that point to matrix should be passed as matrix(arg)
Example:
# Calling *lange to calculate infinity-norm
lapack_util(lange, worksize, 'I', m.nrows, m.ncolumns, matrix(m), m.nrows)
Note that it should be called only from methods of Matrix or its descendants