Statistical programming, matrix languages, and more

Truncated distribution generation

Accepted Solution Solved
Reply
Contributor
Posts: 71
Accepted Solution

Truncated distribution generation

Hello:

 

Expert does any one now what is wrong with the following code:

 

I am simulating a  truncated distribution  that is multivariate in nature with the follow code from Rick's blog, but it not working well:

 

data TruncNormal(keep=x fa fb);
Fa = cdf('Normal', 30); /* for a = 30 */
Fb = cdf('Normal', 50); /* for b = 50 */
call streaminit(1234);
do i = 1 to 1000; /* sample size = 1000 */
v = Fa + (Fb-Fa)*rand('Uniform'); /* V ~ U(F(a), F(b)) */
x = quantile('Normal', v); /* truncated normal on [a,b] */
output;
end;
run;

ods select histogram;
proc univariate data=TruncNormal;
histogram x / endpoints=30 to 50 by 5;
run;

 

The aim is to simulate a truncated  [a=30,b=50] distribution that is normally distribution. Minimum value is 30 maximum value is 50. The orginal normal distribution has a mean of 38 and standard of 5. Following generation,I like to check to see that the generated distribution is in fact a PDF.

 

The above case is aimed to generate on one instance of such a truncated distribution, but I want to genereate three of such variable so that I have a multivariate distrunction  with column=3 and a with specified covariance. The plan is to generate the truncated distribution thrice and then merge but that can't build the covariance.

 

I see that one can still use acceptance-rejection, but building covariance/correlation may be challenging.

 

Thanks for your help.


Accepted Solutions
Solution
‎01-19-2016 06:16 AM
Respected Advisor
Posts: 4,606

Re: Truncated distribution generation

You must specify the parameters of the simulated truncated distribution:

 

data TruncNormal(keep=x fa fb);
Fa = cdf('Normal', 30, 38, 5); /* for a = 30 */
Fb = cdf('Normal', 50, 38, 5); /* for b = 50 */
call streaminit(1234);
do i = 1 to 1000; /* sample size = 1000 */ 
    v = Fa + (Fb-Fa)*rand('Uniform'); /* V ~ U(F(a), F(b)) */
    x = quantile('Normal', v, 38, 5); /* truncated normal on [a,b] */
    output;
    end;
run;

ods select histogram;
proc univariate data=TruncNormal;
histogram x / endpoints=28 to 52 by 2;
run;
PG

View solution in original post


All Replies
Solution
‎01-19-2016 06:16 AM
Respected Advisor
Posts: 4,606

Re: Truncated distribution generation

You must specify the parameters of the simulated truncated distribution:

 

data TruncNormal(keep=x fa fb);
Fa = cdf('Normal', 30, 38, 5); /* for a = 30 */
Fb = cdf('Normal', 50, 38, 5); /* for b = 50 */
call streaminit(1234);
do i = 1 to 1000; /* sample size = 1000 */ 
    v = Fa + (Fb-Fa)*rand('Uniform'); /* V ~ U(F(a), F(b)) */
    x = quantile('Normal', v, 38, 5); /* truncated normal on [a,b] */
    output;
    end;
run;

ods select histogram;
proc univariate data=TruncNormal;
histogram x / endpoints=28 to 52 by 2;
run;
PG
SAS Super FREQ
Posts: 3,234

Re: Truncated distribution generation

Apparently the reference is "The inverse CDF method for simulating from a distribution," which is based on Chapter 7 of Simulating Data with SAS (Wicklin 2013)..

See also "Implement the truncated normal distribution in SAS."

 

If your eventual goal is multivariate correlated, I recommend reading Chapter 9, "Advanced Simulation of Multivariate Data" as well as searching the literature. This looks like a challenging problem!

 

Contributor
Posts: 71

Re: Truncated distribution generation

Thanks. Yes, multivariate correlated is the goal. And yes, it is a challenging problem.
Contributor
Posts: 71

Re: Truncated distribution generation

Thanks PGstat. The code works for univariate case
Post a Question
Discussion Stats
  • 4 replies
  • 321 views
  • 2 likes
  • 3 in conversation