summaryrefslogtreecommitdiff
path: root/numpy/linalg
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/linalg')
-rw-r--r--numpy/linalg/linalg.py162
-rw-r--r--numpy/linalg/tests/test_linalg.py5
2 files changed, 84 insertions, 83 deletions
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
index 771481e8e..92fa6cb73 100644
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -29,6 +29,7 @@ from numpy.core import (
swapaxes, divide, count_nonzero, isnan
)
from numpy.core.multiarray import normalize_axis_index
+from numpy.core.overrides import set_module
from numpy.core import overrides
from numpy.lib.twodim_base import triu, eye
from numpy.linalg import lapack_lite, _umath_linalg
@@ -47,7 +48,8 @@ _L = b'L'
fortran_int = intc
-# Error object
+
+@set_module('numpy.linalg')
class LinAlgError(Exception):
"""
Generic Python-exception-derived object raised by linalg functions.
@@ -75,7 +77,6 @@ class LinAlgError(Exception):
numpy.linalg.LinAlgError: Singular matrix
"""
- pass
def _determine_error_states():
@@ -376,7 +377,7 @@ def solve(a, b):
>>> b = np.array([9,8])
>>> x = np.linalg.solve(a, b)
>>> x
- array([ 2., 3.])
+ array([2., 3.])
Check that the solution is correct:
@@ -534,10 +535,10 @@ def inv(a):
>>> a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
>>> inv(a)
- array([[[-2. , 1. ],
- [ 1.5, -0.5]],
- [[-5. , 2. ],
- [ 3. , -1. ]]])
+ array([[[-2. , 1. ],
+ [ 1.5 , -0.5 ]],
+ [[-1.25, 0.75],
+ [ 0.75, -0.25]]])
"""
a, wrap = _makearray(a)
@@ -729,21 +730,21 @@ def cholesky(a):
--------
>>> A = np.array([[1,-2j],[2j,5]])
>>> A
- array([[ 1.+0.j, 0.-2.j],
+ array([[ 1.+0.j, -0.-2.j],
[ 0.+2.j, 5.+0.j]])
>>> L = np.linalg.cholesky(A)
>>> L
- array([[ 1.+0.j, 0.+0.j],
- [ 0.+2.j, 1.+0.j]])
+ array([[1.+0.j, 0.+0.j],
+ [0.+2.j, 1.+0.j]])
>>> np.dot(L, L.T.conj()) # verify that L * L.H = A
- array([[ 1.+0.j, 0.-2.j],
- [ 0.+2.j, 5.+0.j]])
+ array([[1.+0.j, 0.-2.j],
+ [0.+2.j, 5.+0.j]])
>>> A = [[1,-2j],[2j,5]] # what happens if A is only array_like?
>>> np.linalg.cholesky(A) # an ndarray object is returned
- array([[ 1.+0.j, 0.+0.j],
- [ 0.+2.j, 1.+0.j]])
+ array([[1.+0.j, 0.+0.j],
+ [0.+2.j, 1.+0.j]])
>>> # But a matrix object is returned if A is a matrix object
- >>> LA.cholesky(np.matrix(A))
+ >>> np.linalg.cholesky(np.matrix(A))
matrix([[ 1.+0.j, 0.+0.j],
[ 0.+2.j, 1.+0.j]])
@@ -877,9 +878,9 @@ def qr(a, mode='reduced'):
[1, 1],
[2, 1]])
>>> b = np.array([1, 0, 2, 1])
- >>> q, r = LA.qr(A)
+ >>> q, r = np.linalg.qr(A)
>>> p = np.dot(q.T, b)
- >>> np.dot(LA.inv(r), p)
+ >>> np.dot(np.linalg.inv(r), p)
array([ 1.1e-16, 1.0e+00])
"""
@@ -1048,7 +1049,7 @@ def eigvals(a):
>>> A = np.dot(Q, D)
>>> A = np.dot(A, Q.T)
>>> LA.eigvals(A)
- array([ 1., -1.])
+ array([ 1., -1.]) # random
"""
a, wrap = _makearray(a)
@@ -1130,24 +1131,24 @@ def eigvalsh(a, UPLO='L'):
>>> from numpy import linalg as LA
>>> a = np.array([[1, -2j], [2j, 5]])
>>> LA.eigvalsh(a)
- array([ 0.17157288, 5.82842712])
+ array([ 0.17157288, 5.82842712]) # may vary
>>> # demonstrate the treatment of the imaginary part of the diagonal
>>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]])
>>> a
- array([[ 5.+2.j, 9.-2.j],
- [ 0.+2.j, 2.-1.j]])
+ array([[5.+2.j, 9.-2.j],
+ [0.+2.j, 2.-1.j]])
>>> # with UPLO='L' this is numerically equivalent to using LA.eigvals()
>>> # with:
>>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]])
>>> b
- array([[ 5.+0.j, 0.-2.j],
- [ 0.+2.j, 2.+0.j]])
+ array([[5.+0.j, 0.-2.j],
+ [0.+2.j, 2.+0.j]])
>>> wa = LA.eigvalsh(a)
>>> wb = LA.eigvals(b)
>>> wa; wb
- array([ 1., 6.])
- array([ 6.+0.j, 1.+0.j])
+ array([1., 6.])
+ array([6.+0.j, 1.+0.j])
"""
UPLO = UPLO.upper()
@@ -1263,19 +1264,19 @@ def eig(a):
>>> w, v = LA.eig(np.diag((1, 2, 3)))
>>> w; v
- array([ 1., 2., 3.])
- array([[ 1., 0., 0.],
- [ 0., 1., 0.],
- [ 0., 0., 1.]])
+ array([1., 2., 3.])
+ array([[1., 0., 0.],
+ [0., 1., 0.],
+ [0., 0., 1.]])
Real matrix possessing complex e-values and e-vectors; note that the
e-values are complex conjugates of each other.
>>> w, v = LA.eig(np.array([[1, -1], [1, 1]]))
>>> w; v
- array([ 1. + 1.j, 1. - 1.j])
- array([[ 0.70710678+0.j , 0.70710678+0.j ],
- [ 0.00000000-0.70710678j, 0.00000000+0.70710678j]])
+ array([1.+1.j, 1.-1.j])
+ array([[0.70710678+0.j , 0.70710678-0.j ],
+ [0. -0.70710678j, 0. +0.70710678j]])
Complex-valued matrix with real e-values (but complex-valued e-vectors);
note that a.conj().T = a, i.e., a is Hermitian.
@@ -1283,9 +1284,9 @@ def eig(a):
>>> a = np.array([[1, 1j], [-1j, 1]])
>>> w, v = LA.eig(a)
>>> w; v
- array([ 2.00000000e+00+0.j, 5.98651912e-36+0.j]) # i.e., {2, 0}
- array([[ 0.00000000+0.70710678j, 0.70710678+0.j ],
- [ 0.70710678+0.j , 0.00000000+0.70710678j]])
+ array([2.+0.j, 0.+0.j])
+ array([[ 0. +0.70710678j, 0.70710678+0.j ], # may vary
+ [ 0.70710678+0.j , -0. +0.70710678j]])
Be careful about round-off error!
@@ -1293,9 +1294,9 @@ def eig(a):
>>> # Theor. e-values are 1 +/- 1e-9
>>> w, v = LA.eig(a)
>>> w; v
- array([ 1., 1.])
- array([[ 1., 0.],
- [ 0., 1.]])
+ array([1., 1.])
+ array([[1., 0.],
+ [0., 1.]])
"""
a, wrap = _makearray(a)
@@ -1391,49 +1392,49 @@ def eigh(a, UPLO='L'):
>>> from numpy import linalg as LA
>>> a = np.array([[1, -2j], [2j, 5]])
>>> a
- array([[ 1.+0.j, 0.-2.j],
+ array([[ 1.+0.j, -0.-2.j],
[ 0.+2.j, 5.+0.j]])
>>> w, v = LA.eigh(a)
>>> w; v
- array([ 0.17157288, 5.82842712])
- array([[-0.92387953+0.j , -0.38268343+0.j ],
- [ 0.00000000+0.38268343j, 0.00000000-0.92387953j]])
+ array([0.17157288, 5.82842712])
+ array([[-0.92387953+0.j , -0.38268343+0.j ], # may vary
+ [ 0. +0.38268343j, 0. -0.92387953j]])
>>> np.dot(a, v[:, 0]) - w[0] * v[:, 0] # verify 1st e-val/vec pair
- array([2.77555756e-17 + 0.j, 0. + 1.38777878e-16j])
+ array([5.55111512e-17+0.0000000e+00j, 0.00000000e+00+1.2490009e-16j])
>>> np.dot(a, v[:, 1]) - w[1] * v[:, 1] # verify 2nd e-val/vec pair
- array([ 0.+0.j, 0.+0.j])
+ array([0.+0.j, 0.+0.j])
>>> A = np.matrix(a) # what happens if input is a matrix object
>>> A
- matrix([[ 1.+0.j, 0.-2.j],
+ matrix([[ 1.+0.j, -0.-2.j],
[ 0.+2.j, 5.+0.j]])
>>> w, v = LA.eigh(A)
>>> w; v
- array([ 0.17157288, 5.82842712])
- matrix([[-0.92387953+0.j , -0.38268343+0.j ],
- [ 0.00000000+0.38268343j, 0.00000000-0.92387953j]])
+ array([0.17157288, 5.82842712])
+ matrix([[-0.92387953+0.j , -0.38268343+0.j ], # may vary
+ [ 0. +0.38268343j, 0. -0.92387953j]])
>>> # demonstrate the treatment of the imaginary part of the diagonal
>>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]])
>>> a
- array([[ 5.+2.j, 9.-2.j],
- [ 0.+2.j, 2.-1.j]])
+ array([[5.+2.j, 9.-2.j],
+ [0.+2.j, 2.-1.j]])
>>> # with UPLO='L' this is numerically equivalent to using LA.eig() with:
>>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]])
>>> b
- array([[ 5.+0.j, 0.-2.j],
- [ 0.+2.j, 2.+0.j]])
+ array([[5.+0.j, 0.-2.j],
+ [0.+2.j, 2.+0.j]])
>>> wa, va = LA.eigh(a)
>>> wb, vb = LA.eig(b)
>>> wa; wb
- array([ 1., 6.])
- array([ 6.+0.j, 1.+0.j])
+ array([1., 6.])
+ array([6.+0.j, 1.+0.j])
>>> va; vb
- array([[-0.44721360-0.j , -0.89442719+0.j ],
- [ 0.00000000+0.89442719j, 0.00000000-0.4472136j ]])
- array([[ 0.89442719+0.j , 0.00000000-0.4472136j],
- [ 0.00000000-0.4472136j, 0.89442719+0.j ]])
+ array([[-0.4472136 +0.j , -0.89442719+0.j ], # may vary
+ [ 0. +0.89442719j, 0. -0.4472136j ]])
+ array([[ 0.89442719+0.j , -0. +0.4472136j],
+ [-0. +0.4472136j, 0.89442719+0.j ]])
"""
UPLO = UPLO.upper()
if UPLO not in ('L', 'U'):
@@ -1704,9 +1705,9 @@ def cond(x, p=None):
>>> LA.cond(a, 2)
1.4142135623730951
>>> LA.cond(a, -2)
- 0.70710678118654746
+ 0.70710678118654746 # may vary
>>> min(LA.svd(a, compute_uv=0))*min(LA.svd(LA.inv(a), compute_uv=0))
- 0.70710678118654746
+ 0.70710678118654746 # may vary
"""
x = asarray(x) # in case we have a matrix
@@ -2001,7 +2002,7 @@ def slogdet(a):
>>> a = np.array([[1, 2], [3, 4]])
>>> (sign, logdet) = np.linalg.slogdet(a)
>>> (sign, logdet)
- (-1, 0.69314718055994529)
+ (-1, 0.69314718055994529) # may vary
>>> sign * np.exp(logdet)
-2.0
@@ -2073,7 +2074,7 @@ def det(a):
>>> a = np.array([[1, 2], [3, 4]])
>>> np.linalg.det(a)
- -2.0
+ -2.0 # may vary
Computing determinants for a stack of matrices:
@@ -2180,15 +2181,15 @@ def lstsq(a, b, rcond="warn"):
[ 3., 1.]])
>>> m, c = np.linalg.lstsq(A, y, rcond=None)[0]
- >>> print(m, c)
- 1.0 -0.95
+ >>> m, c
+ (1.0 -0.95) # may vary
Plot the data along with the fitted line:
>>> import matplotlib.pyplot as plt
- >>> plt.plot(x, y, 'o', label='Original data', markersize=10)
- >>> plt.plot(x, m*x + c, 'r', label='Fitted line')
- >>> plt.legend()
+ >>> _ = plt.plot(x, y, 'o', label='Original data', markersize=10)
+ >>> _ = plt.plot(x, m*x + c, 'r', label='Fitted line')
+ >>> _ = plt.legend()
>>> plt.show()
"""
@@ -2204,6 +2205,7 @@ def lstsq(a, b, rcond="warn"):
raise LinAlgError('Incompatible dimensions')
t, result_t = _commonType(a, b)
+ # FIXME: real_t is unused
real_t = _linalgRealType(t)
result_real_t = _realType(result_t)
@@ -2365,7 +2367,7 @@ def norm(x, ord=None, axis=None, keepdims=False):
>>> from numpy import linalg as LA
>>> a = np.arange(9) - 4
>>> a
- array([-4, -3, -2, -1, 0, 1, 2, 3, 4])
+ array([-4, -3, -2, ..., 2, 3, 4])
>>> b = a.reshape((3, 3))
>>> b
array([[-4, -3, -2],
@@ -2401,13 +2403,13 @@ def norm(x, ord=None, axis=None, keepdims=False):
7.3484692283495345
>>> LA.norm(a, -2)
- nan
+ 0.0
>>> LA.norm(b, -2)
- 1.8570331885190563e-016
+ 1.8570331885190563e-016 # may vary
>>> LA.norm(a, 3)
- 5.8480354764257312
+ 5.8480354764257312 # may vary
>>> LA.norm(a, -3)
- nan
+ 0.0
Using the `axis` argument to compute vector norms:
@@ -2582,18 +2584,20 @@ def multi_dot(arrays):
>>> from numpy.linalg import multi_dot
>>> # Prepare some data
- >>> A = np.random.random(10000, 100)
- >>> B = np.random.random(100, 1000)
- >>> C = np.random.random(1000, 5)
- >>> D = np.random.random(5, 333)
+ >>> A = np.random.random((10000, 100))
+ >>> B = np.random.random((100, 1000))
+ >>> C = np.random.random((1000, 5))
+ >>> D = np.random.random((5, 333))
>>> # the actual dot multiplication
- >>> multi_dot([A, B, C, D])
+ >>> _ = multi_dot([A, B, C, D])
instead of::
- >>> np.dot(np.dot(np.dot(A, B), C), D)
+ >>> _ = np.dot(np.dot(np.dot(A, B), C), D)
+ ...
>>> # or
- >>> A.dot(B).dot(C).dot(D)
+ >>> _ = A.dot(B).dot(C).dot(D)
+ ...
Notes
-----
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index affff5312..f95909cd1 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -13,7 +13,7 @@ import pytest
import numpy as np
from numpy import array, single, double, csingle, cdouble, dot, identity, matmul
-from numpy import multiply, atleast_2d, inf, asarray, matrix
+from numpy import multiply, atleast_2d, inf, asarray
from numpy import linalg
from numpy.linalg import matrix_power, norm, matrix_rank, multi_dot, LinAlgError
from numpy.linalg.linalg import _multi_dot_matrix_chain_order
@@ -955,7 +955,6 @@ class TestMatrixPower(object):
dtnoinv = [object, np.dtype('e'), np.dtype('g'), np.dtype('G')]
def test_large_power(self, dt):
- power = matrix_power
rshft = self.rshft_1.astype(dt)
assert_equal(
matrix_power(rshft, 2**100 + 2**10 + 2**5 + 0), self.rshft_0)
@@ -1619,8 +1618,6 @@ class TestQR(object):
def test_qr_empty(self, m, n):
k = min(m, n)
a = np.empty((m, n))
- a_type = type(a)
- a_dtype = a.dtype
self.check_qr(a)