34

crossprod我觉得这个问题很愚蠢,但是 R函数相对于向量输入的意图是什么 ?我想计算欧几里得空间中两个向量的叉积并错误地尝试使用crossprod.
向量叉积的一种定义是N = |A|*|B|*sin(theta)其中 theta 是两个向量之间的角度。(方向N垂直于 AB 平面)。另一种计算方法是 N = Ax*By - Ay*Bx
base::crossprod显然不做这个计算,实际上产生了两个输入的向量点积sum(Ax*Bx, Ay*By)

所以,我可以很容易地编写自己的vectorxprod(A,B)函数,但我不知道crossprod一般在做什么。

另请参阅R - 计算向量的叉积(物理)

4

6 回答 6

27

根据 R 中的帮助函数: crossprod (X,Y) = t(X)%*% Y 是比表达式本身更快的实现。它是两个矩阵的函数,如果有两个向量对应点积。@Hong-Ooi 的评论解释了为什么它被称为交叉产品。

于 2013-03-01T16:59:01.903 回答
13

这是一个简短的代码片段,只要叉积有意义就可以使用:3D 版本返回一个向量,2D 版本返回一个标量。如果您只想要简单的代码来给出正确的答案而不需要引入外部库,那么这就是您所需要的。

# Compute the vector cross product between x and y, and return the components
# indexed by i.
CrossProduct3D <- function(x, y, i=1:3) {
  # Project inputs into 3D, since the cross product only makes sense in 3D.
  To3D <- function(x) head(c(x, rep(0, 3)), 3)
  x <- To3D(x)
  y <- To3D(y)

  # Indices should be treated cyclically (i.e., index 4 is "really" index 1, and
  # so on).  Index3D() lets us do that using R's convention of 1-based (rather
  # than 0-based) arrays.
  Index3D <- function(i) (i - 1) %% 3 + 1

  # The i'th component of the cross product is:
  # (x[i + 1] * y[i + 2]) - (x[i + 2] * y[i + 1])
  # as long as we treat the indices cyclically.
  return (x[Index3D(i + 1)] * y[Index3D(i + 2)] -
          x[Index3D(i + 2)] * y[Index3D(i + 1)])
}

CrossProduct2D <- function(x, y) CrossProduct3D(x, y, i=3)

它有效吗?

让我们看看我在网上找到的一个随机示例

> CrossProduct3D(c(3, -3, 1), c(4, 9, 2)) == c(-15, -2, 39)
[1] TRUE TRUE TRUE

看起来还不错!

为什么这比以前的答案更好?

  • 它是 3D 的(Carl 的只有 2D)。
  • 它简单而惯用。
  • 很好的评论和格式化;因此,易于理解

缺点是数字“3”被硬编码了好几次。实际上,这并不是一件坏事,因为它突出了向量叉积纯粹是一个 3D 构造的事实。就个人而言,我建议完全放弃交叉产品学习几何代数。:)

于 2014-02-12T18:43:02.347 回答
4

帮助?crossprod解释得很清楚。以线性回归为例,对于y = XB + e您要查找的模型,转置和X'X的乘积。要做到这一点,一个简单的调用就足够了:is the same as is the same as 。此外,可用于求两个向​​量的点积。XXcrossprod(X)crossprod(X,X)t(X) %*% Xcrossprod

于 2013-03-01T18:52:40.527 回答
2

应@Bryan Hanson 的请求,这里有一些Q&D 代码来计算平面中两个向量的向量叉积。计算一般的 3 空间向量叉积或扩展到 N 空间有点麻烦。如果你需要这些,你必须去维基百科:-)。

crossvec <- function(x,y){
if(length(x)!=2 |length(y)!=2) stop('bad vectors')
 cv <-  x[1]*y[2]-x[2]*y[1]
return(invisible(cv))
}
于 2013-06-04T15:23:23.287 回答
2

这是 3D 矢量的简约实现:

vector.cross <- function(a, b) {
    if(length(a)!=3 || length(b)!=3){
        stop("Cross product is only defined for 3D vectors.");
    }
    i1 <- c(2,3,1)
    i2 <- c(3,1,2)
    return (a[i1]*b[i2] - a[i2]*b[i1])
}

如果您想获得 2D 向量u和的标量“叉积” v,您可以这样做

vector.cross(c(u,0),c(v,0))[3]
于 2016-03-24T07:16:29.760 回答
-4

我想通过叉积你的意思是矩阵乘法在这种情况下它只是

垫1 %垫2

于 2021-02-01T12:27:32.483 回答