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
然后我们按列应用函数 paired
和 apply(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" 的条件)。它可以以不同的方式编码并更快(参见 paired2
或 paired3
):
> 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
我试图在以下函数中拆分以下代码:
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
然后我们按列应用函数 paired
和 apply(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" 的条件)。它可以以不同的方式编码并更快(参见 paired2
或 paired3
):
> 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