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

Угол между двумя векторами в R

Какой самый эффективный способ в языке программирования R рассчитать угол между двумя векторами?

4b9b3361

Ответ 1

В соответствии со страницей 5 этот PDF, sum(a*b) является командой R, чтобы найти точечный продукт векторов a и b, а sqrt(sum(a * a)) - команда R, чтобы найти норма вектора a, а acos(x) - команда R для дугового косинуса. Отсюда следует, что R-код для вычисления угла между двумя векторами равен

theta <- acos( sum(a*b) / ( sqrt(sum(a * a)) * sqrt(sum(b * b)) ) )

Ответ 2

Мой ответ состоит из двух частей. Часть 1 - математика - дать ясность всем читателям потока и сделать код R, который следует понятным. Часть 2 - это программирование R.

Часть 1 - Математика

Точечное произведение двух векторов x и y можно определить как:

enter image description here

где || x || является евклидовой нормой (также известной как норма L 2) вектора x.

Манипулируя определением точечного произведения, мы можем получить:

enter image description here

где theta - угол между векторами x и y, выраженными в радианах. Заметим, что theta может принимать значение, лежащее на отрезке от 0 до pi.

Решая для самой тэта, получим:

enter image description here

Часть 2 - Код R

Чтобы перевести математику в R-код, нам нужно знать, как выполнять два матричных (векторных) вычисления; точечного произведения и евклидовой нормы (которая является определенным типом нормы, известной как норма L 2). Нам также необходимо знать R-эквивалент обратной косинусной функции, cos -1.

Начиная с вершины. Ссылаясь на ?"%*%", точечный продукт (также называемый внутренним продуктом) может быть рассчитан с использованием оператора %*%. Что касается ?norm, функция norm() (базовый пакет) возвращает норму вектора. Норма, представляющая интерес, представляет собой норму L 2 или, в соответствии с документацией справки R, "спектральный" или "2" -норм. Это означает, что аргумент type функции norm() должен быть установлен равным "2". Наконец, обратная косинусная функция в R представлена ​​функцией acos().

Решение

Оборудованная как математикой, так и соответствующими функциями R, можно использовать прототипную функцию (то есть не производственный стандарт) - используя функции базового пакета - как показано ниже. Если приведенная выше информация имеет смысл, то следующая функция angle() должна быть четкой без дальнейших комментариев.

angle <- function(x,y){
  dot.prod <- x%*%y 
  norm.x <- norm(x,type="2")
  norm.y <- norm(y,type="2")
  theta <- acos(dot.prod / (norm.x * norm.y))
  as.numeric(theta)
}

Проверить функцию

Тест, чтобы проверить работу функции. Пусть x = (2,1) и y = (1,2). Точечный продукт между x и y равен 4. Евклидовой нормой x является sqrt (5). Евклидовой нормой y также является sqrt (5). cos theta = 4/5. Theta составляет приблизительно 0,643 радиана.

x <- as.matrix(c(2,1))
y <- as.matrix(c(1,2))
angle(t(x),y)          # Use of transpose to make vectors (matrices) conformable.
[1] 0.6435011

Надеюсь, это поможет!

Ответ 3

Для 2D-векторов способ, указанный в принятом ответе и других, не учитывает ориентацию (знак) угла (angle(M,N) совпадает с angle(N,M)), и он возвращает правильное значение только для угла между 0 и pi.

Используйте функцию atan2 чтобы получить ориентированный угол и правильное значение (по модулю 2pi).

angle <- function(M,N){
  acos( sum(M*N) / ( sqrt(sum(M*M)) * sqrt(sum(N*N)) ) )
}
angle2 <- function(M,N){
  atan2(N[2],N[1]) - atan2(M[2],M[1]) 
}

Проверьте, что angle2 дает правильное значение:

> theta <- seq(-2*pi, 2*pi, length.out=10)
> O <- c(1,0)
> test1 <- sapply(theta, function(theta) angle(M=O, N=c(cos(theta),sin(theta))))
> all.equal(test1 %% (2*pi), theta %% (2*pi))
[1] "Mean relative difference: 1"
> test2 <- sapply(theta, function(theta) angle2(M=O, N=c(cos(theta),sin(theta))))
> all.equal(test2 %% (2*pi), theta %% (2*pi))
[1] TRUE

Ответ 4

Вы должны использовать точечный продукт. Скажем, что V₁ = (x₁, y₁, z₁) и V₂ = (x₂, y₂, z₂), то точечное произведение, которое я обозначу через V₁ · V₂, вычисляется как

V₁ · V₂ = x₁ · x₂ + y₁ · y₂ + z₁ · z₂ = | V₁ | · | V₂ | · Cos (θ);

Это означает, что указанная сумма слева равна произведению абсолютных значений векторов, умноженных на косинус угла между векторами. абсолютное значение векторов V₁ и V₂ вычисляется как

| V₁ | = √ (x₁² + y₁² + z₁²) и
| V₂ | = √ (x₂² + y₂² + z₂²),

Итак, если вы измените первое уравнение выше, вы получите

cos (θ) = (x₁ · x₂ + y₁ · y₂ + z₁ · z₂) ÷ (| V₁ | · | V₂ |),

и вам нужна функция arccos (или обратный косинус), примененная к cos (θ), чтобы получить угол.

В зависимости от вашей функции arccos угол может быть в градусах или радиан.

(Для двумерных векторов просто забудьте z-координаты и выполните те же вычисления.)

Удачи,

Джон Донер

Ответ 5

Другое решение: корреляция между двумя векторами равна косинусу угла между двумя векторами.

поэтому угол можно вычислить с помощью acos(cor(u,v))

# example u(1,2,0) ; v(0,2,1)

cor(c(1,2),c(2,1))
theta = acos(cor(c(1,2),c(2,1)))

Ответ 6

Я думаю, что вам нужен внутренний продукт. Для двух векторов v,uR^n или любых других пространств внутреннего произведения) <v,u>/|v||u|= cos(alpha). (были alpha - угол между векторами)

для более подробной информации:

http://en.wikipedia.org/wiki/Inner_product_space