1.5.3 线性代数操作:scipy.linalg

scipy.linalg 模块提供了标准的线性代数操作,这依赖于底层的高效实现(BLAS、LAPACK)。

In [3]:

  1. from scipy import linalg
  2. arr = np.array([[1, 2],
  3. [3, 4]])
  4. linalg.det(arr)

Out[3]:

  1. -2.0

In [4]:

  1. arr = np.array([[3, 2],
  2. [6, 4]])
  3. linalg.det(arr)

Out[4]:

  1. 0.0

In [5]:

  1. linalg.det(np.ones((3, 4)))
  1.  ------------- ------------- ------------- ------------- -----------------------
  2. ValueError Traceback (most recent call last)
  3. <ipython-input-5-4d4672bd00a7> in <module>()
  4. ----> 1 linalg.det(np.ones((3, 4)))
  5. /Library/Python/2.7/site-packages/scipy/linalg/basic.pyc in det(a, overwrite_a, check_finite)
  6. 440 a1 = np.asarray(a)
  7. 441 if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
  8. --> 442 raise ValueError('expected square matrix')
  9. 443 overwrite_a = overwrite_a or _datacopied(a1, a)
  10. 444 fdet, = get_flinalg_funcs(('det',), (a1,))
  11. ValueError: expected square matrix

In [6]:

  1. arr = np.array([[1, 2],
  2. [3, 4]])
  3. iarr = linalg.inv(arr)
  4. iarr

Out[6]:

  1. array([[-2\. , 1\. ],
  2. [ 1.5, -0.5]])

In [7]:

  1. np.allclose(np.dot(arr, iarr), np.eye(2))

Out[7]:

  1. True

最后计算逆奇异矩阵(行列式为0)将抛出LinAlgError :

In [8]:

  1. arr = np.array([[3, 2],
  2. [6, 4]])
  3. linalg.inv(arr)
  1.  ------------- ------------- ------------- ------------- -----------------------
  2. LinAlgError Traceback (most recent call last)
  3. <ipython-input-8-e8078a9a17b2> in <module>()
  4. 1 arr = np.array([[3, 2],
  5. 2 [6, 4]])
  6. ----> 3 linalg.inv(arr)
  7. /Library/Python/2.7/site-packages/scipy/linalg/basic.pyc in inv(a, overwrite_a, check_finite)
  8. 381 inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1)
  9. 382 if info > 0:
  10. --> 383 raise LinAlgError("singular matrix")
  11. 384 if info < 0:
  12. 385 raise ValueError('illegal value in %d-th argument of internal '
  13. LinAlgError: singular matrix
  • 还有更多高级的操作,奇异值分解(SVD):

In [9]:

  1. arr = np.arange(9).reshape((3, 3)) + np.diag([1, 0, 1])
  2. uarr, spec, vharr = linalg.svd(arr)

结果的数组频谱是:

In [10]:

  1. spec

Out[10]:

  1. array([ 14.88982544, 0.45294236, 0.29654967])

原始矩阵可以用svdnp.dot矩阵相乘的结果重新获得:

In [11]:

  1. sarr = np.diag(spec)
  2. svd_mat = uarr.dot(sarr).dot(vharr)
  3. np.allclose(svd_mat, arr)

Out[11]:

  1. True

SVD常被用于统计和信号处理。其他标准分解 (QR, LU, Cholesky, Schur), 以及线性系统的求解器,也可以在scipy.linalg中找到。