Generate normal distribution with LGC random issue
Show older comments
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
Accepted Answer
More Answers (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 Comments
Faisal Al-Wazir
on 14 Oct 2022
John D'Errico
on 14 Oct 2022
Ok then. I was wondering just a wee bit about that. What you cannot control... :)
Categories
Find more on Multivariate t Distribution in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






