Code covered by the BSD License  

Highlights from
Truncated Gaussian

5.0

5.0 | 3 ratings Rate this file 64 Downloads (last 30 days) File Size: 3.46 KB File ID: #23832

Truncated Gaussian

by Bruno Luong

 

19 Apr 2009 (Updated 12 Aug 2010)

Generate a pseudo-random vector X drawn from the truncated Gaussian distribution

| Watch this File

File Information
Description

% function X = TruncatedGaussian(sigma, range)
% X = TruncatedGaussian(sigma, range, n)

Generate a pseudo-random vector X of size n, X are drawn from the truncated Gaussian distribution in a RANGE braket; and satisfies std(X)=sigma.

RANGE is of the form [left,right] defining the braket where X belongs. For a scalar input RANGE, the braket is [-RANGE,RANGE].

If input SIGMA is negative, X will be forced to have the same "shape" of distribution function than the unbounded Gaussian with standard deviation -SIGMA: N(0,-SIGMA). It is similar to calling RANDN and throw away values ouside RANGE. In this case, the standard deviation of the truncated Gaussian will be different than -SIGMA. The *effective* mean and the effective standard deviation can be obtained by calling:
 
 [X meaneffective sigmaeffective] = TruncatedGaussian(...)

http://en.wikipedia.org/wiki/Truncated_normal_distribution

Acknowledgements
This submission has inspired the following:
Truncated multivariate normal
MATLAB release MATLAB 7.8 (R2009a)
Other requirements Probably work on most MATLAB version No statistics Toolbox is required
Tags for This File  
Everyone's Tags
Tags I've Applied
Add New Tags Please login to tag files.
Comments and Ratings (24)
09 Apr 2010 summersyu Yu

How to change the mean?

10 Apr 2010 Bruno Luong

To change the mean, you might try this:

shift = something
X = shift + TruncatedGaussian(sigma, range-shift, ...)

10 Aug 2010 Ze Dagher

Bruno,

your code has one problem. Enter this command and see what happens:
Y = TruncatedGaussian(-1,[10 20],[1 1000]);
All the values returned are 20s. I know that 10 to 20 is a very unlikely range with a distribution of N(0,1) but still, I am just showing here that I noticed that your code returns wrong values sometimes.

Another (possibly related) problem is when you try and generate a distribution with non-zero mean with the range being a bit far from the mean. The histogram of the returned values does not match a trusted method I used. I am not sure what this is about.

12 Aug 2010 Bruno Luong

Thanks, Ze I made some correction to the code. The new version is available.

12 Aug 2010 Ze Dagher

Thanks Bruno. This turned out to be the issue in the second problem I described. The output now matches derivations.

15 Aug 2010 summersyu Yu

Dear Bruno,

Thank you for your answer. Following is my understanding:

 [X meaneffective sigmaeffective] = TruncatedGaussian(...)
If meaneffective is 5, but I want the mean to be 15.
Then shift=10
X = shift + TruncatedGaussian(sigma, range-shift, ...)

This is how we generate random variables from truncated normal distribution with mean 15, variance sigmaeffective and range [a,b].

But what is the CDF of a random variable from truncated normal distribution?

Let y be the cdf of a truncated normal variable x, then is the following equation right? I am not sure of the mean and variance in normcdf

y = (normcdf(x) - normcdf(a)) ./ (normcdf(b) - normcdf(a))

 

23 Nov 2010 Bree

Hi Bruno,

Will you generalize this code into the multivariate one?
Trying to generate this kind of numbers, but in high dimensionality. Say something n = [128, 1e6] (rather than n=[1, 1e6].

26 Nov 2010 Bruno Luong

Hi Bree, not in my intention.

08 Feb 2011 Ling Xue

what does "meaneffective sigmaeffective "mean? We need to need the mean and variance before generating Gaussian random variable, right? It seems that meaneffective is changing even the range and sigma remains the same.

03 Jun 2011 Manu

thanks!

04 Jul 2011 milad babaei

Hi Bruno,is that possible to change the bound in a code and generate random numbers??for example in this zone n=[1, 1e4].

07 Jul 2011 Bruno Luong

Midal, the RANGE second argument of TruncatedGaussian can be used for bound.

16 Aug 2011 Zack

Hi bruno
Can you please tell me how to use your function for a truncated gaussian with mean mu non zero a standard deviation sigma and a range [-1 1]?

is it possible to extend this function for a [a b] with a<>b and maybe a or b equal to infinity?

Thanks

16 Aug 2011 Bruno Luong

Zack,
first question: see my comment #2 above.
second question: yes the function accept infinity as range.

24 Aug 2011 Ricardo Giglio

Hi Bruno, I'd like to generate two series with same mean but different variances as described below, but I always get different means... Could you help me understanding why? Thanks

A_bar = 1.5; A_var = 4.5;
B_bar = 1.5; B_var = 6.5;

A = A_bar + TruncatedGaussian(sqrt(A_var), [1 inf], 10);
B = B_bar + TruncatedGaussian(sqrt(B_var), [1 inf], 10);
mean(A(:))
mean(B(:))

ans =

    4.9641

ans =

    5.6081

26 Aug 2011 Bruno Luong

The effective mean of the truncated Gaussian changes with the range. To get the effective mean of the date, call in two outputs form:

>> [X meaneffective] = TruncatedGaussian(sqrt(4.5), [1 inf], [1,1e6]);
>> meaneffective

meaneffective =

    3.7034

>> mean(X)

ans =

    3.7016

>> [X meaneffective] = TruncatedGaussian(sqrt(6.5), [1 inf], [1,1e6]);
>> meaneffective

meaneffective =

    4.2673

>> mean(X)

ans =

    4.2684

HINT: to get the mean you aim for, use FZERO in this function:

function deltamean = meanTG(xbar, meantarget, stdtarget, range)

[~, meaneffective] = TruncatedGaussian(stdtarget, range-xbar, 0);
deltamean = meantarget - (meaneffective + xbar);

end % meanTG

% Call fzero
meantarget = 6;
stdtarget = 3;
range = [1 Inf];

xbarstart = 10;
xbar = fzero(@(xbar) meanTG(xbar, meantarget, stdtarget, range), xbarstart)

% Create a shift TrunccatedGaussian
X = xbar + TruncatedGaussian(stdtarget, range-xbar, [1 1e6]);

% Check
fprintf('mean(X) = %f\n', mean(X));
fprintf('std(X) = %f\n', std(X));
fprintf('min(X) = %f\n', min(X));
fprintf('max(X) = %f\n', mean(X));

27 Aug 2011 milad babaei

tnx bruno,what does "meaneffective sigmaeffective "mean?FOR example: what's the definition of this:

mean(C)=623.066, estimated=624.239
sigma=147.65, effective=91.8246, estimated=90.8613

27 Aug 2011 Bruno Luong

Mean effective, sigma effective are the real mean and standard deviation of the random variable after truncation. The word "effective" is to make the distinction with the mean and standard deviation of the full Gaussian variable BEFORE the truncation.

01 Oct 2011 Bruno Luong

Please note the typo in the last line in my comment from August 26th 2011

fprintf('max(X) = %f\n', max(X));

25 Jan 2012 Raymond

Dear Bruno,

How do a generate from the normal distribution with mean zero and standard deviation 1 a truncated normal on the range [2 500]? I calculate the this random variable has a standard deviation of 0.3381. When I try [X meaneff sigmaeff] = TruncatedGaussian(0.3381, [2 500], 1) I get an error message.

26 Jan 2012 Bruno Luong

Raymond, there exist no random variable in [2 500] with mean = 0. The mean must be in [2, 5000] regardless the distribution. Thus what you ask is mathematically impossible.

13 Feb 2012 Raymond

Dear Bruno,

I'm very sorry not to have been more precise. I wanted to generate a truncated standard normal random variable, truncated to the interval [2,500]. Is this possible?

Raymond

18 Feb 2012 Bruno Luong

@Raymond, you still do not elaborate what is "truncated standard normal random variable". I can only guess:

x = TruncatedGaussian(-1,[2 500],[1 1e6]);

Beside that you need to read the help of TruncatedGaussian

27 Apr 2012 mortain

Ciao Bruno,

thanks for the code you've written. I have a similar doubt as Ricardo. I'd assume the code would divide the domain of the "range" in a number of points equal to the number of points specified in the command "n", TruncatedGaussian(sigma, [range], [n]);

However, the values in X are defined randomly, hence the mean estimated will always be different, even though the range and sigma are the same
>> range=[-3 3];
>> sigma=1;
>> [X meaneff sigmaeff] = TruncatedGaussian(sigma, range, [1 1e3]);
>> fprintf('mean(X)=%g, estimated=%g\n',meaneff, mean(X))
mean(X)=0, estimated=0.0555218
>> fprintf('sigma=%g, effective=%g, estimated=%g\n', sigma, sigmaeff, stdX)
sigma=1, effective=1, estimated=0.992506
>> [X meaneff sigmaeff] = TruncatedGaussian(sigma, range, [1 1e3]);
>> fprintf('mean(X)=%g, estimated=%g\n',meaneff, mean(X))
mean(X)=0, estimated=0.00445842
>> fprintf('sigma=%g, effective=%g, estimated=%g\n', sigma, sigmaeff, stdX)
sigma=1, effective=1, estimated=0.992506

This can be seen as well from hist, using same number of divisions.
Van I ask you if I correctly got your coding, and how to obtain an uniform division of the domain.

Thanks

Please login to add a comment or rating.
Updates
12 Aug 2010

Use asymptotic formula for unbalanced range to avoid round-off error issue

Tag Activity for this File
Tag Applied By Date/Time
gaussian Bruno Luong 20 Apr 2009 12:11:18
normal Bruno Luong 20 Apr 2009 12:11:18
random Bruno Luong 20 Apr 2009 12:11:18
truncated Bruno Luong 20 Apr 2009 12:11:18
pdf Bruno Luong 20 Apr 2009 12:11:18
cdf Bruno Luong 20 Apr 2009 12:11:18
distribution Bruno Luong 20 Apr 2009 12:11:18
normal milad babaei 26 Feb 2011 02:44:31
gaussian milad babaei 26 Feb 2011 02:44:39

Contact us at files@mathworks.com