Что такое функция кросс-продукта R?
Я чувствую себя глупо спрашивать, но какова цель R's crossprod
функция по отношению к векторным входам? Я хотел вычислить перекрестное произведение двух векторов в евклидовом пространстве и по ошибке попытался использовать crossprod
,
Одним из определений векторного перекрестного произведения является N = |A|*|B|*sin(theta)
где тета - угол между двумя векторами. (Направление N
перпендикулярно плоскости AB). Другой способ рассчитать это N = Ax*By - Ay*Bx
,base::crossprod
ясно, что не делает этот расчет, и на самом деле производит векторное скалярное произведение двух входов sum(Ax*Bx, Ay*By)
,
Итак, я могу легко написать свой vectorxprod(A,B)
функция, но я не могу понять, что crossprod
делает в общем.
См. Также R - Расчет перекрестного произведения векторов (физика).
7 ответов
Согласно справочной функции в R: crossprod (X,Y) = t(X)%*% Y является более быстрой реализацией, чем само выражение. Это функция двух матриц, и если у вас есть два вектора, соответствует точечному произведению.
Вот фрагмент кода, который работает всякий раз, когда кросс-произведение имеет смысл: 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 (у Карла было только 2D).
- Это просто и идиоматично.
- Приятно комментируется и форматируется; следовательно, легко понять
Недостатком является то, что число 3 жестко закодировано несколько раз. На самом деле, это не так уж и плохо, поскольку подчеркивает тот факт, что векторное перекрестное произведение является чисто трехмерной конструкцией. Лично я бы порекомендовал полностью отказаться от перекрестных продуктов и вместо этого изучать геометрическую алгебру.:)
Помощь ?crossprod
объясняет это довольно четко. Возьмем линейную регрессию, например, для модели y = XB + e
ты хочешь найти X'X
, продукт X
транспонировать и X
, Чтобы получить это, достаточно простого вызова: crossprod(X)
такой же как crossprod(X,X)
такой же как t(X) %*% X
, Также, crossprod
может быть использован, чтобы найти скалярное произведение двух векторов.
В ответ на запрос @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))
}
Вот минималистичная реализация для 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]
Существует полезный пакет математических операций под названием pracma ( https://rdrr.io/rforge/pracma/api/ или CRAN https://cran.r-project.org/web/packages/pracma/index.html). Простой в использовании и быстрый. Перекрестное произведение буквально задается pracma::cross(x, y) для любых двух векторов.
я полагаю, что под перекрестным произведением вы имеете в виду умножение матриц, в этом случае это просто
мат1 % мат2