[Scipy-svn] r6319 - in trunk: doc/source scipy/linalg scipy/linalg/tests
scipy-svn at scipy.org
scipy-svn at scipy.org
Fri Apr 9 21:47:20 EDT 2010
Author: warren.weckesser
Date: 2010-04-09 20:47:20 -0500 (Fri, 09 Apr 2010)
New Revision: 6319
Added:
trunk/scipy/linalg/decomp_cholesky.py
trunk/scipy/linalg/decomp_lu.py
trunk/scipy/linalg/decomp_qr.py
trunk/scipy/linalg/decomp_schur.py
trunk/scipy/linalg/decomp_svd.py
Modified:
trunk/doc/source/linalg.rst
trunk/scipy/linalg/__init__.py
trunk/scipy/linalg/basic.py
trunk/scipy/linalg/decomp.py
trunk/scipy/linalg/generic_flapack.pyf
trunk/scipy/linalg/info.py
trunk/scipy/linalg/matfuncs.py
trunk/scipy/linalg/misc.py
trunk/scipy/linalg/tests/test_basic.py
trunk/scipy/linalg/tests/test_decomp.py
Log:
linalg:
REF: Split basic.py and decomp.py into multiple modules.
Removed duplicated versions of the functions cho_solve and lu_solve.
Return value of solveh_banded no longer includes the Choleskey factor
(ticket #676).
ENH: Added cho_solve_banded.
STY: Clean up python style in many places.
Modified: trunk/doc/source/linalg.rst
===================================================================
--- trunk/doc/source/linalg.rst 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/doc/source/linalg.rst 2010-04-10 01:47:20 UTC (rev 6319)
@@ -20,8 +20,8 @@
pinv
pinv2
-Eigenvalues and Decompositions
-==============================
+Eigenvalue Problem
+==================
.. autosummary::
:toctree: generated/
@@ -32,6 +32,13 @@
eigvalsh
eig_banded
eigvals_banded
+
+Decompositions
+==============
+
+.. autosummary::
+ :toctree: generated/
+
lu
lu_factor
lu_solve
@@ -43,6 +50,7 @@
cholesky_banded
cho_factor
cho_solve
+ cho_solve_banded
qr
schur
rsf2csf
Modified: trunk/scipy/linalg/__init__.py
===================================================================
--- trunk/scipy/linalg/__init__.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/__init__.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -5,12 +5,19 @@
from info import __doc__
from linalg_version import linalg_version as __version__
+from misc import *
from basic import *
from decomp import *
+from decomp_lu import *
+from decomp_cholesky import *
+from decomp_qr import *
+from decomp_svd import *
+from decomp_schur import *
from matfuncs import *
from blas import *
+from special_matrices import *
-__all__ = filter(lambda s:not s.startswith('_'),dir())
+__all__ = filter(lambda s: not s.startswith('_'), dir())
from numpy.dual import register_func
for k in ['norm', 'inv', 'svd', 'solve', 'det', 'eig', 'eigh', 'eigvals',
Modified: trunk/scipy/linalg/basic.py
===================================================================
--- trunk/scipy/linalg/basic.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/basic.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -1,108 +1,22 @@
-## Automatically adapted for scipy Oct 18, 2005 by
-
-## Automatically adapted for scipy Oct 18, 2005 by
-
#
# Author: Pearu Peterson, March 2002
#
# w/ additions by Travis Oliphant, March 2002
-__all__ = ['solve', 'inv', 'det', 'lstsq', 'pinv', 'pinv2',
- 'cholesky_banded', 'solveh_banded', 'lu_solve', 'cho_solve',
- 'solve_banded',
- # From special_matrices:
- 'tri','tril', 'triu', 'toeplitz', 'circulant', 'hankel', 'kron',
- 'hadamard', 'block_diag', 'all_mat',
- # From misc:
- 'LinAlgError', 'norm',
- ]
+__all__ = ['solve', 'solveh_banded', 'solve_banded',
+ 'inv', 'det', 'lstsq', 'pinv', 'pinv2']
from numpy import asarray, zeros, sum, conjugate, dot, transpose, \
asarray_chkfinite, single
import numpy
-#from blas import get_blas_funcs
from flinalg import get_flinalg_funcs
from lapack import get_lapack_funcs
-from misc import LinAlgError, norm
-from special_matrices import tri, tril, triu, toeplitz, circulant, hankel, \
- hadamard, kron, block_diag, all_mat
+from misc import LinAlgError
from scipy.linalg import calc_lwork
-import decomp
+import decomp_svd
-def lu_solve((lu, piv), b, trans=0, overwrite_b=False):
- """Solve an equation system, a x = b, given the LU factorization of a
-
- Parameters
- ----------
- (lu, piv)
- Factorization of the coefficient matrix a, as given by lu_factor
- b : array
- Right-hand side
- trans : {0, 1, 2}
- Type of system to solve:
-
- ===== =========
- trans system
- ===== =========
- 0 a x = b
- 1 a^T x = b
- 2 a^H x = b
- ===== =========
-
- Returns
- -------
- x : array
- Solution to the system
-
- See also
- --------
- lu_factor : LU factorize a matrix
-
- """
- b1 = asarray_chkfinite(b)
- overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__'))
- if lu.shape[0] != b1.shape[0]:
- raise ValueError, "incompatible dimensions."
- getrs, = get_lapack_funcs(('getrs',),(lu,b1))
- x,info = getrs(lu,piv,b1,trans=trans,overwrite_b=overwrite_b)
- if info==0:
- return x
- raise ValueError(
- 'illegal value in %d-th argument of internal gesv|posv' % (-info))
-
-def cho_solve((c, lower), b, overwrite_b=False):
- """Solve an equation system, a x = b, given the Cholesky factorization of a
-
- Parameters
- ----------
- (c, lower)
- Cholesky factorization of a, as given by cho_factor
- b : array
- Right-hand side
-
- Returns
- -------
- x : array
- The solution to the system a x = b
-
- See also
- --------
- cho_factor : Cholesky factorization of a matrix
-
- """
- b1 = asarray_chkfinite(b)
- overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__'))
- if c.shape[0] != b1.shape[0]:
- raise ValueError, "incompatible dimensions."
- potrs, = get_lapack_funcs(('potrs',),(c,b1))
- x,info = potrs(c,b1,lower=lower,overwrite_b=overwrite_b)
- if info==0:
- return x
- raise ValueError(
- 'illegal value in %d-th argument of internal gesv|posv' % (-info))
-
# Linear equations
def solve(a, b, sym_pos=False, lower=False, overwrite_a=False, overwrite_b=False,
debug=False):
@@ -141,25 +55,23 @@
print 'solve:overwrite_a=',overwrite_a
print 'solve:overwrite_b=',overwrite_b
if sym_pos:
- posv, = get_lapack_funcs(('posv',),(a1,b1))
- c,x,info = posv(a1,b1,
- lower = lower,
+ posv, = get_lapack_funcs(('posv',), (a1,b1))
+ c, x, info = posv(a1, b1, lower=lower,
overwrite_a=overwrite_a,
overwrite_b=overwrite_b)
else:
- gesv, = get_lapack_funcs(('gesv',),(a1,b1))
- lu,piv,x,info = gesv(a1,b1,
- overwrite_a=overwrite_a,
- overwrite_b=overwrite_b)
+ gesv, = get_lapack_funcs(('gesv',), (a1,b1))
+ lu, piv, x, info = gesv(a1, b1, overwrite_a=overwrite_a,
+ overwrite_b=overwrite_b)
- if info==0:
+ if info == 0:
return x
- if info>0:
- raise LinAlgError, "singular matrix"
- raise ValueError(
- 'illegal value in %d-th argument of internal gesv|posv' % (-info))
+ if info > 0:
+ raise LinAlgError("singular matrix")
+ raise ValueError('illegal value in %d-th argument of internal gesv|posv'
+ % -info)
-def solve_banded((l,u), ab, b, overwrite_ab=False, overwrite_b=False,
+def solve_banded((l, u), ab, b, overwrite_ab=False, overwrite_b=False,
debug=False):
"""Solve the equation a x = b for x, assuming a is banded matrix.
@@ -193,32 +105,29 @@
The solution to the system a x = b
"""
- a1, b1 = map(asarray_chkfinite,(ab,b))
+ a1, b1 = map(asarray_chkfinite, (ab, b))
# Validate shapes.
if a1.shape[-1] != b1.shape[0]:
raise ValueError("shapes of ab and b are not compatible.")
- if l+u+1 != a1.shape[0]:
+ if l + u + 1 != a1.shape[0]:
raise ValueError("invalid values for the number of lower and upper diagonals:"
" l+u+1 (%d) does not equal ab.shape[0] (%d)" % (l+u+1, ab.shape[0]))
overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__'))
- gbsv, = get_lapack_funcs(('gbsv',),(a1,b1))
- a2 = zeros((2*l+u+1,a1.shape[1]), dtype=gbsv.dtype)
+ gbsv, = get_lapack_funcs(('gbsv',), (a1, b1))
+ a2 = zeros((2*l+u+1, a1.shape[1]), dtype=gbsv.dtype)
a2[l:,:] = a1
- lu,piv,x,info = gbsv(l,u,a2,b1,
- overwrite_ab=1,
- overwrite_b=overwrite_b)
- if info==0:
+ lu, piv, x, info = gbsv(l, u, a2, b1, overwrite_ab=True,
+ overwrite_b=overwrite_b)
+ if info == 0:
return x
- if info>0:
- raise LinAlgError, "singular matrix"
- raise ValueError(
- 'illegal value in %d-th argument of internal gbsv' % (-info))
+ if info > 0:
+ raise LinAlgError("singular matrix")
+ raise ValueError('illegal value in %d-th argument of internal gbsv' % -info)
-def solveh_banded(ab, b, overwrite_ab=False, overwrite_b=False,
- lower=False):
+def solveh_banded(ab, b, overwrite_ab=False, overwrite_b=False, lower=False):
"""Solve equation a x = b. a is Hermitian positive-definite banded matrix.
The matrix a is stored in ab either in lower diagonal or upper
@@ -256,81 +165,27 @@
Returns
-------
- c : array, shape (M, u+1)
- Cholesky factorization of a, in the same banded format as ab
x : array, shape (M,) or (M, K)
The solution to the system a x = b
"""
- ab, b = map(asarray_chkfinite,(ab,b))
+ ab, b = map(asarray_chkfinite, (ab, b))
# Validate shapes.
if ab.shape[-1] != b.shape[0]:
raise ValueError("shapes of ab and b are not compatible.")
- pbsv, = get_lapack_funcs(('pbsv',),(ab,b))
- c,x,info = pbsv(ab,b,
- lower=lower,
- overwrite_ab=overwrite_ab,
- overwrite_b=overwrite_b)
- if info==0:
- return c, x
- if info>0:
- raise LinAlgError, "%d-th leading minor not positive definite" % info
- raise ValueError(
- 'illegal value in %d-th argument of internal pbsv' % (-info))
+ pbsv, = get_lapack_funcs(('pbsv',), (ab, b))
+ c, x, info = pbsv(ab, b, lower=lower, overwrite_ab=overwrite_ab,
+ overwrite_b=overwrite_b)
+ if info > 0:
+ raise LinAlgError("%d-th leading minor not positive definite" % info)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal pbsv'
+ % -info)
+ return x
-def cholesky_banded(ab, overwrite_ab=False, lower=False):
- """Cholesky decompose a banded Hermitian positive-definite matrix
- The matrix a is stored in ab either in lower diagonal or upper
- diagonal ordered form:
-
- ab[u + i - j, j] == a[i,j] (if upper form; i <= j)
- ab[ i - j, j] == a[i,j] (if lower form; i >= j)
-
- Example of ab (shape of a is (6,6), u=2)::
-
- upper form:
- * * a02 a13 a24 a35
- * a01 a12 a23 a34 a45
- a00 a11 a22 a33 a44 a55
-
- lower form:
- a00 a11 a22 a33 a44 a55
- a10 a21 a32 a43 a54 *
- a20 a31 a42 a53 * *
-
- Parameters
- ----------
- ab : array, shape (u + 1, M)
- Banded matrix
- overwrite_ab : boolean
- Discard data in ab (may enhance performance)
- lower : boolean
- Is the matrix in the lower form. (Default is upper form)
-
- Returns
- -------
- c : array, shape (u+1, M)
- Cholesky factorization of a, in the same banded format as ab
-
- """
- ab = asarray_chkfinite(ab)
-
- pbtrf, = get_lapack_funcs(('pbtrf',),(ab,))
- c,info = pbtrf(ab,
- lower=lower,
- overwrite_ab=overwrite_ab)
-
- if info==0:
- return c
- if info>0:
- raise LinAlgError, "%d-th leading minor not positive definite" % info
- raise ValueError(
- 'illegal value in %d-th argument of internal pbtrf' % (-info))
-
-
# matrix inversion
def inv(a, overwrite_a=False):
"""Compute the inverse of a matrix.
@@ -360,7 +215,7 @@
"""
a1 = asarray_chkfinite(a)
if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
- raise ValueError, 'expected square matrix'
+ raise ValueError('expected square matrix')
overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__'))
#XXX: I found no advantage or disadvantage of using finv.
## finv, = get_flinalg_funcs(('inv',),(a1,))
@@ -371,21 +226,21 @@
## if info>0: raise LinAlgError, "singular matrix"
## if info<0: raise ValueError,\
## 'illegal value in %d-th argument of internal inv.getrf|getri'%(-info)
- getrf,getri = get_lapack_funcs(('getrf','getri'),(a1,))
+ getrf, getri = get_lapack_funcs(('getrf','getri'), (a1,))
#XXX: C ATLAS versions of getrf/i have rowmajor=1, this could be
# exploited for further optimization. But it will be probably
# a mess. So, a good testing site is required before trying
# to do that.
- if getrf.module_name[:7]=='clapack'!=getri.module_name[:7]:
+ if getrf.module_name[:7] == 'clapack' != getri.module_name[:7]:
# ATLAS 3.2.1 has getrf but not getri.
- lu,piv,info = getrf(transpose(a1),
- rowmajor=0,overwrite_a=overwrite_a)
+ lu, piv, info = getrf(transpose(a1), rowmajor=0,
+ overwrite_a=overwrite_a)
lu = transpose(lu)
else:
- lu,piv,info = getrf(a1,overwrite_a=overwrite_a)
- if info==0:
+ lu, piv, info = getrf(a1, overwrite_a=overwrite_a)
+ if info == 0:
if getri.module_name[:7] == 'flapack':
- lwork = calc_lwork.getri(getri.prefix,a1.shape[0])
+ lwork = calc_lwork.getri(getri.prefix, a1.shape[0])
lwork = lwork[1]
# XXX: the following line fixes curious SEGFAULT when
# benchmarking 500x500 matrix inverse. This seems to
@@ -393,14 +248,15 @@
# minimal (when using lwork[0] instead of lwork[1]) then
# all tests pass. Further investigation is required if
# more such SEGFAULTs occur.
- lwork = int(1.01*lwork)
- inv_a,info = getri(lu,piv,
- lwork=lwork,overwrite_lu=1)
+ lwork = int(1.01 * lwork)
+ inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1)
else: # clapack
- inv_a,info = getri(lu,piv,overwrite_lu=1)
- if info>0: raise LinAlgError, "singular matrix"
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal getrf|getri' % (-info))
+ inv_a, info = getri(lu, piv, overwrite_lu=1)
+ if info > 0:
+ raise LinAlgError("singular matrix")
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal '
+ 'getrf|getri' % -info)
return inv_a
@@ -424,12 +280,13 @@
"""
a1 = asarray_chkfinite(a)
if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
- raise ValueError, 'expected square matrix'
+ raise ValueError('expected square matrix')
overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__'))
- fdet, = get_flinalg_funcs(('det',),(a1,))
- a_det,info = fdet(a1,overwrite_a=overwrite_a)
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal det.getrf' % (-info))
+ fdet, = get_flinalg_funcs(('det',), (a1,))
+ a_det, info = fdet(a1, overwrite_a=overwrite_a)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal '
+ 'det.getrf' % -info)
return a_det
### Linear Least Squares
@@ -468,41 +325,47 @@
Raises LinAlgError if computation does not converge
"""
- a1, b1 = map(asarray_chkfinite,(a,b))
+ a1, b1 = map(asarray_chkfinite, (a, b))
if len(a1.shape) != 2:
raise ValueError, 'expected matrix'
- m,n = a1.shape
- if len(b1.shape)==2: nrhs = b1.shape[1]
- else: nrhs = 1
+ m, n = a1.shape
+ if len(b1.shape) == 2:
+ nrhs = b1.shape[1]
+ else:
+ nrhs = 1
if m != b1.shape[0]:
- raise ValueError, 'incompatible dimensions'
- gelss, = get_lapack_funcs(('gelss',),(a1,b1))
- if n>m:
+ raise ValueError('incompatible dimensions')
+ gelss, = get_lapack_funcs(('gelss',), (a1, b1))
+ if n > m:
# need to extend b matrix as it will be filled with
# a larger solution matrix
- b2 = zeros((n,nrhs), dtype=gelss.dtype)
- if len(b1.shape)==2: b2[:m,:] = b1
- else: b2[:m,0] = b1
+ b2 = zeros((n, nrhs), dtype=gelss.dtype)
+ if len(b1.shape) == 2:
+ b2[:m,:] = b1
+ else:
+ b2[:m,0] = b1
b1 = b2
overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__'))
overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__'))
if gelss.module_name[:7] == 'flapack':
- lwork = calc_lwork.gelss(gelss.prefix,m,n,nrhs)[1]
- v,x,s,rank,info = gelss(a1,b1,cond = cond,
- lwork = lwork,
- overwrite_a = overwrite_a,
- overwrite_b = overwrite_b)
+ lwork = calc_lwork.gelss(gelss.prefix, m, n, nrhs)[1]
+ v, x, s, rank, info = gelss(a1, b1, cond=cond, lwork=lwork,
+ overwrite_a=overwrite_a,
+ overwrite_b=overwrite_b)
else:
- raise NotImplementedError,'calling gelss from %s' % (gelss.module_name)
- if info>0: raise LinAlgError, "SVD did not converge in Linear Least Squares"
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal gelss' % (-info))
+ raise NotImplementedError('calling gelss from %s' % gelss.module_name)
+ if info > 0:
+ raise LinAlgError("SVD did not converge in Linear Least Squares")
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal gelss'
+ % -info)
resids = asarray([], dtype=x.dtype)
- if n<m:
+ if n < m:
x1 = x[:n]
- if rank==n: resids = sum(x[n:]**2,axis=0)
+ if rank == n:
+ resids = sum(x[n:]**2, axis=0)
x = x1
- return x,resids,rank,s
+ return x, resids, rank, s
def pinv(a, cond=None, rcond=None):
@@ -544,11 +407,6 @@
return lstsq(a, b, cond=cond)[0]
-eps = numpy.finfo(float).eps
-feps = numpy.finfo(single).eps
-
-_array_precision = {'f': 0, 'd': 1, 'F': 0, 'D': 1}
-
def pinv2(a, cond=None, rcond=None):
"""Compute the (Moore-Penrose) pseudo-inverse of a matrix.
@@ -585,15 +443,18 @@
"""
a = asarray_chkfinite(a)
- u, s, vh = decomp.svd(a)
+ u, s, vh = decomp_svd.svd(a)
t = u.dtype.char
if rcond is not None:
cond = rcond
if cond in [None,-1]:
+ eps = numpy.finfo(float).eps
+ feps = numpy.finfo(single).eps
+ _array_precision = {'f': 0, 'd': 1, 'F': 0, 'D': 1}
cond = {0: feps*1e3, 1: eps*1e6}[_array_precision[t]]
- m,n = a.shape
+ m, n = a.shape
cutoff = cond*numpy.maximum.reduce(s)
- psigma = zeros((m,n),t)
+ psigma = zeros((m, n), t)
for i in range(len(s)):
if s[i] > cutoff:
psigma[i,i] = 1.0/conjugate(s[i])
Modified: trunk/scipy/linalg/decomp.py
===================================================================
--- trunk/scipy/linalg/decomp.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/decomp.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -1,5 +1,3 @@
-## Automatically adapted for scipy Oct 18, 2005 by
-
#
# Author: Pearu Peterson, March 2002
#
@@ -9,83 +7,70 @@
# additions by Bart Vandereycken, June 2006
# additions by Andrew D Straw, May 2007
# additions by Tiziano Zito, November 2008
-
+#
+# April 2010: Functions for LU, QR, SVD, Schur and Cholesky decompositions were
+# moved to their own files. Still in this file are functions for eigenstuff
+# and for the Hessenberg form.
+
__all__ = ['eig','eigh','eig_banded','eigvals','eigvalsh', 'eigvals_banded',
- 'lu','svd','svdvals','diagsvd','cholesky','qr','qr_old','rq',
- 'schur','rsf2csf','lu_factor','cho_factor','cho_solve','orth',
'hessenberg']
-from misc import LinAlgError
-import misc
-import special_matrices
-
-from warnings import warn
-from lapack import get_lapack_funcs, find_best_lapack_type
-from blas import get_blas_funcs
-from flinalg import get_flinalg_funcs
-from scipy.linalg import calc_lwork
import numpy
from numpy import array, asarray_chkfinite, asarray, diag, zeros, ones, \
- single, isfinite, inexact, complexfloating, nonzero, iscomplexobj
+ isfinite, inexact, nonzero, iscomplexobj, cast
-cast = numpy.cast
-r_ = numpy.r_
+# Local imports
+from scipy.linalg import calc_lwork
+from misc import LinAlgError, _datanotshared
+from lapack import get_lapack_funcs
+from blas import get_blas_funcs
+
_I = cast['F'](1j)
-def _make_complex_eigvecs(w,vin,cmplx_tcode):
- v = numpy.array(vin,dtype=cmplx_tcode)
+
+def _make_complex_eigvecs(w, vin, cmplx_tcode):
+ v = numpy.array(vin, dtype=cmplx_tcode)
#ind = numpy.flatnonzero(numpy.not_equal(w.imag,0.0))
- ind = numpy.flatnonzero(numpy.logical_and(numpy.not_equal(w.imag,0.0),
+ ind = numpy.flatnonzero(numpy.logical_and(numpy.not_equal(w.imag, 0.0),
numpy.isfinite(w)))
- vnew = numpy.zeros((v.shape[0],len(ind)>>1),cmplx_tcode)
- vnew.real = numpy.take(vin,ind[::2],1)
- vnew.imag = numpy.take(vin,ind[1::2],1)
+ vnew = numpy.zeros((v.shape[0], len(ind)>>1), cmplx_tcode)
+ vnew.real = numpy.take(vin, ind[::2],1)
+ vnew.imag = numpy.take(vin, ind[1::2],1)
count = 0
conj = numpy.conjugate
for i in range(len(ind)/2):
- v[:,ind[2*i]] = vnew[:,count]
- v[:,ind[2*i+1]] = conj(vnew[:,count])
+ v[:, ind[2*i]] = vnew[:, count]
+ v[:, ind[2*i+1]] = conj(vnew[:, count])
count += 1
return v
-
-
-def _datanotshared(a1,a):
- if a1 is a:
- return False
- else:
- #try comparing data pointers
- try:
- return a1.__array_interface__['data'][0] != a.__array_interface__['data'][0]
- except:
- return True
-
-
-def _geneig(a1,b,left,right,overwrite_a,overwrite_b):
+def _geneig(a1, b, left, right, overwrite_a, overwrite_b):
b1 = asarray(b)
- overwrite_b = overwrite_b or _datanotshared(b1,b)
+ overwrite_b = overwrite_b or _datanotshared(b1, b)
if len(b1.shape) != 2 or b1.shape[0] != b1.shape[1]:
- raise ValueError, 'expected square matrix'
- ggev, = get_lapack_funcs(('ggev',),(a1,b1))
- cvl,cvr = left,right
+ raise ValueError('expected square matrix')
+ ggev, = get_lapack_funcs(('ggev',), (a1, b1))
+ cvl, cvr = left, right
if ggev.module_name[:7] == 'clapack':
- raise NotImplementedError,'calling ggev from %s' % (ggev.module_name)
- res = ggev(a1,b1,lwork=-1)
+ raise NotImplementedError('calling ggev from %s' % ggev.module_name)
+ res = ggev(a1, b1, lwork=-1)
lwork = res[-2][0]
if ggev.prefix in 'cz':
- alpha,beta,vl,vr,work,info = ggev(a1,b1,cvl,cvr,lwork,
- overwrite_a,overwrite_b)
+ alpha, beta, vl, vr, work, info = ggev(a1, b1, cvl, cvr, lwork,
+ overwrite_a, overwrite_b)
w = alpha / beta
else:
- alphar,alphai,beta,vl,vr,work,info = ggev(a1,b1,cvl,cvr,lwork,
- overwrite_a,overwrite_b)
- w = (alphar+_I*alphai)/beta
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal ggev' % (-info))
- if info>0: raise LinAlgError(
- "generalized eig algorithm did not converge (info=%d)" % (info))
+ alphar, alphai, beta, vl, vr, work, info = ggev(a1, b1, cvl, cvr, lwork,
+ overwrite_a,overwrite_b)
+ w = (alphar + _I * alphai) / beta
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal ggev'
+ % -info)
+ if info > 0:
+ raise LinAlgError("generalized eig algorithm did not converge (info=%d)"
+ % info)
- only_real = numpy.logical_and.reduce(numpy.equal(w.imag,0.0))
+ only_real = numpy.logical_and.reduce(numpy.equal(w.imag, 0.0))
if not (ggev.prefix in 'cz' or only_real):
t = w.dtype.char
if left:
@@ -100,7 +85,7 @@
return w, vl
return w, vr
-def eig(a,b=None, left=False, right=True, overwrite_a=False, overwrite_b=False):
+def eig(a, b=None, left=False, right=True, overwrite_a=False, overwrite_b=False):
"""Solve an ordinary or generalized eigenvalue problem of a square matrix.
Find eigenvalues w and right or left eigenvectors of a general matrix::
@@ -153,49 +138,50 @@
a1 = asarray_chkfinite(a)
if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
raise ValueError('expected square matrix')
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
if b is not None:
b = asarray_chkfinite(b)
if b.shape != a1.shape:
raise ValueError('a and b must have the same shape')
- return _geneig(a1,b,left,right,overwrite_a,overwrite_b)
- geev, = get_lapack_funcs(('geev',),(a1,))
- compute_vl,compute_vr=left,right
+ return _geneig(a1, b, left, right, overwrite_a, overwrite_b)
+ geev, = get_lapack_funcs(('geev',), (a1,))
+ compute_vl, compute_vr = left, right
if geev.module_name[:7] == 'flapack':
- lwork = calc_lwork.geev(geev.prefix,a1.shape[0],
- compute_vl,compute_vr)[1]
+ lwork = calc_lwork.geev(geev.prefix, a1.shape[0],
+ compute_vl, compute_vr)[1]
if geev.prefix in 'cz':
- w,vl,vr,info = geev(a1,lwork = lwork,
- compute_vl=compute_vl,
- compute_vr=compute_vr,
- overwrite_a=overwrite_a)
+ w, vl, vr, info = geev(a1, lwork=lwork,
+ compute_vl=compute_vl,
+ compute_vr=compute_vr,
+ overwrite_a=overwrite_a)
else:
- wr,wi,vl,vr,info = geev(a1,lwork = lwork,
- compute_vl=compute_vl,
- compute_vr=compute_vr,
- overwrite_a=overwrite_a)
+ wr, wi, vl, vr, info = geev(a1, lwork=lwork,
+ compute_vl=compute_vl,
+ compute_vr=compute_vr,
+ overwrite_a=overwrite_a)
t = {'f':'F','d':'D'}[wr.dtype.char]
- w = wr+_I*wi
+ w = wr + _I * wi
else: # 'clapack'
if geev.prefix in 'cz':
- w,vl,vr,info = geev(a1,
- compute_vl=compute_vl,
- compute_vr=compute_vr,
- overwrite_a=overwrite_a)
- else:
- wr,wi,vl,vr,info = geev(a1,
+ w, vl, vr, info = geev(a1,
compute_vl=compute_vl,
compute_vr=compute_vr,
overwrite_a=overwrite_a)
+ else:
+ wr, wi, vl, vr, info = geev(a1,
+ compute_vl=compute_vl,
+ compute_vr=compute_vr,
+ overwrite_a=overwrite_a)
t = {'f':'F','d':'D'}[wr.dtype.char]
- w = wr+_I*wi
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal geev' % (-info))
- if info>0: raise LinAlgError(
- "eig algorithm did not converge (only eigenvalues "\
- "with order >=%d have converged)" % (info))
+ w = wr + _I * wi
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal geev'
+ % -info)
+ if info > 0:
+ raise LinAlgError("eig algorithm did not converge (only eigenvalues "
+ "with order >= %d have converged)" % info)
- only_real = numpy.logical_and.reduce(numpy.equal(w.imag,0.0))
+ only_real = numpy.logical_and.reduce(numpy.equal(w.imag, 0.0))
if not (geev.prefix in 'cz' or only_real):
t = w.dtype.char
if left:
@@ -281,17 +267,17 @@
"""
a1 = asarray_chkfinite(a)
if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
- raise ValueError, 'expected square matrix'
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
+ raise ValueError('expected square matrix')
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
if iscomplexobj(a1):
cplx = True
else:
cplx = False
if b is not None:
b1 = asarray_chkfinite(b)
- overwrite_b = overwrite_b or _datanotshared(b1,b)
+ overwrite_b = overwrite_b or _datanotshared(b1, b)
if len(b1.shape) != 2 or b1.shape[0] != b1.shape[1]:
- raise ValueError, 'expected square matrix'
+ raise ValueError('expected square matrix')
if b1.shape != a1.shape:
raise ValueError("wrong b dimensions %s, should "
@@ -401,7 +387,7 @@
def eig_banded(a_band, lower=False, eigvals_only=False, overwrite_a_band=False,
select='a', select_range=None, max_ev = 0):
- """Solve real symmetric or complex hermetian band matrix eigenvalue problem.
+ """Solve real symmetric or complex hermitian band matrix eigenvalue problem.
Find eigenvalues w and optionally right eigenvectors v of a::
@@ -472,34 +458,34 @@
"""
if eigvals_only or overwrite_a_band:
a1 = asarray_chkfinite(a_band)
- overwrite_a_band = overwrite_a_band or (_datanotshared(a1,a_band))
+ overwrite_a_band = overwrite_a_band or (_datanotshared(a1, a_band))
else:
a1 = array(a_band)
if issubclass(a1.dtype.type, inexact) and not isfinite(a1).all():
- raise ValueError, "array must not contain infs or NaNs"
+ raise ValueError("array must not contain infs or NaNs")
overwrite_a_band = 1
if len(a1.shape) != 2:
- raise ValueError, 'expected two-dimensional array'
+ raise ValueError('expected two-dimensional array')
if select.lower() not in [0, 1, 2, 'a', 'v', 'i', 'all', 'value', 'index']:
- raise ValueError, 'invalid argument for select'
+ raise ValueError('invalid argument for select')
if select.lower() in [0, 'a', 'all']:
if a1.dtype.char in 'GFD':
- bevd, = get_lapack_funcs(('hbevd',),(a1,))
+ bevd, = get_lapack_funcs(('hbevd',), (a1,))
# FIXME: implement this somewhen, for now go with builtin values
# FIXME: calc optimal lwork by calling ?hbevd(lwork=-1)
# or by using calc_lwork.f ???
# lwork = calc_lwork.hbevd(bevd.prefix, a1.shape[0], lower)
internal_name = 'hbevd'
else: # a1.dtype.char in 'fd':
- bevd, = get_lapack_funcs(('sbevd',),(a1,))
+ bevd, = get_lapack_funcs(('sbevd',), (a1,))
# FIXME: implement this somewhen, for now go with builtin values
# see above
# lwork = calc_lwork.sbevd(bevd.prefix, a1.shape[0], lower)
internal_name = 'sbevd'
- w,v,info = bevd(a1, compute_v = not eigvals_only,
- lower = lower,
- overwrite_ab = overwrite_a_band)
+ w,v,info = bevd(a1, compute_v=not eigvals_only,
+ lower=lower,
+ overwrite_ab=overwrite_a_band)
if select.lower() in [1, 2, 'i', 'v', 'index', 'value']:
# calculate certain range only
if select.lower() in [2, 'i', 'index']:
@@ -517,31 +503,33 @@
max_ev = 1
# calculate optimal abstol for dsbevx (see manpage)
if a1.dtype.char in 'fF': # single precision
- lamch, = get_lapack_funcs(('lamch',),(array(0, dtype='f'),))
+ lamch, = get_lapack_funcs(('lamch',), (array(0, dtype='f'),))
else:
- lamch, = get_lapack_funcs(('lamch',),(array(0, dtype='d'),))
+ lamch, = get_lapack_funcs(('lamch',), (array(0, dtype='d'),))
abstol = 2 * lamch('s')
if a1.dtype.char in 'GFD':
- bevx, = get_lapack_funcs(('hbevx',),(a1,))
+ bevx, = get_lapack_funcs(('hbevx',), (a1,))
internal_name = 'hbevx'
else: # a1.dtype.char in 'gfd'
- bevx, = get_lapack_funcs(('sbevx',),(a1,))
+ bevx, = get_lapack_funcs(('sbevx',), (a1,))
internal_name = 'sbevx'
# il+1, iu+1: translate python indexing (0 ... N-1) into Fortran
# indexing (1 ... N)
w, v, m, ifail, info = bevx(a1, vl, vu, il+1, iu+1,
- compute_v = not eigvals_only,
- mmax = max_ev,
- range = select, lower = lower,
- overwrite_ab = overwrite_a_band,
+ compute_v=not eigvals_only,
+ mmax=max_ev,
+ range=select, lower=lower,
+ overwrite_ab=overwrite_a_band,
abstol=abstol)
# crop off w and v
w = w[:m]
if not eigvals_only:
v = v[:, :m]
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal %s'%(-info, internal_name))
- if info>0: raise LinAlgError,"eig algorithm did not converge"
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal %s'
+ % (-info, internal_name))
+ if info > 0:
+ raise LinAlgError("eig algorithm did not converge")
if eigvals_only:
return w
@@ -580,7 +568,7 @@
eigh : eigenvalues and eigenvectors of symmetric/Hermitean arrays.
"""
- return eig(a,b=b,left=0,right=0,overwrite_a=overwrite_a)
+ return eig(a, b=b, left=0, right=0, overwrite_a=overwrite_a)
def eigvalsh(a, b=None, lower=True, overwrite_a=False,
overwrite_b=False, turbo=True, eigvals=None, type=1):
@@ -710,837 +698,13 @@
eig : eigenvalues and right eigenvectors for non-symmetric arrays
"""
- return eig_banded(a_band,lower=lower,eigvals_only=1,
+ return eig_banded(a_band, lower=lower, eigvals_only=1,
overwrite_a_band=overwrite_a_band, select=select,
select_range=select_range)
-def lu_factor(a, overwrite_a=False):
- """Compute pivoted LU decomposition of a matrix.
-
- The decomposition is::
-
- A = P L U
-
- where P is a permutation matrix, L lower triangular with unit
- diagonal elements, and U upper triangular.
-
- Parameters
- ----------
- a : array, shape (M, M)
- Matrix to decompose
- overwrite_a : boolean
- Whether to overwrite data in A (may increase performance)
-
- Returns
- -------
- lu : array, shape (N, N)
- Matrix containing U in its upper triangle, and L in its lower triangle.
- The unit diagonal elements of L are not stored.
- piv : array, shape (N,)
- Pivot indices representing the permutation matrix P:
- row i of matrix was interchanged with row piv[i].
-
- See also
- --------
- lu_solve : solve an equation system using the LU factorization of a matrix
-
- Notes
- -----
- This is a wrapper to the *GETRF routines from LAPACK.
-
- """
- a1 = asarray(a)
- if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]):
- raise ValueError, 'expected square matrix'
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- getrf, = get_lapack_funcs(('getrf',),(a1,))
- lu, piv, info = getrf(a,overwrite_a=overwrite_a)
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal getrf (lu_factor)' % (-info))
- if info>0: warn("Diagonal number %d is exactly zero. Singular matrix." % info,
- RuntimeWarning)
- return lu, piv
-
-def lu_solve(a_lu_pivots, b):
- """Solve an equation system, a x = b, given the LU factorization of a
-
- Parameters
- ----------
- (lu, piv)
- Factorization of the coefficient matrix a, as given by lu_factor
- b : array
- Right-hand side
-
- Returns
- -------
- x : array
- Solution to the system
-
- See also
- --------
- lu_factor : LU factorize a matrix
-
- """
- a_lu, pivots = a_lu_pivots
- a_lu = asarray_chkfinite(a_lu)
- pivots = asarray_chkfinite(pivots)
- b = asarray_chkfinite(b)
- _assert_squareness(a_lu)
-
- getrs, = get_lapack_funcs(('getrs',),(a_lu,))
- b, info = getrs(a_lu,pivots,b)
- if info < 0:
- msg = "Argument %d to lapack's ?getrs() has an illegal value." % info
- raise TypeError, msg
- if info > 0:
- msg = "Unknown error occured int ?getrs(): error code = %d" % info
- raise TypeError, msg
- return b
-
-
-def lu(a, permute_l=False, overwrite_a=False):
- """Compute pivoted LU decompostion of a matrix.
-
- The decomposition is::
-
- A = P L U
-
- where P is a permutation matrix, L lower triangular with unit
- diagonal elements, and U upper triangular.
-
- Parameters
- ----------
- a : array, shape (M, N)
- Array to decompose
- permute_l : boolean
- Perform the multiplication P*L (Default: do not permute)
- overwrite_a : boolean
- Whether to overwrite data in a (may improve performance)
-
- Returns
- -------
- (If permute_l == False)
- p : array, shape (M, M)
- Permutation matrix
- l : array, shape (M, K)
- Lower triangular or trapezoidal matrix with unit diagonal.
- K = min(M, N)
- u : array, shape (K, N)
- Upper triangular or trapezoidal matrix
-
- (If permute_l == True)
- pl : array, shape (M, K)
- Permuted L matrix.
- K = min(M, N)
- u : array, shape (K, N)
- Upper triangular or trapezoidal matrix
-
- Notes
- -----
- This is a LU factorization routine written for Scipy.
-
- """
- a1 = asarray_chkfinite(a)
- if len(a1.shape) != 2:
- raise ValueError, 'expected matrix'
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- flu, = get_flinalg_funcs(('lu',),(a1,))
- p,l,u,info = flu(a1,permute_l=permute_l,overwrite_a = overwrite_a)
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal lu.getrf' % (-info))
- if permute_l:
- return l,u
- return p,l,u
-
-def svd(a, full_matrices=True, compute_uv=True, overwrite_a=False):
- """Singular Value Decomposition.
-
- Factorizes the matrix a into two unitary matrices U and Vh and
- an 1d-array s of singular values (real, non-negative) such that
- a == U S Vh if S is an suitably shaped matrix of zeros whose
- main diagonal is s.
-
- Parameters
- ----------
- a : array, shape (M, N)
- Matrix to decompose
- full_matrices : boolean
- If true, U, Vh are shaped (M,M), (N,N)
- If false, the shapes are (M,K), (K,N) where K = min(M,N)
- compute_uv : boolean
- Whether to compute also U, Vh in addition to s (Default: true)
- overwrite_a : boolean
- Whether data in a is overwritten (may improve performance)
-
- Returns
- -------
- U: array, shape (M,M) or (M,K) depending on full_matrices
- s: array, shape (K,)
- The singular values, sorted so that s[i] >= s[i+1]. K = min(M, N)
- Vh: array, shape (N,N) or (K,N) depending on full_matrices
-
- For compute_uv = False, only s is returned.
-
- Raises LinAlgError if SVD computation does not converge
-
- Examples
- --------
- >>> from scipy import random, linalg, allclose, dot
- >>> a = random.randn(9, 6) + 1j*random.randn(9, 6)
- >>> U, s, Vh = linalg.svd(a)
- >>> U.shape, Vh.shape, s.shape
- ((9, 9), (6, 6), (6,))
-
- >>> U, s, Vh = linalg.svd(a, full_matrices=False)
- >>> U.shape, Vh.shape, s.shape
- ((9, 6), (6, 6), (6,))
- >>> S = linalg.diagsvd(s, 6, 6)
- >>> allclose(a, dot(U, dot(S, Vh)))
- True
-
- >>> s2 = linalg.svd(a, compute_uv=False)
- >>> allclose(s, s2)
- True
-
- See also
- --------
- svdvals : return singular values of a matrix
- diagsvd : return the Sigma matrix, given the vector s
-
- """
- # A hack until full_matrices == 0 support is fixed here.
- if full_matrices == 0:
- import numpy.linalg
- return numpy.linalg.svd(a, full_matrices=0, compute_uv=compute_uv)
- a1 = asarray_chkfinite(a)
- if len(a1.shape) != 2:
- raise ValueError, 'expected matrix'
- m,n = a1.shape
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- gesdd, = get_lapack_funcs(('gesdd',),(a1,))
- if gesdd.module_name[:7] == 'flapack':
- lwork = calc_lwork.gesdd(gesdd.prefix,m,n,compute_uv)[1]
- u,s,v,info = gesdd(a1,compute_uv = compute_uv, lwork = lwork,
- overwrite_a = overwrite_a)
- else: # 'clapack'
- raise NotImplementedError,'calling gesdd from %s' % (gesdd.module_name)
- if info>0: raise LinAlgError, "SVD did not converge"
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal gesdd' % (-info))
- if compute_uv:
- return u,s,v
- else:
- return s
-
-def svdvals(a, overwrite_a=False):
- """Compute singular values of a matrix.
-
- Parameters
- ----------
- a : array, shape (M, N)
- Matrix to decompose
- overwrite_a : boolean
- Whether data in a is overwritten (may improve performance)
-
- Returns
- -------
- s: array, shape (K,)
- The singular values, sorted so that s[i] >= s[i+1]. K = min(M, N)
-
- Raises LinAlgError if SVD computation does not converge
-
- See also
- --------
- svd : return the full singular value decomposition of a matrix
- diagsvd : return the Sigma matrix, given the vector s
-
- """
- return svd(a,compute_uv=0,overwrite_a=overwrite_a)
-
-def diagsvd(s, M, N):
- """Construct the sigma matrix in SVD from singular values and size M,N.
-
- Parameters
- ----------
- s : array, shape (M,) or (N,)
- Singular values
- M : integer
- N : integer
- Size of the matrix whose singular values are s
-
- Returns
- -------
- S : array, shape (M, N)
- The S-matrix in the singular value decomposition
-
- """
- part = diag(s)
- typ = part.dtype.char
- MorN = len(s)
- if MorN == M:
- return r_['-1',part,zeros((M,N-M),typ)]
- elif MorN == N:
- return r_[part,zeros((M-N,N),typ)]
- else:
- raise ValueError, "Length of s must be M or N."
-
-def cholesky(a, lower=False, overwrite_a=False):
- """Compute the Cholesky decomposition of a matrix.
-
- Returns the Cholesky decomposition, :lm:`A = L L^*` or :lm:`A = U^* U`
- of a Hermitian positive-definite matrix :lm:`A`.
-
- Parameters
- ----------
- a : array, shape (M, M)
- Matrix to be decomposed
- lower : boolean
- Whether to compute the upper or lower triangular Cholesky factorization
- (Default: upper-triangular)
- overwrite_a : boolean
- Whether to overwrite data in a (may improve performance)
-
- Returns
- -------
- B : array, shape (M, M)
- Upper- or lower-triangular Cholesky factor of A
-
- Raises LinAlgError if decomposition fails
-
- Examples
- --------
- >>> from scipy import array, linalg, dot
- >>> a = array([[1,-2j],[2j,5]])
- >>> L = linalg.cholesky(a, lower=True)
- >>> L
- array([[ 1.+0.j, 0.+0.j],
- [ 0.+2.j, 1.+0.j]])
- >>> dot(L, L.T.conj())
- array([[ 1.+0.j, 0.-2.j],
- [ 0.+2.j, 5.+0.j]])
-
- """
- a1 = asarray_chkfinite(a)
- if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
- raise ValueError, 'expected square matrix'
- overwrite_a = overwrite_a or _datanotshared(a1,a)
- potrf, = get_lapack_funcs(('potrf',),(a1,))
- c,info = potrf(a1,lower=lower,overwrite_a=overwrite_a,clean=1)
- if info>0: raise LinAlgError(
- "matrix not positive definite (leading minor of order %d"\
- "is not positive definite)" % (info-1))
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal potrf' % (-info))
- return c
-
-def cho_factor(a, lower=False, overwrite_a=False):
- """Compute the Cholesky decomposition of a matrix, to use in cho_solve
-
- Returns a matrix containing the Cholesky decomposition,
- ``A = L L*`` or ``A = U* U`` of a Hermitian positive-definite matrix `a`.
- The return value can be directly used as the first parameter to cho_solve.
-
- .. warning::
- The returned matrix also contains random data in the entries not
- used by the Cholesky decomposition. If you need to zero these
- entries, use the function `cholesky` instead.
-
- Parameters
- ----------
- a : array, shape (M, M)
- Matrix to be decomposed
- lower : boolean
- Whether to compute the upper or lower triangular Cholesky factorization
- (Default: upper-triangular)
- overwrite_a : boolean
- Whether to overwrite data in a (may improve performance)
-
- Returns
- -------
- c : array, shape (M, M)
- Matrix whose upper or lower triangle contains the Cholesky factor
- of `a`. Other parts of the matrix contain random data.
- lower : boolean
- Flag indicating whether the factor is in the lower or upper triangle
-
- Raises
- ------
- LinAlgError
- Raised if decomposition fails.
-
- """
- a1 = asarray_chkfinite(a)
- if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
- raise ValueError, 'expected square matrix'
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- potrf, = get_lapack_funcs(('potrf',),(a1,))
- c,info = potrf(a1,lower=lower,overwrite_a=overwrite_a,clean=0)
- if info>0: raise LinAlgError(
- "matrix not positive definite (leading minor of order %d"\
- "is not positive definite)"%(info-1))
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal potrf' % (-info))
- return c, lower
-
-def cho_solve(clow, b):
- """Solve a previously factored symmetric system of equations.
-
- The equation system is
-
- A x = b, A = U^H U = L L^H
-
- and A is real symmetric or complex Hermitian.
-
- Parameters
- ----------
- clow : tuple (c, lower)
- Cholesky factor and a flag indicating whether it is lower triangular.
- The return value from cho_factor can be used.
- b : array
- Right-hand side of the equation system
-
- First input is a tuple (LorU, lower) which is the output to cho_factor.
- Second input is the right-hand side.
-
- Returns
- -------
- x : array
- Solution to the equation system
-
- """
- c, lower = clow
- c = asarray_chkfinite(c)
- _assert_squareness(c)
- b = asarray_chkfinite(b)
- potrs, = get_lapack_funcs(('potrs',),(c,))
- b, info = potrs(c,b,lower)
- if info < 0:
- msg = "Argument %d to lapack's ?potrs() has an illegal value." % info
- raise TypeError, msg
- if info > 0:
- msg = "Unknown error occured int ?potrs(): error code = %d" % info
- raise TypeError, msg
- return b
-
-def qr(a, overwrite_a=False, lwork=None, econ=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.
- econ : boolean
- Whether to 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).
- Default is False.
- mode : {'qr', 'r'}
- Determines what information is to be returned: either both Q and R
- or only R.
-
- 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))
-
- """
- if econ is None:
- econ = False
- else:
- warn("qr econ argument will be removed after scipy 0.7. "
- "The economy transform will then be available through "
- "the mode='economic' argument.", DeprecationWarning)
-
- 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))
-
- 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 %d-th argument of internal geqrf"
- % -info)
-
- if not econ or M<N:
- R = special_matrices.triu(qr)
- else:
- R = special_matrices.triu(qr[0:N,0:N])
-
- if mode=='r':
- 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 %d-th argument of internal gorgqr"
- % -info)
-
- return Q, R
-
-
-
-def qr_old(a, overwrite_a=False, lwork=None):
- """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.
-
- Returns
- -------
- Q : double or complex array, shape (M, M)
- R : double or complex array, shape (M, N)
- Size K = min(M, N)
-
- Raises LinAlgError if decomposition fails
-
- """
- a1 = asarray_chkfinite(a)
- if len(a1.shape) != 2:
- raise ValueError, 'expected matrix'
- M,N = a1.shape
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- 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 %d-th argument of internal geqrf' % (-info))
- gemm, = get_blas_funcs(('gemm',),(qr,))
- t = qr.dtype.char
- R = special_matrices.triu(qr)
- Q = numpy.identity(M,dtype=t)
- ident = numpy.identity(M,dtype=t)
- zeros = numpy.zeros
- for i in range(min(M,N)):
- v = zeros((M,),t)
- v[i] = 1
- v[i+1:M] = qr[i+1:M,i]
- H = gemm(-tau[i],v,v,1+0j,ident,trans_b=2)
- Q = gemm(1,Q,H)
- return Q, R
-
-
-
-def rq(a, overwrite_a=False, lwork=None):
- """Compute RQ decomposition of a square real matrix.
-
- Calculate the decomposition :lm:`A = R Q` where Q is unitary/orthogonal
- and R upper triangular.
-
- Parameters
- ----------
- a : array, shape (M, M)
- Square real 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.
- econ : boolean
-
- Returns
- -------
- R : double array, shape (M, N) or (K, N) for econ==True
- Size K = min(M, N)
- Q : double or complex array, shape (M, M) or (M, K) for econ==True
-
- Raises LinAlgError if decomposition fails
-
- """
- # TODO: implement support for non-square and complex arrays
- a1 = asarray_chkfinite(a)
- if len(a1.shape) != 2:
- raise ValueError, 'expected matrix'
- M,N = a1.shape
- if M != N:
- raise ValueError, 'expected square matrix'
- if issubclass(a1.dtype.type,complexfloating):
- raise ValueError, 'expected real (non-complex) matrix'
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- gerqf, = get_lapack_funcs(('gerqf',),(a1,))
- if lwork is None or lwork == -1:
- # get optimal work array
- rq,tau,work,info = gerqf(a1,lwork=-1,overwrite_a=1)
- lwork = work[0]
- rq,tau,work,info = gerqf(a1,lwork=lwork,overwrite_a=overwrite_a)
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal geqrf' % (-info))
- gemm, = get_blas_funcs(('gemm',),(rq,))
- t = rq.dtype.char
- R = special_matrices.triu(rq)
- Q = numpy.identity(M,dtype=t)
- ident = numpy.identity(M,dtype=t)
- zeros = numpy.zeros
-
- k = min(M,N)
- for i in range(k):
- v = zeros((M,),t)
- v[N-k+i] = 1
- v[0:N-k+i] = rq[M-k+i,0:N-k+i]
- H = gemm(-tau[i],v,v,1+0j,ident,trans_b=2)
- Q = gemm(1,Q,H)
- return R, Q
-
_double_precision = ['i','l','d']
-def schur(a, output='real', lwork=None, overwrite_a=False):
- """Compute Schur decomposition of a matrix.
- The Schur decomposition is
-
- A = Z T Z^H
-
- where Z is unitary and T is either upper-triangular, or for real
- Schur decomposition (output='real'), quasi-upper triangular. In
- the quasi-triangular form, 2x2 blocks describing complex-valued
- eigenvalue pairs may extrude from the diagonal.
-
- Parameters
- ----------
- a : array, shape (M, M)
- Matrix to decompose
- output : {'real', 'complex'}
- Construct the real or complex Schur decomposition (for real matrices).
- lwork : integer
- Work array size. If None or -1, it is automatically computed.
- overwrite_a : boolean
- Whether to overwrite data in a (may improve performance)
-
- Returns
- -------
- T : array, shape (M, M)
- Schur form of A. It is real-valued for the real Schur decomposition.
- Z : array, shape (M, M)
- An unitary Schur transformation matrix for A.
- It is real-valued for the real Schur decomposition.
-
- See also
- --------
- rsf2csf : Convert real Schur form to complex Schur form
-
- """
- if not output in ['real','complex','r','c']:
- raise ValueError, "argument must be 'real', or 'complex'"
- a1 = asarray_chkfinite(a)
- if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]):
- raise ValueError, 'expected square matrix'
- typ = a1.dtype.char
- if output in ['complex','c'] and typ not in ['F','D']:
- if typ in _double_precision:
- a1 = a1.astype('D')
- typ = 'D'
- else:
- a1 = a1.astype('F')
- typ = 'F'
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- gees, = get_lapack_funcs(('gees',),(a1,))
- if lwork is None or lwork == -1:
- # get optimal work array
- result = gees(lambda x: None,a,lwork=-1)
- lwork = result[-2][0]
- result = gees(lambda x: None,a,lwork=result[-2][0],overwrite_a=overwrite_a)
- info = result[-1]
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal gees' % (-info))
- elif info>0: raise LinAlgError, "Schur form not found. Possibly ill-conditioned."
- return result[0], result[-3]
-
-eps = numpy.finfo(float).eps
-feps = numpy.finfo(single).eps
-
-_array_kind = {'b':0, 'h':0, 'B': 0, 'i':0, 'l': 0, 'f': 0, 'd': 0, 'F': 1, 'D': 1}
-_array_precision = {'i': 1, 'l': 1, 'f': 0, 'd': 1, 'F': 0, 'D': 1}
-_array_type = [['f', 'd'], ['F', 'D']]
-
-def _commonType(*arrays):
- kind = 0
- precision = 0
- for a in arrays:
- t = a.dtype.char
- kind = max(kind, _array_kind[t])
- precision = max(precision, _array_precision[t])
- return _array_type[kind][precision]
-
-def _castCopy(type, *arrays):
- cast_arrays = ()
- for a in arrays:
- if a.dtype.char == type:
- cast_arrays = cast_arrays + (a.copy(),)
- else:
- cast_arrays = cast_arrays + (a.astype(type),)
- if len(cast_arrays) == 1:
- return cast_arrays[0]
- else:
- return cast_arrays
-
-def _assert_squareness(*arrays):
- for a in arrays:
- if max(a.shape) != min(a.shape):
- raise LinAlgError, 'Array must be square'
-
-def rsf2csf(T, Z):
- """Convert real Schur form to complex Schur form.
-
- Convert a quasi-diagonal real-valued Schur form to the upper triangular
- complex-valued Schur form.
-
- Parameters
- ----------
- T : array, shape (M, M)
- Real Schur form of the original matrix
- Z : array, shape (M, M)
- Schur transformation matrix
-
- Returns
- -------
- T : array, shape (M, M)
- Complex Schur form of the original matrix
- Z : array, shape (M, M)
- Schur transformation matrix corresponding to the complex form
-
- See also
- --------
- schur : Schur decompose a matrix
-
- """
- Z,T = map(asarray_chkfinite, (Z,T))
- if len(Z.shape) !=2 or Z.shape[0] != Z.shape[1]:
- raise ValueError, "matrix must be square."
- if len(T.shape) !=2 or T.shape[0] != T.shape[1]:
- raise ValueError, "matrix must be square."
- if T.shape[0] != Z.shape[0]:
- raise ValueError, "matrices must be same dimension."
- N = T.shape[0]
- arr = numpy.array
- t = _commonType(Z, T, arr([3.0],'F'))
- Z, T = _castCopy(t, Z, T)
- conj = numpy.conj
- dot = numpy.dot
- r_ = numpy.r_
- transp = numpy.transpose
- for m in range(N-1,0,-1):
- if abs(T[m,m-1]) > eps*(abs(T[m-1,m-1]) + abs(T[m,m])):
- k = slice(m-1,m+1)
- mu = eigvals(T[k,k]) - T[m,m]
- r = misc.norm([mu[0], T[m,m-1]])
- c = mu[0] / r
- s = T[m,m-1] / r
- G = r_[arr([[conj(c),s]],dtype=t),arr([[-s,c]],dtype=t)]
- Gc = conj(transp(G))
- j = slice(m-1,N)
- T[k,j] = dot(G,T[k,j])
- i = slice(0,m+1)
- T[i,k] = dot(T[i,k], Gc)
- i = slice(0,N)
- Z[i,k] = dot(Z[i,k], Gc)
- T[m,m-1] = 0.0;
- return T, Z
-
-
-# Orthonormal decomposition
-
-def orth(A):
- """Construct an orthonormal basis for the range of A using SVD
-
- Parameters
- ----------
- A : array, shape (M, N)
-
- Returns
- -------
- Q : array, shape (M, K)
- Orthonormal basis for the range of A.
- K = effective rank of A, as determined by automatic cutoff
-
- See also
- --------
- svd : Singular value decomposition of a matrix
-
- """
- u,s,vh = svd(A)
- M,N = A.shape
- tol = max(M,N)*numpy.amax(s)*eps
- num = numpy.sum(s > tol,dtype=int)
- Q = u[:,:num]
- return Q
-
def hessenberg(a, calc_q=False, overwrite_a=False):
"""Compute Hessenberg form of a matrix.
@@ -1572,39 +736,41 @@
"""
a1 = asarray(a)
if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]):
- raise ValueError, 'expected square matrix'
- overwrite_a = overwrite_a or (_datanotshared(a1,a))
- gehrd,gebal = get_lapack_funcs(('gehrd','gebal'),(a1,))
- ba,lo,hi,pivscale,info = gebal(a,permute=1,overwrite_a = overwrite_a)
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal gebal (hessenberg)' % (-info))
+ raise ValueError('expected square matrix')
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
+ gehrd,gebal = get_lapack_funcs(('gehrd','gebal'), (a1,))
+ ba, lo, hi, pivscale, info = gebal(a, permute=1, overwrite_a=overwrite_a)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal gebal '
+ '(hessenberg)' % -info)
n = len(a1)
- lwork = calc_lwork.gehrd(gehrd.prefix,n,lo,hi)
- hq,tau,info = gehrd(ba,lo=lo,hi=hi,lwork=lwork,overwrite_a=1)
- if info<0: raise ValueError(
- 'illegal value in %d-th argument of internal gehrd (hessenberg)' % (-info))
+ lwork = calc_lwork.gehrd(gehrd.prefix, n, lo, hi)
+ hq, tau, info = gehrd(ba, lo=lo, hi=hi, lwork=lwork, overwrite_a=1)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal gehrd '
+ '(hessenberg)' % -info)
if not calc_q:
- for i in range(lo,hi):
- hq[i+2:hi+1,i] = 0.0
+ for i in range(lo, hi):
+ hq[i+2:hi+1, i] = 0.0
return hq
# XXX: Use ORGHR routines to compute q.
- ger,gemm = get_blas_funcs(('ger','gemm'),(hq,))
+ ger,gemm = get_blas_funcs(('ger','gemm'), (hq,))
typecode = hq.dtype.char
q = None
- for i in range(lo,hi):
+ for i in range(lo, hi):
if tau[i]==0.0:
continue
- v = zeros(n,dtype=typecode)
+ v = zeros(n, dtype=typecode)
v[i+1] = 1.0
- v[i+2:hi+1] = hq[i+2:hi+1,i]
- hq[i+2:hi+1,i] = 0.0
- h = ger(-tau[i],v,v,a=diag(ones(n,dtype=typecode)),overwrite_a=1)
+ v[i+2:hi+1] = hq[i+2:hi+1, i]
+ hq[i+2:hi+1, i] = 0.0
+ h = ger(-tau[i], v, v,a=diag(ones(n, dtype=typecode)), overwrite_a=1)
if q is None:
q = h
else:
- q = gemm(1.0,q,h)
+ q = gemm(1.0, q, h)
if q is None:
- q = diag(ones(n,dtype=typecode))
- return hq,q
+ q = diag(ones(n, dtype=typecode))
+ return hq, q
Added: trunk/scipy/linalg/decomp_cholesky.py
===================================================================
--- trunk/scipy/linalg/decomp_cholesky.py (rev 0)
+++ trunk/scipy/linalg/decomp_cholesky.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -0,0 +1,217 @@
+"""Cholesky decomposition functions."""
+
+from numpy import asarray_chkfinite
+
+# Local imports
+from misc import LinAlgError, _datanotshared
+from lapack import get_lapack_funcs
+
+__all__ = ['cholesky', 'cho_factor', 'cho_solve', 'cholesky_banded',
+ 'cho_solve_banded']
+
+
+def _cholesky(a, lower=False, overwrite_a=False, clean=True):
+ """Common code for cholesky() and cho_factor()."""
+
+ a1 = asarray_chkfinite(a)
+ if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
+ raise ValueError('expected square matrix')
+
+ overwrite_a = overwrite_a or _datanotshared(a1, a)
+ potrf, = get_lapack_funcs(('potrf',), (a1,))
+ c, info = potrf(a1, lower=lower, overwrite_a=overwrite_a, clean=clean)
+ if info > 0:
+ raise LinAlgError("%d-th leading minor not positive definite" % info)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal potrf'
+ % -info)
+ return c, lower
+
+def cholesky(a, lower=False, overwrite_a=False):
+ """Compute the Cholesky decomposition of a matrix.
+
+ Returns the Cholesky decomposition, :lm:`A = L L^*` or :lm:`A = U^* U`
+ of a Hermitian positive-definite matrix :lm:`A`.
+
+ Parameters
+ ----------
+ a : array, shape (M, M)
+ Matrix to be decomposed
+ lower : boolean
+ Whether to compute the upper or lower triangular Cholesky factorization
+ (Default: upper-triangular)
+ overwrite_a : boolean
+ Whether to overwrite data in a (may improve performance)
+
+ Returns
+ -------
+ c : array, shape (M, M)
+ Upper- or lower-triangular Cholesky factor of A
+
+ Raises LinAlgError if decomposition fails
+
+ Examples
+ --------
+ >>> from scipy import array, linalg, dot
+ >>> a = array([[1,-2j],[2j,5]])
+ >>> L = linalg.cholesky(a, lower=True)
+ >>> L
+ array([[ 1.+0.j, 0.+0.j],
+ [ 0.+2.j, 1.+0.j]])
+ >>> dot(L, L.T.conj())
+ array([[ 1.+0.j, 0.-2.j],
+ [ 0.+2.j, 5.+0.j]])
+
+ """
+ c, lower = _cholesky(a, lower=lower, overwrite_a=overwrite_a, clean=True)
+ return c
+
+
+def cho_factor(a, lower=False, overwrite_a=False):
+ """Compute the Cholesky decomposition of a matrix, to use in cho_solve
+
+ Returns a matrix containing the Cholesky decomposition,
+ ``A = L L*`` or ``A = U* U`` of a Hermitian positive-definite matrix `a`.
+ The return value can be directly used as the first parameter to cho_solve.
+
+ .. warning::
+ The returned matrix also contains random data in the entries not
+ used by the Cholesky decomposition. If you need to zero these
+ entries, use the function `cholesky` instead.
+
+ Parameters
+ ----------
+ a : array, shape (M, M)
+ Matrix to be decomposed
+ lower : boolean
+ Whether to compute the upper or lower triangular Cholesky factorization
+ (Default: upper-triangular)
+ overwrite_a : boolean
+ Whether to overwrite data in a (may improve performance)
+
+ Returns
+ -------
+ c : array, shape (M, M)
+ Matrix whose upper or lower triangle contains the Cholesky factor
+ of `a`. Other parts of the matrix contain random data.
+ lower : boolean
+ Flag indicating whether the factor is in the lower or upper triangle
+
+ Raises
+ ------
+ LinAlgError
+ Raised if decomposition fails.
+
+ See also
+ --------
+ cho_solve : Solve a linear set equations using the Cholesky factorization
+ of a matrix.
+
+ """
+ c, lower = _cholesky(a, lower=lower, overwrite_a=overwrite_a, clean=False)
+ return c, lower
+
+
+def cho_solve((c, lower), b, overwrite_b=False):
+ """Solve the linear equations A x = b, given the Cholesky factorization of A.
+
+ Parameters
+ ----------
+ (c, lower) : tuple, (array, bool)
+ Cholesky factorization of a, as given by cho_factor
+ b : array
+ Right-hand side
+
+ Returns
+ -------
+ x : array
+ The solution to the system A x = b
+
+ See also
+ --------
+ cho_factor : Cholesky factorization of a matrix
+
+ """
+
+ b1 = asarray_chkfinite(b)
+ c = asarray_chkfinite(c)
+ if c.ndim != 2 or c.shape[0] != c.shape[1]:
+ raise ValueError("The factored matrix c is not square.")
+ if c.shape[1] != b1.shape[0]:
+ raise ValueError("incompatible dimensions.")
+
+ overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__'))
+
+ potrs, = get_lapack_funcs(('potrs',), (c, b1))
+ x, info = potrs(c, b1, lower=lower, overwrite_b=overwrite_b)
+ if info != 0:
+ raise ValueError('illegal value in %d-th argument of internal potrs'
+ % -info)
+ return x
+
+def cholesky_banded(ab, overwrite_ab=False, lower=False):
+ """Cholesky decompose a banded Hermitian positive-definite matrix
+
+ The matrix a is stored in ab either in lower diagonal or upper
+ diagonal ordered form:
+
+ ab[u + i - j, j] == a[i,j] (if upper form; i <= j)
+ ab[ i - j, j] == a[i,j] (if lower form; i >= j)
+
+ Example of ab (shape of a is (6,6), u=2)::
+
+ upper form:
+ * * a02 a13 a24 a35
+ * a01 a12 a23 a34 a45
+ a00 a11 a22 a33 a44 a55
+
+ lower form:
+ a00 a11 a22 a33 a44 a55
+ a10 a21 a32 a43 a54 *
+ a20 a31 a42 a53 * *
+
+ Parameters
+ ----------
+ ab : array, shape (u + 1, M)
+ Banded matrix
+ overwrite_ab : boolean
+ Discard data in ab (may enhance performance)
+ lower : boolean
+ Is the matrix in the lower form. (Default is upper form)
+
+ Returns
+ -------
+ c : array, shape (u+1, M)
+ Cholesky factorization of a, in the same banded format as ab
+
+ """
+ ab = asarray_chkfinite(ab)
+
+ pbtrf, = get_lapack_funcs(('pbtrf',), (ab,))
+ c, info = pbtrf(ab, lower=lower, overwrite_ab=overwrite_ab)
+ if info > 0:
+ raise LinAlgError("%d-th leading minor not positive definite" % info)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal pbtrf'
+ % -info)
+ return c
+
+# my new function
+def cho_solve_banded((ab, lower), b, overwrite_b=False):
+ """To be written..."""
+
+ ab = asarray_chkfinite(ab)
+ b = asarray_chkfinite(b)
+
+ # Validate shapes.
+ if ab.shape[-1] != b.shape[0]:
+ raise ValueError("shapes of ab and b are not compatible.")
+
+ pbtrs, = get_lapack_funcs(('pbtrs',), (ab, b))
+ x, info = pbtrs(ab, b, lower=lower, overwrite_b=overwrite_b)
+ if info > 0:
+ raise LinAlgError("%d-th leading minor not positive definite" % info)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal pbtrs'
+ % -info)
+ return x
Added: trunk/scipy/linalg/decomp_lu.py
===================================================================
--- trunk/scipy/linalg/decomp_lu.py (rev 0)
+++ trunk/scipy/linalg/decomp_lu.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -0,0 +1,159 @@
+"""LU decomposition functions."""
+
+from warnings import warn
+
+from numpy import asarray, asarray_chkfinite
+
+# Local imports
+from misc import _datanotshared
+from lapack import get_lapack_funcs
+from flinalg import get_flinalg_funcs
+
+
+def lu_factor(a, overwrite_a=False):
+ """Compute pivoted LU decomposition of a matrix.
+
+ The decomposition is::
+
+ A = P L U
+
+ where P is a permutation matrix, L lower triangular with unit
+ diagonal elements, and U upper triangular.
+
+ Parameters
+ ----------
+ a : array, shape (M, M)
+ Matrix to decompose
+ overwrite_a : boolean
+ Whether to overwrite data in A (may increase performance)
+
+ Returns
+ -------
+ lu : array, shape (N, N)
+ Matrix containing U in its upper triangle, and L in its lower triangle.
+ The unit diagonal elements of L are not stored.
+ piv : array, shape (N,)
+ Pivot indices representing the permutation matrix P:
+ row i of matrix was interchanged with row piv[i].
+
+ See also
+ --------
+ lu_solve : solve an equation system using the LU factorization of a matrix
+
+ Notes
+ -----
+ This is a wrapper to the *GETRF routines from LAPACK.
+
+ """
+ a1 = asarray(a)
+ if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]):
+ raise ValueError, 'expected square matrix'
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
+ getrf, = get_lapack_funcs(('getrf',), (a1,))
+ lu, piv, info = getrf(a, overwrite_a=overwrite_a)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of '
+ 'internal getrf (lu_factor)' % -info)
+ if info > 0:
+ warn("Diagonal number %d is exactly zero. Singular matrix." % info,
+ RuntimeWarning)
+ return lu, piv
+
+
+def lu_solve((lu, piv), b, trans=0, overwrite_b=False):
+ """Solve an equation system, a x = b, given the LU factorization of a
+
+ Parameters
+ ----------
+ (lu, piv)
+ Factorization of the coefficient matrix a, as given by lu_factor
+ b : array
+ Right-hand side
+ trans : {0, 1, 2}
+ Type of system to solve:
+
+ ===== =========
+ trans system
+ ===== =========
+ 0 a x = b
+ 1 a^T x = b
+ 2 a^H x = b
+ ===== =========
+
+ Returns
+ -------
+ x : array
+ Solution to the system
+
+ See also
+ --------
+ lu_factor : LU factorize a matrix
+
+ """
+ b1 = asarray_chkfinite(b)
+ overwrite_b = overwrite_b or (b1 is not b and not hasattr(b, '__array__'))
+ if lu.shape[0] != b1.shape[0]:
+ raise ValueError("incompatible dimensions.")
+
+ getrs, = get_lapack_funcs(('getrs',), (lu, b1))
+ x,info = getrs(lu, piv, b1, trans=trans, overwrite_b=overwrite_b)
+ if info == 0:
+ return x
+ raise ValueError('illegal value in %d-th argument of internal gesv|posv'
+ % -info)
+
+
+def lu(a, permute_l=False, overwrite_a=False):
+ """Compute pivoted LU decompostion of a matrix.
+
+ The decomposition is::
+
+ A = P L U
+
+ where P is a permutation matrix, L lower triangular with unit
+ diagonal elements, and U upper triangular.
+
+ Parameters
+ ----------
+ a : array, shape (M, N)
+ Array to decompose
+ permute_l : boolean
+ Perform the multiplication P*L (Default: do not permute)
+ overwrite_a : boolean
+ Whether to overwrite data in a (may improve performance)
+
+ Returns
+ -------
+ (If permute_l == False)
+ p : array, shape (M, M)
+ Permutation matrix
+ l : array, shape (M, K)
+ Lower triangular or trapezoidal matrix with unit diagonal.
+ K = min(M, N)
+ u : array, shape (K, N)
+ Upper triangular or trapezoidal matrix
+
+ (If permute_l == True)
+ pl : array, shape (M, K)
+ Permuted L matrix.
+ K = min(M, N)
+ u : array, shape (K, N)
+ Upper triangular or trapezoidal matrix
+
+ Notes
+ -----
+ This is a LU factorization routine written for Scipy.
+
+ """
+ a1 = asarray_chkfinite(a)
+ if len(a1.shape) != 2:
+ raise ValueError('expected matrix')
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
+ flu, = get_flinalg_funcs(('lu',), (a1,))
+ p, l, u, info = flu(a1, permute_l=permute_l, overwrite_a=overwrite_a)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of '
+ 'internal lu.getrf' % -info)
+ if permute_l:
+ return l, u
+ return p, l, u
Added: trunk/scipy/linalg/decomp_qr.py
===================================================================
--- trunk/scipy/linalg/decomp_qr.py (rev 0)
+++ trunk/scipy/linalg/decomp_qr.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -0,0 +1,248 @@
+"""QR decomposition functions."""
+
+from warnings import warn
+
+import numpy
+from numpy import asarray_chkfinite, complexfloating
+
+# Local imports
+import special_matrices
+from blas import get_blas_funcs
+from lapack import get_lapack_funcs, find_best_lapack_type
+from misc import _datanotshared
+
+
+def qr(a, overwrite_a=False, lwork=None, econ=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.
+ econ : boolean
+ Whether to 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).
+ Default is False.
+ mode : {'qr', 'r'}
+ Determines what information is to be returned: either both Q and R
+ or only R.
+
+ 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))
+
+ """
+ if econ is None:
+ econ = False
+ else:
+ warn("qr econ argument will be removed after scipy 0.7. "
+ "The economy transform will then be available through "
+ "the mode='economic' argument.", DeprecationWarning)
+
+ 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))
+
+ 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 %d-th argument of internal geqrf"
+ % -info)
+ if not econ or M < N:
+ R = special_matrices.triu(qr)
+ else:
+ R = special_matrices.triu(qr[0:N, 0:N])
+
+ if mode == 'r':
+ 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 %d-th argument of internal gorgqr"
+ % -info)
+ return Q, R
+
+
+
+def qr_old(a, overwrite_a=False, lwork=None):
+ """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.
+
+ Returns
+ -------
+ Q : double or complex array, shape (M, M)
+ R : double or complex array, shape (M, N)
+ Size K = min(M, N)
+
+ Raises LinAlgError if decomposition fails
+
+ """
+ a1 = asarray_chkfinite(a)
+ if len(a1.shape) != 2:
+ raise ValueError, 'expected matrix'
+ M,N = a1.shape
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
+ 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 %d-th argument of internal geqrf'
+ % -info)
+ gemm, = get_blas_funcs(('gemm',), (qr,))
+ t = qr.dtype.char
+ R = special_matrices.triu(qr)
+ Q = numpy.identity(M, dtype=t)
+ ident = numpy.identity(M, dtype=t)
+ zeros = numpy.zeros
+ for i in range(min(M, N)):
+ v = zeros((M,), t)
+ v[i] = 1
+ v[i+1:M] = qr[i+1:M, i]
+ H = gemm(-tau[i], v, v, 1+0j, ident, trans_b=2)
+ Q = gemm(1, Q, H)
+ return Q, R
+
+
+def rq(a, overwrite_a=False, lwork=None):
+ """Compute RQ decomposition of a square real matrix.
+
+ Calculate the decomposition :lm:`A = R Q` where Q is unitary/orthogonal
+ and R upper triangular.
+
+ Parameters
+ ----------
+ a : array, shape (M, M)
+ Square real 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.
+ econ : boolean
+
+ Returns
+ -------
+ R : double array, shape (M, N) or (K, N) for econ==True
+ Size K = min(M, N)
+ Q : double or complex array, shape (M, M) or (M, K) for econ==True
+
+ Raises LinAlgError if decomposition fails
+
+ """
+ # TODO: implement support for non-square and complex arrays
+ a1 = asarray_chkfinite(a)
+ if len(a1.shape) != 2:
+ raise ValueError('expected matrix')
+ M,N = a1.shape
+ if M != N:
+ raise ValueError('expected square matrix')
+ if issubclass(a1.dtype.type, complexfloating):
+ raise ValueError('expected real (non-complex) matrix')
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
+ gerqf, = get_lapack_funcs(('gerqf',), (a1,))
+ if lwork is None or lwork == -1:
+ # get optimal work array
+ rq, tau, work, info = gerqf(a1, lwork=-1, overwrite_a=1)
+ lwork = work[0]
+ rq, tau, work, info = gerqf(a1, lwork=lwork, overwrite_a=overwrite_a)
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal geqrf'
+ % -info)
+ gemm, = get_blas_funcs(('gemm',), (rq,))
+ t = rq.dtype.char
+ R = special_matrices.triu(rq)
+ Q = numpy.identity(M, dtype=t)
+ ident = numpy.identity(M, dtype=t)
+ zeros = numpy.zeros
+
+ k = min(M, N)
+ for i in range(k):
+ v = zeros((M,), t)
+ v[N-k+i] = 1
+ v[0:N-k+i] = rq[M-k+i, 0:N-k+i]
+ H = gemm(-tau[i], v, v, 1+0j, ident, trans_b=2)
+ Q = gemm(1, Q, H)
+ return R, Q
Added: trunk/scipy/linalg/decomp_schur.py
===================================================================
--- trunk/scipy/linalg/decomp_schur.py (rev 0)
+++ trunk/scipy/linalg/decomp_schur.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -0,0 +1,167 @@
+"""Schur decomposition functions."""
+
+import numpy
+from numpy import asarray_chkfinite, single
+
+# Local imports.
+import misc
+from misc import LinAlgError, _datanotshared
+from lapack import get_lapack_funcs
+from decomp import eigvals
+
+
+__all__ = ['schur', 'rsf2csf']
+
+_double_precision = ['i','l','d']
+
+def schur(a, output='real', lwork=None, overwrite_a=False):
+ """Compute Schur decomposition of a matrix.
+
+ The Schur decomposition is
+
+ A = Z T Z^H
+
+ where Z is unitary and T is either upper-triangular, or for real
+ Schur decomposition (output='real'), quasi-upper triangular. In
+ the quasi-triangular form, 2x2 blocks describing complex-valued
+ eigenvalue pairs may extrude from the diagonal.
+
+ Parameters
+ ----------
+ a : array, shape (M, M)
+ Matrix to decompose
+ output : {'real', 'complex'}
+ Construct the real or complex Schur decomposition (for real matrices).
+ lwork : integer
+ Work array size. If None or -1, it is automatically computed.
+ overwrite_a : boolean
+ Whether to overwrite data in a (may improve performance)
+
+ Returns
+ -------
+ T : array, shape (M, M)
+ Schur form of A. It is real-valued for the real Schur decomposition.
+ Z : array, shape (M, M)
+ An unitary Schur transformation matrix for A.
+ It is real-valued for the real Schur decomposition.
+
+ See also
+ --------
+ rsf2csf : Convert real Schur form to complex Schur form
+
+ """
+ if not output in ['real','complex','r','c']:
+ raise ValueError, "argument must be 'real', or 'complex'"
+ a1 = asarray_chkfinite(a)
+ if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]):
+ raise ValueError, 'expected square matrix'
+ typ = a1.dtype.char
+ if output in ['complex','c'] and typ not in ['F','D']:
+ if typ in _double_precision:
+ a1 = a1.astype('D')
+ typ = 'D'
+ else:
+ a1 = a1.astype('F')
+ typ = 'F'
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
+ gees, = get_lapack_funcs(('gees',), (a1,))
+ if lwork is None or lwork == -1:
+ # get optimal work array
+ result = gees(lambda x: None, a, lwork=-1)
+ lwork = result[-2][0]
+ result = gees(lambda x: None, a, lwork=result[-2][0], overwrite_a=overwrite_a)
+ info = result[-1]
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal gees'
+ % -info)
+ elif info > 0:
+ raise LinAlgError("Schur form not found. Possibly ill-conditioned.")
+ return result[0], result[-3]
+
+
+eps = numpy.finfo(float).eps
+feps = numpy.finfo(single).eps
+
+_array_kind = {'b':0, 'h':0, 'B': 0, 'i':0, 'l': 0, 'f': 0, 'd': 0, 'F': 1, 'D': 1}
+_array_precision = {'i': 1, 'l': 1, 'f': 0, 'd': 1, 'F': 0, 'D': 1}
+_array_type = [['f', 'd'], ['F', 'D']]
+
+def _commonType(*arrays):
+ kind = 0
+ precision = 0
+ for a in arrays:
+ t = a.dtype.char
+ kind = max(kind, _array_kind[t])
+ precision = max(precision, _array_precision[t])
+ return _array_type[kind][precision]
+
+def _castCopy(type, *arrays):
+ cast_arrays = ()
+ for a in arrays:
+ if a.dtype.char == type:
+ cast_arrays = cast_arrays + (a.copy(),)
+ else:
+ cast_arrays = cast_arrays + (a.astype(type),)
+ if len(cast_arrays) == 1:
+ return cast_arrays[0]
+ else:
+ return cast_arrays
+
+
+def rsf2csf(T, Z):
+ """Convert real Schur form to complex Schur form.
+
+ Convert a quasi-diagonal real-valued Schur form to the upper triangular
+ complex-valued Schur form.
+
+ Parameters
+ ----------
+ T : array, shape (M, M)
+ Real Schur form of the original matrix
+ Z : array, shape (M, M)
+ Schur transformation matrix
+
+ Returns
+ -------
+ T : array, shape (M, M)
+ Complex Schur form of the original matrix
+ Z : array, shape (M, M)
+ Schur transformation matrix corresponding to the complex form
+
+ See also
+ --------
+ schur : Schur decompose a matrix
+
+ """
+ Z, T = map(asarray_chkfinite, (Z, T))
+ if len(Z.shape) != 2 or Z.shape[0] != Z.shape[1]:
+ raise ValueError("matrix must be square.")
+ if len(T.shape) != 2 or T.shape[0] != T.shape[1]:
+ raise ValueError("matrix must be square.")
+ if T.shape[0] != Z.shape[0]:
+ raise ValueError("matrices must be same dimension.")
+ N = T.shape[0]
+ arr = numpy.array
+ t = _commonType(Z, T, arr([3.0],'F'))
+ Z, T = _castCopy(t, Z, T)
+ conj = numpy.conj
+ dot = numpy.dot
+ r_ = numpy.r_
+ transp = numpy.transpose
+ for m in range(N-1, 0, -1):
+ if abs(T[m,m-1]) > eps*(abs(T[m-1,m-1]) + abs(T[m,m])):
+ k = slice(m-1, m+1)
+ mu = eigvals(T[k,k]) - T[m,m]
+ r = misc.norm([mu[0], T[m,m-1]])
+ c = mu[0] / r
+ s = T[m,m-1] / r
+ G = r_[arr([[conj(c), s]], dtype=t), arr([[-s, c]], dtype=t)]
+ Gc = conj(transp(G))
+ j = slice(m-1, N)
+ T[k,j] = dot(G, T[k,j])
+ i = slice(0, m+1)
+ T[i,k] = dot(T[i,k], Gc)
+ i = slice(0, N)
+ Z[i,k] = dot(Z[i,k], Gc)
+ T[m,m-1] = 0.0;
+ return T, Z
Added: trunk/scipy/linalg/decomp_svd.py
===================================================================
--- trunk/scipy/linalg/decomp_svd.py (rev 0)
+++ trunk/scipy/linalg/decomp_svd.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -0,0 +1,173 @@
+"""SVD decomposition functions."""
+
+import numpy
+from numpy import asarray_chkfinite, zeros, r_, diag
+from scipy.linalg import calc_lwork
+
+# Local imports.
+from misc import LinAlgError, _datanotshared
+from lapack import get_lapack_funcs
+
+
+def svd(a, full_matrices=True, compute_uv=True, overwrite_a=False):
+ """Singular Value Decomposition.
+
+ Factorizes the matrix a into two unitary matrices U and Vh and
+ an 1d-array s of singular values (real, non-negative) such that
+ a == U S Vh if S is an suitably shaped matrix of zeros whose
+ main diagonal is s.
+
+ Parameters
+ ----------
+ a : array, shape (M, N)
+ Matrix to decompose
+ full_matrices : boolean
+ If true, U, Vh are shaped (M,M), (N,N)
+ If false, the shapes are (M,K), (K,N) where K = min(M,N)
+ compute_uv : boolean
+ Whether to compute also U, Vh in addition to s (Default: true)
+ overwrite_a : boolean
+ Whether data in a is overwritten (may improve performance)
+
+ Returns
+ -------
+ U: array, shape (M,M) or (M,K) depending on full_matrices
+ s: array, shape (K,)
+ The singular values, sorted so that s[i] >= s[i+1]. K = min(M, N)
+ Vh: array, shape (N,N) or (K,N) depending on full_matrices
+
+ For compute_uv = False, only s is returned.
+
+ Raises LinAlgError if SVD computation does not converge
+
+ Examples
+ --------
+ >>> from scipy import random, linalg, allclose, dot
+ >>> a = random.randn(9, 6) + 1j*random.randn(9, 6)
+ >>> U, s, Vh = linalg.svd(a)
+ >>> U.shape, Vh.shape, s.shape
+ ((9, 9), (6, 6), (6,))
+
+ >>> U, s, Vh = linalg.svd(a, full_matrices=False)
+ >>> U.shape, Vh.shape, s.shape
+ ((9, 6), (6, 6), (6,))
+ >>> S = linalg.diagsvd(s, 6, 6)
+ >>> allclose(a, dot(U, dot(S, Vh)))
+ True
+
+ >>> s2 = linalg.svd(a, compute_uv=False)
+ >>> allclose(s, s2)
+ True
+
+ See also
+ --------
+ svdvals : return singular values of a matrix
+ diagsvd : return the Sigma matrix, given the vector s
+
+ """
+ # A hack until full_matrices == 0 support is fixed here.
+ if full_matrices == 0:
+ import numpy.linalg
+ return numpy.linalg.svd(a, full_matrices=0, compute_uv=compute_uv)
+ a1 = asarray_chkfinite(a)
+ if len(a1.shape) != 2:
+ raise ValueError('expected matrix')
+ m,n = a1.shape
+ overwrite_a = overwrite_a or (_datanotshared(a1, a))
+ gesdd, = get_lapack_funcs(('gesdd',), (a1,))
+ if gesdd.module_name[:7] == 'flapack':
+ lwork = calc_lwork.gesdd(gesdd.prefix, m, n, compute_uv)[1]
+ u,s,v,info = gesdd(a1,compute_uv = compute_uv, lwork = lwork,
+ overwrite_a = overwrite_a)
+ else: # 'clapack'
+ raise NotImplementedError('calling gesdd from %s' % gesdd.module_name)
+ if info > 0:
+ raise LinAlgError("SVD did not converge")
+ if info < 0:
+ raise ValueError('illegal value in %d-th argument of internal gesdd'
+ % -info)
+ if compute_uv:
+ return u, s, v
+ else:
+ return s
+
+def svdvals(a, overwrite_a=False):
+ """Compute singular values of a matrix.
+
+ Parameters
+ ----------
+ a : array, shape (M, N)
+ Matrix to decompose
+ overwrite_a : boolean
+ Whether data in a is overwritten (may improve performance)
+
+ Returns
+ -------
+ s: array, shape (K,)
+ The singular values, sorted so that s[i] >= s[i+1]. K = min(M, N)
+
+ Raises LinAlgError if SVD computation does not converge
+
+ See also
+ --------
+ svd : return the full singular value decomposition of a matrix
+ diagsvd : return the Sigma matrix, given the vector s
+
+ """
+ return svd(a, compute_uv=0, overwrite_a=overwrite_a)
+
+def diagsvd(s, M, N):
+ """Construct the sigma matrix in SVD from singular values and size M,N.
+
+ Parameters
+ ----------
+ s : array, shape (M,) or (N,)
+ Singular values
+ M : integer
+ N : integer
+ Size of the matrix whose singular values are s
+
+ Returns
+ -------
+ S : array, shape (M, N)
+ The S-matrix in the singular value decomposition
+
+ """
+ part = diag(s)
+ typ = part.dtype.char
+ MorN = len(s)
+ if MorN == M:
+ return r_['-1', part, zeros((M, N-M), typ)]
+ elif MorN == N:
+ return r_[part, zeros((M-N,N), typ)]
+ else:
+ raise ValueError("Length of s must be M or N.")
+
+
+# Orthonormal decomposition
+
+def orth(A):
+ """Construct an orthonormal basis for the range of A using SVD
+
+ Parameters
+ ----------
+ A : array, shape (M, N)
+
+ Returns
+ -------
+ Q : array, shape (M, K)
+ Orthonormal basis for the range of A.
+ K = effective rank of A, as determined by automatic cutoff
+
+ See also
+ --------
+ svd : Singular value decomposition of a matrix
+
+ """
+ u, s, vh = svd(A)
+ M, N = A.shape
+ eps = numpy.finfo(float).eps
+ tol = max(M,N) * numpy.amax(s) * eps
+ num = numpy.sum(s > tol, dtype=int)
+ Q = u[:,:num]
+ return Q
Modified: trunk/scipy/linalg/generic_flapack.pyf
===================================================================
--- trunk/scipy/linalg/generic_flapack.pyf 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/generic_flapack.pyf 2010-04-10 01:47:20 UTC (rev 6319)
@@ -56,6 +56,57 @@
end subroutine <tchar=c,z>pbtrf
+
+ subroutine <tchar=s,d>pbtrs(lower, n, kd, nrhs, ab, ldab, b, ldb, info)
+
+ ! Solve a system of linear equations A*X = B with a symmetric
+ ! positive definite band matrix A using the Cholesky factorization.
+ ! AB is the triangular factur U or L from the Cholesky factorization
+ ! previously computed with *PBTRF.
+ ! A = U^T * U, AB = U if lower = 0
+ ! A = L * L^T, AB = L if lower = 1
+
+ callstatement (*f2py_func)((lower?"L":"U"),&n,&kd,&nrhs,ab,&ldab,b,&ldb,&info);
+ callprotoargument char*,int*,int*,int*,<type_in_c>*,int*,<type_in_c>*,int*,int*
+
+ integer optional,check(shape(ab,0)==ldab),depend(ab) :: ldab=shape(ab,0)
+ integer intent(hide),depend(ab) :: n=shape(ab,1)
+ integer intent(hide),depend(ab) :: kd=shape(ab,0)-1
+ integer intent(hide),depend(b) :: ldb=shape(b,0)
+ integer intent(hide),depend(b) :: nrhs=shape(b,1)
+ integer optional,intent(in),check(lower==0||lower==1) :: lower = 0
+
+ <type_in> dimension(ldb, nrhs),intent(in,out,copy,out=x) :: b
+ <type_in> dimension(ldab,n),intent(in) :: ab
+ integer intent(out) :: info
+
+ end subroutine <tchar=s,d>pbtrs
+
+ subroutine <tchar=c,z>pbtrs(lower, n, kd, nrhs, ab, ldab, b, ldb, info)
+
+ ! Solve a system of linear equations A*X = B with a symmetric
+ ! positive definite band matrix A using the Cholesky factorization.
+ ! AB is the triangular factur U or L from the Cholesky factorization
+ ! previously computed with *PBTRF.
+ ! A = U^T * U, AB = U if lower = 0
+ ! A = L * L^T, AB = L if lower = 1
+
+ callstatement (*f2py_func)((lower?"L":"U"),&n,&kd,&nrhs,ab,&ldab,b,&ldb,&info);
+ callprotoargument char*,int*,int*,int*,<type_in_c>*,int*,<type_in_c>*,int*,int*
+
+ integer optional,check(shape(ab,0)==ldab),depend(ab) :: ldab=shape(ab,0)
+ integer intent(hide),depend(ab) :: n=shape(ab,1)
+ integer intent(hide),depend(ab) :: kd=shape(ab,0)-1
+ integer intent(hide),depend(b) :: ldb=shape(b,0)
+ integer intent(hide),depend(b) :: nrhs=shape(b,1)
+ integer optional,intent(in),check(lower==0||lower==1) :: lower = 0
+
+ <type_in> dimension(ldb, nrhs),intent(in,out,copy,out=x) :: b
+ <type_in> dimension(ldab,n),intent(in) :: ab
+ integer intent(out) :: info
+
+ end subroutine <tchar=c,z>pbtrs
+
subroutine <tchar=s,d>pbsv(lower,n,kd,nrhs,ab,ldab,b,ldb,info)
!
Modified: trunk/scipy/linalg/info.py
===================================================================
--- trunk/scipy/linalg/info.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/info.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -14,12 +14,17 @@
pinv --- Pseudo-inverse (Moore-Penrose) using lstsq
pinv2 --- Pseudo-inverse using svd
-Eigenvalues and Decompositions::
+Eigenvalue Problem::
eig --- Find the eigenvalues and vectors of a square matrix
eigvals --- Find the eigenvalues of a square matrix
+ eigh --- Find the eigenvalues and eigenvectors of a complex Hermitian or real symmetric matrix.
+ eigvalsh --- Find the eigenvalues of a complex Hermitian or real symmetric matrix.
eig_banded --- Find the eigenvalues and vectors of a band matrix
eigvals_banded --- Find the eigenvalues of a band matrix
+
+Decompositions::
+
lu --- LU decomposition of a matrix
lu_factor --- LU decomposition returning unordered matrix and pivots
lu_solve --- solve Ax=b using back substitution with output of lu_factor
Modified: trunk/scipy/linalg/matfuncs.py
===================================================================
--- trunk/scipy/linalg/matfuncs.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/matfuncs.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -1,5 +1,3 @@
-## Automatically adapted for scipy Oct 18, 2005 by
-
#
# Author: Travis Oliphant, March 2002
#
@@ -13,9 +11,15 @@
isfinite, sqrt, identity, single
from numpy import matrix as mat
import numpy as np
-from basic import solve, inv, norm, triu, all_mat
-from decomp import eig, schur, rsf2csf, orth, svd
+# Local imports
+from misc import norm
+from basic import solve, inv
+from special_matrices import triu, all_mat
+from decomp import eig
+from decomp_svd import orth, svd
+from decomp_schur import schur, rsf2csf
+
eps = np.finfo(float).eps
feps = np.finfo(single).eps
Modified: trunk/scipy/linalg/misc.py
===================================================================
--- trunk/scipy/linalg/misc.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/misc.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -1,10 +1,21 @@
import numpy as np
from numpy.linalg import LinAlgError
-### Norm
+__all__ = ['LinAlgError', 'norm']
+
def norm(a, ord=None):
# Differs from numpy only in non-finite handling
return np.linalg.norm(np.asarray_chkfinite(a), ord=ord)
norm.__doc__ = np.linalg.norm.__doc__
+
+def _datanotshared(a1,a):
+ if a1 is a:
+ return False
+ else:
+ #try comparing data pointers
+ try:
+ return a1.__array_interface__['data'][0] != a.__array_interface__['data'][0]
+ except:
+ return True
\ No newline at end of file
Modified: trunk/scipy/linalg/tests/test_basic.py
===================================================================
--- trunk/scipy/linalg/tests/test_basic.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/tests/test_basic.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -107,7 +107,7 @@
# with the RHS as a 1D array.
ab = array([[-99, 1.0, 1.0], [4.0, 4.0, 4.0]])
b = array([1.0, 4.0, 1.0])
- c, x = solveh_banded(ab, b)
+ x = solveh_banded(ab, b)
assert_array_almost_equal(x, [0.0, 1.0, 0.0])
def test_02_upper(self):
@@ -121,7 +121,7 @@
b = array([[1.0, 4.0],
[4.0, 2.0],
[1.0, 4.0]])
- c, x = solveh_banded(ab, b)
+ x = solveh_banded(ab, b)
expected = array([[0.0, 1.0],
[1.0, 0.0],
[0.0, 1.0]])
@@ -135,7 +135,7 @@
# with the RHS as a 2D array with shape (3,1).
ab = array([[-99, 1.0, 1.0], [4.0, 4.0, 4.0]])
b = array([1.0, 4.0, 1.0]).reshape(-1,1)
- c, x = solveh_banded(ab, b)
+ x = solveh_banded(ab, b)
assert_array_almost_equal(x, array([0.0, 1.0, 0.0]).reshape(-1,1))
def test_01_lower(self):
@@ -147,7 +147,7 @@
ab = array([[4.0, 4.0, 4.0],
[1.0, 1.0, -99]])
b = array([1.0, 4.0, 1.0])
- c, x = solveh_banded(ab, b, lower=True)
+ x = solveh_banded(ab, b, lower=True)
assert_array_almost_equal(x, [0.0, 1.0, 0.0])
def test_02_lower(self):
@@ -161,7 +161,7 @@
b = array([[1.0, 4.0],
[4.0, 2.0],
[1.0, 4.0]])
- c, x = solveh_banded(ab, b, lower=True)
+ x = solveh_banded(ab, b, lower=True)
expected = array([[0.0, 1.0],
[1.0, 0.0],
[0.0, 1.0]])
@@ -175,7 +175,7 @@
#
ab = array([[-99, 1.0, 1.0], [4.0, 4.0, 4.0]], dtype=float32)
b = array([1.0, 4.0, 1.0], dtype=float32)
- c, x = solveh_banded(ab, b)
+ x = solveh_banded(ab, b)
assert_array_almost_equal(x, [0.0, 1.0, 0.0])
def test_02_float32(self):
@@ -189,7 +189,7 @@
b = array([[1.0, 4.0],
[4.0, 2.0],
[1.0, 4.0]], dtype=float32)
- c, x = solveh_banded(ab, b)
+ x = solveh_banded(ab, b)
expected = array([[0.0, 1.0],
[1.0, 0.0],
[0.0, 1.0]])
@@ -203,7 +203,7 @@
#
ab = array([[-99, -1.0j, -1.0j], [4.0, 4.0, 4.0]])
b = array([-1.0j, 4.0-1j, 4+1j])
- c, x = solveh_banded(ab, b)
+ x = solveh_banded(ab, b)
assert_array_almost_equal(x, [0.0, 1.0, 1.0])
def test_02_complex(self):
@@ -217,7 +217,7 @@
b = array([[ -1j, 4.0j],
[4.0-1j, -1.0-1j],
[4.0+1j, 4.0]])
- c, x = solveh_banded(ab, b)
+ x = solveh_banded(ab, b)
expected = array([[0.0, 1.0j],
[1.0, 0.0],
[1.0, 1.0]])
Modified: trunk/scipy/linalg/tests/test_decomp.py
===================================================================
--- trunk/scipy/linalg/tests/test_decomp.py 2010-04-09 17:57:46 UTC (rev 6318)
+++ trunk/scipy/linalg/tests/test_decomp.py 2010-04-10 01:47:20 UTC (rev 6319)
@@ -17,8 +17,8 @@
import numpy as np
from numpy.testing import *
-from scipy.linalg import eig,eigvals,lu,svd,svdvals,cholesky,qr, \
- schur,rsf2csf, lu_solve,lu_factor,solve,diagsvd,hessenberg,rq, \
+from scipy.linalg import eig, eigvals, lu, svd, svdvals, cholesky, qr, \
+ schur, rsf2csf, lu_solve, lu_factor, solve, diagsvd, hessenberg, rq, \
eig_banded, eigvals_banded, eigh
from scipy.linalg.flapack import dgbtrf, dgbtrs, zgbtrf, zgbtrs, \
dsbev, dsbevd, dsbevx, zhbevd, zhbevx
@@ -837,8 +837,8 @@
c = transpose(c)
a = dot(c,transpose(conjugate(c)))
assert_array_almost_equal(cholesky(a,lower=1),c)
+
-
class TestQR(TestCase):
def test_simple(self):
More information about the Scipy-svn
mailing list