Drawing pseudorandoms from a truncated normal distribution

只谈情不闲聊 提交于 2020-01-10 03:19:00

问题


Matlab has the function randn to draw from a normal distribution e.g.

x = 0.5 + 0.1*randn() 

draws a pseudorandom number from a normal distribution of mean 0.5 and standard deviation 0.1.

Given this, is the following Matlab code equivalent to sampling from a normal distribution truncated at 0 at 1?

    while x <=0 || x > 1

    x = 0.5 + 0.1*randn();

    end

回答1:


Using MATLAB's Probability Distribution Objects makes sampling from truncated distributions very easy.

You can use the makedist and truncate functions to define the object and then modify (truncate it) to prepare the object for the random function which allows generating random variates from it.

% MATLAB R2017a
pd = makedist('Normal',0.5,0.1)     % Normal(mu,sigma)
pdt = truncate(pd,0,1)              % truncated to interval (0,1)
sample = random(pdt,numRows,numCols)  % Sample from distribution `pdt`

Once the object is created (here it is pdt, the truncated version of pd), you can use it in a variety of function calls.

To generate samples, random(pdt,m,n) produces a m x n array of samples from pdt.


Further, if you want to avoid use of toolboxes, this answer from @Luis Mendo is correct (proof below).

figure, hold on
h = histogram(cr,'Normalization','pdf','DisplayName','@Luis Mendo samples');
X = 0:.01:1;
p = plot(X,pdf(pdt,X),'b-','DisplayName','Theoretical (w/ truncation)');



回答2:


You need the following steps 1. Draw a random value from uniform distribution, u. 2. Assuming the normal distribution is truncated at a and b. get

u_bar = F(a)*u +F(b) *(1-u)

3. Use the inverse of F

epsilon= F^{-1}(u_bar)

epsilon is a random value for the truncated normal distribution.




回答3:


Why don't you vectorize? It will probably be faster:

N = 1e5; % desired number of samples
m = .5; % desired mean of underlying Gaussian
s = .1; % desired std of underlying Gaussian
lower = 0; % lower value for truncation
upper = 1; % upper value for truncation

remaining = 1:N;
while remaining
    result(remaining) = m + s*randn(1,numel(remaining)); % (pre)allocates the first time
    remaining = find(result<=lower | result>upper);
end


来源:https://stackoverflow.com/questions/18099201/drawing-pseudorandoms-from-a-truncated-normal-distribution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!