Что такое функция кросс-продукта 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

Другие вопросы по тегам