самый простой способ построить ортогональный вектор в R

Как бы я построил ортогональный вектор для двух существующих векторов, v1 и v2?

[К сожалению, stackoverflow хочет еще немного прозы здесь или жалуется, что не соответствует стандартам.]


person ivo Welch    schedule 28.07.2020    source источник
comment
может быть актуально: math.stackexchange.com/questions/501949/, а также stackoverflow.com/questions/36798301/   -  person chinsoon12    schedule 29.07.2020


Ответы (3)


В базе R для любых двух векторов ОРТОГОНАЛЬНЫЙ вектор может быть получен следующим образом:

 a <- rbind(v1, v2)
 orth.vec <- sapply(seq(ncol(a)), function(x)(-1)^(x-1)*det(a[,-x]))

если вам нужно его нормализовать, то есть ортонормированный вектор:

 orth.vec/norm(orth.vec,"2")

РЕДАКТИРОВАТЬ: обратите внимание, что этот код одинаков, независимо от того, заданы ли n векторов. т.е. a должна быть матрицей размеров: n x (n + 1)

например: Сравните два результата ниже:

a <- matrix(sample(90),9)
MASS::Null(t(a))
             [,1]
 [1,] -0.16836356
 [2,] -0.41335337
 [3,]  0.55917161
 [4,] -0.36823759
 [5,] -0.16845300
 [6,]  0.29331428
 [7,]  0.09284215
 [8,]  0.10840769
 [9,] -0.13890032
[10,]  0.44547280

get_orth_vec <- function(y)sapply(seq(ncol(y)), function(x)(-1)^(x-1)*det(y[,-x]))

# Unnormalized Orthogonal Vector
orth.vec <- get_orth_vec(a)
 [1]  2.418607e+15  5.937980e+15 -8.032715e+15  5.289874e+15  2.419892e+15 -4.213572e+15 -1.333713e+15
 [8] -1.557318e+15  1.995356e+15 -6.399388e+15
 # Orthonormal vector
 orth.vec/norm(orth.vec,"2")
 [1]  0.16836356  0.41335337 -0.55917161  0.36823759  0.16845300 -0.29331428 -0.09284215 -0.10840769
 [9]  0.13890032 -0.44547280

Обратите внимание, что единственная разница между ними заключается в направлении. Если у вас есть большие матрицы, используйте пакеты, так как они используют разложение qr

person Onyambu    schedule 29.07.2020
comment
Хороший ответ с домашним рецептом, +1! - person ThomasIsCoding; 30.07.2020

Может быть, вы можете попробовать null из пакета pracma, например,

vout <- pracma::null(M)

или Null из MASS, например,

vout <- MASS::Null(t(M))

такой, что

> M%*%vout
            [,1]
v1 -2.220446e-16
v2  4.440892e-16

Данные

v1 <- c(1,2,3)
v2 <- c(3,2,4)
M <- rbind(v1,v2)
person ThomasIsCoding    schedule 28.07.2020

самым простым способом может быть злоупотребление моделью ols:

orthogonal.vector <- resid( lm( rnorm(length(v1)) ~ v1 + v2 ) )

пример:

> v1 <- rnorm(5); v2 <- rnorm(5);
> orthogonal.vector <- resid( lm( rnorm(length(v1)) ~ v1 + v2 ) )
> orthogonal.vector %*% v1
                       [,1]
[1,] -0.0000000000000004441
> orthogonal.vector %*% v2
                     [,1]
[1,] 0.000000000000000111
person Community    schedule 28.07.2020
comment
Технически это не совсем правильно. c(0,0,0) - это начало координат, а не ортогональный вектор - person Onyambu; 29.07.2020
comment
пожалуйста, дополните. результат не является источником. - person ivo Welch; 08.08.2020
comment
Потому что вы генерируете случайным образом, но остатки должны быть равны нулю. Если модель идеально подходит, остатки равны нулю. Попробуйте снова - person Onyambu; 09.08.2020
comment
понятно. Однако идеально подходящая модель y является событием с нулевой вероятностью для случайно нарисованного вектора y. и в этом случае можно просто переделать это с другим случайно нарисованным вектором. - person ivo Welch; 10.08.2020
comment
Я пробовал 5 раз, и во всех случаях остатки были c (0,0,0). Это не ортогональный вектор - person Onyambu; 10.08.2020
comment
Я предполагаю, что ваши векторы уже исчерпывают пространство (т.е. у вас есть двумерные векторы). вы можете найти новый ортогональный вектор для обоих, только если у вас больше измерений, чем векторов. Я добавил пример. - person ivo Welch; 11.08.2020
comment
Что для вас означают остатки? - person Onyambu; 11.08.2020