Skip to content

np.linalg.svd gives weird output #13401

Closed
@mortonjt

Description

@mortonjt

It appears that numpy.linalg.svd has different outputs between 1.15.4 and 1.16.3 -- and I don't see any hints that this should happen in the changelog.

Reproducing code example:

If you run numpy==1.15.4 with the following input, you get the following

In [20]: np.random.seed(0)

In [21]: X = np.random.randn(100, 100) * 10

In [22]: u, s, v = np.linalg.svd(X)

In [23]: s[:5]
Out[23]:
array([193.6995948 , 183.01489365, 180.94983595, 178.47342134,
       174.07146491])

In [24]: u[:5, :5]
Out[24]:
array([[-0.12777193,  0.1473861 , -0.04626332,  0.09269663,  0.12149756],
       [-0.23535239,  0.06543527, -0.02588301, -0.05401032, -0.02436388],
       [ 0.09956489, -0.07108259, -0.10083294,  0.16710062, -0.0333519 ],
       [-0.05718053, -0.11184903, -0.12280465,  0.04707958,  0.16647603],
       [ 0.25422798,  0.01464547, -0.15071626, -0.03225463, -0.12620621]])

In [25]: np.mean(X - u @ np.diag(s) @ v)
Out[25]: 1.336599234069702e-16

In [26]: np.std(X - u @ np.diag(s) @ v)
Out[26]: 2.0947185697750298e-14

However, if you run svd with numpy==1.16.3, you get the following

In [13]: np.random.seed(0)

In [14]: X = np.random.randn(100, 100) * 10

In [15]: u, s, v = np.linalg.svd(X)

In [16]: s[:5]
Out[16]:
array([193.6995948 , 183.01489365, 180.94983595, 178.47342134,
       174.07146491])

In [17]: u[:5, :5]
Out[17]:
array([[-0.07680886,  0.17809124, -0.41179481,  0.14073815,  0.14494919],
       [ 0.46612298, -0.38573887,  0.34177276, -0.11314353, -0.03170648],
       [-0.62584307,  0.10539512,  0.20991414, -0.24513665, -0.11505925],
       [-0.43937521, -0.07100245,  0.2941617 , -0.03515797,  0.04093411],
       [ 0.00359183, -0.64178218,  0.69484207, -0.09871542,  0.28272959]])

In [18]: np.mean(X - u @ np.diag(s) @ v)
Out[18]: 1.0356975839816995

In [19]: np.std(X - u @ np.diag(s) @ v)
Out[19]: 92.84521345330656

Numpy/Python version information:

numpy version 1.15

In [18]: np.__config__.show()
mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/include']
blas_mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/include']
blas_opt_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/include']
lapack_mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/include']
lapack_opt_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/Users/jmorton/miniconda3/envs/qiime2-2019.1/include']
In [27]:  import sys, numpy; print(numpy.__version__, sys.version)
1.15.4 3.6.5 | packaged by conda-forge | (default, Apr  6 2018, 13:44:09)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]

numpy version 1.16

In [3]: np.__config__.show()
blas_mkl_info:
  NOT AVAILABLE
blis_info:
  NOT AVAILABLE
openblas_info:
    libraries = ['openblas', 'openblas']
    library_dirs = ['/usr/local/lib']
    language = c
    define_macros = [('HAVE_CBLAS', None)]
blas_opt_info:
    libraries = ['openblas', 'openblas']
    library_dirs = ['/usr/local/lib']
    language = c
    define_macros = [('HAVE_CBLAS', None)]
lapack_mkl_info:
  NOT AVAILABLE
openblas_lapack_info:
    libraries = ['openblas', 'openblas']
    library_dirs = ['/usr/local/lib']
    language = c
    define_macros = [('HAVE_CBLAS', None)]
lapack_opt_info:
    libraries = ['openblas', 'openblas']
    library_dirs = ['/usr/local/lib']
    language = c
    define_macros = [('HAVE_CBLAS', None)]

In [20]:  import sys, numpy; print(numpy.__version__, sys.version)
1.16.3 3.6.7 | packaged by conda-forge | (default, Feb 28 2019, 02:16:08)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]

As you can see, the output from 1.16.3 is broken, and the svd is no longer a true reconstruction.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions