2016-11-13 15 views
3

行列乗算演算子をRにオーバーロードする方法は?私は他のほとんどの演算子(オプスを使用して)でそれを行うことができましたが、行列演算で私はこのエラーを取得する:ここでS3クラス用オーバーロード行列乗算R

requires numeric/complex matrix/vector arguments 

は最小作業例です:

speed = function(x){ 
    structure(list(y = x), 
       class = "speed") 
} 

m = matrix(c(1,2,3,4), ncol = 2) 
s = speed(m) 

# Addition works fine 
`+.speed` = function(e1, e2){ e1$y + e2 } 

s + 10 

# But matrix multiplication doesn't 
`%*%.speed` = function(e1, e2){ e1$y %*% e2 } 

s %*% c(1,2) 
+0

'スピード'がクラスである場合、 'スピード'機能を定義したくありません。 as.speed関数を定義することを検討するかもしれません。 –

+0

@ 42-フィードバックのためのThx。しかし、コンストラクタの名前を変更しても、動作を変更するようには見えません。 – dudu

+0

\ '%*%。speed \'(s、c(1,2))は実際に動作することに注意してください。私は十分に精通していないので、「プリミティブ」にその作業をどうやって行うかを知ってもらう必要があります。 –

答えて

2

私はこれがあると思いますなぜなら%*%はデフォルトではS3汎用関数ではないからです。あなたはこれをそうすることによってこれを回避することができます。

`%*%.default` = .Primitive("%*%") # assign default as current definition 
`%*%` = function(x,...){ #make S3 
    UseMethod("%*%",x) 
} 
`%*%.speed` = function(e1, e2){ e1$y %*% e2 } # define for speed 

s %*% c(1,2) 
    [,1] 
[1,] 7 
[2,] 10 

あなたが以下のコメントに照らして編集このhere

に関する追加情報を望んでいた場合は、ハドレーの本を見ることができます。

+0

ありがとうございます。 '%*%.default' = .Primitive("%*% ")が'%*%.default' = '%*%'よりも優れているかどうか疑問です。思考? – dudu

+0

@dudu '%*%'が '.Primitive'を呼び出すので、それは問題ではないはずです。誰かが間違っていることを証明するのはうれしいですが、これまでのような状況でそれを心配していたことは思いもしません。 – jamieRowen

+0

あなたのスニペットが複数回実行されるかどうかは重要です。 2回目に '%*%。default 'は.Primitive("%*% ")ではなくS3メソッドとして定義されます。 – dudu