Here's a quick tip to keep in mind when you write SAS/IML programs: although the SAS/IML documentation lists about 300 functions that are built into the SAS/IML language, you can also call hundreds of functions in Base SAS. Furthermore, you can pass in SAS/IML vectors for arguments to the functions. This article shows that you can also pass in multiple vectors, provided that they are all the same dimensions.

I recently blogged about the four essential functions for statistical programmers: the PDF (probability density function), CDF (cumulative distribution function), QUANTILE, and RAND (or RANDGEN) functions. The first three of these functions are Base SAS functions, but you can call them from SAS/IML programs and you can send in vectors as arguments, as shown in the following statements:

```proc iml; x = do(-3, 3, 0.5); /* 13 points: -3, -2.5, ..., 2.5, 3 */ /* call Base SAS function with one vector */ f = pdf("Normal", x);/* 13 points out: f(-3), f(-2.5), ..., f(3) */```

The f vector contains the density of the standard normal distribution at 13 locations. I sent 13 points into the function, I got 13 points out.

The PDF function for the normal distribution accepts two optional parameters: a mean and a standard deviation parameter. By default, the mean for the normal family is set to zero. Therefore, the previous PDF call is equivalent to the following call, which explicitly specifies the mean parameter to zero:

`f = pdf("Normal", x, 0); /* one vector parameter; one scalar */`

It is perfectly fine to mix and match parameters in this way. You can specify one vector parameter and one or more scalar parameters. You can also specify two or more vector parameters for the PDF function, provided that they are all the same dimensions (shape). For example, the following statements are valid:

```mu = -6:6; /* vector of 13 means */ f = pdf("Normal", x, mu); /* f(x[i]; mu[i]), i=1..13 */```

This code evaluates the normal PDF function with parameter mu[i] at the point x[i] for i=1..13. The syntax shows that you can pass multiple vectors to a Base SAS function, provided that the vectors are the same shape, in this case a 1x13 vector. However, you usually cannot pass vectors of different shapes into a Base SAS function, as shown in the following statement:

`f = pdf("Normal", x, {0 1}); /* mean=0 and 1? Nope, wrong dimensions! */`

If you execute the previous statement, the following error message appears:

`»ERROR: (execution) Matrices do not conform to the operation.`

The message says "Matrices do not conform to the operation," which means that the parameters have different shapes.

In general, when you call Base SAS functions from the SAS/IML language, you can pass in vectors of parameters. The shape of the parameter vector determines the shape of the function's output. You can also mix scalar parameters and vector parameters. However, if you pass in more than one vector (or matrix) as a parameter, each non-scalar parameter must have the same shape.

Share Distinguished Researcher in Computational Statistics

Rick Wicklin, PhD, is a distinguished researcher in computational statistics at SAS and is a principal developer of PROC IML and SAS/IML Studio. His areas of expertise include computational statistics, simulation, statistical graphics, and modern methods in statistical data analysis. Rick is author of the books Statistical Programming with SAS/IML Software and Simulating Data with SAS.

1. Hello Rick, I am wondering can PROC IML Do Loop call a standard procedure like PROC MCMC in the loop? Thanks

2. Hello Rick,

Thanks for the helpful blogs... I recently read the post regarding the creating matrix by using do loops and have a question for you. I am very new to proc IML and really want to tackle it with all of your guys advises..By folloing a logic, I am trying to create a matrix and pass my variables that had been read from the data set into the matrix.
this is what I do
proc IML;
USE work.Test1;
READ ALL VAR {Var 1....Var 26} into rm ;
CLOSE work.Test1;
n=NROW(rm);
d=J(n,1,0);
c=d;
c=n[,2:27]-n[,1:26];
x=n|d||c;
free n;
quit;
This is what passed through the log:
ERROR: (execution) Matrix has not been set to a value.
operation : || at line 1006 column 9
operands : d, c

d 0 row 0 col (type ?, size 0)

How can I deal with the problem? I would highly appreciate the specific advise

• The best way to get programming advice is to post questions to the SAS/IML Discussion Forum at http://communities.sas.com/community/sas_iml_and_sas_iml_studio
Someone there will help.

There are many mistakes in this program. I can't give specific advise to everyone who writes, but try:
c=d || rm;
c = c[,2:27]-c[,1:26];
x=n||d||c;
free c;

3. hi ,

the following code generates a column vector of a sample of size 10 from the standard normal density, do i have a code to directly generate a column vector without taking the transpose:

proc iml;
mhat=0;
do e=1 to10;
*generating standard normal random variable;
x=rannor(100);
mhat=mhat//x;
end;
mhat=remove(mhat,1);
mhat=t(mhat);
print mhat;
quit;

• To generate a vector of random normal values, use

```proc iml;
x = j(10, 1);              /* allocate 10 x 1 vector */
call randgen(x, "Normal"); /* random sample from normal distribution */
```

See p. 28 of my book Statistical Programming in SAS/IML Software. That chapter is available as a FREE download.