Finished with complex arithematic
This commit is contained in:
parent
5f73aa5083
commit
fc46b8622e
|
@ -1,5 +1,6 @@
|
||||||
require "json"
|
require "json"
|
||||||
require "./vector"
|
require "./matrix/eigenvalue_decomposition"
|
||||||
|
require "./matrix/lup_decomposition"
|
||||||
|
|
||||||
module Apatite::LinearAlgebra
|
module Apatite::LinearAlgebra
|
||||||
class Matrix(T)
|
class Matrix(T)
|
||||||
|
@ -1064,12 +1065,6 @@ module Apatite::LinearAlgebra
|
||||||
# MATRIX FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
# MATRIX FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
#++
|
#++
|
||||||
|
|
||||||
# Attempt to coerce the elements in the matrix to another type.
|
|
||||||
def coerce(klass)
|
|
||||||
rws = @rows.map { |r| r.map { |i| klass.new(i) } }
|
|
||||||
Matrix.rows(rws)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the determinant of the matrix.
|
# Returns the determinant of the matrix.
|
||||||
#
|
#
|
||||||
# Beware that using Float values can yield erroneous results
|
# Beware that using Float values can yield erroneous results
|
||||||
|
@ -1262,6 +1257,115 @@ module Apatite::LinearAlgebra
|
||||||
self.class.vstack(self, *matrices)
|
self.class.vstack(self, *matrices)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#--
|
||||||
|
# DECOMPOSITIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
#++
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# ```
|
||||||
|
def eigensystem
|
||||||
|
EigenvalueDecomposition.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 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)]
|
||||||
|
# ```
|
||||||
|
def lup
|
||||||
|
LUPDecomposition.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
#--
|
||||||
|
# COMPLEX ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
#++
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# ```
|
||||||
|
def conj
|
||||||
|
raise ArgumentError.new("Matrix#conj only works with real matrices (i.e. Matrix(Complex))") unless real?
|
||||||
|
map(&.conj)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 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 ]
|
||||||
|
# ```
|
||||||
|
def imag
|
||||||
|
raise ArgumentError.new("Matrix#imag only works with real matrices (i.e. Matrix(Complex))") unless real?
|
||||||
|
map(&.imag)
|
||||||
|
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 ]
|
||||||
|
# ```
|
||||||
|
def real
|
||||||
|
raise ArgumentError.new("Matrix#real only works with real matrices (i.e. Matrix(Complex))") unless real?
|
||||||
|
map(&.real)
|
||||||
|
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
|
||||||
|
# ```
|
||||||
|
def rect
|
||||||
|
raise ArgumentError.new("Matrix#real only works with real matrices (i.e. Matrix(Complex))") unless real?
|
||||||
|
[real, imag]
|
||||||
|
end
|
||||||
|
|
||||||
|
#--
|
||||||
|
# CONVERTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
#++
|
||||||
|
|
||||||
|
# Attempt to coerce the elements in the matrix to another type.
|
||||||
|
def coerce(klass)
|
||||||
|
rws = @rows.map { |r| r.map { |i| klass.new(i) } }
|
||||||
|
Matrix.rows(rws)
|
||||||
|
end
|
||||||
|
|
||||||
def to_s(io)
|
def to_s(io)
|
||||||
if empty?
|
if empty?
|
||||||
"Matrix.empty(#{row_count}, #{column_count})"
|
"Matrix.empty(#{row_count}, #{column_count})"
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
module Apatite
|
||||||
|
class Matrix(T)
|
||||||
|
# Eigenvalues and eigenvectors of a real matrix.
|
||||||
|
#
|
||||||
|
# Computes the eigenvalues and eigenvectors of a matrix A.
|
||||||
|
#
|
||||||
|
# If A is diagonalizable, this provides matrices V and D
|
||||||
|
# such that A = V*D*V.inv, where D is the diagonal matrix with entries
|
||||||
|
# equal to the eigenvalues and V is formed by the eigenvectors.
|
||||||
|
#
|
||||||
|
# If A is symmetric, then V is orthogonal and thus A = V*D*V.t
|
||||||
|
class EigenvalueDecomposition
|
||||||
|
def initialize(matrix)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,17 @@
|
||||||
|
module Apatite
|
||||||
|
class Matrix(T)
|
||||||
|
# For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
|
||||||
|
# unit lower triangular matrix L, an n-by-n upper triangular matrix U,
|
||||||
|
# and a m-by-m permutation matrix P so that L*U = P*A.
|
||||||
|
# If m < n, then L is m-by-m and U is m-by-n.
|
||||||
|
#
|
||||||
|
# The LUP decomposition with pivoting always exists, even if the matrix is
|
||||||
|
# singular, so the constructor will never fail. The primary use of the
|
||||||
|
# LU decomposition is in the solution of square systems of simultaneous
|
||||||
|
# linear equations. This will fail if singular? returns true.
|
||||||
|
class LupDecomposition
|
||||||
|
def initialize(matrix)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue