Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Commit

Permalink
* impl - linalg matrix_rank for cpu and gpu implemented
Browse files Browse the repository at this point in the history
* fix - python interface
  • Loading branch information
Ubuntu committed Apr 11, 2020
1 parent 8d065cc commit 75ffcfe
Show file tree
Hide file tree
Showing 10 changed files with 876 additions and 11 deletions.
48 changes: 47 additions & 1 deletion python/mxnet/ndarray/numpy/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,53 @@
from . import _api_internal

__all__ = ['norm', 'svd', 'cholesky', 'qr', 'inv', 'det', 'slogdet', 'solve', 'tensorinv', 'tensorsolve',
'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq']
'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq', 'matrix_rank']


def matrix_rank(M, tol=None, hermitian=False):
"""
Return matrix rank of array using SVD method
Rank of the array is the number of singular values of the array that are
greater than `tol`.
Parameters
M : {(M,), (..., M, N)} ndarray
Input vector or stack of matrices.
tol : (...) ndarray, float, optional
Threshold below which SVD values are considered zero. If `tol` is
None, and ``S`` is an array with singular values for `M`, and
``eps`` is the epsilon value for datatype of ``S``, then `tol` is
set to ``S.max() * max(M.shape) * eps``.
hermitian : bool, optional
If True, `M` is assumed to be Hermitian (symmetric if real-valued),
enabling a more efficient method for finding singular values.
Defaults to False.
Returns
-------
rank : (...) ndarray
Rank of M.
Examples
--------
>>> from mxnet import np
>>> np.matrix_rank(np.eye(4)) # Full rank matrix
4
>>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix
>>> np.matrix_rank(I)
3
>>> np.matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0
1
>>> np.matrix_rank(np.zeros((4,)))
0
"""
finfo_eps_32 = _np.finfo(_np.float32).eps
finfo_eps_64 = _np.finfo(_np.float64).eps
if tol is None:
return _npi.matrix_rank_none_tol(M, finfo_eps_32, finfo_eps_64, hermitian)
else:
return _npi.matrix_rank(M, tol, hermitian)


def lstsq(a, b, rcond='warn'):
Expand Down
2 changes: 0 additions & 2 deletions python/mxnet/numpy/fallback_linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@
__all__ = [
'cond',
'matrix_power',
'matrix_rank',
'multi_dot'
]

cond = onp.linalg.cond
matrix_power = onp.linalg.matrix_power
matrix_rank = onp.linalg.matrix_rank
multi_dot = onp.linalg.multi_dot
43 changes: 42 additions & 1 deletion python/mxnet/numpy/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,51 @@
from . import fallback_linalg

__all__ = ['norm', 'svd', 'cholesky', 'qr', 'inv', 'det', 'slogdet', 'solve', 'tensorinv', 'tensorsolve',
'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq']
'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq', 'matrix_rank']
__all__ += fallback_linalg.__all__


def matrix_rank(M, tol=None, hermitian=False):
"""
Return matrix rank of array using SVD method
Rank of the array is the number of singular values of the array that are
greater than `tol`.
Parameters
M : {(M,), (..., M, N)} ndarray
Input vector or stack of matrices.
tol : (...) ndarray, float, optional
Threshold below which SVD values are considered zero. If `tol` is
None, and ``S`` is an array with singular values for `M`, and
``eps`` is the epsilon value for datatype of ``S``, then `tol` is
set to ``S.max() * max(M.shape) * eps``.
hermitian : bool, optional
If True, `M` is assumed to be Hermitian (symmetric if real-valued),
enabling a more efficient method for finding singular values.
Defaults to False.
Returns
-------
rank : (...) ndarray
Rank of M.
Examples
--------
>>> from mxnet import np
>>> np.matrix_rank(np.eye(4)) # Full rank matrix
4
>>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix
>>> np.matrix_rank(I)
3
>>> np.matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0
1
>>> np.matrix_rank(np.zeros((4,)))
0
"""
return _mx_nd_np.linalg.matrix_rank(M, tol, hermitian)


def lstsq(a, b, rcond='warn'):
r"""
Return the least-squares solution to a linear matrix equation.
Expand Down
1 change: 1 addition & 0 deletions python/mxnet/numpy_dispatch_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def _run_with_array_ufunc_proto(*args, **kwargs):
'linalg.eigvalsh',
'linalg.eigh',
'linalg.qr',
'linalg.matrix_rank',
'shape',
'trace',
'tril',
Expand Down
35 changes: 34 additions & 1 deletion python/mxnet/symbol/numpy/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,40 @@
from . import _internal as _npi

__all__ = ['norm', 'svd', 'cholesky', 'qr', 'inv', 'det', 'slogdet', 'solve', 'tensorinv', 'tensorsolve',
'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq']
'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq', 'matrix_rank']


def matrix_rank(M, tol=None, hermitian=False):
"""
Return matrix rank of array using SVD method
Rank of the array is the number of singular values of the array that are
greater than `tol`.
Parameters
M : {(M,), (..., M, N)} _Symbol
Input vector or stack of matrices.
tol : (...) _Symbol, float, optional
Threshold below which SVD values are considered zero. If `tol` is
None, and ``S`` is an array with singular values for `M`, and
``eps`` is the epsilon value for datatype of ``S``, then `tol` is
set to ``S.max() * max(M.shape) * eps``.
hermitian : bool, optional
If True, `M` is assumed to be Hermitian (symmetric if real-valued),
enabling a more efficient method for finding singular values.
Defaults to False.
Returns
-------
rank : (...) _Symbol
Rank of M.
"""
finfo_eps_32 = _np.finfo(_np.float32).eps
finfo_eps_64 = _np.finfo(_np.float64).eps
if tol is None:
return _npi.matrix_rank_none_tol(M, finfo_eps_32, finfo_eps_64, hermitian)
else:
return _npi.matrix_rank(M, tol, hermitian)


def lstsq(a, b, rcond='warn'):
Expand Down
Loading

0 comments on commit 75ffcfe

Please sign in to comment.