SAS IML

Solved
Occasional Contributor
Posts: 7

SAS IML

Hello,

Can you help me with an answer?

Given e.g. the following statement:

proc iml;

A=I(2);

B=expmatrix(A);

print A B;

quit;

Then the printed matrix A is I-halved instead of I. Why?

Many thanks,

Dan

Accepted Solutions
Solution
‎02-19-2016 04:11 AM
SAS Super FREQ
Posts: 4,239

Re: SAS IML

This does not happen in PROC IML, but it does happen in SAS/IML Studio.

I'm guessing that you are running this in SAS/IML Studio or got a copy of the module that is distributed with SAS/IML Studio.

You are right: The ExpMatrix function is incorrectly changing your input matrix A.

There is a simple fix: Use the following (correct) module to store a new module in SAS/IML Studio. As long as the new module is stored in a location earlier in the search path, you will pick up the new copy. This should happen automatically, unless you have changed the default search path.

In summary, run the following in SAS/IML Studio one time.  From then on, you will pick up the correct behavior.

``````start ExpMatrix( A );
/* Compute a matrix exponential. Algorithm from
Golub/Van Loan, 2nd ed, p. 558. Based on
Moler & Van Loan (1978) "Nineteen Dubious Ways
to Compute the Exponential of a Matrix,"
SIAM Review 20, 801-836.

Given delta>0 and an nxn matrix A, the algorithm
computes F = exp(A+E) where
InfinityNorm(E)<= delta*InfinityNorm(A).
We use a delta of approx 1e-15. */

AX = A;
n = nrow(AX);
InfinityNorm = max( abs(AX)[+,] );
j = max( 0, 1+floor( Log2(InfinityNorm) ) );
AX = AX / 2##j;

/* Compute Pade' approximation to exp(A) */
X = AX;
c = 0.5;
M = I(n) + c*AX;
D = I(n) - c*AX;
q = 6; /* try to approximate with 6 terms (implies delta approx 1e-15)*/
do k = 2 to q;
c = c*(q-k+1)/( (2*q-k+1)*k );
X = AX*X;
M = M + c*X;
D = D + (-1)##k * c*X;
end;
F = solve(D,M);
do k = 1 to j;
F = F*F;
end;
return ( F );
finish ExpMatrix;
store module=ExpMatrix;``````

All Replies
Regular Contributor
Posts: 168

Re: SAS IML

This works for me.  Try using commas to make the output more clear.

print A, B;

Occasional Contributor
Posts: 7

Re: SAS IML

thaks for the answer. it doesn't work; same effect... it seems that I should put the "print" option for A before exponetiating the matrix... quite strange...

Regular Contributor
Posts: 168

Re: SAS IML

expmatrix is not an in-built function, it is an IML module that is read from the library.  So it is possible we have different versions of the library, and that your versions modifies the matrix A.  You can examine the source code of the module by entering

COPY SASHELP.IML.EXPMATRIX.SOURCE into the SAS command box.

Solution
‎02-19-2016 04:11 AM
SAS Super FREQ
Posts: 4,239

Re: SAS IML

This does not happen in PROC IML, but it does happen in SAS/IML Studio.

I'm guessing that you are running this in SAS/IML Studio or got a copy of the module that is distributed with SAS/IML Studio.

You are right: The ExpMatrix function is incorrectly changing your input matrix A.

There is a simple fix: Use the following (correct) module to store a new module in SAS/IML Studio. As long as the new module is stored in a location earlier in the search path, you will pick up the new copy. This should happen automatically, unless you have changed the default search path.

In summary, run the following in SAS/IML Studio one time.  From then on, you will pick up the correct behavior.

``````start ExpMatrix( A );
/* Compute a matrix exponential. Algorithm from
Golub/Van Loan, 2nd ed, p. 558. Based on
Moler & Van Loan (1978) "Nineteen Dubious Ways
to Compute the Exponential of a Matrix,"
SIAM Review 20, 801-836.

Given delta>0 and an nxn matrix A, the algorithm
computes F = exp(A+E) where
InfinityNorm(E)<= delta*InfinityNorm(A).
We use a delta of approx 1e-15. */

AX = A;
n = nrow(AX);
InfinityNorm = max( abs(AX)[+,] );
j = max( 0, 1+floor( Log2(InfinityNorm) ) );
AX = AX / 2##j;

/* Compute Pade' approximation to exp(A) */
X = AX;
c = 0.5;
M = I(n) + c*AX;
D = I(n) - c*AX;
q = 6; /* try to approximate with 6 terms (implies delta approx 1e-15)*/
do k = 2 to q;
c = c*(q-k+1)/( (2*q-k+1)*k );
X = AX*X;
M = M + c*X;
D = D + (-1)##k * c*X;
end;
F = solve(D,M);
do k = 1 to j;
F = F*F;
end;
return ( F );
finish ExpMatrix;
store module=ExpMatrix;``````
Occasional Contributor
Posts: 7

Re: SAS IML

Yep

Occasional Contributor
Posts: 7

Re: SAS IML

In order to avoid the expmatrix function, I could tried to approximate the exponential matrix by writing in IML the Taylor expansion (summation up to e.g.100), but I would prefer your option. Thanks Rick!

SAS Super FREQ
Posts: 4,239

Re: SAS IML

I should have mentioned an even simpler solution, pass in a COPY of your matrix instead of the matrix itself!

start MyExpMatrix(A);

A2 = A; /* copy it; A2 gets changed, but A does not */

return( ExpMatrix(A2) );

finish;

Occasional Contributor
Posts: 7

Re: SAS IML

Many thanks Rick.

🔒 This topic is solved and locked.