<div dir="ltr"><div>Thanks Stefan, this proves that it dates back to matlab pre6.5 days, for some reason I vaguely remember using pinv2 on some non-python tool but couldn't find anything online. <br></div><div><br></div><div>I attempted to fix the atol/rtol issue that apparently caused some difficulties in over scikit-learn for quite some timesee [1], [2] reported by @ogrisel and then deprecated pinv2. The PR is here <a href="https://github.com/scipy/scipy/pull/13831">https://github.com/scipy/scipy/pull/13831</a></div><div><br></div><div>Feedback always welcome<br></div><div><br></div><br><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>[1] : <a href="https://github.com/scipy/scipy/issues/13704">https://github.com/scipy/scipy/issues/13704</a></div><div>[2] : <a href="https://github.com/scikit-learn/scikit-learn/pull/19646">https://github.com/scikit-learn/scikit-learn/pull/19646</a></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Mar 22, 2021 at 9:33 PM Stefan van der Walt <<a href="mailto:stefanv@berkeley.edu">stefanv@berkeley.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u><div><div>On Sun, Mar 21, 2021, at 16:17, Robert Kern wrote:<br></div><blockquote type="cite" id="gmail-m_2243154058158406344qt"><div dir="ltr"><div dir="ltr">On Sun, Mar 21, 2021 at 6:53 PM Robert Kern <<a href="mailto:robert.kern@gmail.com" target="_blank">robert.kern@gmail.com</a>> wrote:<br></div><div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Sun, Mar 21, 2021 at 6:00 PM Ralf Gommers <<a href="mailto:ralf.gommers@gmail.com" target="_blank">ralf.gommers@gmail.com</a>> wrote:<br></div><div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><br></div><div><div>Do you happen to know the history of how we ended up with pinv2?<br></div></div></div></blockquote><div><br></div><div>I suspect that when `pinv2()` was added, the `lstsq()` call underlying `pinv()` was not SVD-based. The precise LAPACK driver has changed over the years. We might have started with the QR-based driver.<br></div></div></div></blockquote><div><br></div><div>It's going to be very hard to tell definitively because I think the history got lost in the SVN->git conversion due to some directory renames that happened in the early days. The pinv/pinv2 split seems to have been very early, though, so it may have dated from the original Multipack library (the source tarballs of which are also linkrotted away). <br></div></div></div></blockquote><div><br></div><div>I think you're right, this was pre-SVN.  I was looking at the following commit from <a href="https://github.com/scipy/scipy-svn" target="_blank">https://github.com/scipy/scipy-svn</a><br></div><div><br></div><div>commit c6ef539392f31bda0b56541a1c8fdd61a0c0e6eb (HEAD)<br></div><div>Author: pearu <pearu@d6536bca-fef9-0310-8506-e4c0a848fbcf><br></div><div>Date:   Sun Apr 7 15:03:50 2002 +0000<br></div><div><br></div><div>    Replacing linalg with linalg2: linalg->linalg/linalg1 and linalg2->linalg<br></div><div><br></div><div><br></div><div>There, the linalg/basic.py file is added, and inside it both pinv and pinv2 already exist:<br></div><div><br></div><div>def pinv(a, cond=-1):<br></div><div>    """Compute generalized inverse of A using least-squares solver.<br></div><div>    """<br></div><div>    a = asarray(a)<br></div><div>    t = a.typecode()<br></div><div>    b = scipy.identity(a.shape[0],t)<br></div><div>    return lstsq(a, b, cond=cond)[0]<br></div><div><br></div><div>def pinv2(a, cond=-1):<br></div><div>    """Compute the generalized inverse of A using svd.<br></div><div>    """<br></div><div>    a = asarray(a)<br></div><div>    u, s, vh = decomp.svd(a)<br></div><div>    m = u.shape[1]<br></div><div>    n = vh.shape[0]<br></div><div>    t = u.typecode()<br></div><div>    if cond is -1 or cond is None:<br></div><div>        cond = {0: feps*1e3, 1: eps*1e6}[_array_precision[t]]<br></div><div>    cutoff = cond*scipy_base.maximum.reduce(s)<br></div><div>    for i in range(min(n,m)):<br></div><div>        if s[i] > cutoff:<br></div><div>            s[i] = 1.0/s[i]<br></div><div>        else:<br></div><div>            s[i] = 0.0<br></div><div>    return dot(tran(conj(vh)),tran(conj(u))*s[:,NewAxis])<br></div><div><br></div><div><br></div><div>I have not been able to find a copy of multipack-0.7.tar.gz</div><div><br></div><div>Stéfan<br></div><div><br></div></div>_______________________________________________<br>
SciPy-Dev mailing list<br>
<a href="mailto:SciPy-Dev@python.org" target="_blank">SciPy-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/scipy-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/scipy-dev</a><br>
</blockquote></div>