Transformed Dirichlet array with range [-1,1] in numpy

498 views Asked by At

A random vector sampled from the Dirichlet distribution contains values that fall in the domain [0,1] and they sum to 1. In numpy it can be programmed like this for a vector size of 5:

x = numpy.random.dirichlet(np.ones(5))

Instead, I would like a random vector that contains values that are [-1,1] and sum to 1, which I was told can be achieved by transforming the Dirichlet generated x vector as y = 2x -1

Below is an attempt at this transformation. The script doesn't work properly however because y doesn't sum to 1 as needed. How can it be fixed, or could it be that y = 2x -1 does not do what they said?

x = numpy.random.dirichlet(np.ones(5))
y = 2*x -1
print(x, np.sum(x))
print(y, np.sum(y))

which outputs:

[0.0209344  0.44791586 0.21002354 0.04107336 0.28005284] 1.0
[-0.9581312  -0.10416828 -0.57995291 -0.91785327 -0.43989433] -3.0000000000000004
3

There are 3 answers

1
Charlie On BEST ANSWER

Try y=1/(dimension/3)-2*x. That worked for me.

2
Sextus Empiricus On

As one of the answers on stats.stackexchange explains: there is only one way that you can map the variables of a Dirichlet distribution to [-1,1] while keeping the sum equal to 1. This is when the dimension is 3 and when you use y=1-2x

import numpy
numpy.random.seed(seed = 1)
x = numpy.random.dirichlet(alpha = numpy.ones(3), size = 1)
y = 1-2*x
print(x, numpy.sum(x))
print(y, numpy.sum(y))

which prints:

[[2.97492728e-01 7.02444212e-01 6.30601451e-05]] 1.0000000000000002
[[0.40501454 -0.40488842  0.99987388]] 0.9999999999999998
4
mathfux On

The thing is that interval [0, 1] can have one and the only one linear map to interval [-1, 1] which is actualy a map x -> 2x - 1. But it can't guarantee that your sum will be stable. A reason can be seen in these observations:

np.sum(x)
0.9999999999999999
np.sum(2*x)
1.9999999999999998
np.sum(2*x-1)
-3.0

As you can see, the last sum doesn't decrease by 1 as expected. It actually decreases by 5 because every of 5 items were decreased by 1.