Question

I want to develop a lognormal distribution with range [0.42,1.19], whose few elements are given as D=[1.19,1.00,0.84,0.71,0.59,0.50,0.42]. The mean should be 0.84 and standard deviation as small as possible. Also given is that the 90% of cdf (=90% of the grains) lies between 0.59 and 1.19.

Once I know all the elements of this lognormal distribution which incorporate the given conditions I can find its pdf, which is what I require. Here are simple steps I tried:

D=[1.19,1.00,0.84,0.71,0.59,0.50,0.42];

s=0.30; % std dev of the lognormal distribution

m=0.84; % mean of the lognormal distribution

mu=log(m^2/sqrt(s^2+m^2)); % mean of the associated normal dist.

sigma=sqrt(log((s^2/m^2)+1)); % std dev of the associated normal dist.

[r,c]=size(D);

for i=1:c

D_normal(i)=mu+(sigma.*randn(1));

w(i)=(D_normal(i)-mu)/sigma; % the probability or the wt. percentage

end

sizes=exp(D_normal);
Was it helpful?

Solution

If you have the statistics toolbox and you want to draw random values from the lognormal distribution, you can simply call LOGNRND. If you want to know the density of the lognormal distribution with a given mean and sigma at a specific value, you use LOGNPDF.

Since you're calculating weights, you may be looking for the density. These would be, in your example:

weights = lognpdf([1.19,1.00,0.84,0.71,0.59,0.50,0.42],0.84,0.3)

weights =
     0.095039     0.026385     0.005212   0.00079218   6.9197e-05   5.6697e-06   2.9244e-07

EDIT

If you want to know what percentage of grains falls into the range of 0.59 to 1.19, you use LOGNCDF:

100*diff(logncdf([0.59,1.19],0.84,0.3))
ans =
       1.3202

That's not a lot. If you plot the distribution, you'll notice that the lognormal distribution with your values peaks a bit above 2

x = 0:0.01:10;
figure
plot(x,lognpdf(x,0.84,0.3))

OTHER TIPS

It seems that you are looking to generate truncated lognormal random numbers. If my assumption is correct you can either use the rejection sampling or inverse transform sampling to generate the necessary samples. Caveat: Rejection sampling is very inefficient if your bounds are very far from the mean.

Rejection Sampling

If x ~ LogNormal(mu,sigma) I(lb < x < ub )

Then generate, x ~ LogNormal(mu,sigma) and accept the draw if lb < x < ub.

Inverse Transform Sampling

If x ~ LogNormal(mu,sigma) I(lb < x < ub ) then

CDF(x) = phi((log(x) - mu)/sigma) /( phi((log(ub) - mu)/sigma) - phi((log(lb) - mu)/sigma))

Generate, u ~ Uniform(0,1).

Set, CDF(x) = u and invert for x.

In other words,

x = exp( mu + sigma * phi_inverse( u * ( phi((log(ub) - mu)/sigma) - phi((log(lb) - mu)/sigma)) ) )

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top