web-dev-qa-db-ja.com

Rの行列のべき乗

Rで行列のべき乗を計算しようとすると、パッケージexpmが演算子 %^% を実装していることがわかりました。

したがって、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に変更されました!!!

行列のべき乗演算をどのように実行しますか?

30
George Dontas

(「expm」パッケージの)R-forgeソースのバグ、svn revを修正しました。 53.-> expm R-forge page 何らかの理由でWebページにまだ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にも独自のバグ追跡機能があることに注意してください。
マーティント

30
Martin Mächler

これは適切な答えではありませんが、この議論を行い、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コードにグローバル環境での副作用を許可する理由を理解していません。

8
Eduardo Leoni

非常に迅速な解決策パッケージを使用せずには再帰性を使用しています:マトリックスが

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

HTH

2
DKK

_.dll file_にパックされているため、ソースコードはパッケージには表示されませんが、パッケージで使用されているアルゴリズムは 高速指数アルゴリズム であると考えています。代わりにmatpowfastと呼ばれる関数で。

2つの変数が必要です。

  1. result、出力を保存するために、
  2. mat、中間変数として。

_A^6_を計算するには、_6 = 110_(バイナリ書き込み)以降、最後に_result = A^6_および_mat = A^4_を計算します。これは_A^5_の場合も同じです。

_mat = A^8_に対して_A^n_を計算しようとすると、_8<n<16_かどうかを簡単に確認できます。もしそうなら、あなたはあなたの説明があります。

パッケージ関数は、初期変数Aを中間変数matとして使用します。

2
Wok

あまり努力せずにbaseの非効率なバージョン(最初に行列を対角化する方が効率的であるため)は次のとおりです。

pow = function(x, n) Reduce(`%*%`, replicate(n, x, simplify = FALSE))

この質問がexpmの古いバグに関するものであることはわかっていますが、これは現時点で「マトリックスパワーR」の最初の結果の1つであるため、この小さな省略形がここで終わる他の人に役立つことを願っていますパッケージをインストールせずに行列のパワーを実行する簡単な方法を探しています。

1
MichaelChirico

A ^ 5 =(A ^ 4)* A

ライブラリが元の変数Aを変更するので、各ステップで結果までの結果に元の行列Aを乗算する必要があると思います。取得した結果は正常に見えるので、新しい変数に割り当てます。

0
Michiel