SAS/IML Software and Matrix Computations

Statistical programming, matrix languages, and more
BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
SWEETSAS
Obsidian | Level 7

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.

1 ACCEPTED SOLUTION

Accepted Solutions
PGStats
Opal | Level 21

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

4 REPLIES 4
PGStats
Opal | Level 21

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
Rick_SAS
SAS Super FREQ

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!

 

SWEETSAS
Obsidian | Level 7
Thanks. Yes, multivariate correlated is the goal. And yes, it is a challenging problem.
SWEETSAS
Obsidian | Level 7
Thanks PGstat. The code works for univariate case

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 4 replies
  • 3406 views
  • 2 likes
  • 3 in conversation