[Numpy-discussion] svd error checking vs. speed
Dave Hirschfeld
novin01 at gmail.com
Mon Feb 17 04:49:34 EST 2014
alex <argriffi <at> ncsu.edu> writes:
>
> Hello list,
>
> Here's another idea resurrection from numpy github comments that I've
> been advised could be posted here for re-discussion.
>
> The proposal would be to make np.linalg.svd more like scipy.linalg.svd
> with respect to input checking. The argument against the change is
> raw speed; if you know that you will never feed non-finite input to
> svd, then np.linalg.svd is a bit faster than scipy.linalg.svd. An
> argument for the change could be to avoid issues reported on github
> like crashes, hangs, spurious non-convergence exceptions, etc. from
> the undefined behavior of svd of non-finite input.
>
> """
> [...] the following numpy code hangs until I `kill -9` it.
>
> ```
> $ python runtests.py --shell
> $ python
> Python 2.7.5+
> [GCC 4.8.1] on linux2
> >>> import numpy as np
> >>> np.__version__
> '1.9.0.dev-e3f0f53'
> >>> A = np.array([[1e3, 0], [0, 1]])
> >>> B = np.array([[1e300, 0], [0, 1]])
> >>> C = np.array([[1e3000, 0], [0, 1]])
> >>> np.linalg.svd(A)
> (array([[ 1., 0.],
> [ 0., 1.]]), array([ 1000., 1.]), array([[ 1., 0.],
> [ 0., 1.]]))
> >>> np.linalg.svd(B)
> (array([[ 1., 0.],
> [ 0., 1.]]), array([ 1.00000000e+300, 1.00000000e+000]),
> array([[ 1., 0.],
> [ 0., 1.]]))
> >>> np.linalg.svd(C)
> [hangs forever]
> ```
> """
>
> Alex
>
I'm -1 on checking finiteness - if there's one place you usually want
maximum performance it's linear algebra operations.
It certainly shouldn't crash or hang though and for me at least it doesn't -
it returns NaN which immediately suggests to me that I've got bad input
(maybe just because I've seen it before).
I'm not sure adding an extra kwarg is worth cluttering up the api when a
simple call to isfinite beforehand will do the job if you think you may
potentially have non-finite input.
Python 2.7.5 |Anaconda 1.8.0 (64-bit)| (default, Jul 1 2013, 12:37:52) [MSC
v.1500 64 bit (AMD64)]
In [1]: import numpy as np
In [2]: >>> A = np.array([[1e3, 0], [0, 1]])
...: >>> B = np.array([[1e300, 0], [0, 1]])
...: >>> C = np.array([[1e3000, 0], [0, 1]])
...: >>> np.linalg.svd(A)
...:
Out[2]:
(array([[ 1., 0.],
[ 0., 1.]]),
array([ 1000., 1.]),
array([[ 1., 0.],
[ 0., 1.]]))
In [3]: np.linalg.svd(B)
Out[3]:
(array([[ 1., 0.],
[ 0., 1.]]),
array([ 1.0000e+300, 1.0000e+000]),
array([[ 1., 0.],
[ 0., 1.]]))
In [4]: C
Out[4]:
array([[ inf, 0.],
[ 0., 1.]])
In [5]: np.linalg.svd(C)
Out[5]:
(array([[ 0., 1.],
[ 1., 0.]]),
array([ nan, nan]),
array([[ 0., 1.],
[ 1., 0.]]))
In [6]: np.__version__
Out[6]: '1.7.1'
Regards,
Dave
More information about the NumPy-Discussion
mailing list