I received the following question:

In the DATA step I always use the ** operator to raise a values to a power, like this:x**2. But on your blog I you use the ## operator to raise values to a power in SAS/IML programs. Does SAS/IML not support the ** operator? Why do you always use ## instead?

The answer is that ** and ## are two different operators. The SAS/IML language supports both operators. The SAS DATA step, which only handles scalar quantities, uses the ** operator for raising values to a power.

- The ## operator is the elementwise power operator. If
`A`is a matrix of any shape,`E=A##p`is a matrix with the same dimensions. The (*i,j*)th element of`E`is the (*i,j*)th element of`A`raised to the*p*th power. For the ## operator, the power*p*can be any number (positive, zero, or negative) and does not have to be an integer. - The ** operator is the matrix power operator. If
`A`is a matrix,`A**p`multiplies`A`by itself*p*times. For the ** operator, the power*p*is usually a nonnegative integer, although*p = –1*is handled as special cases. The matrix`A`must be square.

Compare the following SAS/IML statements that demonstrate each power operator:

proc iml; A = {1 2, 3 4}; E1 = A##2; /* powers of elements */ M1 = A**2; /* matrix multiplication */ print E1[label="A##2"] M1[label="A**2"]; |

The output shows that the first matrix contains the elements of `A` raised to the second power, whereas the second is the matrix product `A*A`.

How do these operators behave if the power is positive but not an integer? The ## operator raises each element to the specified power, which is well-defined provided that the elements of `A` are not negative. The ** operator truncates the power to an integer, which gives the same result as `A**2`, as shown in the following example:

E2 = A##2.5; /* powers of elements */ M2 = A**2.5; /* truncates to integer */ print E2[label="A##2.5"] M2[label="A**2.5"]; |

If the power is negative, the elementwise power operator (##) is still well-defined (again assuming that the elements of `A` are not negative), but the ** operator usually returns an error:

E3 = A##(-2); /* powers of elements */ M3 = A**(-2); /* ERROR! */ print E3[label="A##(-2)"]; |

However, it is possible to use the ** operator to "raise a matrix to the –1 power." By convention, this matrix operation is interpreted as the matrix inverse. In other words `A**(-1)` is equivalent to `INV(A)`.

E4 = A##(-1); /* powers of elements */ M4 = A**(-1); /* matrix inverse */ print E4[label="A##(-1)"] M4[label="A**(-1)=INV(A)"]; |

What does the SAS/IML language do if `A` is a scalar (1 x 1) quantity? Try it yourself! You'll discover that the ** and the ## operators are equivalent in that case.