R中S3类的重载矩阵乘法

Posted

技术标签:

【中文标题】R中S3类的重载矩阵乘法【英文标题】:Overload matrix multiplication for S3 class in R 【发布时间】: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 好的,并承认 matrixlist 是我主张的很好的 R 反例。 【参考方案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("%*%")

以上是关于R中S3类的重载矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章

矩阵乘法(超详细!!!)

C ++分段在进行矩阵乘法时出错

矩阵的乘法运算

在 SYCL 中实现矩阵加法和乘法

在 SYCL 中实现矩阵加法和乘法

动态规划 - 矩阵链乘法