# [Numpy-svn] r5102 - in trunk/numpy/linalg: . tests

numpy-svn@scip... numpy-svn@scip...
Sun Apr 27 10:27:32 CDT 2008

```Author: charris
Date: 2008-04-27 10:27:30 -0500 (Sun, 27 Apr 2008)
New Revision: 5102

Modified:
trunk/numpy/linalg/linalg.py
trunk/numpy/linalg/tests/test_linalg.py
Log:
Make functions in linalg.py accept nestes lists.
Use wrap to keep matrix environment intact.
Base patch from nmb.

Modified: trunk/numpy/linalg/linalg.py
===================================================================
--- trunk/numpy/linalg/linalg.py	2008-04-26 23:36:55 UTC (rev 5101)
+++ trunk/numpy/linalg/linalg.py	2008-04-27 15:27:30 UTC (rev 5102)
@@ -148,10 +148,10 @@

Parameters
----------
-    a : array, shape b.shape+Q
+    a : array-like, shape b.shape+Q
Coefficient tensor. Shape Q of the rightmost indices of a must
be such that a is 'square', ie., prod(Q) == prod(b.shape).
-    b : array, any shape
+    b : array-like, any shape
Right-hand tensor.
axes : tuple of integers
Axes in a to reorder to the right, before inversion.
@@ -192,7 +192,7 @@

a = a.reshape(-1, prod)
b = b.ravel()
-    res = solve(a, b)
+    res = wrap(solve(a, b))
res.shape = oldshape
return res

@@ -201,8 +201,8 @@

Parameters
----------
-    a : array, shape (M, M)
-    b : array, shape (M,)
+    a : array-like, shape (M, M)
+    b : array-like, shape (M,)

Returns
-------
@@ -211,6 +211,8 @@
Raises LinAlgError if a is singular or not square

"""
+    a, _ = _makearray(a)
+    b, wrap = _makearray(b)
one_eq = len(b.shape) == 1
if one_eq:
b = b[:, newaxis]
@@ -232,9 +234,9 @@
if results['info'] > 0:
raise LinAlgError, 'Singular matrix'
if one_eq:
-        return b.ravel().astype(result_t)
+        return wrap(b.ravel().astype(result_t))
else:
-        return b.transpose().astype(result_t)
+        return wrap(b.transpose().astype(result_t))

def tensorinv(a, ind=2):
@@ -250,7 +252,7 @@

Parameters
----------
-    a : array
+    a : array-like
Tensor to 'invert'. Its shape must 'square', ie.,
prod(a.shape[:ind]) == prod(a.shape[ind:])
ind : integer > 0
@@ -340,12 +342,12 @@

Parameters
----------
-    a : array, shape (M, M)
+    a : array-like, shape (M, M)
Matrix to be decomposed

Returns
-------
-    L : array, shape (M, M)
+    L : array-like, shape (M, M)
Lower-triangular Cholesky factor of A

Raises LinAlgError if decomposition fails
@@ -363,6 +365,7 @@
[ 0.+2.j,  5.+0.j]])

"""
+    a, wrap = _makearray(a)
_assertRank2(a)
_assertSquareness(a)
t, result_t = _commonType(a)
@@ -379,8 +382,8 @@
Cholesky decomposition cannot be computed'
s = triu(a, k=0).transpose()
if (s.dtype != result_t):
-        return s.astype(result_t)
-    return s
+        s = s.astype(result_t)
+    return wrap(s)

# QR decompostion

@@ -392,7 +395,7 @@

Parameters
----------
-    a : array, shape (M, N)
+    a : array-like, shape (M, N)
Matrix to be decomposed
mode : {'full', 'r', 'economic'}
Determines what information is to be returned. 'full' is the default.
@@ -413,6 +416,8 @@
The diagonal and the upper triangle of A2 contains R,
while the rest of the matrix is undefined.

+    If a is a matrix, so are all the return values.
+
Raises LinAlgError if decomposition fails

Notes
@@ -435,6 +440,7 @@
True

"""
+    a, wrap = _makearray(a)
_assertRank2(a)
m, n = a.shape
t, result_t = _commonType(a)
@@ -503,7 +509,7 @@

q = _fastCopyAndTranspose(result_t, a[:mn,:])

-    return q, r
+    return wrap(q), wrap(r)

# Eigenvalues
@@ -514,7 +520,7 @@

Parameters
----------
-    a : array, shape (M, M)
+    a : array-like, shape (M, M)
A complex or real matrix whose eigenvalues and eigenvectors
will be computed.

@@ -525,6 +531,8 @@
They are not necessarily ordered, nor are they necessarily
real for real matrices.

+    If a is a matrix, so is w.
+
Raises LinAlgError if eigenvalue computation does not converge

@@ -545,6 +553,7 @@
determinant and I is the identity matrix.

"""
+    a, wrap = _makearray(a)
_assertRank2(a)
_assertSquareness(a)
_assertFinite(a)
@@ -585,7 +594,7 @@
result_t = _complexType(result_t)
if results['info'] > 0:
raise LinAlgError, 'Eigenvalues did not converge'
-    return w.astype(result_t)
+    return wrap(w.astype(result_t))

def eigvalsh(a, UPLO='L'):
@@ -593,7 +602,7 @@

Parameters
----------
-    a : array, shape (M, M)
+    a : array-like, shape (M, M)
A complex or real matrix whose eigenvalues and eigenvectors
will be computed.
UPLO : {'L', 'U'}
@@ -627,6 +636,7 @@
determinant and I is the identity matrix.

"""
+    a, wrap = _makearray(a)
_assertRank2(a)
_assertSquareness(a)
t, result_t = _commonType(a)
@@ -663,7 +673,7 @@
iwork, liwork, 0)
if results['info'] > 0:
raise LinAlgError, 'Eigenvalues did not converge'
-    return w.astype(result_t)
+    return wrap(w.astype(result_t))

def _convertarray(a):
t, result_t = _commonType(a)
@@ -679,7 +689,7 @@

Parameters
----------
-    a : array, shape (M, M)
+    a : array-like, shape (M, M)
A complex or real 2-d array whose eigenvalues and eigenvectors
will be computed.

@@ -693,6 +703,8 @@
The normalized eigenvector corresponding to the eigenvalue w[i] is
the column v[:,i].

+    If a is a matrix, so are all the return values.
+
Raises LinAlgError if eigenvalue computation does not converge

@@ -774,7 +786,7 @@
if results['info'] > 0:
raise LinAlgError, 'Eigenvalues did not converge'
vt = v.transpose().astype(result_t)
-    return w.astype(result_t), wrap(vt)
+    return wrap(w.astype(result_t)), wrap(vt)

def eigh(a, UPLO='L'):
@@ -782,7 +794,7 @@

Parameters
----------
-    a : array, shape (M, M)
+    a : array-like, shape (M, M)
A complex Hermitian or symmetric real matrix whose eigenvalues
and eigenvectors will be computed.
UPLO : {'L', 'U'}
@@ -798,6 +810,8 @@
The normalized eigenvector corresponding to the eigenvalue w[i] is
the column v[:,i].

+    If a is a matrix, then so are the return values.
+
Raises LinAlgError if eigenvalue computation does not converge

@@ -858,7 +872,7 @@
if results['info'] > 0:
raise LinAlgError, 'Eigenvalues did not converge'
at = a.transpose().astype(result_t)
-    return w.astype(_realType(result_t)), wrap(at)
+    return wrap(w.astype(_realType(result_t))), wrap(at)

# Singular value decomposition
@@ -873,13 +887,13 @@

Parameters
----------
-    a : array, shape (M, N)
+    a : array-like, 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
+        Whether to compute U and Vh in addition to s

Returns
-------
@@ -889,7 +903,7 @@
K = min(M, N)
Vh: array, shape (N,N) or (K,N) depending on full_matrices

-    For compute_uv = False, only s is returned.
+    If a is a matrix, so are all the return values.

Raises LinAlgError if SVD computation does not converge

@@ -965,9 +979,9 @@
if compute_uv:
u = u.transpose().astype(result_t)
vt = vt.transpose().astype(result_t)
-        return wrap(u), s, wrap(vt)
+        return wrap(u), wrap(s), wrap(vt)
else:
-        return s
+        return wrap(s)

def cond(x,p=None):
"""Compute the condition number of a matrix.
@@ -978,7 +992,7 @@

Parameters
----------
-    x : array, shape (M, N)
+    x : array-like, shape (M, N)
The matrix whose condition number is sought.
p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}
Order of the norm:
@@ -1017,7 +1031,7 @@

Parameters
----------
-    a : array, shape (M, N)
+    a : array-like, shape (M, N)
Matrix to be pseudo-inverted
rcond : float
Cutoff for 'small' singular values.
@@ -1027,6 +1041,7 @@
Returns
-------
B : array, shape (N, M)
+        If a is a matrix, then so is B.

Raises LinAlgError if SVD computation does not converge

@@ -1053,8 +1068,8 @@
s[i] = 1./s[i]
else:
s[i] = 0.;
-    return wrap(dot(transpose(vt),
-                       multiply(s[:, newaxis],transpose(u))))
+    res = dot(transpose(vt), multiply(s[:, newaxis],transpose(u)))
+    return wrap(res)

# Determinant

@@ -1063,7 +1078,7 @@

Parameters
----------
-    a : array, shape (M, M)
+    a : array-like, shape (M, M)

Returns
-------
@@ -1104,8 +1119,8 @@

Parameters
----------
-    a : array, shape (M, N)
-    b : array, shape (M,) or (M, K)
+    a : array-like, shape (M, N)
+    b : array-like, shape (M,) or (M, K)
rcond : float
Cutoff for 'small' singular values.
Singular values smaller than rcond*largest_singular_value are
@@ -1125,6 +1140,10 @@
Rank of matrix a
s : array, shape (min(M,N),)
Singular values of a
+
+    If b is a matrix, then all results except the rank are also returned as
+    matrices.
+
"""
import math
a = asarray(a)
@@ -1188,14 +1207,14 @@
if results['rank'] == n and m > n:
resids = sum((transpose(bstar)[n:,:])**2, axis=0).astype(result_t)
st = s[:min(n, m)].copy().astype(_realType(result_t))
-    return wrap(x), resids, results['rank'], st
+    return wrap(x), wrap(resids), results['rank'], wrap(st)

def norm(x, ord=None):
"""Matrix or vector norm.

Parameters
----------
-    x : array, shape (M,) or (M, N)
+    x : array-like, shape (M,) or (M, N)
ord : number, or {None, 1, -1, 2, -2, inf, -inf, 'fro'}
Order of the norm:

Modified: trunk/numpy/linalg/tests/test_linalg.py
===================================================================
--- trunk/numpy/linalg/tests/test_linalg.py	2008-04-26 23:36:55 UTC (rev 5101)
+++ trunk/numpy/linalg/tests/test_linalg.py	2008-04-27 15:27:30 UTC (rev 5102)
@@ -4,14 +4,14 @@
from numpy.testing import *
set_package_path()
from numpy import array, single, double, csingle, cdouble, dot, identity, \
-        multiply, atleast_2d, inf
+        multiply, atleast_2d, inf, asarray
from numpy import linalg
from linalg import matrix_power
restore_path()

old_assert_almost_equal = assert_almost_equal
def assert_almost_equal(a, b, **kw):
-    if a.dtype.type in (single, csingle):
+    if asarray(a).dtype.type in (single, csingle):
decimal = 6
else:
decimal = 12
@@ -47,6 +47,12 @@
except linalg.LinAlgError, e:
pass

+    def check_nonarray(self):
+        a = [[1,2], [3,4]]
+        b = [2, 1]
+        self.do(a,b)
+
+
class TestSolve(LinalgTestCase):
def do(self, a, b):
x = linalg.solve(a, b)
@@ -55,7 +61,7 @@
class TestInv(LinalgTestCase):
def do(self, a, b):
a_inv = linalg.inv(a)
-        assert_almost_equal(dot(a, a_inv), identity(a.shape[0]))
+        assert_almost_equal(dot(a, a_inv), identity(asarray(a).shape[0]))

class TestEigvals(LinalgTestCase):
def do(self, a, b):
@@ -91,15 +97,15 @@
class TestPinv(LinalgTestCase):
def do(self, a, b):
a_ginv = linalg.pinv(a)
-        assert_almost_equal(dot(a, a_ginv), identity(a.shape[0]))
+        assert_almost_equal(dot(a, a_ginv), identity(asarray(a).shape[0]))

class TestDet(LinalgTestCase):
def do(self, a, b):
d = linalg.det(a)
-        if a.dtype.type in (single, double):
+        if asarray(a).dtype.type in (single, double):
else:
assert_almost_equal(d, multiply.reduce(ev))

@@ -108,7 +114,7 @@
u, s, vt = linalg.svd(a, 0)
x, residuals, rank, sv = linalg.lstsq(a, b)
assert_almost_equal(b, dot(a, x))
-        assert_equal(rank, a.shape[0])
+        assert_equal(rank, asarray(a).shape[0])
assert_almost_equal(sv, s)

class TestMatrixPower(ParametricTestCase):

```