[SciPy-User] linalg.decomp code contribution
collinstocks at gmail.com
collinstocks at gmail.com
Thu Jul 7 17:42:59 EDT 2011
I realize that no one has responded to my post yet, and I hate to double
post like this, but this update is rather important.
The code I attached previously contains a bug (well, makes a bug in cvxopt
apparent, actually...) whereby creating new matrices in cvxopt from numpy
arrays can sometimes cause a segmentation fault or memory access violation
(or something...Windows doesn't really seem to give enough information to
differentiate between different types of failures) under certain
circumstances on Windows XP.
I have fixed my code and attached it. I also changed some abbreviations in
my code ("np") to the full name ("numpy") to be more consistent with the
surrounding code.
-- Collin
On Wed, Jul 6, 2011 at 14:17, Collin Stocks <collinstocks at gmail.com> wrote:
> Over the past several years, there have been various requests for the
> linalg.decomp.qr() function to (optionally) implement qr with pivots.
> I have written a solution which, unfortunately, requires cvxopt, since
> there is no wrapper within scipy for lapack.geqp3(). However, this
> should be an effective starting place for anyone who wants to complete
> the job. If this does eventually end up in scipy, I would appreciate a
> little mention, though! :)
>
> The code can also be found at: http://pastebin.com/HFJdQ67H
>
> I have also extended the "mode" keyword slightly, and have removed the
> "econ" keyword, as it is deprecated anyway (assuming that I have the
> very latest release on my own machine, which is not all that
> likely...).
>
> ########################################################
> import cvxopt
> from cvxopt import lapack
>
> def qr(a, overwrite_a=0, lwork=None, mode='qr'):
> """Compute QR decomposition of a matrix.
>
> Calculate the decomposition :lm:`A = Q R` where Q is unitary/
> orthogonal
> and R upper triangular.
>
> Parameters
> ----------
> a : array, shape (M, N)
> Matrix to be decomposed
> overwrite_a : boolean
> Whether data in a is overwritten (may improve performance)
> lwork : integer
> Work array size, lwork >= a.shape[1]. If None or -1, an
> optimal size
> is computed.
> mode : {'qr', 'r', 'qrp'}
> Determines what information is to be returned: either both Q
> and R
> or only R, or Q and R and P, a permutation matrix. Any of
> these can
> be combined with 'economic' using the '+' sign as a separator.
> Economic mode means the following:
> Compute the economy-size QR decomposition, making shapes
> of Q and R (M, K) and (K, N) instead of (M,M) and (M,N).
> K=min(M,N).
>
> Returns
> -------
> (if mode == 'qr')
> Q : double or complex array, shape (M, M) or (M, K) for econ==True
>
> (for any mode)
> R : double or complex array, shape (M, N) or (K, N) for econ==True
> Size K = min(M, N)
>
> Raises LinAlgError if decomposition fails
>
> Notes
> -----
> This is an interface to the LAPACK routines dgeqrf, zgeqrf,
> dorgqr, and zungqr.
>
> Examples
> --------
> >>> from scipy import random, linalg, dot
> >>> a = random.randn(9, 6)
> >>> q, r = linalg.qr(a)
> >>> allclose(a, dot(q, r))
> True
> >>> q.shape, r.shape
> ((9, 9), (9, 6))
>
> >>> r2 = linalg.qr(a, mode='r')
> >>> allclose(r, r2)
>
> >>> q3, r3 = linalg.qr(a, econ=True)
> >>> q3.shape, r3.shape
> ((9, 6), (6, 6))
>
> """
> mode = mode.split("+")
> if "economic" in mode:
> econ = True
> else:
> econ = False
>
> a1 = asarray_chkfinite(a)
> if len(a1.shape) != 2:
> raise ValueError("expected 2D array")
> M, N = a1.shape
> overwrite_a = overwrite_a or (_datanotshared(a1,a))
>
> if 'qrp' in mode:
> qr = cvxopt.matrix(np.asarray(a1, dtype = float))
>
> tau = cvxopt.matrix(np.zeros(min(M, N), dtype = float))
> jpvt = cvxopt.matrix(np.zeros(N, dtype = int))
>
> lapack.geqp3(qr, jpvt, tau)
>
> qr = np.asarray(qr)
> tau = np.asarray(tau)
> jpvt = (np.asarray(jpvt) - 1).flatten()
> else:
> geqrf, = get_lapack_funcs(('geqrf',),(a1,))
> if lwork is None or lwork == -1:
> # get optimal work array
> qr,tau,work,info = geqrf(a1,lwork=-1,overwrite_a=1)
> lwork = work[0]
>
> qr,tau,work,info =
> geqrf(a1,lwork=lwork,overwrite_a=overwrite_a)
> if info<0:
> raise ValueError("illegal value in %-th argument of
> internal geqrf"
> % -info)
>
> if not econ or M<N:
> R = basic.triu(qr)
> else:
> R = basic.triu(qr[0:N,0:N])
>
> if 'r' in mode:
> return R
>
> if find_best_lapack_type((a1,))[0]=='s' or
> find_best_lapack_type((a1,))[0]=='d':
> gor_un_gqr, = get_lapack_funcs(('orgqr',),(qr,))
> else:
> gor_un_gqr, = get_lapack_funcs(('ungqr',),(qr,))
>
> if M<N:
> # get optimal work array
> Q,work,info = gor_un_gqr(qr[:,0:M],tau,lwork=-1,overwrite_a=1)
> lwork = work[0]
> Q,work,info = gor_un_gqr(qr[:,
> 0:M],tau,lwork=lwork,overwrite_a=1)
> elif econ:
> # get optimal work array
> Q,work,info = gor_un_gqr(qr,tau,lwork=-1,overwrite_a=1)
> lwork = work[0]
> Q,work,info = gor_un_gqr(qr,tau,lwork=lwork,overwrite_a=1)
> else:
> t = qr.dtype.char
> qqr = numpy.empty((M,M),dtype=t)
> qqr[:,0:N]=qr
> # get optimal work array
> Q,work,info = gor_un_gqr(qqr,tau,lwork=-1,overwrite_a=1)
> lwork = work[0]
> Q,work,info = gor_un_gqr(qqr,tau,lwork=lwork,overwrite_a=1)
>
> if info < 0:
> raise ValueError("illegal value in %-th argument of internal
> gorgqr"
> % -info)
>
> if 'qrp' in mode:
> return Q, R, jpvt
>
> return Q, R
> ########################################################
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.scipy.org/pipermail/scipy-user/attachments/20110707/6c312502/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: qr.py
Type: application/octet-stream
Size: 4209 bytes
Desc: not available
URL: <http://mail.scipy.org/pipermail/scipy-user/attachments/20110707/6c312502/attachment.obj>
More information about the SciPy-User
mailing list