ssspy.linalg#
ssspy.linalg
is linear algebra module related to source separation.
Algorithms#
- ssspy.linalg.inv2(X)#
Compute the (multiplicative) inverse of a 2x2 matrix.
- Parameters:
X (numpy.ndarray) – 2x2 matrix to be inverted. The shape is (*, 2, 2).
- Returns:
(Multiplicative) inverse of the matrix X.
- Return type:
numpy.ndarray
Examples
>>> import numpy as np >>> from ssspy.linalg import inv2 >>> X = np.array([[0, 1], [2, 3]]) >>> X_inv = inv2(X) >>> np.allclose(X @ X_inv, np.eye(2)) True >>> np.allclose(X_inv @ X, np.eye(2)) True
>>> import numpy as np >>> from ssspy.linalg import inv2 >>> X = np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) >>> inv2(X) array([[[-1.5, 0.5], [ 1. , -0. ]], [[-3.5, 2.5], [ 3. , -2. ]]])
- ssspy.linalg.eigh(A, B=None, type=1)#
Compute the (generalized) eigenvalues and eigenvectors of a complex Hermitian (conjugate symmetric) or a real symmetric matrix.
If
B
isNone
, solve \(\boldsymbol{A}\boldsymbol{z} = \lambda\boldsymbol{z}\).If
B
is given, solve \(\boldsymbol{A}\boldsymbol{z} = \lambda\boldsymbol{B}\boldsymbol{z}\).- Parameters:
A (numpy.ndarray) – A complex Hermitian matrix with shape of (*, n_channels, n_channels).
B (numpy.ndarray, optional) – A complex Hermitian matrix with shape of (*, n_channels, n_channels).
type (int) –
For the generalized eigenproblem, this value specifies the type of problem. Only
1
,2
, and3
are supported.When
type=1
, solve \(\boldsymbol{Az}=\lambda\boldsymbol{Bz}\).When
type=2
, solve \(\boldsymbol{ABz}=\lambda\boldsymbol{z}\).When
type=3
, solve \(\boldsymbol{BAz}=\lambda\boldsymbol{z}\).
- Return type:
Union
[ndarray
,Tuple
[ndarray
,ndarray
]]- Returns:
- A tuple of (eigenvalues, eigenvectors)
Eigenvalues have shape of (*, n_channels).
Eigenvectors have shape of (*, n_channels, n_channels).
Note
If
B
is given, we use cholesky decomposition to satisfy \(\boldsymbol{L}\boldsymbol{L}^{\mathsf{H}}=\boldsymbol{B}\).Then, solve \(\boldsymbol{C}\boldsymbol{y} = \lambda\boldsymbol{y}\), where \(\boldsymbol{C}=\boldsymbol{L}^{-1}\boldsymbol{A}\boldsymbol{L}^{-\mathsf{H}}\).
The generalized eigenvalues of \(\boldsymbol{A}\) and \(\boldsymbol{B}\) are computed by \(\boldsymbol{L}^{-\mathsf{H}}\boldsymbol{y}\).
Examples
>>> import numpy as np >>> from ssspy.linalg import eigh >>> A = np.array([[1, -2j], [2j, 3]]) >>> lamb, z = eigh(A) >>> lamb; z array([-0.23606798, 4.23606798]) array([[-0.85065081+0.j , -0.52573111+0.j ], [ 0. +0.52573111j, 0. -0.85065081j]]) >>> np.allclose(A @ z, lamb * z) True
>>> import numpy as np >>> from ssspy.linalg import eigh >>> A = np.array([[1, -2j], [2j, 3]]) >>> B = np.array([[2, -3j], [3j, 5]]) >>> lamb, z = eigh(A, B) >>> lamb; z array([-1.61803399, 0.61803399]) array([[ 2.22703273+0.j , -0.20081142+0.j ], [ 0. -1.37638192j, 0. -0.3249197j ]]) >>> np.allclose(A @ z, lamb * (B @ z)) True
- ssspy.linalg.eigh2(A, B=None, type=1)#
Compute the (generalized) eigenvalues and eigenvectors of a 2x2 complex Hermitian (conjugate symmetric) or a real symmetric matrix.
If
B
isNone
, solve \(\boldsymbol{A}\boldsymbol{z} = \lambda\boldsymbol{z}\).If
B
is given, solve \(\boldsymbol{A}\boldsymbol{z} = \lambda\boldsymbol{B}\boldsymbol{z}\).- Parameters:
A (numpy.ndarray) – A complex Hermitian matrix with shape of (*, 2, 2).
B (numpy.ndarray, optional) – A complex Hermitian matrix with shape of (*, 2, 2).
type (int) –
For the generalized eigenproblem, this value specifies the type of problem. Only
1
,2
, and3
are supported.When
type=1
, solve \(\boldsymbol{Az}=\lambda\boldsymbol{Bz}\).When
type=2
, solve \(\boldsymbol{ABz}=\lambda\boldsymbol{z}\).When
type=3
, solve \(\boldsymbol{BAz}=\lambda\boldsymbol{z}\).
- Return type:
Union
[ndarray
,Tuple
[ndarray
,ndarray
]]- Returns:
- A tuple of (eigenvalues, eigenvectors)
Eigenvalues have shape of (*, 2).
Eigenvectors have shape of (*, 2, 2).
Note
If
B
is given, we use cholesky decomposition to satisfy \(\boldsymbol{L}\boldsymbol{L}^{\mathsf{H}}=\boldsymbol{B}\).Then, solve \(\boldsymbol{C}\boldsymbol{y} = \lambda\boldsymbol{y}\), where \(\boldsymbol{C}=\boldsymbol{L}^{-1}\boldsymbol{A}\boldsymbol{L}^{-\mathsf{H}}\).
The generalized eigenvalues of \(\boldsymbol{A}\) and \(\boldsymbol{B}\) are computed by \(\boldsymbol{L}^{-\mathsf{H}}\boldsymbol{y}\).
See also https://github.com/tky823/ssspy/issues/115 for this implementation.
Examples
>>> import numpy as np >>> from ssspy.linalg import eigh2 >>> A = np.array([[1, -2j], [2j, 3]]) >>> lamb, z = eigh2(A) >>> lamb; z array([-0.23606798, 4.23606798]) array([[-0.85065081+0.j , -0.52573111+0.j ], [ 0. +0.52573111j, 0. -0.85065081j]]) >>> np.allclose(A @ z, lamb * z) True
>>> import numpy as np >>> from ssspy.linalg import eigh2 >>> A = np.array([[1, -2j], [2j, 3]]) >>> B = np.array([[2, -3j], [3j, 5]]) >>> lamb, z = eigh2(A, B) >>> lamb; z array([-1.61803399, 0.61803399]) array([[ 2.22703273+0.j , -0.20081142+0.j ], [ 0. -1.37638192j, 0. -0.3249197j ]]) >>> np.allclose(A @ z, lamb * (B @ z)) True
- ssspy.linalg.gmeanmh(A, B, type=1)#
Compute the geometric mean of complex Hermitian (conjugate symmetric) or real symmetric matrices.
The geometric mean of \(\boldsymbol{A}\) and \(\boldsymbol{B}\) is defined as follows [1]:
\[\begin{split}\boldsymbol{A}\#\boldsymbol{B} &= \boldsymbol{A}^{1/2} (\boldsymbol{A}^{-1/2}\boldsymbol{B}\boldsymbol{A}^{-1/2})^{1/2} \boldsymbol{A}^{1/2} \\ &= \boldsymbol{A}(\boldsymbol{A}^{-1}\boldsymbol{B})^{1/2} \\ &= (\boldsymbol{A}\boldsymbol{B}^{-1})^{1/2}\boldsymbol{B}.\end{split}\]This is a solution of the following equation for complex Hermitian or real symmetric matrices, \(\boldsymbol{A}\), \(\boldsymbol{B}\), and \(\boldsymbol{X}\):
\[\boldsymbol{X}\boldsymbol{A}^{-1}\boldsymbol{X} = \boldsymbol{B}.\]Note
In this toolkit, \(\boldsymbol{A}\#\boldsymbol{B}\) is computed by \(\boldsymbol{B}(\boldsymbol{B}^{-1}\boldsymbol{A})^{1/2}\) in terms of computational speed. Note that \(\boldsymbol{A}\#\boldsymbol{B}\) is equal to \(\boldsymbol{B}\#\boldsymbol{A}\). For comparison of computational time, see https://github.com/tky823/ssspy/issues/210.
Note
\((\boldsymbol{B}^{-1}\boldsymbol{A})^{1/2}\) is computed by generalized eigendecomposition. Let \(\lambda\) and \(z\) be the eigenvalue and eigenvector of the generalized eigenproblem \(\boldsymbol{Az}=\lambda\boldsymbol{Bz}\). Then, \((\boldsymbol{B}^{-1}\boldsymbol{A})^{1/2}\) is computed by \(\boldsymbol{Z}\boldsymbol{\Lambda}^{1/2}\boldsymbol{Z}^{-1}\), where the main diagonals of \(\boldsymbol{\Lambda}\) are \(\lambda\) s and the columns of \(\boldsymbol{Z}\) are \(\boldsymbol{z}\) s.
- Parameters:
A (numpy.ndarray) – A complex Hermitian matrix with shape of (*, n_channels, n_channels).
B (numpy.ndarray) – A complex Hermitian matrix with shape of (*, n_channels, n_channels).
type (int) –
This value specifies the type of geometric mean. Only
1
,2
, and3
are supported.When
type=1
, return \(\boldsymbol{A}\#\boldsymbol{B}\).When
type=2
, return \(\boldsymbol{A}^{-1}\#\boldsymbol{B}\).When
type=3
, return \(\boldsymbol{A}\#\boldsymbol{B}^{-1}\).
- Return type:
ndarray
- Returns:
Geometric mean of matrices with shape of (*, n_channels, n_channels).
- ssspy.linalg.lqpqm2(H, v, z, flooring_fn=functools.partial(<function max_flooring>, eps=1e-10), singular_fn='flooring', max_iter=10)#
Solve of log-quadratically penelized quadratic minimization (type 2).
\[\check{\boldsymbol{q}}_{in} = \min_{\check{\boldsymbol{q}}_{in}} ~~\check{\boldsymbol{q}}_{in}^{\mathsf{H}}\check{\boldsymbol{q}}_{in} - \log\left((\check{\boldsymbol{q}}_{in}+\boldsymbol{v}_{in})^{\mathsf{H}} \boldsymbol{H}_{in}(\check{\boldsymbol{q}}_{in}+\boldsymbol{v}_{in}) + z_{in} \right)\]- Parameters:
H (numpy.ndarray) – Positive semidefinite matrices of shape (n_bins, n_sources - 1, n_sources - 1).
v (numpy.ndarray) – Linear terms in LQPQM of shape (n_bins, n_sources - 1).
z (numpy.ndarray) – Constant terms in LQPQM of shape (n_bins,).
flooring_fn (callable, optional) – A flooring function for numerical stability. This function is expected to return the same shape tensor as the input. If you explicitly set
flooring_fn=None
, the identity function (lambda x: x
) is used. Default:functools.partial(max_flooring, eps=1e-10)
.singular_fn (callable, optional) – A flooring function to return singular condition. This function is expected to return the same shape bool tensor as the input. If
singular_fn=None
,lambda x: x == 0
is used. Default:flooring
.max_iter (int) – Maximum number of Newton-Raphson method. Default:
10
.
- Returns:
Solutions of LQPQM type-2 of shape (n_bins, n_sources - 1).
- Return type:
np.ndarray