1

Suppose I have a vector v1 with values in the set {-1,0,1}

> v1
0  0 -1  1  0  0  0  0  0  0  0  0  0  0 -1  1  0  0  0  0  0  0  0  0  0  0  1 -1  0  0  0  0  0  0  0  0  0  0 -1  1  0  0  0  0

How to generate a vector v2 (with values in the set {-1,0,1}) that has zero correlation (or close to zero) with v1?

  • 1
    You might get some ideas from https://stats.stackexchange.com/questions/15011 and https://stats.stackexchange.com/a/152034/919. – whuber Nov 26 '19 at 18:48

3 Answers3

1

You can generate a vector that has, on average, zero correlation simply by randomly permuting your original vector.

v2 = v1[sample(length(v1),length(v1)]

This won't get you a zero-correlation vector every time, but if you run this many times, you'll see that the average correlation value is zero. The method is simple and fast enough that you could permute the vector many times until you find one that does, in fact, have sufficiently small correlation with the original vector.

As a bonus, this method preserves some aspects of your original vector, like the values appearing and their relative frequencies, which might be desirable depending on your application.

Nuclear Hoagie
  • 5,553
  • 16
  • 24
0

Very simple. You can easily create three vectors by taking any number in the set and repeating that number till the length of v1. R code:

rep(1, length(v1))

or take value 0 or -1

Neeraj
  • 2,150
  • 18
  • 28
  • 1
    Good point, using a constant I have zero correlation, but what if I want some "randomness" in v2? v2 is a simulated "realistic" timeseries that need to be not correlated with v1 – Raffaele Giannella Nov 26 '19 at 17:14
  • What about the fact that the second vector has zero variance? – Dave Nov 26 '19 at 21:57
0

Here is an inelegant R algorithm that works. It makes use of https://math.stackexchange.com/a/3385346. x is the input vector and y is the output vector (instead of v1 and v2). Not extensively checked. Build a function out of it.

x <- sample(c(-1, 0, 1), 100, replace=TRUE)
v <- x[x != 0]
done <- FALSE
while(done == FALSE){
  w <- sample(c(-1, 0, 1)*sqrt(2), length(v), replace=TRUE)
  u <- (w - ((t(v)%*%w)/(t(v)%*%v))%*%v)[1,]
  if(min(abs(u)) < 10e-12){done <- TRUE}
}
u <- round(u, 0)
u%*%v
y <- rep(NA, length(x))
y[x==0] <- sample(c(-1, 0, 1), length(x[x==0]), replace=TRUE)
y[x!=0] <- u
x
y
x%*%y
JWalker
  • 559
  • 2
  • 8