Python NumPy: матричные инверсии дают неточные результаты при умножении - PullRequest
0 голосов
/ 21 мая 2018

Хорошо, поэтому у меня есть 3 пустые матрицы:

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.

Моя цель - получить m2, используя только m1 и m3.Кто-то сказал мне, что это возможно, так как 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).

Будет лиМожно ли быть более точным с такими расчетами?Есть ли альтернатива, которая могла бы работать для больших матриц?

1 Ответ

0 голосов
/ 21 мая 2018

Вы правы, инвертирование большой матрицы может быть неэффективным и численно нестабильным.К счастью, в линейной алгебре есть методы, которые решают эту проблему, не требуя обратного.

В этом случае m2 = np.linalg.solve(m1, m3) работает.

...