Подтвердить что ты не робот

Что такое функция кросспроизведения 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 - вычислить перекрестный продукт векторов (физика)

4b9b3361

Ответ 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]