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 pth 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.