簡體   English   中英

python中的反轉矩陣稍微關閉

[英]Inverting matrix in python slightly off

我正在嘗試使用這個http://www.irma-international.org/viewtitle/41011/算法來反轉 nxn 矩陣。

我在這個矩陣上運行了這個函數

[[1.0, -0.5],

 [-0.4444444444444444, 1.0]]

並得到輸出

[[ 1.36734694,  0.64285714]

 [ 0.57142857,  1.28571429]]

正確的輸出應該是

[[ 1.28571429,  0.64285714]

 [ 0.57142857,  1.28571429]]

我的功能:

def inverse(m):
    n = len(m)
    P = -1
    D =  1
    mI = m
    while True:
        P += 1
        if m[P][P] == 0:
           raise Exception("Not Invertible")
        else:
            D = D * m[P][P]
            for j in range(n):
                if j != P:
                    mI[P][j] =  m[P][j] / m[P][P]
            for i in range(n):
                if i != P:
                    mI[i][P] = -m[i][P] / m[P][P]
            for i in range(n):
                for j in range(n):
                    if i != P and j != P:
                        mI[i][j] = m[i][j] + (m[P][j] * mI[i][P])
            mI[P][P] = 1 / m[P][P]
            if P == n - 1: # All elements have been looped through
                break

    return mI

我在哪里犯了錯誤?

https://repl.it/repls/PowerfulOriginalOpensoundsystem

輸出

逆:[[十進制( '1.285714285714285693893862813'),十進制( '0.6428571428571428469469314065')],[十進制( '0.5714285714285713877877256260'),十進制( '1.285714285714285693893862813')]] numpy的:[[1.28571429 0.64285714] [0.57142857 1.28571429]]

from decimal import Decimal
import numpy as np

def inverse(m):
    m = [[Decimal(n) for n in a] for a in m]
    n = len(m)
    P = -1
    D =  Decimal(1)
    mI = [[Decimal(0) for n in a] for a in m]
    while True:
        P += 1
        if m[P][P] == 0:
           raise Exception("Not Invertible")
        else:
            D = D * m[P][P]
            for j in range(n):
                if j != P:
                    mI[P][j] =  m[P][j] / m[P][P]
            for i in range(n):
                if i != P:
                    mI[i][P] = -m[i][P] / m[P][P]
            for i in range(n):
                for j in range(n):
                    if i != P and j != P:
                      mI[i][j] = m[i][j] + (m[P][j] * mI[i][P])
            mI[P][P] = 1 / m[P][P]
            m = [[Decimal(n) for n in a] for a in mI]
            mI = [[Decimal(0) for n in a] for a in m]
            if P == n - 1: # All elements have been looped through
                break

    return m

m = [[1.0, -0.5],

 [-0.4444444444444444, 1.0]]

print(inverse(m))
print(np.linalg.inv(np.array(m)))

我的思考過程:

起初,我認為您可能存在潛在的浮點舍入錯誤。 事實證明這不是真的。 這就是十進制爵士樂的用途。

你的錯誤在這里

mI = m # this just creates a pointer that points to the SAME list as m

和這里

for i in range(n):
                for j in range(n):
                    if i != P and j != P:
                        mI[i][j] = m[i][j] + (m[P][j] * mI[i][P])
            mI[P][P] = 1 / m[P][P] 
            # you are not copying mI to m for the next iteration
            # you are also not zeroing mI 
            if P == n - 1: # All elements have been looped through
                break

    return mI

根據算法,每次迭代都會創建一個新的 a' 矩陣,它不會繼續修改相同的舊 a。 我推斷這意味着在循環不變式中,a 變為 a'。 適用於您的測試用例,結果證明是正確的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM