Что такое функция кросспроизведения R?
Мне кажется, что глупо спрашивать, но какова цель функции R crossprod
по отношению к векторным входам? Я хотел вычислить перекрестное произведение двух векторов в евклидовом пространстве и по ошибке попытался использовать crossprod
.
Одно определение векторного перекрестного произведения N = |A|*|B|*sin(theta)
, где theta - угол между двумя векторами. (Направление N
перпендикулярно плоскости A-B). Другой способ его расчета - N = Ax*By - Ay*Bx
.
base::crossprod
явно не делает этого вычисления и фактически производит векторное точечное произведение двух входов sum(Ax*Bx, Ay*By)
.
Итак, я могу легко написать свою собственную функцию vectorxprod(A,B)
, но я не могу понять, что делает crossprod
вообще.
См. также R - вычислить перекрестный продукт векторов (физика)
Ответы
Ответ 1
Согласно справочной функции в R: crossprod (X, Y) = t (X)% *% Y является более быстрой реализацией, чем само выражение. Это функция двух матриц, и если у вас есть два вектора, соответствует точечному произведению. @Hong-Ooi комментарии объясняет, почему это называется кросс-продукт.
Ответ 2
Вот фрагмент кода, который работает всякий раз, когда кросс-произведение имеет смысл: 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 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 (Карл был только в 2D).
- Это просто и идиоматично.
- Приятно комментируется и форматируется; следовательно, легко понять
Недостатком является то, что число 3 жестко закодировано несколько раз. На самом деле, это не так уж и плохо, поскольку подчеркивает тот факт, что векторное перекрестное произведение является чисто трехмерной конструкцией. Лично я бы порекомендовал полностью отказаться от перекрестных продуктов и изучать геометрическую алгебру. :)
Ответ 3
Справка ?crossprod
объясняет это довольно четко. Возьмем линейную регрессию, например, для модели y = XB + e
вы хотите найти X'X
, продукт X
транспонировать и X
. Для этого достаточно простого вызова: crossprod(X)
совпадает с crossprod(X,X)
совпадает с t(X) %*% X
. Кроме того, crossprod
можно использовать для нахождения точечного произведения двух векторов.
Ответ 4
В ответ на запрос @Bryan Hanson вот некоторый Q & D-код для вычисления векторного кросспроизведения для двух векторов в плоскости. Это немного беспорядочно для вычисления общего трехпролетного векторного кросспроизведения или для перехода в 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))
}
Ответ 5
Ниже приведена минимальная реализация для трехмерных векторов:
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]