Lapis Lazuli | Level 10

SAS IML

I searched on line and found the following link:

https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/bring-back-Lower-triangular-matrix/td-p/6...

which discussed  calculating the lower triangular matrix.  The attached code was provided at the link:

``````/*LOWER TRIANGULAR CODE SAS IML*/

proc import out=a
datafile='/folders/myfolders/dmatrix/lnparam.csv/'
dbms=csv replace;
getnames=yes;
datarow=2;
run;

proc iml;
/*To get the values in a vector, you can use*/
lower = symsqr(a);
upper = symsqr(a`);

/*If you need the lower triangular matrix with zeros above the diagonal, you can use:*/
n = nrow(a);
p = ncol(a);
low = j(n, p, 0);
do i = 1 to n;
cols = 1:i; /* or cols=iSmiley Tongue; */
low[i, cols] = a[i, cols];
end;
quit;``````

When I run the code I get several errors:

/*To get the values in a vector, you can use*/
107 lower = symsqr(a);
ERROR: (execution) Matrix has not been set to a value.  I get the same error for a'

/*If you need the lower triangular matrix with zeros above the diagonal, you can use:*/
111 n = nrow(a);
112 p = ncol(a);
113 low = j(n, p, 0);
ERROR: (execution) Invalid operand to operation.

I have attached my data set lnparam.txt
Can someone with expertise in SAS IML tell me  how to correct the error?
A final question related to the lower triangle matrix.  If one calls the lower triangular matrix D  and D' its transpose (i.e., does the
var cov matrix=DxD')?
1 ACCEPTED SOLUTION

Accepted Solutions
SAS Super FREQ

Re: SAS IML

The matrix 'a' is a data matrix.  The "lower triangular portion" of a data matrix is not useful.

If you compute C=cov(A), then C is a symmetric matrix, so the lower triangular portion is relevant and useful.  However, the lower triangular matrix does not have the property that you are trying to claim.

I am going to guess that you want the Cholesky decomposition of the covariance matrix, which is the upper triangular matrix U such that C = U` * U.  Equivalently, you can define L = U` so that C = L * L`. You can compute the Cholesky matrix by using the ROOT function in SAS/IML, as follows:

``````proc iml;
use a;
read all var _NUM_ into a;
close;

C = cov(a);
U = root(C);  /* C = U` * U */
L = U`;       /* C = L * L` */

/* test to make sure it works */
C2 = L*L`;
print L, C, C2;``````

4 REPLIES 4
SAS Super FREQ

Re: SAS IML

First, could you please edit the title of this thread to make it more informative? Perhaps "How to extract the lower triangular portion of a matrix".

a = {1 2 3, 4 5 6, 7 8 9};

before writing the code that you quote.  Your problem is that you have not read the data into an IML matrix.

Use

``````proc iml;
use a;
read all var _NUM_ into a;
close a;``````

> A final question related to the lower triangle matrix.  If one calls the lower triangular matrix D and D'

> its transpose, does the var cov matrix=DxD'

No. You are reading in the data matrix. You can obtain the variance-covariance matrix by using

C = cov(a);

You can then get the lower triangular elements of C, if that is important.

Lapis Lazuli | Level 10

Re: SAS IML

I was able to modify code to read:

proc iml;

use a;

read all var _ALL_ into A;

close a;

show names;

The code read the data in to ( a), however I got an error related to the
symsqr statement which I looked up which states that it packs the elements
from the lower triangular portion into a column. The error was:

113 lower = symsqr(a);

ERROR: (execution) Matrix should be square.

How do I address this issue since my matrix is not square?

There is also an issue with the i subscript which I guess would be related
to the matrix not being square:

121 cols = 1:i;
121 ! /* or cols=iSmiley Tongue; */
122 low[i, cols] = a[i, cols];
123 end;
ERROR: (execution) Invalid subscript or subscript out of range.

How can this issue be resolved?

Based upon your answer related to my final question > does the var cov
matrix=DxD' I would surmise that

If C=cov(a) then VAR COV=lower triangular C x C'. Would that be correct?

SAS Super FREQ

Re: SAS IML

The matrix 'a' is a data matrix.  The "lower triangular portion" of a data matrix is not useful.

If you compute C=cov(A), then C is a symmetric matrix, so the lower triangular portion is relevant and useful.  However, the lower triangular matrix does not have the property that you are trying to claim.

I am going to guess that you want the Cholesky decomposition of the covariance matrix, which is the upper triangular matrix U such that C = U` * U.  Equivalently, you can define L = U` so that C = L * L`. You can compute the Cholesky matrix by using the ROOT function in SAS/IML, as follows:

``````proc iml;
use a;
read all var _NUM_ into a;
close;

C = cov(a);
U = root(C);  /* C = U` * U */
L = U`;       /* C = L * L` */

/* test to make sure it works */
C2 = L*L`;
print L, C, C2;``````

Lapis Lazuli | Level 10

Re: SAS IML

Worked just as you stated and the key element was use of the Cholesky matrix and the root function in SAS IML.

Thanks

From The DO Loop