2

+演算子をオーバーロードしようとして、Matrixパッケージを疎行列で使用すると、奇妙な効果が得られます。最初に、Matrix パッケージを使用しないが+演算子を持つ非常に単純なクラスを定義します。次に、2 つの疎行列を合計します。最初のM+M加算では期待どおりの結果が得られますが、2 番目の加算ではエラーがスローされます。エラーを生成する非常に単純なコードを次に示します。

require(Matrix)
setClass("TestM",representation(M='numeric'))
setMethod("initialize", "TestM", function(.Object,x) { 
  .Object@M = x
  .Object
})
setMethod("+", c("TestM","TestM"), function(e1,e2) {
  e1@M + e2@M
})

M = Matrix(diag(1:10),sparse=T)
M+M  # > FINE
M+M  # > ERROR

M = Matrix(diag(1:10),sparse=F)
M+M  # > FINE
M+M  # > FINE

2 番目の追加では、次のエラーがスローされます。

Error in forceSymmetric(callGeneric(as(e1, "dgCMatrix"), as(e2, "dgCMatrix"))) : 
  error in evaluating the argument 'x' in selecting a method for function
'forceSymmetric': Error in .Arith.Csparse(e1, e2, .Generic, class. = "dgCMatrix") :
  object '.Generic' not found

また、行列が疎でない場合、エラーは発生しません。+I define と+for sparseMatrixの間に干渉はありますか? +演算子を正しく定義していませんか?

ありがとうございました!

4

2 に答える 2

3

Ops クラスをオーバーロードするように設定してみてください。

> setMethod(Ops, c("TestM","TestM"), function(e1,e2) {
+   e1@M + e2@M
+ })
[1] "Ops"
attr(,"package")
[1] "base"
> 
> M = Matrix(diag(1:10),sparse=T)
> M+M  # > FINE
10 x 10 sparse Matrix of class "dsCMatrix"

 [1,] 2 . . .  .  .  .  .  .  .
 [2,] . 4 . .  .  .  .  .  .  .
 [3,] . . 6 .  .  .  .  .  .  .
 [4,] . . . 8  .  .  .  .  .  .
 [5,] . . . . 10  .  .  .  .  .
 [6,] . . . .  . 12  .  .  .  .
 [7,] . . . .  .  . 14  .  .  .
 [8,] . . . .  .  .  . 16  .  .
 [9,] . . . .  .  .  .  . 18  .
[10,] . . . .  .  .  .  .  . 20
> M+M  # (NOT error)... was  ERROR
10 x 10 sparse Matrix of class "dsCMatrix"

 [1,] 2 . . .  .  .  .  .  .  .
 [2,] . 4 . .  .  .  .  .  .  .
 [3,] . . 6 .  .  .  .  .  .  .
 [4,] . . . 8  .  .  .  .  .  .
 [5,] . . . . 10  .  .  .  .  .
 [6,] . . . .  . 12  .  .  .  .
 [7,] . . . .  .  . 14  .  .  .
 [8,] . . . .  .  .  . 16  .  .
 [9,] . . . .  .  .  .  . 18  .
[10,] . . . .  .  .  .  .  . 20
于 2012-12-11T02:10:05.137 に答える
0

ほぼ 3,5 年後、私は同じエラーに出くわしました。これは、最近の質問のトピックでもあります: setMethod とパッケージ Matrix。R-devel にバグ レポートを送信しましたが、パッケージの外部でオーバーロードが行われた場合にのみエラーが再現可能であることが後でわかりました。つまり、パッケージ内+のクラスのオブジェクトに対してメソッドを定義しtestM、パッケージをロードしてオーバーロード+された関数をロードすると、グループ全体を一般的な方法でオーバーロードする必要なく、最初の問題が解決されます (常に可能であるとは限りません)。 )。

于 2016-06-01T11:01:13.640 に答える