Obsidian | Level 7

## 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.

1 ACCEPTED SOLUTION

Accepted Solutions
Opal | Level 21

## 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
4 REPLIES 4
Opal | Level 21

## 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

## 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)..

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!

Obsidian | Level 7

## Re: Truncated distribution generation

Thanks. Yes, multivariate correlated is the goal. And yes, it is a challenging problem.
Obsidian | Level 7

## Re: Truncated distribution generation

Thanks PGstat. The code works for univariate case
From The DO Loop