Generate normal distribution with LGC random issue
Afficher commentaires plus anciens
hi as you can see im trying to compere values btween my function randi and built in function rand but i can't find a way to make myrandi plot normal distribution plot
clc
%N=input('sequence_length')
N=5000
la=65539
MinSec = fix(clock);
seed = 100*(MinSec(5) + MinSec(6));
Urand = myrandi(seed,N);
subplot(3,2,1)
hist(Urand)
%% Task 1: : the Linear Congruential Generator (LCG)
v = rand(1,N);
%u=u./max(u);
subplot(3,2,2);
hist(v,100);
title(subplot(3,2,2),'Uniform random: rand()');
%% Task 2: Generate exponential distribution with LGC random
u=myrandi(seed,N);
e=-log(1-u)./la;
subplot(3,2,3);
hist(e,100);
title(subplot(3,2,3),'Exponential random: myrand()');
%% Task 2: Generate exponential distribution with rand() random
u=rand(1,N);
f=-log(1-u)./la;
subplot(3,2,4);
hist(f,100);
title(subplot(3,2,4),'Exponential random: rand()');
%% Task 2: Generate normal distribution with LGC random
u1 = myrandi(seed,N);
u2 = myrandi(seed,N);
a = (-2*log(u1));
b = 2*pi*u2;
n = sqrt(a.*sin(b));
m = real(sqrt(a).*cos(b));
M = mean(m,'all'); %mean
s = std(m); %standard deaviation
T = normrnd(M, s);
subplot(3,2,5);
hist(T);
title(subplot(3,2,5),'Normal random: myrand()');
%% Task 2: Generate normal distribution with rand() function
u1 = rand(1,N);
u2 = rand(1,N);
a = (-2*log(u1)).^.5;
b = 2*pi*u2;
p = real(a.*sin(b));%p and q are both
q = real(a.*cos(b));%normal random variables
subplot(3,2,6);
hist(q,100);
title(subplot(3,2,6),'Normal random: rand()');
%Function that produce an uniform random numbers
%Using the technic of LCG r(k) = [lambda*r(k-1)]modulo(P)
function Urand = myrandi(seed,sequence_length)
la=65539;
N=sequence_length;
P=2^31;
%change N accordingly
%part a
Urand=zeros(1,N);
seed(1)=seed;
for i=2:N
Urand(i)= mod((la*seed*(i-1)),P);
end
Urand = Urand./(P-1);
end
Réponse acceptée
Plus de réponses (1)
After looking at your code in my other answer, the problem clearly reduces to your RNG. Is that even a valid linear congruential RNG? GOD NO! For example, I'll use a simple starting seed to show what is happening.
seed = 1000;
myrandi(seed,10)
Do you see that each such random number is just a multiple of the first one, and that it starts out at 0? We could have gotten the same result from linspace. You had this:
Urand(i)= mod((la*seed*(i-1)),P);
Effectively, you have not much more than a call to linspace, at least for the first few thousand random numbers you generated. And even after that, it is not much different.
Was that really your plan? Were you directed to write the RNG like that?
Try out this generator.
myslightlybetterrand(seed,10)
Do you see these already look now more random?
histogram(myslightlybetterrand(seed,100000),1000,'norm','pdf')
And again, this is starting to look more random. Still a completely crappy RNG, as I could surely show with some effort.
N = 1000000;
seed1 = 56554;
seed2 = 343453;
u1 = myslightlybetterrand(seed1,N);
u2 = myslightlybetterrand(seed2,N);
r = sqrt(-2*log(u1)).*cos(2*pi*u2);
hist(r,1000,'norm','pdf')
And that works. Your problem was in the basic RNG.
function Seq = myslightlybetterrand(seed,N)
Seq = zeros(1,N);
% don't use the seed as the first element of your sequence.
% make it effectively the 0'th element instead.
Seq0 = seed;
la = 65539;
P = 2^31;
for n = 1:N
Seq0 = mod(Seq0*la,P);
Seq(n) = Seq0;
end
Seq = Seq/(P-1);
end
function Urand = myrandi(seed,sequence_length)
la=65539;
N=sequence_length;
P=2^31;
%change N accordingly
%part a
Urand=zeros(1,N);
seed(1)=seed;
for i=2:N
Urand(i)= mod((la*seed*(i-1)),P);
end
Urand = Urand./(P-1);
end
2 commentaires
Faisal Al-Wazir
le 14 Oct 2022
John D'Errico
le 14 Oct 2022
Ok then. I was wondering just a wee bit about that. What you cannot control... :)
Catégories
En savoir plus sur Multivariate t 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!







