How simulate correlated Poisson distributions
Afficher commentaires plus anciens
Hi Is there a way to simulate correlated RVs where each RV follows poisson distribution? I have 2 RVs X1 and X2, and both follow Poisson distribution. I would like simulate final results such that I can control correlation between X1 and X2. Either simulating straight correlated process or post-processing of 2 independent run would work.
Réponse acceptée
Plus de réponses (2)
Jeff Miller
le 8 Oct 2018
Modifié(e) : Jeff Miller
le 8 Oct 2018
NRVs = 2;
RVs = cell(NRVs,1);
RVs{1}=Poisson(23); % The Poisson parameter is the mean
RVs{2}=Poisson(12);
TargetCorrs = [1 0.3; 0.3 1]; % Replace 0.3 with whatever correlation you want.
mymultivar = RandGen(RVs,TargetCorrs,'Adjust','NSteps',500);
r=mymultivar.Rands(10000); % r is the array of random numbers with desired marginals & correlation
Look at DemoRandGen.m for more details.
15 commentaires
Pete sherer
le 8 Oct 2018
Torsten
le 8 Oct 2018
https://github.com/milleratotago/RawRT/blob/master/ExtractNamei.m
Jeff Miller
le 8 Oct 2018
Yes, Cupid uses some routines from ExtractNameVal, so you also need that. I guess I need to document that more prominently--sorry.
Pete sherer
le 10 Oct 2018
Pete sherer
le 13 Oct 2018
Modifié(e) : Pete sherer
le 13 Oct 2018
Jeff Miller
le 13 Oct 2018
Sorry again. Here it is:
function [ bool ] = LegalCorrMatrix( CorrMatrix )
% Returns 1 if the input matrix is a legal correlation matrix,
% 0 otherwise.
[~, err] = cholcov(CorrMatrix);
if err == 0
bool = true;
else
bool = false;
end
end
Pete sherer
le 14 Oct 2018
Jeff Miller
le 14 Oct 2018
Good that it is working.
I'm not entirely sure what you mean by "Poisson-Gamma simulation". According to Wikipedia, it looks like you would just need the negative binomial distribution for that. Is that what you are after, or would you need something more?
Bruno Luong
le 14 Oct 2018
As I understood, Poisson-Gamma is the probability law of the number event occurring in a unit time, but the average rate (lambda) of the events instead fix as with Poisson, follows a Gamma law with alpha/beta parameters.
Pete sherer
le 14 Oct 2018
Jeff Miller
le 14 Oct 2018
@Bruno: Yes, that was my understanding too. But according to Wikipedia, the probability law resulting from that process seems to be a negative binomial.
@Pete: Cupid can make random variables that are any arbitrary mixtures of (any number of) Poissons, e.g.:
rvmix = Mixture(0.3,Poisson(4),0.35,Poisson(5),0.35,Poisson(7.2))
and you can then use one of these distributions as one of your marginals. It might be a bit slow, though.
Bruno Luong
le 14 Oct 2018
Modifié(e) : Bruno Luong
le 14 Oct 2018
Thanks I'll read wikipedia. ;-)
Poisson Mixture would be indeed easier to deal with than jumping around as Gamma.
Pete sherer
le 15 Oct 2018
Jeff Miller
le 15 Oct 2018
No, you can't pass data, but I think you can get what you want anyway using the NegativeBinomial distribution (which I added to Cupid yesterday). Again, I refer you to Wikipedia which explains the equivalence. Here is a small script illustrating the equivalence:
alpha=4;
beta=22;
nSim=100000;
simLambda = gamrnd( alpha, beta, [nSim, 1]);
simVec= poissrnd( simLambda, [nSim, 1]);
figure; histogram(simVec)
% Equivalent negative binomial, according to https://en.wikipedia.org/wiki/Negative_binomial_distribution
p = 1/(1+beta);
nb = NegativeBinomial(alpha,p);
simVec2 = nb.Random([nSim,1]);
figure; histogram(simVec2);
For all values of alpha and beta that I have tried, the histograms look identical, so this might convince you of the equivalence even if the math in Wikipedia does not. I think this means you can get what you want using the NegativeBinomial, which is a regular cupid distribution.
Jeff Miller
le 16 Oct 2018
Another option--just added--is to use a "List" random variable, which is defined by an arbitrary vector of discrete random values and another arbitrary vector of the probabilities of each value. You would get these values by random generation, more or less like this:
simLambda = gamrnd( alpha, beta, [nSim, 1]);
simVec= poissrnd( simLambda, [nSim, 1]);
[Xs, ~, addresses] = unique(simVec);
Counts = accumarray(addresses,1);
Ps = Counts / sum(Counts);
gpRV = List(Xs',Ps'); % Note transpose relative to unique & accumarray outputs
Now gpRV is a Cupid distribution object that you can assign to RV{1}, etc, and use with RandGen. It won't give you exactly the values in simVec, but it will give you values from the marginal distribution defined by simVec.
Pete sherer
le 17 Oct 2018
2 commentaires
Pete sherer
le 17 Oct 2018
Jeff Miller
le 17 Oct 2018
List and NegativeBinomial were both added to the repo since we started this discussion. If you just downloaded Cupid once at the beginning, you didn't get them, and you'll need to update to the latest version for these functions to be defined.
Catégories
En savoir plus sur Binomial Distribution dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!