向量与R中向量列表之间的角度

时间:2019-01-11 12:12:11

标签: r trigonometry

比较两个向量时,很容易计算它们之间的角度,但是在R中,要有效地计算向量和向量矩阵之间的角度显然要困难得多。

假设您有一个2D向量A =(2,0),然后有一个矩阵B = {(1,3),(-2,4),(-3,-3),(1,-4) }。我对找出A与B中的向量之间的最小角度感兴趣。 如果我尝试使用

min(acos( sum(a%*%b) / ( sqrt(sum(a %*% a)) * sqrt(sum(b %*% b)) ) ))

由于参数不一致,因此失败。

是否有与上述类似的代码可以处理向量和矩阵?

注意:冒着被标记为重复的风险,在几种sources中找到的解决方案在这种情况下不适用

编辑:原因是我有一个大矩阵X,而A只是其中的一行。我仅根据每个向量的角度来减少元素的数量。 B的第一个元素是X中的第一个元素,然后是B中的任何元素与下一个元素X[,2](此处为A)之间的夹角大于某个公差,则将其添加到列表B中。我只是用B<-rbind(B,X[,2])来做,所以这导致B是一个矩阵。

2 个答案:

答案 0 :(得分:2)

您没有详细描述A和B的格式,因此我假设它们是按行排列的矩阵。

(A <- c(2, 0))
# [1] 2 0

(B <- rbind(c(1,3), c(-2,4), c(-3,-3), c(1,-4)))
#      [,1] [,2]
# [1,]    1    3
# [2,]   -2    4
# [3,]   -3   -3
# [4,]    1   -4

解决方案1 ​​apply()

apply(B, 1, FUN = function(x){
  acos(sum(x*A) / (sqrt(sum(x*x)) * sqrt(sum(A*A))))
})

# [1] 1.249046 2.034444 2.356194 1.325818

解决方案2 sweep() :(用sum()替换上方的rowSums()

sweep(B, 2, A, FUN = function(x, y){
  acos(rowSums(x*y) / (sqrt(rowSums(x*x)) * sqrt(rowSums(y*y))))
})

# [1] 1.249046 2.034444 2.356194 1.325818

解决方案3 split()mapply

mapply(function(x, y){
  acos(sum(x*y) / (sqrt(sum(x*x)) * sqrt(sum(y*y))))
}, split(B, row(B)), list(A))

#        1        2        3        4 
# 1.249046 2.034444 2.356194 1.325818 

答案 1 :(得分:0)

B行与向量A之间的点积向量为B %*% AB行的向量长度为​​sqrt(rowSums(B^2))

要找到最小角度,您需要最大余弦值,但实际上不需要计算角度,因此A的长度无关紧要。

因此,角度最小的行将由row <- which.max((B %*% A)/sqrt(rowSums(B^2)))给出。凭借达伦的数据,该行位于第1行。

如果确实需要最小角度,则可以将公式用于两个向量到B[row,]A。如果需要所有角度,则公式为

acos((B %*% A)/sqrt(rowSums(B^2))/sqrt(sum(A^2)))