2010-07-18 101 views
29

試圖計算R中矩陣的功率,我發現包expm實現了運算符%^%R中的矩陣功率

因此x%^%k計算矩陣的k次冪。

> A<-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3) 

> A %^% 5 
     [,1] [,2] [,3] 
[1,] 6469 18038 2929 
[2,] 21837 60902 9889 
[3,] 10440 29116 4729 

但是,出乎我的意料:

> A 
    [,1] [,2] [,3] 
[1,] 691 1926 312 
[2,] 2331 6502 1056 
[3,] 1116 3108 505 

莫名其妙初始矩陣A已更改爲A%^%4!

您如何執行矩陣功率操作?

回答

25

我有固定該錯誤在R-鍛造源, SVN轉( 「expm」 包)。 53. - >expm R-forge page 出於某種原因,網頁仍顯示rev.52,所以下面可能尚未 解決你的問題(但應在24小時內):

install.packages("expm", repos="http://R-Forge.R-project.org") 

否則,獲得SVN版本直接並自行安裝:

svn checkout svn://svn.r-forge.r-project.org/svnroot/expm 

感謝「gd047」通過電子郵件向我通知問題。 請注意,R-forge也有自己的錯誤跟蹤功能。
Martint

0

甲^ 5 =(A^4)* A

我想庫變異原變量,A,使得每個步驟涉及的結果 - 上 - 直到 - 然後乘以與原矩陣, A.你回來的結果看起來很好,只需將它們分配給一個新的變量。

+0

計算A%^%6也使A作爲(初期甲 )%^%4。將結果分配給新變量不會阻止我的初始矩陣被更改。 – 2010-07-18 09:17:30

+0

聽起來像是你只需先取矩陣分配到一個新的變量不尋常的一步。 – John 2010-07-18 13:01:11

2

雖然,因爲它是裝在一個.dll file的源代碼是不是在包裝可見,相信包所使用的算法是fast exponentiation algorithm,您可以通過查看功能研究稱爲matpowfast代替。

需要兩個變量:

  1. result,爲了存儲輸出,
  2. mat,作爲中間變量。

爲了計算A^6,由於6 = 110(二進制寫入),在結束時,result = A^6mat = A^4。這與A^5相同。

當您嘗試爲任何8<n<16計算A^n時,您可以輕鬆檢查是否mat = A^8。如果是這樣,你有你的解釋。

包函數使用初始變量A作爲中間變量mat

8

這不是一個正確的答案,但可能是進行這個討論並理解R的內部工作的好地方。這種錯誤在我使用的另一個軟件包之前就已經出現了。

首先,請注意,僅僅分配矩陣到一個新的變量先不幫助:

> A <- B <-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3) 
> r1 <- A %^% 5 
> A 
    [,1] [,2] [,3] 
[1,] 691 1926 312 
[2,] 2331 6502 1056 
[3,] 1116 3108 505 
> B 
    [,1] [,2] [,3] 
[1,] 691 1926 312 
[2,] 2331 6502 1056 
[3,] 1116 3108 505 

我的猜測是,R爲試圖成爲智能引用傳遞,而不是值。要真正做到這一點,你需要做一些事情來區分A和B:

`%m%` <- function(x, k) { 
    tmp <- x*1 
    res <- tmp%^%k 
    res 
} 
> B <-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3) 
> r2 <- B %m% 5 
> B 
    [,1] [,2] [,3] 
[1,] 1 2 1 
[2,] 3 8 1 
[3,] 0 4 1 

這樣做的顯式方法是什麼?

最後,在該包的C代碼,有這樣的評論:

  • 注:x將被改變!如果需要,來電者必須複製

但我不明白爲什麼R讓C/Fortran代碼在全球環境中有副作用。

+0

它沒有副作用,在全球環境 - C代碼被傳遞到R的對象的引用,所以能夠代替修改的對象。這對於某些優化是必需的,但不應該暴露給R用戶。 – hadley 2010-07-19 01:58:49

+0

@hadley我明白這一點。但是,如果兩個對象有一個引用(就像上面的情況,可能是爲了提高效率),並且讓C代碼修改對象,您(我認爲)會在全局環境中產生副作用,對? – 2010-07-20 00:31:29

+2

你的解釋基本上是正確的,但你使用的是不是最理想的術語。在此討論修改全球環境是沒有意義的,因爲該對象可能不在全球環境中。 – hadley 2010-07-20 15:30:27

2

非常快速的解決方案,而無需使用任何包使用遞歸性:如果你的基質是

powA = function(n) 
{ 
    if (n==1) return (a) 
    if (n==2) return (a%*%a) 
    if (n>2) return (a%*%powA(n-1)) 
} 

HTH

+1

這不是非常有用,因爲原始錯誤在兩年前已修復...... – 2013-09-25 19:01:58

+0

加上這是對大指數執行矩陣求冪的可怕方法 – m09 2013-10-14 13:10:36