【问题标题】:Overload matrix multiplication for S3 class in RR中S3类的重载矩阵乘法
【发布时间】:2022-01-02 14:21:52
【问题描述】:

如何重载R 中的矩阵乘法运算符?我已经能够使用大多数其他运算符(使用 Ops)来做到这一点,但是使用矩阵运算我得到了这个错误:

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)

【问题讨论】:

  • 如果'speed'是一个类,那么你不想定义'speed'函数。你可以考虑定义一个 as.speed 函数。
  • @42- 感谢反馈。更改构造函数的名称似乎并没有改变行为。
  • 请注意,`%*%.speed`(s, c(1,2)) 确实有效。我对重载Primitives 不够熟悉,不知道如何使其工作。
  • @42- 我不同意,最好让构造函数反映类名(视情况而定)。
  • @KonradRudolph 好的,并承认 matrix 和 list 是我主张的很好的 R 反例。

标签: r class matrix operator-overloading


【解决方案1】:

我认为这是因为 %*% 默认不是 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 的更多信息,可以查看 Hadley 的书

根据以下评论进行编辑。

【讨论】:

  • 谢谢。我想知道%*%.default = .Primitive("%*%") 是否比%*%.default = %*% 更好。想法?
  • @dudu 我不应该认为这很重要,因为%*% 无论如何都会调用.Primitive。很高兴被某人证明是错误的,但我不记得过去曾在类似情况下担心过,据我所知从未遇到过问题。
  • 如果你的 sn-p 被多次执行似乎很重要。第二次,%*%.default will be defined as the S3 method instead of the .Primitive("%*%")。
猜你喜欢
  • 2021-01-31
  • 2012-04-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
相关资源
最近更新 更多