簡體   English   中英

Python中的快速逆和轉置矩陣

[英]Fast inverse and transpose matrix in Python

我有一個大的矩陣A形狀(n, n, 3, 3)n約為5000 現在我想找到矩陣A的逆和轉置:

import numpy as np
A = np.random.rand(1000, 1000, 3, 3)
identity = np.identity(3, dtype=A.dtype)
Ainv = np.zeros_like(A)
Atrans = np.zeros_like(A)
for i in range(1000):
    for j in range(1000):
        Ainv[i, j] = np.linalg.solve(A[i, j], identity)
        Atrans[i, j] = np.transpose(A[i, j])

有沒有更快,更有效的方法來做到這一點?

這是從我的一個項目中獲得的,我也在許多3x3矩陣上進行矢量化線性代數。

請注意,只有一個超過3的循環; 不是n上的循環,因此代碼在重要維度中被矢量化。 我不想保證這與C / numba擴展相比如何做同樣的事情,性能明智。 這可能會大大加快,但至少這會使循環超過水中的n。

def adjoint(A):
    """compute inverse without division by det; ...xv3xc3 input, or array of matrices assumed"""
    AI = np.empty_like(A)
    for i in xrange(3):
        AI[...,i,:] = np.cross(A[...,i-2,:], A[...,i-1,:])
    return AI

def inverse_transpose(A):
    """
    efficiently compute the inverse-transpose for stack of 3x3 matrices
    """
    I = adjoint(A)
    det = dot(I, A).mean(axis=-1)
    return I / det[...,None,None]

def inverse(A):
    """inverse of a stack of 3x3 matrices"""
    return np.swapaxes( inverse_transpose(A), -1,-2)
def dot(A, B):
    """dot arrays of vecs; contract over last indices"""
    return np.einsum('...i,...i->...', A, B)


A = np.random.rand(2,2,3,3)
I = inverse(A)
print np.einsum('...ij,...jk',A,I)

轉置:

在ipython中測試了一下顯示:

In [1]: import numpy
In [2]: x = numpy.ones((5,6,3,4))
In [3]: numpy.transpose(x,(0,1,3,2)).shape
Out[3]: (5, 6, 4, 3)

所以你可以做到

Atrans = numpy.transpose(A,(0,1,3,2))

轉置第二維和第三維(同時保持維0和1相同)

反轉:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.inv.html#numpy.linalg.inv的最后一個例子

可以一次計算幾個矩陣的逆:

from numpy.linalg import inv
a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
>>> inv(a)
array([[[-2. ,  1. ],
        [ 1.5, -0.5]],
       [[-5. ,  2. ],
        [ 3. , -1. ]]])

所以我想在你的情況下,反演可以完成

Ainv = inv(A)

並且它將知道最后兩個維度是它應該反轉的維度,並且第一維度就是您堆疊數據的方式。 這應該快得多

速度差異

轉置:你的方法需要3.77557015419秒,我的需要2.86102294922e-06秒(加速超過100萬次)

對於反轉:我猜我的numpy版本不夠高,無法嘗試使用(n,n,3,3)形狀的numpy.linalg.inv技巧,以查看那里的加速(我的版本是1.6.2,和文檔我的解決方案是基於1.8,但它應該工作在1.8,如果其他人可以測試嗎?)

Numpy有array.T屬性,這是轉置的快捷方式。

對於反轉,您使用np.linalg.inv(A)

正如wim AI發布的那樣,AI也適用於矩陣。 例如

打印(AI)

對於numpy-matrix對象,使用matrix.getI。 例如

A=numpy.matrix('1 3;5 6')
print (A.getI())

暫無
暫無

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

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