Composite lognormal Pareto distribution - netlogo

For the model I am working on in NetLogo, I would like to distribute a certain variable X as a composite lognormal-pareto, which takes a lognormal density up to an unknown threshold value θ and a two-parameter Pareto density with scaling parameter α thereafter.
The pdf is the following:
f1(x) = (αθ^α / (1+Φ(k))x^(α+1))exp{(-α^2/2k^2)ln^2(x/θ)} , 0 < x ≤ θ
f2(x) = αθ^α / (1+Φ(k))x^(α+1). , θ < x < ∞
where Φ(·) is the cumulative distribution function of the standard normal distribution and k is a constant.
How can I write this in NetLogo?

Related

Generating a random number based off normal distribution in matlab

I am trying to generate a random number based off of normal distribution traits that I have (mean and standard deviation). I do NOT have the Statistics and Machine Learning toolbox.
I know one way to do it would be to randomly generate a random number r from 0 to 1 and find the value that gives a probability of that random number. I can do this by entering the standard normal function
f= #(y) (1/(1*2.50663))*exp(-((y).^2)/(2*1^2))
and solving for
r=integral(f,-Inf,z)
and then extrapolating from that z-value to the final answer X with the equation
z=(X-mew)/sigma
But as far as I know, there is no matlab command that allows you to solve for x where x is the limit of an integral. Is there a way to do this, or is there a better way to randomly generate this number?
You can use the built-in randn function which yields random numbers pulled from a standard normal distribution with a zero mean and a standard deviation of 1. To alter this distribution, you can multiply the output of randn by your desired standard deviation and then add your desired mean.
% Define the distribution that you'd like to get
mu = 2.5;
sigma = 2.0;
% You can any size matrix of values
sz = [10000 1];
value = (randn(sz) * sigma) + mu;
% mean(value)
% 2.4696
%
% std(value)
% 1.9939
If you just want a single number from the distribution, you can use the no-input version of randn to yield a scalar
value = (randn * sigma) + mu;
Just for the fun of it, you can generate a Gaussian random variable using a uniform random generator:
The logarithm of a uniform random variable on (0,1) has an exponential distribution
The square root of that has a Rayleigh distribution
Multiply by the cosine (or sine) of a uniform random variable on (0,2*pi) and the result is Gaussian. You need to multiply by sqrt(2) to normalize.
The obtained Gaussian variable is normalized (zero mean, unit standard deviation). If you need specific mean and standard deviation, multiply by the latter and then add the former.
Example (normalized Gaussian):
m = 1; n = 1e5; % desired output size
x = sqrt(-2*log(rand(m,n))).*cos(2*pi*rand(m,n));
Check:
>> mean(x)
ans =
-0.001194631660594
>> std(x)
ans =
0.999770464360453
>> histogram(x,41)

calculate x value from normal distribution in matlab

I have data x , with nonzero mean. I can plot normal distribution with following
x=randi([1 20],1,60);
a=mean(x);
b=sqrt(var(x));
x= [-130:1:120];
norm = normpdf(x,a,b);
plot(x,norm)
to calculate x value for 97%, I have to see z score for 97% and then use z=(x-mean)/standard deviation for calculation of x value but how can I calculate x value directly by code.

How to generate n points and restrict the distance between them to be greater than a given value?

I would like to generate, randomly with uniform distribution, n points such that the distance between any point is greater than some fixed value.
Here is the scenario that I have in MATLAB:
I have M red points which I generate randomly with uniform distribution as follow: the x-abscissa of the M red points are xr = rand(1, M) and the y-ordinate of the M red points are yr = rand(1, M).
Also, I have M black points which I generate similarly as the red points, i.e., xb = rand(1, M) and yb = rand(1, M).
Then, I calculate the distances between all the points as follow:
x = [xr, xb];
y = [yr, yb];
D = sqrt(bsxfun(#minus, x, x').^2 + bsxfun(#minus, y, y').^2);
d = D(1:M, M + 1:end);
Now, I have to restrict the distance d to be always greater than some given value, say d0=0.5.
How to do this?
While such sampling (which is equivalent to non-overlapping circles generation) is discussed on math.stackexchange, see https://mathematica.stackexchange.com/questions/2594/efficient-way-to-generate-random-points-with-a-predefined-lower-bound-on-their-p and https://mathematica.stackexchange.com/questions/69649/generate-nonoverlapping-random-circles, I would like to point out to another potential solution which involves quasi-random numbers. For quasi-random Sobol sequences there is a statement which says that there is minimum positive distance between points which amounts to 0.5*sqrt(d)/N, where d is dimension of the problem, and N is number of points sampled in hypercube. Paper from the man himself http://www.sciencedirect.com/science/article/pii/S0378475406002382

Generating multivariate normally distributed random numbers in Matlab

This question is about the use of the covariance matrix in the multidimensional normal distribution:
I want to generate multi-dimensional random numbers x in Matlab with a given mean mu and covariance matrix Sigma. Assuming Z is a standard normally distributed random number (e.g. generated using randn), what is the correct code:
x = mu + chol(Sigma) * Z
or
x = mu + Sigma ^ 0.5 * Z
?
I am not sure about the use of the covariance matrix in the definition of the multidimensional normal distribution – whether the determinant in the denominator is of the square root or the Cholesky factor...
If by definition you refer to the density of the multivariate normal distribution:
it contains neither the Cholesky decomposition nor the matrix square root of Σ, but its inverse and the scalar square root of its determinant.
But for numerically generating random numbers from this distribution, the density is not helpful. It is not even the most general description of the multivariate normal distribution, since the density formula makes only sense for positive definite matrices Σ, while the distribution is also defined if there are zero eigenvalues – that just means that the variance is 0 in the direction of the respective eigenvector.
Your question follows the approach to start from standard multivariate normally distributed random numbers Z as produced by randn, and then apply a linear transformation. Assuming that mu is a p-dimensional row vector we want an nxp-dimensional random matrix (each row one observation, each column one variable):
Z = randn(n, p);
x = mu + Z * A;
We need a matrix A such that the covariance of x is Sigma. Since the covariance of Z is the identity matrix, the covariance of x is given by A' * A. A solution to this is given by the Cholesky decomposition, so the natural choice is
A = chol(Sigma);
where A is an upper triangular matrix.
However, we can also search for a Hermitian solution, A' = A, and then A' * A becomes A^2, the matrix square. A solution to this is given by a matrix square root, which is computed by replacing each eigenvalue of Sigma by its square root (or its negative); in general there are 2ⁿ possible solutions for n positive eigenvalues. The Matlab function sqrtm returns the principal matrix square root, which is the unique nonnegative-definite solution. Therefore,
A = sqrtm(Sigma)
works also. A ^ 0.5 should in principle do the same.
Simulations using this code
p = 10;
n = 1000;
nr = 1000;
cp = nan(nr, 1);
sp = nan(nr, 1);
pp = nan(nr, 1);
for i = 1 : nr
x = randn(n, p);
Sigma = cov(x);
cS = chol(Sigma);
cp(i) = norm(cS' * cS - Sigma);
sS = sqrtm(Sigma);
sp(i) = norm(sS' * sS - Sigma);
pS = Sigma ^ 0.5;
pp(i) = norm(pS' * pS - Sigma);
end
mean([cp sp pp])
yield that chol is more precise than the two other methods, and profiling shows that it is also much faster, for both p = 10 and p = 100.
The Cholesky decomposition does however have the disadvantage that it is only defined for positive-definite Σ, while the requirement of the matrix square root is merely that Σ is nonnegative-definite (sqrtm returns a warning for a singular input, but returns a valid result).

Lognormal random numbers in specific range in Matlab

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);
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))
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)) ) )