QChem QChem - 5 months ago 33
Python Question

How to know when to use numpy.linalg instead of scipy.linalg?

Received wisdom is to prefer

scipy.linalg
over
nump.linalg
functions. For doing linear algebra, ideally (and conveniently) I would like to combine the functionalities of
numpy.array
and
scipy.linalg
without ever looking towards
numpy.linalg
. This is not always possible and may become too frustrating.

Is there a comparative checklist of equivalent functions from these two modules to quickly determine when to use
numpy.linalg
in case a function is absent in
scipy.linalg
?

e.g. There are
scipy.linalg.norm()
and
numpy.linalg.norm()
, but there seem to be no scipy equivalents of
numpy.linalg.matrix_rank()
and
numpy.linalg.cond()
.

Answer

So, the normal rule is to just use scipy.linalg as it generally supports all of the numpy.linalg functionality and more. The documentation says this:

See also

numpy.linalg for more linear algebra functions. Note that although scipy.linalg imports most of them, identically named functions from scipy.linalg may offer more or slightly differing functionality.

However, matrix_rank() is only in NumPy.

Here we can see the differences between the functions provided by both libraries, and how SciPy is more complete:

In [2]: from scipy import linalg as scipy_linalg
In [3]: from numpy import linalg as numpy_linalg
In [4]: dir(scipy_linalg)
Out[4]:
[
 ...
 'absolute_import',
 'basic',
 'bench',
 'blas',
 'block_diag',
 'cho_factor',
 'cho_solve',
 'cho_solve_banded',
 'cholesky',
 'cholesky_banded',
 'circulant',
 'companion',
 'coshm',
 'cosm',
 'cython_blas',
 'cython_lapack',
 'decomp',
 'decomp_cholesky',
 'decomp_lu',
 'decomp_qr',
 'decomp_schur',
 'decomp_svd',
 'det',
 'dft',
 'diagsvd',
 'division',
 'eig',
 'eig_banded',
 'eigh',
 'eigvals',
 'eigvals_banded',
 'eigvalsh',
 'expm',
 'expm2',
 'expm3',
 'expm_cond',
 'expm_frechet',
 'find_best_blas_type',
 'flinalg',
 'fractional_matrix_power',
 'funm',
 'get_blas_funcs',
 'get_lapack_funcs',
 'hadamard',
 'hankel',
 'helmert',
 'hessenberg',
 'hilbert',
 'inv',
 'invhilbert',
 'invpascal',
 'kron',
 'lapack',
 'leslie',
 'linalg_version',
 'logm',
 'lstsq',
 'lu',
 'lu_factor',
 'lu_solve',
 'matfuncs',
 'misc',
 'norm',
 'ordqz',
 'orth',
 'orthogonal_procrustes',
 'pascal',
 'pinv',
 'pinv2',
 'pinvh',
 'polar',
 'print_function',
 'qr',
 'qr_delete',
 'qr_insert',
 'qr_multiply',
 'qr_update',
 'qz',
 'rq',
 'rsf2csf',
 's',
 'schur',
 'signm',
 'sinhm',
 'sinm',
 'solve',
 'solve_banded',
 'solve_circulant',
 'solve_continuous_are',
 'solve_discrete_are',
 'solve_discrete_lyapunov',
 'solve_lyapunov',
 'solve_sylvester',
 'solve_toeplitz',
 'solve_triangular',
 'solveh_banded',
 'special_matrices',
 'sqrtm',
 'svd',
 'svdvals',
 'tanhm',
 'tanm',
 'test',
 'toeplitz',
 'tri',
 'tril',
 'triu']

In [5]: dir(numpy_linalg)
Out[5]:
[
 ...
 'absolute_import',
 'bench',
 'cholesky',
 'cond',
 'det',
 'division',
 'eig',
 'eigh',
 'eigvals',
 'eigvalsh',
 'info',
 'inv',
 'lapack_lite',
 'linalg',
 'lstsq',
 'matrix_power',
 'matrix_rank',
 'multi_dot',
 'norm',
 'pinv',
 'print_function',
 'qr',
 'slogdet',
 'solve',
 'svd',
 'tensorinv',
 'tensorsolve',
 'test']

In [6]:

Note that not all of these are functions.

SciPy does provide scipy.linalg.expm_cond(), but this only returns the condition in the Frobenius norm, whereas numpy.linalg.cond() supports multiple norms.