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 1`x`13 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.

## 6 Comments

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

Yes. See my blog post "Calling SAS Procedures from the SAS/IML Language."

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;

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

See p. 28 of my book

Statistical Programming in SAS/IML Software. That chapter is available as a FREE download.## 3 Trackbacks

[...] a scalar value for each parameter that you specify as an argument. (This is generally true when calling Base SAS functions from SAS/IML software.) This means that the RAND function returns a vector of random values when you pass in a vector of [...]

[…] Base SAS function, the function returns a vector that is the same size and shape as the parameter. In this way, you can vectorize the calling of Base SAS functions. In particular, you can pass in a vector of indices to the SCAN function and get back a vector of […]

[…] The range of the data is [14, 60]. You can extend that range by the half-width of the kernel components, which is 15. Consequently the following statements use the interval [0, 75] as a convenient interval on which to sum the density components. The actual summation is easy in SAS/IML because you can pass a vector of positions to the PDF function i Base SAS. […]