2010-03-18 65 views
35

我想使用scipy來計算矩陣的mathematical rank。最明顯的函數numpy.rank計算數組的維數(即標量具有維0,向量1,矩陣2等)。我知道numpy.linalg.lstsq模塊具有這種能力,但我想知道這樣的基本操作是否構建在矩陣類中。使用scipy計算矩陣排名

這裏有一個明顯的例子:

from numpy import matrix, rank 
A = matrix([[1,3,7],[2,8,3],[7,8,1]]) 
print rank(A) 

這給2維度,在那裏我正在尋找的3答案。

+0

我使用Mathematica檢查了排名 - 確實是3.你在Python中調用的函數要麼不正確,要麼你使用錯了。 – duffymo 2010-03-18 23:37:00

+3

用法是正確的 - 這首先讓我感到困惑。在這篇文章中,我解釋了排名的作用:它計算數組的維數。 「等級3」數組將是列表的列表。 – Hooked 2010-03-18 23:44:21

+0

請注意,術語「排名」有些模棱兩可。對於張量,排名告訴你指數的數量(例如,標量是0級張量,矢量級1和矩陣級2)。對於線性代數,還有上面引用的定義。 從文檔字符串來看,Numpy顯然使用前者。 – 2010-03-29 13:17:15

回答

50

numpy的提供numpy.linalg.matrix_rank()

>>> import numpy 
>>> numpy.__version__ 
'1.5.1' 
>>> A = numpy.matrix([[1,3,7],[2,8,3],[7,8,1]]) 
>>> numpy.linalg.matrix_rank(A) 
3 
+1

如何找到**整數**矩陣** modulo n **的等級?在Mathematica中有這個函數MatrixRank [...,Modulus - > n],但是我怎樣才能在Python中實現這個功能? – 2015-06-18 08:09:55

1

我特別不瞭解Numpy,但這不太可能是矩陣的內置操作;它涉及相當密集的數值計算(以及浮點舍入誤差等的相關問題)和閾值選擇,這些選擇在給定的上下文中可能適用也可能不適用,並且算法選擇對於準確而快速地計算它很重要。

構建在基本類中的東西往往是可以以獨特和直接的方式執行的事情,例如最複雜的矩陣乘法。

+0

這是一個很好的觀點,數值不穩定的矩陣可能會導致秩由於舍入誤差而改變。然而,這是一個已知的問題,我想知道scipy/numpy庫是否有直接的功能。如果答案是否定的 - 也沒關係,我可以隨時使用SVD。 – Hooked 2010-03-18 23:52:44

+1

這不僅僅是數字不穩定的。那麼{{1.0,3.0},{1.0/3.0,1.0}}呢?該分部不能產生確切的答案,所以這應該算作1級還是2級? – 2010-03-19 18:17:58

1

線性代數函數一般分爲numpy.linalg。 (它們也可從scipy.linalg獲得,它具有更多的功能。)這允許多態性:函數可以接受SciPy處理的任何類型。

所以,是的,numpy.linalg.lstsq功能做你在問什麼。爲什麼這不夠?

+2

這是我所要求的 - 但它不必要地做了很多事情,並且帶着大量行李。用LU分解和行排序也可以實現同樣的效果。問題的意圖 - 如果不明確的話,是否存在一個功能,其唯一目的是計算等級。 IE瀏覽器。接受一個matrx,吐出一個int。 – Hooked 2010-03-18 23:48:28

2

此答案已過期。

答案是否定的 - 目前沒有專門用於計算矩陣在矩陣中的矩陣秩的函數。之前已經討論過添加一個,但是如果它會發生,我不相信它已經存在。

+1

順便說一下,http://mail.scipy.org/pipermail/numpy-discussion/2008-February/031214.html是關於此的短新聞組討論的第一篇文章。 – 2010-03-19 00:24:23

+5

現在,有'numpy.linalg.matrix_rank()'。看到我的答案。 – Simon 2011-12-02 05:17:01

12

爲需要在實踐中完成此操作的人提供粗略的代碼片段。隨意改進。

u, s, v = np.linalg.svd(A) 
rank = np.sum(s > 1e-10) 
5

如果numpy不提供排名的設施,你爲什麼不寫自己的?

計算秩的有效方法是通過奇異值分解 - 矩陣的秩等於非零奇異值的數量。

def rank(A, eps=1e-12): 
    u, s, vh = numpy.linalg.svd(A) 
    return len([x for x in s if abs(x) > eps]) 

注意eps取決於您的應用程序 - 大多數人都認爲1E-12相當於零,但你可以看到數值不穩定甚至EPS = 1E-9。

用你的例子,答案是三。如果將第二行更改爲[2, 6, 14](與第一行呈線性關係),則答案爲2(「零」特徵值爲4。9960E-16)

1

scipy現在包含一個有效的interpolative method用於使用隨機方法估計矩陣/ LinearOperator的秩,其可以經常是足夠精確:

>>> from numpy import matrix 
>>> A = matrix([[1,3,7],[2,8,3],[7,8,1]], dtype=float) # doesn't accept int 

>>> import scipy.linalg.interpolative as sli 
>>> sli.estimate_rank(A, eps=1e-10) 
3