Repository: numpy/numpy

Issue:
lstsq problem
I have noticed a problem with numpy's lstsq when I have a complex matrix and multiple right hand sides. If the number of right hand sides is large enough - then I end up with a malloc core dump. This is strange since lstsq should compute the SVD and then just multiply it across all of the right hand sides (and my work around is to use SVD in exactly this way). This seems to happen on linux and windows - and also Python 2.7 and 3.5. I am attaching a code segment. I would appreciate to know if anyone thinks that I have made a mistake in my usage of lstsq or maybe a namespace conflict.

```python
    # test python complex lstsq against multiple right hand sides
    # The lstsq code works great on real valued problems 
    # - but freaks out on complex - and can cause a malloc core dump
    from scipy import *
    from pylab import *
    
    Ntest = 700
    G = randn(200,50)+1j*randn(200,50)
    u = randn(50,Ntest) + 1j*randn(50,Ntest)
    b = dot(G,u)
    
    # this works for moderately large Ntest (linus and windows, python 2.7 and 3.5)
    U,S,VH = svd(G,full_matrices=False)
    K = dot(VH.conjugate().transpose(),dot(diag(1.0/S),U.conjugate().transpose()))
    u2 = dot(K,b)
    
    print('found u2 shape',u2.shape)
    print('SVD solution is good - error {0:g}'.format(abs(u2-u).max()))
    
    print('\n')
    
    # whereas, this crashes for some Ntest big enough for your system
    u3,res,rnk,sv = lstsq(G,b)
    print('found u3 shape',u3.shape)
    print('LSTSQ solution is good - error {0:g}'.format(abs(u3-u).max())) 
```


Discussion:
scipy.linalg.lstsq works fine here, numpy.linalg.lstsq crashes
Works for me with numpy 1.13.1 (slightly outdated).
I will look at updating
also crashes on Mac
The scipy.linalg.lstsq works - but the numpy.linalg.lstsq crashes (core dumps)
Confirm I get a segmentation fault with the above settings (on Debian testing: python 3.5.4, numpy 1.13.1, as well as current master). I did a quick check in `linalg.py` -- the segmentation fault occurs within the last call to `lapack_lite.zgelsd` - I'll see if I can figure out whether it is just an improperly passed on size (which would be my suspicion).
OK, I think it is indeed setting up the work arrays that was broken. Fix in the works.

Resolving patch:
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -2021,14 +2021,8 @@ def lstsq(a, b, rcond="warn"):
         work = zeros((lwork,), t)
         results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
                                  0, work, -1, rwork, iwork, 0)
-        lwork = int(abs(work[0]))
-        rwork = zeros((lwork,), real_t)
-        a_real = zeros((m, n), real_t)
-        bstar_real = zeros((ldb, n_rhs,), real_t)
-        results = lapack_lite.dgelsd(m, n, n_rhs, a_real, m,
-                                     bstar_real, ldb, s, rcond,
-                                     0, rwork, -1, iwork, 0)
         lrwork = int(rwork[0])
+        lwork = int(work[0].real)
         work = zeros((lwork,), t)
         rwork = zeros((lrwork,), real_t)
         results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,


Test patch:
diff --git a/numpy/linalg/tests/test_regression.py b/numpy/linalg/tests/test_regression.py
--- a/numpy/linalg/tests/test_regression.py
+++ b/numpy/linalg/tests/test_regression.py
@@ -137,6 +137,18 @@ def test_norm_object_array(self):
         assert_raises(TypeError, linalg.norm, testmatrix, ord=-2)
         assert_raises(ValueError, linalg.norm, testmatrix, ord=3)
 
+    def test_lstsq_complex_larger_rhs(self):
+        # gh-9891
+        size = 20
+        n_rhs = 70
+        G = np.random.randn(size, size) + 1j * np.random.randn(size, size)
+        u = np.random.randn(size, n_rhs) + 1j * np.random.randn(size, n_rhs)
+        b = G.dot(u)
+        # This should work without segmentation fault.
+        u_lstsq, res, rank, sv = linalg.lstsq(G, b, rcond=None)
+        # check results just in case
+        assert_array_almost_equal(u_lstsq, u)
+
 
 if __name__ == '__main__':
     run_module_suite()