Obtaining sigma of a Normal distibution in Matlab - matlab

I have the mean and the percentile 60 of a Normal Distribution. I need to obtain a random array of numbers form it with those two values in Matlab.
Is this somehow posible?
Thanks

I'm not exactly sure of what your looking. I understood that you want to know the standard deviation for a certain value of a quantile at 0.6 (percentile = quantile * 100)?
From wikipedia. (look at the quantile function for a mean μ and variance σ2).
From this you have all you need:
p = 0.6
F^-1(p) is your percentile
erf^{-1} is erfinv
Get the \sigma it's your standard deviation and then to generate your vector simply use x=randn(nbSamples,1)*sigma + mean

m = 2; %// number of rows
n = 5; %// number of columns
mu = 3.2; %// mean
p60 = 0.4; %// 60-percentile
sigma = p60 / norminv(.6); %// compute sigma from p60
result = mu + sigma*randn(m,n); %// random numbers with desired distribution
%// Or: result = normrnd(mu, sigma, m, n);

Related

Vectors must be the same length error in Curve Fitting in Matlab

I'm having problems in curve fitting my randomized data for the function
Here is my code
N = 100;
mu = 5; stdev = 2;
x = mu+stdev*randn(N,1);
bin=mu-6*stdev:0.5:mu+6*stdev;
f=hist(x,bin);
plot(bin,f,'bo'); hold on;
x_ = x(1):0.1:x(end);
y_ = (1./sqrt(8.*pi)).*exp(-((x_-mu).^2)./8);
plot(x_,y_,'b-'); hold on;
It seems like I'm having vector size problems since it is giving me the error
Error using plot
Vectors must be the same length.
Note that I simplified y_ since mu and the standard deviation is known.
Plot:
Well first of all some adjustments to your question:
You are not trying to do curve fitting. What you are trying to do (in my opinion) is to overlay a probability density function on an histogram obtained by taking random points from the same distribution (A normal distribution with parameters (mu,sigma)). These two curve should indeed overlay, as they represent the same thing, only one is analytical and the other one is obtained numerically.
As seen in the hist documentation, hist is not recommended and you should use histogram instead
First step: Generating your random data
Knowing the distribution is the Normal distribution, we can use MATLAB's random function to do that :
N = 150;
rng('default') % For reproducibility
mu = 5;
sigma = 2;
r = random('Normal',mu,sigma,N,1);
Second step: Plot the histogram
Because we don't just want a count of the elements in each bin, but a feel of the probability density function, we can use the 'Normalization' 'pdf' arguments
Nbins = 25;
f=histogram(r,Nbins,'Normalization','pdf');
hold on
Here I'd rather specify a number of bins than specifying the bins themselves, because you never know in advance how far from the mean your data is going to be.
Last step: overlay the probability density function over the histogram
The histogram being already consistent with a probability density function, it is sufficient to just overlay the density function:
x_ = linspace(min(r),max(r),100);
y_ = (1./sqrt(2*sigma^2*pi)).*exp(-((x_-mu).^2)./(2*sigma^2));
plot(x_,y_,'b-');
With N = 150
With N = 1500
With N = 150.000 and Nbins = 50
If for some obscure reason you want to use old hist() function
The old hist() function can't handle normalization, so you'll have to do it by hand, by normalizing your density function to fit your histogram:
N = 1500;
% rng('default') % For reproducibility
mu = 5;
sigma = 2;
r = random('Normal',mu,sigma,1,N);
Nbins = 50;
[~,centers]=hist(r,Nbins);
hist(r,Nbins); hold on
% Width of bins
Widths = diff(centers);
x_ = linspace(min(r),max(r),100);
y_ = N*mean(Widths)*(1./sqrt(2*sigma^2*pi)).*exp(-((x_-mu).^2)./(2*sigma^2));
plot(x_,y_,'r-');

Generating two correlated uniform random variables in Matlab

Like the title suggests, I am facing difficulty in understanding how we generate two correlated uniform [0,1] random variables. I am new to the idea of copulas.
I am struggling to write a MATLAB code wherein I am required to generate two correlated uniform [0,1] random variables.
Generating correlated uniform random variables with Gaussian Copula
rho = .75; % Desired target correlation
N = 1000; % Number of samples
Z = mvnrnd([0 0],[1 rho; rho 1], N);
U = normcdf(Z); % Correlated U(0,1) random variables
scatterhist(U(:,1),U(:,2),'Direction','out') % Visualize (change `rho` to see impact)
Note: Method not guaranteed to hit target correlation exactly but should be close enough for many applications.
This can be very useful to quickly generate correlated distributions using the inverse transform method (either analytically or numerically). Both use cases illustrated below.
Analytical approach
lambda = 2; alpha = 2; beta = 3;
rho = -.35; N = 1000;
Z = mvnrnd([0 0],[1 rho; rho 1], N);
U = normcdf(Z);
X = (-1/lambda)*log(U(:,1)); % Inverse Transform for Exponential
Y = beta*(-log(U(:,2))).^(1/alpha); % Inverse Transform for Weibull
corr(X,Y)
scatterhist(X,Y,'Direction','out')
Numerical approach
% Parameters
alpha = 6.7; lambda = 3;
mu = 0.1; sigma = 0.5;
rho = 0.75; N = 1000;
% Make distributions
pd_X = makedist('Gamma',alpha,lambda);
pd_Y = makedist('Lognormal',mu,sigma);
Z = mvnrnd([0 0],[1 rho; rho 1], N);
U = normcdf(Z);
% Use Inverse Transform for marginal distributions (numerically)
X = icdf(pd_X,U(:,1)); % Inverse CDF for X
Y = icdf(pd_Y,U(:,2)); % Inverse CDF for Y
corr(X,Y)
scatterhist(X,Y,'Direction','out')
References:
Inverse Transform
Copulas
Gaussian copula:
Ross, Sheldon. (2013). Simulation. Academic Press, San Diego, CA, 5th edition. 103--105.
Modified related answer from here.

Matlab and normal realizations

I have wrote this code:.
N=10000; % number of experiments
o= 1000+randn(1,N)*sqrt(10^4); % random normal distribution with mean 1000 and variance 10^4
b=700:50:1300; % specify the number of bins (possible values of the realizations)
prob=hist(o,b)/N %create ad histogram
X=[700:50:1300]
**
Now, how I can create a matrix which contains the values of b and prob?
In other words, I want a matrix of this kind:
matrix=[ value of X(i) ; probability associate at the value of X(i) ]
es: matrix=[... X(i)=850... ; ... prob(X(i)=850).. ]
Thank you a lot! ;)
I think you want the probabilities of the intervals for which the histogram is computed:
N = 100000; %// number of experiments
b = 700:50:1300; %// bin centers
mu = 1000; %// mean of distribution
sigma = 100; %// standard deviation of distribution
delta = (b(2)-b(1))/2; %// compute bin half-width
pb = normcdf(b+delta,mu,sigma)-normcdf(b-delta,mu,sigma); %// compute probability
Check:
o = mu + sigma*randn(1,N);
hist(o, b)
hold on
plot(b, N*pb, 'r', 'linewidth', 2)

Random Numbers with Gaussian and Uniform Distributions in matlab

I want generate a number in Gaussian and Uniform distributions in matlab.
I know this function randi and rand() but all of them are in normal (Gaussian) distribution. How can a generate a random number in uniform distribution?
Use rand(dimensions) for a Uniform Distribution between 0 and 1.
Use randn(dimensions) * sqrt(sigma) + mu for a Gaussian Distribution with a mean of mu and standard deviation of sigma.
randn is the function to generate Gaussian distributed variables (randi and rand produce uniformly distributed ones).
You can generate any distribution from rand().
For example , lets say you want to generate 100000 samples for rayleigh dist.The way to do this is that you invert the cdf of that particular function.The basic idea is that since the cdf has to be between 0 and 1 , we can find the value of the random variable by inputting the value of cdf b/w 0 and 1. So for rayleigh, it would be
for i = 1:100000
data(i) = (2*sigma^2 *(-(log(1 - rand(1,1)))))^.5;
end
You can do something similar for gaussian distribution.
Congrulations, you already generating pseudo-random numbers with a gaussian distribution. Normal distribution is a synonym for it.
The only other possible interpretation I can get from your question is that you want something that has mean != 0 and/or variance != 1. To do that, simply perform mean + sqrt(var) * randn(X).
It is true you can generate just about anything from rand but that it isn't always convenient, especially for some complicated distributions.
MATLAB has introduced Probability Distribution Objects which make this a lot easier and allow you to seamlessly access mean, var, truncate, pdf, cdf, icdf (inverse transform), median, and other functions.
You can fit a distribution to data. In this case, we use makedist to define the probability distribution object. Then we can generate using random.
% Parameters
mu = 10;
sigma = 3;
a = 5; b = 15;
N = 5000;
% Older Approaches Still Work
rng(1775)
Z = randn(N,1); % Standard Normal Z~N(0,1)
X = mu + Z*sigma; % X ~ Normal(mu,sigma)
U = rand(N,1); % U ~ Uniform(0,1)
V = a + (b-a)*U; % V ~ Uniform(a,b)
% New Approaches Are Convenient
rng(1775)
pdX = makedist('Normal',mu,sigma);
X2 = random(pdX,N,1);
pdV = makedist('Uniform',a,b);
V2 = random(pdV,N,1);
A reproducible example:
Support = (0:0.01:20)';
figure
s(1) = subplot(2,2,1)
h(1) = histogram(X,'Normalization','pdf')
xlabel('Normal')
s(2) = subplot(2,2,2)
h(2) = histogram(V,'Normalization','pdf')
xlabel('Uniform')
s(3) = subplot(2,2,3), hold on, box on
h(3) = histogram(X2,'Normalization','pdf')
plot(Support,pdf(pdX,Support),'r-','LineWidth',1.2)
xlabel('Normal (new)')
s(4) = subplot(2,2,4), hold on, box on
h(4) = histogram(V2,'Normalization','pdf')
plot(Support,pdf(pdV,Support),'r-','LineWidth',1.2)
xlabel('Uniform (new)')
xlim(s,[0 20])
References:
Uniform Distribution
Normal (Gaussian) Distribution
Following raj's answer: by using the Box-Muller Transform you can generate independent standard Normal/Gaussian random numbers:
N = 1e6; z = sqrt(-2*log(rand(N, 1))) .* cos(2*pi * rand(N, 1)); figure; hist(z, 100)
N = 1e6; z = sqrt(-2*log(rand(N, 1))) .* sin(2*pi * rand(N, 1)); figure; hist(z, 100)
If you want to apply the Inverse Transformation Method, you can use the Inverse Complementary Error Function (erfcinv):
N = 1e6; z = -sqrt(2) * erfcinv(2 * rand(1e6, 1)); figure; hist(z, 100)
But I hope randn works better.

Creating Gaussian random variable with MATLAB

By using randn function I want to create a Gaussian random variable X such that X ~ N(2,4) and plot this simulated PDF together with theoretic curve.
Matlab randn generates realisations from a normal distribution with zero mean and a standard deviation of 1.
Samples from any other normal distribution can simply be generated via:
numSamples = 1000;
mu = 2;
sigma = 4;
samples = mu + sigma.*randn(numSamples, 1);
You can verify this by plotting the histogram:
figure;hist(samples(:));
See the matlab help.
N = 1000;
x = [-20:20];
samples = 2 + 4*randn(N, 1);
ySamples = histc(samples,x) / N;
yTheoretical = pdf('norm', x, 2, 4);
plot(x, yTheoretical, x, ySamples)
randn(N, 1) creates an N-by-1 vector.
histc is histogram count by bins given in x - you can use hist to plot the result immediately, but here we want to divide it by N.
pdf contains many useful PDFs, normal is just one example.
remember this: X ~ N(mean, variance)
randn in matlab produces normal distributed random variables W with zero mean and unit variance.
To change the mean and variance to be the random variable X (with custom mean and variance), follow this equation:
X = mean + standard_deviation*W
Please be aware of that standard_deviation is square root of variance.
N = 1000;
x = [-20:20];
samples = 2 + sqrt(4)*randn(N, 1);
ySamples = histc(samples,x) / N;
yTheoretical = pdf('norm', x, 2, sqrt(4)); %put std_deviation not variance
plot(x, yTheoretical, x, ySamples)
A quick and easy way to achieve this using one line of code is to use :
mu = 2;
sigma = 2;
samples = normrnd(mu,sigma,M,N);
This will generate an MxN matrix, sampled from N(μ,𝜎), (= N(2,2) in this particular case).
For additional information, see normrnd.