R 语法中的 crossprod()

crossprod() in R syntax

我试图在以下函数中拆分以下代码:

paired <- function(x) crossprod(x[x]-1:length(x))==0

关于上下文,这出现在 this answer in CV

我们有一个包含十个 8 维向量的矩阵,对应于向量的随机排列 1:8

n <- 8
x <- replicate(10, sample(1:n, n))  

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    3    5    2    5    1    8    8     3
[2,]    4    3    5    4    3    8    5    2    1     8
[3,]    5    5    4    3    8    2    6    3    6     7
[4,]    6    8    1    7    4    3    8    6    2     2
[5,]    7    4    8    2    7    4    4    1    3     4
[6,]    2    6    2    6    5    1    3    4    7     6
[7,]    8    2    7    8    1    6    7    5    5     1
[8,]    3    7    6    1    6    7    2    7    4     5 

然后我们按列应用函数 pairedapply(x, 2, paired) 得到布尔运算的结果,我想评估 function(x) crossprod(x[x]-1:length(x)) 的任何结果是否等于零:

intermediate <- function(x) crossprod(x[x]-1:length(x))
apply(x, 2, intermediate)
 [1]  74  80  88  88 100 108  26  90 124 106

apply(x, 2, paired)
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

intermediate 调用中的值不是按列 x[x] - 1 中的列向量与它们自身的点积,对于第一列来说是:

> w <- c(1,4,5,6,7,2,8,3)
> v <- w[w] - 1
> t(v)%*%v
     [,1]
[1,]  140

而不是74

那么问题来了,length(x)修改crossprod()的作用是什么?

编辑:根据评论(谢谢),如果我将代码尝试为:

w <- c(1,4,5,6,7,2,8,3)
v <- w[w] - 1:length(x)
t(v)%*%v

我得到 crossprod(v) [1,] 146660 也不同于 74

不要太在意paired函数中的crossprod。它所做的只是检查 x[x] - 1:length(x) 是否为零向量(即 "perfect pairing" 的条件)。它可以以不同的方式编码并更快(参见 paired2paired3):

> n <- 8
> set.seed(17)
> x <- replicate(1e6, sample(1:n, n))
>
> paired <- function(x) crossprod(x[x] - 1:length(x))==0
> paired2 <- function(x) sum(x[x]==1:length(x))==length(x)
> paired3 <- function(x) sum(abs(x[x]-1:length(x)))==0
>
> system.time(i.paired  <- apply(x, 2, paired))
   user  system elapsed
  9.812   0.000   9.821
> system.time(i.paired2 <- apply(x, 2, paired2))
   user  system elapsed
  4.548   0.000   4.550
> system.time(i.paired3 <- apply(x, 2, paired3))
   user  system elapsed
  4.617   0.000   4.617
>
> all.equal(i.paired,i.paired2)
[1] TRUE
> all.equal(i.paired,i.paired3)
[1] TRUE