代码之家  ›  专栏  ›  技术社区  ›  Christian

R中两个矢量之间的角度

  •  26
  • Christian  · 技术社区  · 15 年前

    编程语言中最有效的方法是什么? R 计算两个向量之间的角度?

    6 回复  |  直到 7 年前
        1
  •  41
  •   las3rjock    12 年前

    根据第5页 this PDF , sum(a*b) 是r命令来查找向量的点积 a b sqrt(sum(a * a)) 是r命令来查找向量的范数 ,和 acos(x) 是圆弧余弦的r命令。因此,计算两个矢量之间夹角的r代码是

    theta <- acos( sum(a*b) / ( sqrt(sum(a * a)) * sqrt(sum(b * b)) ) )
    
        2
  •  16
  •   Graeme Walsh    11 年前

    我的答案由两部分组成。第1部分是数学——为线程的所有读者提供清晰的理解,并使后面的R代码易于理解。第2部分是R编程。

    第1部分-马思

    两个向量的点积 X 可定义为:

    enter image description here

    何处 X ||是欧几里得范数(也称为L 向量的范数) X .

    操纵点积的定义,我们可以得到:

    enter image description here

    其中θ是矢量之间的角度 X Y 以弧度表示。注意θ可以取一个值,这个值位于从0到π的闭合区间上。

    对于theta本身,我们得到:

    enter image description here

    第2部分-R代码

    要将数学转换成R代码,我们需要知道如何执行两个矩阵(向量)计算:点积和欧几里德范数(这是一种特殊的范数,称为L 规范)。我们还需要知道反余弦函数的r等价,cos - 1 .

    从顶部开始。通过引用 ?"%*%" ,点积(也称为内积)可以使用 %*% 操作员。关于 ?norm , the norm() 函数(基包)返回 向量的范数。这里的兴趣标准是L 规范,或者,用R帮助文档的说法,“光谱”或“2”-规范。这意味着 type 论证 规范() 函数应设置为等于 "2" . 最后,r中的反余弦函数用 acos() 功能。

    解决方案

    配备了数学和相关的R函数,可以使用基本包函数将原型函数(即,不是生产标准)组合在一起,如下所示。如果上述信息合理,则 angle() 后面的函数应该是清晰的,没有进一步的注释。

    angle <- function(x,y){
      dot.prod <- x%*%y 
      norm.x <- norm(x,type="2")
      norm.y <- norm(y,type="2")
      theta <- acos(dot.prod / (norm.x * norm.y))
      as.numeric(theta)
    }
    

    测试功能

    验证功能是否正常工作的测试。让 X =(2,1)和 Y =(1,2)。点积介于 X Y 是4。欧几里得范数 X 为SqRT(5)。欧几里得范数 Y 也是sqrt(5)。cos theta=4/5。θ约为0.643弧度。

    x <- as.matrix(c(2,1))
    y <- as.matrix(c(1,2))
    angle(t(x),y)          # Use of transpose to make vectors (matrices) conformable.
    [1] 0.6435011
    

    希望这有帮助!

        3
  •  10
  •   Stéphane Laurent    7 年前

    对于二维矢量,接受答案和其他答案中给出的方法不考虑角度的方向(符号)。( angle(M,N) 是一样的 angle(N,M) )它只返回一个正确的值 0 pi .

    使用 atan2 函数得到一个定向角度和一个正确的值(模 2pi )

    angle <- function(M,N){
      acos( sum(M*N) / ( sqrt(sum(M*M)) * sqrt(sum(N*N)) ) )
    }
    angle2 <- function(M,N){
      atan2(N[2],N[1]) - atan2(M[2],M[1]) 
    }
    

    检查一下 angle2 给出正确的值:

    > theta <- seq(-2*pi, 2*pi, length.out=10)
    > O <- c(1,0)
    > test1 <- sapply(theta, function(theta) angle(M=O, N=c(cos(theta),sin(theta))))
    > all.equal(test1 %% (2*pi), theta %% (2*pi))
    [1] "Mean relative difference: 1"
    > test2 <- sapply(theta, function(theta) angle2(M=O, N=c(cos(theta),sin(theta))))
    > all.equal(test2 %% (2*pi), theta %% (2*pi))
    [1] TRUE
    
        4
  •  6
  •   flying sheep    9 年前

    你应该使用点积。说你有 V 艾尔= X 艾尔, Y 艾尔, Z 艾尔)和 V 艾尔= X 艾尔, Y _ Z _ V 艾········· V _楞,按

    V V 阿兹= X 艾········· X 阿斯+ Y 艾········· Y 阿斯+ Z轴 艾········· Z轴 艾氏= 艾斯···· V _( _ ;

    这意味着左边显示的和等于向量的绝对值乘以向量之间角度的余弦的乘积。向量的绝对值 V 艾尔和 V _

    γ V __=__( X 阿斯加 Y 阿斯加 Z _
    γ V _( X 阿斯加 Y 阿斯加 Z A.Y.Y.*)

    所以,如果你重新排列上面的第一个方程,你会得到

    余弦函数 γ (=) X 艾········· X 阿斯+ Y Y 阿斯+ Z Z (α)(·) V 艾斯···· V _

    你只需要对cos应用arccos函数(或反cosine)。( γ )以获得角度。

    根据你的arccos函数,角度可以是度或弧度。

    (对于二维向量,只需忘记 Z -坐标和做同样的计算。)

    祝你好运,

    约翰多纳

        5
  •  4
  •   Radim Köhler user2134822    12 年前

    另一种解决方案是:两个向量之间的相关性等于两个向量之间角度的余弦。

    所以这个角度可以用 acos(cor(u,v))

    # example u(1,2,0) ; v(0,2,1)
    
    cor(c(1,2),c(2,1))
    theta = acos(cor(c(1,2),c(2,1)))
    
        6
  •  0
  •   Guy    15 年前

    我认为你需要的是一种内在的产品。两矢量 v,u R^n 或任何其他内部产品空间) <v,u>/|v||u|= cos(alpha) .(曾 alpha 是向量之间的角度)

    有关详细信息,请参阅:

    http://en.wikipedia.org/wiki/Inner_product_space