【问题标题】:Python numpy : Matrix Inverses give unprecise results when multipliedPython numpy:矩阵求逆在相乘时给出不精确的结果
【发布时间】:2018-05-21 19:31:51
【问题描述】:

好的,所以我有 3 个 numpy 矩阵:

m1 = [[  3   2   2 ...   2   2   3]
      [  3   2   2 ...   3   3   2]
      [500 501 502 ... 625 626 627]
      ...
      [623 624 625 ... 748 749 750]
      [624 625 626 ... 749 750 751]
      [625 626 627 ... 750 751 752]]

m2 = [[  3   2 500 ... 623 624 625]
      [  3   2 500 ... 623 624 625]
      [  2   3 500 ... 623 624 625]
      ...
      [  2   2 500 ... 623 624 625]
      [  2   2 500 ... 623 624 625]
      [  3   2 500 ... 623 624 625]]

m3 = [[     813      827   160500 ...   199983   200304   200625]
      [     830      843   164000 ...   204344   204672   205000]
      [  181317   185400 36064000 ... 44935744 45007872 45080000]
      ...
      [  221046   225867 43936000 ... 54744256 54832128 54920000]
      [  221369   226196 44000000 ... 54824000 54912000 55000000]
      [  221692   226525 44064000 ... 54903744 54991872 55080000]]

m1、m2 和 m3 是非常大的方阵(这些示例是 128x128,但它们可以达到 2048x2048)。还有 m1*m2=m3。

我的目标是只使用 m1 和 m3 来获得 m2。有人告诉我这是可能的,因为 m1*m2=m3 意味着 (m1**-1) * m3 = m2 (我相信是这样,如果我错了,请纠正我);所以我计算了 m1 的倒数:

m1**-1 = [[ 7.70884284e-01 -8.13188394e-01 -1.65131146e+13 ... -2.49697170e+12
           -7.70160676e+12 -4.13395320e+13]
          [-3.38144598e-01  2.54532610e-01  1.01286404e+13 ... -3.64296085e+11
            2.60327813e+12  2.41783491e+13]
          [ 1.77721050e-01 -3.54566231e-01 -5.00564604e+12 ...  5.82415184e+10
           -5.98354744e+11 -1.29817153e+13]
          ...
          [-6.56772812e-02  1.54498025e-01  3.21826474e+12 ...  2.61432526e+11
            1.14203762e+12  3.61036457e+12]
          [ 5.82732587e-03 -3.44252762e-02 -4.79430664e+11 ...  5.10855381e+11
           -1.07679881e+11 -1.71485373e+12]
          [ 6.55360708e-02 -8.24446025e-02 -1.19618881e+12 ...  4.45713678e+11
           -3.48073716e+11 -4.89344092e+12]]

结果看起来相当混乱,所以我运行了一个测试并将 m1**-1 和 m1 相乘以查看它是否有效:

(m1**-1)*m1 = [[-125.296875  , -117.34375   , -117.390625  , ..., -139.15625   ,
                -155.203125  , -147.25      ],
               [ 483.1640625 ,  483.953125  ,  482.7421875 , ...,  603.796875  ,
                 590.5859375 ,  593.375     ],
               [-523.22851562, -522.36328125, -523.49804688, ..., -633.07421875,
                -635.20898438, -637.34375   ],
               ...,
               [  10.58691406,   11.68945312,   10.29199219, ...,   14.40429688,
                  13.00683594,   11.609375  ],
               [  -5.32177734,   -5.47949219,   -4.63720703, ...,   -5.28613281,
                  -5.31884766,   -5.6015625 ],
               [  -4.93554688,   -3.58984375,   -3.24414062, ...,   -8.72265625,
                  -5.37695312,   -8.03125   ]]

结果与预期的不同(恒等矩阵)。我的猜测是 m1 太大,导致数值不精确。但是,如果之前获得单位矩阵的计算不能正常工作,那么 (m1**-1)*m3 肯定不会(而且它不会)。 但我真的无法减小 m1、m2 和 m3 的矩阵大小,事实上我希望它能够处理更大的尺寸(如前所述,最大尺寸为 2048x2048)。

这样的计算有什么方法可以更精确吗?是否有适用于更大矩阵的替代方案?

【问题讨论】:

  • 在 python 中 * 是元素乘法。您需要使用@ 进行矩阵乘法,如果您想反转使用linalg.solve 或最差的linalg.inv
  • @percusse *@ 似乎给出了相同的结果。同样linalg.solvelinalg.inv 也不起作用,因为m1 的行列式非常接近于0,之后实际上不可能获得m2。我目前正在尝试找出一种以某种方式通过算法生成m1 的方法,以获得非零行列式并保持一些计算完整。
  • 这是不可能的。尝试np.ones((3,3)) @ np.ones((3,3)),然后尝试*
  • @percusse 很奇怪,这实际上给出了两个不同的结果,同时在我的程序中我尝试了m1*m2 == m1@m2,它返回了一个True 的数组。两个 numpy 矩阵的元素乘法和两个矩阵的矩阵乘法之间到底有什么区别?
  • 这意味着它们都是对角矩阵。或全零

标签: python numpy matrix inverse


【解决方案1】:

您是对的,对大型矩阵求逆可能效率低下且数值不稳定。幸运的是,线性代数中有一些方法可以解决这个问题而无需逆。

在这种情况下,m2 = np.linalg.solve(m1, m3) 有效。

【讨论】:

  • 您好,感谢您的意见!虽然我得到了一个与 m2 的包含不匹配的奇怪结果:dl.free.fr/nXpK6PfSU Are m1 和 m3 还是太大了吗?
  • 你能运行np.linalg.det(m1.T)吗?如果结果为0,则排名条件失败,您将无法恢复m2
  • 结果是-0.0。它是一个非常小的浮点数,四舍五入为 0,使其成为可能,还是严格为 0,因此阻止了 m2 的任何恢复?
  • 好的,我会看看我能做些什么,如果我还有任何问题,我会回复你。非常感谢 ! ^^
  • 经过几天的研究,我决定不修改m1,而是使用np.linalg.pinv()来计算m1的Moore-Penrose Pseudoinverse,它不需要非奇异矩阵和数学允许我找到m2。我正在验证您的答案,因为它在其他一些情况下可以证明是有用的;它还帮助我理解了为什么它不能很好地工作。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 2018-06-10
相关资源
最近更新 更多