# Using Random-Number Functions and CALL Routines

 Seed Values

Each random-number function and CALL routine generates pseudo-random numbers from a specific statistical distribution. Every random-number function requires a seed value expressed as an integer constant, or a variable that contains the integer constant. Every CALL routine calls a variable that contains the seed value. Additionally, every CALL routine requires a variable that contains the generated random numbers.

The seed variable must be initialized prior to the first execution of the function or CALL statement. After each execution of a function, the current seed is updated internally, but the value of the seed argument remains unchanged. After each iteration of the CALL statement, however, the seed variable contains the current seed in the stream that generates the next random number. With a function, it is not possible to control the seed values, and, therefore, the random numbers after the initialization.

 Comparison of Random-Number Functions and CALL Routines

Except for the NORMAL and UNIFORM functions, which are equivalent to the RANNOR and RANUNI functions, respectively, SAS provides a CALL routine that has the same name as each random-number function. Using CALL routines gives you greater control over the seed values.

With a CALL routine, you can generate multiple streams of random numbers within a single DATA step. If you supply a different seed value to initialize each of the seed variables, the streams of the generated random numbers are computationally independent. With a function, however, you cannot generate more than one stream by supplying multiple seeds within a DATA step. The following two examples illustrate the difference.

 Examples

### Example 1: Generating Multiple Streams from a CALL Routine

```options nodate pageno=1 linesize=80 pagesize=60;

data multiple(drop=i);
retain Seed_1 1298573062 Seed_2 447801538
Seed_3 631280;
do i=1 to 10;
call ranuni (Seed_1,X1);
call ranuni (Seed_2,X2);
call ranuni (Seed_3,X3);
output;
end;
run;

proc print data=multiple;
title 'Multiple Streams from a CALL Routine';
run; ```

The CALL Routine Example
 ``` Multiple Streams from a CALL Routine 1 Obs Seed_1 Seed_2 Seed_3 X1 X2 X3 1 1394231558 512727191 367385659 0.64924 0.23876 0.17108 2 1921384255 1857602268 1297973981 0.89471 0.86501 0.60442 3 902955627 422181009 188867073 0.42047 0.19659 0.08795 4 440711467 761747298 379789529 0.20522 0.35472 0.17685 5 1044485023 1703172173 591320717 0.48638 0.79310 0.27536 6 2136205611 2077746915 870485645 0.99475 0.96753 0.40535 7 1028417321 1800207034 1916469763 0.47889 0.83829 0.89243 8 1163276804 473335603 753297438 0.54169 0.22041 0.35078 9 176629027 1114889939 2089210809 0.08225 0.51916 0.97286 10 1587189112 399894790 284959446 0.73909 0.18622 0.13269```

### Example 2: Assigning Values from a Single Stream to Multiple Variables

```options nodate pageno=1 linesize=80 pagesize=60;

data single(drop=i);
do i=1 to 3;
Y1=ranuni(1298573062);
Y2=ranuni(447801538);
Y3=ranuni(631280);
output;
end;
run;

proc print data=single;
title 'A Single Stream across Multiple Variables';
run;  ```

The following example shows the results. The values of Y1, Y2, and Y3 in this example come from the same random-number stream that was generated from the first seed. You can see this by comparing the values by observation across these three variables, with the values of X1 in The CALL Routine Example.

The Function Example
 ``` A Single Stream across Multiple Variables 1 Obs Y1 Y2 Y3 1 0.64924 0.89471 0.42047 2 0.20522 0.48638 0.99475 3 0.47889 0.54169 0.08225```