Draw samples using a Non-Gaussian distribution
20 views (last 30 days)
Show older comments
Hi!
Let's say I have a vector X of 100 values. How can I draw a sample from this vector using a Non-Gaussian distribution?
Consider the following example in which I'm trying to draw 50 values from the original vector:
x = randn(100,1);
x(random('poisson',1:50))
Here, the Poisson distribution is just an example. This does not work because of the values I got from the random distribution are not always positive integers or logical values.
Any advice?
Thanks!
5 Comments
Paul
on 19 Sep 2023
So you have a discrete random variable N. Its probability distribution function is P(N = n) = p(n) for n = 1:100, and 0 otherwise. As must be the case, sum(p) = 1.
Do you know the distribution function, i.e., the values of p(n), n = 1:100?
Once you define the distribution function, you want to generate 50 samples of N. Are those samples to be generated with or without replacement? The former is straightforward based on the distribution function. The latter would involve reconditioning p(n) after each selection, but also doesn't sound too bad.
Accepted Answer
Image Analyst
on 18 Sep 2023
Let's say you have a vector of 100 numbers. The numbers could be anything -- doesn't matter, and we don't care. To make x from rand (uniform) or randn (normal distribution) just serves to confuse the issue with another, unrelated distribution. Let's just say that you have x and it is whatever it is and how you got it doesn't matter at all.
Now let's say you have a Normal distribution with a mean of 60 and a standard deviation of 10. So does that mean you would draw indexes in the range 60 +/- 10, in other words you'd pick indexes from about 50 to 70 from the vector? If not, please clarify.
OK, so now let's say you do not want a Gaussian distribution. Does that mean you don't want indexes from 50-70, but want indexes ranging from 1 to 100 (which would be a uniform distribution), or indexes drawn from some other distribution (like Poisson, log normal, Rayleigh, or some other known distribution)?
If you want to get the indexes of x from some arbitrary, but known, distribution, you can use random to get samples drawn from dozens of commonly used distribution functions. If you get floating point numbers, then scale them from 1 to 100 using rescale and then round them so they can be used as indexes. If you have some custom distribution, then you can use Inverse Transform Sampling ( https://en.wikipedia.org/wiki/Inverse_transform_sampling ) to get some numbers drawn from your custom distribution. See the attached demo for how I used inverse transform sampling to get numbers drawn from a Rayleigh distribution.
Finally, is this your homework, or just something you're curious about?
More Answers (3)
John D'Errico
on 18 Sep 2023
I think you don't understand random numbers, AND you don't understand indexing in MATLAB. What does this do?
random('poisson',1:50)
It generates a list of 50 Poisson random numbers, with 50 different rate parameters, the numbers 1:50. I have absolutely no idea why you would want to do that.
And worse, some of those Poisson samples will be ZERO. Some might even be larger than 100.
Then you are trying to index into a vector of length 100 using those Poisson samples. The result is? Garbage, since you will often see an indexing error.
Finally, the resulting sample? It will have the same underlying distribution as your original vector x, since you are just sampling from the original vector.
What you mean about a non-Gaussian sample? Using a Poisson distribution there is meaningless.
I think you just want to sample from the vector x. For example, suppose you have a vector of prime numbers. They certainly are not Gaussian, or even uniform.
x = primes(100)
Now we can sample from that set.
nx = numel(x);
This will be a sample WITH replacement. So some elements may be replicated.
x(randi(nx,[1,10]))
Sampling without replacement is as easy.
x(randperm(nx,10))
Be careful, as sampling without replacement is not possible, if you want to sample more than 25 elements from a vector of length 25. (Why do I feel this should be both unecessary to say, as well as totally necessary on this forum?)
3 Comments
John D'Errico
on 18 Sep 2023
Edited: John D'Errico
on 18 Sep 2023
@torsten: I'm sorry, but it is NOT wrong. It does matter how you sample, of course. So I might give you credit for misunderstanding my statement.
If the index operation has no connection to the samples themselves, then a random sampling from that set does not change the distribution of the sample. That is EXACTLY what was done by the OP.
For example, suppose I have a very simple set:
x = rand(1,5);
the vector x is statistically uniformly distributed, on the interval [0,1]. Now, choose 3 elements from that set, also randomly chosen.
y = x(randperm(5,3));
The vector y WILL be just as uniformly distributed on the interval [0,1], as was the vector x. Can you do things that are not what I was talking about, but are a bit silly? Yes.
z = x(ones(1,1000));
Then z is just a random number, with uniform distribution on the interval [0,1], but then repeated 1000 times. We could split hairs about the distribution of z, but that seems meaningless to me, and was not in the spirit of what I was saying.
Or, if you create y, by selectively sampling more often from the elements of x that are less than 1/2, or something equally silly, then of course it will change things.
Torsten
on 18 Sep 2023
Edited: Torsten
on 18 Sep 2023
z = x(ones(1,1000));
z is dirac_x(1) distributed.
As far as I understood, that's an extreme case for what the OP aims at: x(distribution(1:50)) where "distribution" can be any distribution defined on the set {1,2,...,100}. So indices (unlike for randperm) will most probably repeat.
Bruno Luong
on 19 Sep 2023
Edited: Bruno Luong
on 19 Sep 2023
x = rand(1,10000); % whatever, randn(1,100) in your case
n = 5000; % number of drawing 50 in your case
% Set up wanted drawing probability
ix = 1:numel(x);
lambda = 60;
p = poisspdf(ix,lambda);
% generate index according to the above discrete pdf
c = cumsum([0 p]);
c = c/c(end);
rix = discretize(rand(1,n), c);
% Check graphically what the drawing pdf looks like
histogram(rix,'Normalization','pdf')
current_xlim = xlim;
% Compare with the prescribed pdf, it looks OK
hold on
plot(ix, p, '-+', 'Linewidth', 2);
xlim(current_xlim)
title('This is truncated poisson pdf')
% draw randomy from x (with replacement) with the above pdf
rx = x(rix)
% how it looks like, still random like
% histogram(x)
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!