背景
MATLABで書かれたコードを、Rに移植したい。
しかし機能的に互換1なコードをRでまっさらから書くのはしんどい。
そうだ、pracma, signal, controlパッケージなどがあるじゃないか
うまくいかない…原因は行列の足し算にあった。
具体例
Rは要素数が1でもベクトル。ベクトルの足し算はリサイクル規則が働くので2つ目の例のように各要素に足される。
しかし行列はリサイクル規則が働かない。3番目のコードのように。
1行1列だって例外ではないのだ。4番目のコードのように。
# 行列 matrix(1:8,2,4) #> [,1] [,2] [,3] [,4] #> [1,] 1 3 5 7 #> [2,] 2 4 6 8 # 行列にスカr...ベクトルを足す matrix(1:8,2,4)+1 #> [,1] [,2] [,3] [,4] #> [1,] 2 4 6 8 #> [2,] 3 5 7 9 # 列数があわないので足せない matrix(1:8,2,4)+matrix(1:4,2,2) #> Error in matrix(1:8, 2, 4) + matrix(1:4, 2, 2) : non-conformable arrays # こっちも matrix(1:8,2,4)+matrix(1,1,1) #> Error in matrix(1:8, 2, 4) + matrix(1, 1, 1) : non-conformable arrays
カルマンフィルタのMATLABで書かれたコードを、pracmaなどのパッケージの関数に置き換えてみたところ、これは常に行列を返すようで上記4のようなことが起こったのでした。
as.vectorでmatrix(1,1,1)を変換すると下記の通り。
matrix(1,1,1) #> [,1] #> [1,] 1 as.vector(matrix(1,1,1)) #> [1] 1 str(matrix(1,1,1)) #> num [1, 1] 1 str(as.vector(matrix(1,1,1))) #> num 1 matrix(1,1,1) #> [,1] #> [1,] 1 as.vector(matrix(1,1,1)) #> [1] 1 str(matrix(1,1,1)) #> num [1, 1] 1 str(as.vector(matrix(1,1,1))) #> num 1 class(matrix(1,1,1)) #> [1] "matrix" class(as.vector(matrix(1,1,1))) #> [1] "numeric" typeof(matrix(1,1,1)) #> [1] "double" typeof(as.vector(matrix(1,1,1))) #> [1] "double" is.vector(matrix(1,1,1)) #> [1] FALSE is.vector(as.vector(matrix(1,1,1))) #> [1] TRUE is.matrix(matrix(1,1,1)) #> [1] TRUE is.matrix(as.vector(matrix(1,1,1))) #> [1] FALSE
後ろの方は蛇足ですが…。
MATLABのコードはおとなしくMATLAB上で動かすことにします2
なお、昨今の記事はreprex::reprex()を使用して整形していますが、エラーが出る箇所については基本的にはNAが返ってきています。それらの行だけは通常のコンソールに打ち込んで出てきた文字列を加工しています
Enjoy!!