How would I construct an orthogonal vector to two existing vectors, v1 and v2?
[Unfortunately, stackoverflow wants some more prose here or complains that it does not meet standards.]
How would I construct an orthogonal vector to two existing vectors, v1 and v2?
[Unfortunately, stackoverflow wants some more prose here or complains that it does not meet standards.]
In base R, given any two vectors, the ORTHOGONAL vector can be obtained by:
a <- rbind(v1, v2)
orth.vec <- sapply(seq(ncol(a)), function(x)(-1)^(x-1)*det(a[,-x]))
if you need to normalize it, ie the orthonormal vector:
orth.vec/norm(orth.vec,"2")
EDIT:
Note that this code is the same whether given n vectors. ie a must be a matrix of dimensions: n x (n + 1)
eg: Compare the two results below:
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
Note that the only difference between the two is the direction. If you have larger matrices, use the packages since they use the qr decomposition
the easiest way may well be an abuse of the ols model:
orthogonal.vector <- resid( lm( rnorm(length(v1)) ~ v1 + v2 ) )
example:
> 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
Maybe you can try null from pracma package, e.g.,
vout <- pracma::null(M)
or Null from MASS, e.g.,
vout <- MASS::Null(t(M))
such that
> M%*%vout
[,1]
v1 -2.220446e-16
v2 4.440892e-16
Data
v1 <- c(1,2,3)
v2 <- c(3,2,4)
M <- rbind(v1,v2)