三、线性代数

  1. numpyscipy都提供了线性代数函数库linalg。但是scipy的线性代数库比numpy更加全面。

  2. numpy中的求解线性方程组:numpy.linalg.solve(a, b)。而scipy中的求解线性方程组:

    1. scipy.linalg.solve(a, b, sym_pos=False, lower=False, overwrite_a=False,
    2. overwrite_b=False, debug=False, check_finite=True)
    • a:方阵,形状为 (M,M)
    • b:一维向量,形状为(M,)。它求解的是线性方程组 三、线性代数 - 图1。如果有 三、线性代数 - 图2 个线性方程组要求解,且 a,相同,则 b的形状为 (M,k)
    • sym_pos:一个布尔值,指定a是否正定的对称矩阵
    • lower:一个布尔值。如果sym_pos=True时:如果为lower=True,则使用a的下三角矩阵。默认使用a的上三角矩阵。
    • overwrite_a:一个布尔值,指定是否将结果写到a的存储区。
    • overwrite_b:一个布尔值,指定是否将结果写到b的存储区。
    • check_finite:如果为True,则检测输入中是否有nan或者inf

    返回线性方程组的解。

    通常求解矩阵 三、线性代数 - 图3,如果使用solve(A,B),要比先求逆矩阵、再矩阵相乘来的快。

    solve

  3. 矩阵的LU分解:

    1. scipy.linalg.lu_factor(a, overwrite_a=False, check_finite=True)
    • a:方阵,形状为(M,M),要求非奇异矩阵
    • overwrite_a:一个布尔值,指定是否将结果写到a的存储区。
    • check_finite:如果为True,则检测输入中是否有nan或者inf

    返回:

    • lu:一个数组,形状为(N,N),该矩阵的上三角矩阵就是U,下三角矩阵就是LL矩阵的对角线元素并未存储,因为它们全部是1)
    • piv:一个数组,形状为(N,)。它给出了P矩阵:矩阵a的第 i行被交换到了第piv[i]

    矩阵LU分解:

    三、线性代数 - 图5

    其中: 三、线性代数 - 图6 为转置矩阵,该矩阵任意一行只有一个1,其他全零;任意一列只有一个1,其他全零。三、线性代数 - 图7 为单位下三角矩阵(对角线元素为1), 三、线性代数 - 图8 为上三角矩阵(对角线元素为0)

    lu_factor

  4. 当对矩阵进行了LU分解之后,可以方便的求解线性方程组。

    1. scipy.linalg.lu_solve(lu_and_piv, b, trans=0, overwrite_b=False, check_finite=True)
    • lu_and_piv:一个元组,由lu_factor返回

    • b:一维向量,形状为(M,)。它求解的是线性方程组 三、线性代数 - 图10。如果有 三、线性代数 - 图11 个线性方程组要求解,且 a,相同,则 b的形状为 (M,k)

    • overwrite_b:一个布尔值,指定是否将结果写到b的存储区。

    • check_finite:如果为True,则检测输入中是否有nan或者inf

    • trans:指定求解类型.

      • 如果为 0 ,则求解: 三、线性代数 - 图12
      • 如果为 1 ,则求解: 三、线性代数 - 图13
      • 如果为 2 ,则求解: 三、线性代数 - 图14
  5. lstsqsolve更一般化,它不要求矩阵 三、线性代数 - 图15 是方阵。 它找到一组解 三、线性代数 - 图16,使得 三、线性代数 - 图17 最小,我们称得到的结果为最小二乘解。

    1. scipy.linalg.lstsq(a, b, cond=None, overwrite_a=False, overwrite_b=False,
    2. check_finite=True, lapack_driver=None)
    • a:为矩阵,形状为(M,N)
    • b:一维向量,形状为(M,)。它求解的是线性方程组 三、线性代数 - 图18。如果有 三、线性代数 - 图19 个线性方程组要求解,且 a,相同,则 b的形状为 (M,k)
    • cond:一个浮点数,去掉最小的一些特征值。当特征值小于cond * largest_singular_value时,该特征值认为是零
    • overwrite_a:一个布尔值,指定是否将结果写到a的存储区。
    • overwrite_b:一个布尔值,指定是否将结果写到b的存储区。
    • check_finite:如果为True,则检测输入中是否有nan或者inf
    • lapack_driver:一个字符串,指定求解算法。可以为:'gelsd'/'gelsy'/'gelss'。默认的'gelsd'效果就很好,但是在许多问题上'gelsy'效果更好。

    返回值:

    • x:最小二乘解,形状和b相同
    • residures:残差。如果 三、线性代数 - 图20 大于N或者小于M,或者使用了gelsy,则是个空数组;如果b是一维的,则它的形状是(1,);如果b是二维的,则形状为(K,)
    • rank:返回矩阵a的秩
    • sa的奇异值。如果使用gelsy,则返回None

    lstsq

  6. 求解特征值和特征向量:

    1. scipy.linalg.eig(a, b=None, left=False, right=True, overwrite_a=False,
    2. overwrite_b=False, check_finite=True)
    • a:一个方阵,形状为(M,M)。待求解特征值和特征向量的矩阵。
    • b:默认为None,表示求解标准的特征值问题: 三、线性代数 - 图22。 也可以是一个形状与a相同的方阵,此时表示广义特征值问题: 三、线性代数 - 图23
    • left:一个布尔值。如果为True,则计算左特征向量
    • right:一个布尔值。如果为True,则计算右特征向量
    • overwrite_a:一个布尔值,指定是否将结果写到a的存储区。
    • overwrite_b:一个布尔值,指定是否将结果写到b的存储区。
    • check_finite:如果为True,则检测输入中是否有nan或者inf

    返回值:

    • w:一个一维数组,代表了M特特征值。
    • vl:一个数组,形状为(M,M),表示正则化的左特征向量(每个特征向量占据一列,而不是一行)。仅当left=True时返回
    • vr:一个数组,形状为(M,M),表示正则化的右特征向量(每个特征向量占据一列,而不是一行)。仅当right=True时返回

    numpy提供了numpy.linalg.eig(a)来计算特征值和特征向量

    右特征值: 三、线性代数 - 图24;左特征值: 三、线性代数 - 图25,其中 三、线性代数 - 图26 为特征值的共轭。

    三、线性代数 - 图27,令

    三、线性代数 - 图28

    则有:

    三、线性代数 - 图29

    eig

  7. 矩阵的奇异值分解: 设矩阵 三、线性代数 - 图31三、线性代数 - 图32 阶的矩阵,则存在一个分解,使得: 三、线性代数 - 图33,其中 三、线性代数 - 图34三、线性代数 - 图35 阶酉矩阵; 三、线性代数 - 图36 为半正定的 三、线性代数 - 图37 阶的对焦矩阵; 而 三、线性代数 - 图38三、线性代数 - 图39 阶酉矩阵。

    三、线性代数 - 图40 对角线上的元素为 三、线性代数 - 图41 的奇异值,通常按照从大到小排列。

    1. scipy.linalg.svd(a, full_matrices=True, compute_uv=True, overwrite_a=False,
    2. check_finite=True, lapack_driver='gesdd')
    • a:一个矩阵,形状为(M,N),待分解的矩阵。
    • full_matrices:如果为True,则 三、线性代数 - 图42 的形状为(M,M)三、线性代数 - 图43 的形状为(N,N);否则 三、线性代数 - 图44 的形状为(M,K)三、线性代数 - 图45 的形状为(K,N),其中 K=min(M,N)
    • compute_uv:如果True,则结果中额外返回U以及Vh;否则只返回奇异值
    • overwrite_a:一个布尔值,指定是否将结果写到a的存储区。
    • overwrite_b:一个布尔值,指定是否将结果写到b的存储区。
    • check_finite:如果为True,则检测输入中是否有nan或者inf
    • lapack_driver:一个字符串,指定求解算法。可以为:'gesdd'/'gesvd'。默认的'gesdd'

    返回值:

    • U三、线性代数 - 图46 矩阵
    • s:奇异值,它是一个一维数组,按照降序排列。长度为 K=min(M,N)
    • Vh:就是 三、线性代数 - 图47 矩阵

    判断两个数组是否近似相等 np.allclose(a1,a2)(主要是浮点数的精度问题)

    svd