【问题标题】:np.linalg.inv() giving unexpected resultsnp.linalg.inv() 给出意想不到的结果
【发布时间】:2021-06-11 12:22:27
【问题描述】:

我正在使用 numpy 对矩阵求逆,但得到了一些意想不到的结果。

运行我的程序,我得到 p1 的最终结果:

>>> p1
array([[1.69133481e+11, 3.74575030e+09, 8.29681977e+07, 1.83800903e+06],
       [3.74575030e+09, 8.29681977e+07, 1.83800903e+06, 4.07236156e+04],
       [8.29681977e+07, 1.83800903e+06, 4.07236156e+04, 9.02416997e+02],
       [1.83800903e+06, 4.07236156e+04, 9.02416997e+02, 2.00000000e+01]])

然后,当我尝试使用 np.linalg.inv() 反转 p1 时,我得到:

>>> np.linalg.inv(p1)
array([[ 2.33378273e+00, -3.16566294e+02,  1.43119558e+04,
        -2.15657094e+05],
       [-3.16566293e+02,  4.29411791e+04, -1.94139249e+06,
         2.92538609e+07],
       [ 1.43119557e+04, -1.94139249e+06,  8.77723669e+07,
        -1.32261292e+09],
       [-2.15657092e+05,  2.92538606e+07, -1.32261291e+09,
         1.99302540e+10]])

这显然是不正确的:

>>> (p1 @ np.linalg.inv(p1))
array([[ 9.99968764e-01, -1.28189335e-03, -7.44723976e-01,
         3.60136516e+00],
       [-2.53043124e-06,  9.99986814e-01, -3.83602548e-02,
         1.12390996e-01],
       [-8.71254524e-08,  9.18930849e-06,  9.99317258e-01,
         4.33950341e-03],
       [-6.98491931e-10,  7.45058060e-08, -1.23977661e-05,
         1.00001526e+00]])
>>> (p1 @ np.linalg.inv(p1)).astype(int)
array([[0, 0, 0, 3],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 1]])

我的结果显然不是单位矩阵。

然而,这就是事情变得更奇怪的地方。如果我在键入“p1”时使用打印到终端的值重新定义 p1 并计算与之前相同的命令:

>>> p1 = np.array([[1.69133481e+11, 3.74575030e+09, 8.29681977e+07, 1.83800903e+06],
...        [3.74575030e+09, 8.29681977e+07, 1.83800903e+06, 4.07236156e+04],
...        [8.29681977e+07, 1.83800903e+06, 4.07236156e+04, 9.02416997e+02],
...        [1.83800903e+06, 4.07236156e+04, 9.02416997e+02, 2.00000000e+01]])
>>> p1 @ np.linalg.inv(p1)
array([[ 9.99999999e-01, -4.85794104e-07, -2.14803652e-05,
        -4.95130838e-04],
       [ 2.61335278e-10,  9.99999940e-01,  9.92065715e-07,
        -3.11477404e-05],
       [ 1.87780333e-13, -5.48610778e-10,  1.00000001e+00,
        -1.02864912e-07],
       [ 9.94759830e-14, -2.00088834e-11,  5.82076609e-10,
         9.99999998e-01]])
>>> (p1 @ np.linalg.inv(p1)).astype(int)
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 1, 0],
       [0, 0, 0, 0]])

在这里,结果与我得到单位矩阵时的预期结果非常吻合。

在重新定义 p1 之前矩阵逆不正确的事实导致我的代码出现问题。有什么想法吗?

【问题讨论】:

  • 什么是np.linalg.det(p1)?我怀疑p1 接近单数,实际数组比重新创建的数组更接近。
  • 您能否分享更多关于这究竟是如何导致您的代码出现问题的详细信息?
  • @hpaulj np.linalg.det(p1) 是:99.53509638901218
  • @FelipeLanza 我正在编写一个程序来计算一组点的多项式回归。我正在使用等式 np.linalg.inv(X.T @ X) @ X.T @ y 来计算权重。但是,一旦多项式达到某个阶 np.linalg.inv(X.T @ X) 就会给出一个意想不到的(可能是错误的)值,这会导致权重不准确(我认为)。这意味着我绘制的曲线甚至没有接近点。
  • p1 中的最大值比较小。重构数组的det 更大,1193590

标签: python arrays numpy matrix inverse


【解决方案1】:

结果是正确的,你的问题是浮点(in)精度:

In [1]: arr = np.array([[1.69133481e+11, 3.74575030e+09, 8.29681977e+07, 1.83800903e+06], 
   ...:        [3.74575030e+09, 8.29681977e+07, 1.83800903e+06, 4.07236156e+04], 
   ...:        [8.29681977e+07, 1.83800903e+06, 4.07236156e+04, 9.02416997e+02], 
   ...:        [1.83800903e+06, 4.07236156e+04, 9.02416997e+02, 2.00000000e+01]])                                     

In [2]: inv = np.linalg.inv(arr)                                                                                      

In [3]: np.isclose(arr @ inv, np.eye(*arr.shape), atol=1e-3)                                                          
Out[3]: 
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 2017-01-05
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2021-04-22
    相关资源
    最近更新 更多