🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Obsidian | Level 7

## How to use a formula or expression in a matrix cell

I have a question about IML but I keep getting an error about post flooding. What is it? How can I post my question?

1 ACCEPTED SOLUTION

Accepted Solutions
SAS Super FREQ

## How to use a formula or expression in a matrix cell

I suspect you need to read the article "How to build a vector from expressions," which explains what you can and cannot do with matrix literals. Based on your description, it sounds like you tried something like this:

``````proc iml;
val = -sqrt(2);
/* you can't put a variable inside a matrix literal.
For example, this DOES NOT work: */
A = {1   val,
val 2};   /* ERROR: Mixing character with numeric in matrix literal */
``````

Instead, use the matrix concatenation operators to build your 2x2 matrix:

``````proc iml;
val = -sqrt(2);
A = (1   || val) //
(val || 2);
print A;
``````

10 REPLIES 10
Community Manager

## Re: How to ask a question

It can happen when you edit/re-edit a post multiple times. But I don't see any of your attempts in our spam quarantine. And you managed to post this question, so I'd say please just try again.
Obsidian | Level 7

## Re: How to ask a question

I tried to post the question multiple times. It alternative between saying fix highlighted problem, I didn't see a highlighted problem and the post flood.

I think my question is likely a very simple question.

I had text, sas code, and log results in the post.

Super User

## Re: How to ask a question

It might not hurt to consider how much stuff you were posting and what format.

Were you providing code examples as text in the text or code boxes (opened on the forum with the </> and 'running man' icons above message window)?

Data examples should be provided as a data step in the text or code box. Other forms of copy/paste tables are likely to be full of other "stuff" and might cause problems as the forum window tries to interpret that.

Example data should be that, enough to show the issue, not 1000's of lines.

Obsidian | Level 7

## Re: How to ask a question

I am trying to type values into a matrix in proc iml. A simple 2x2 matrix and I want the negative square root of 2 for the off-diagonal elements.

I tried 4 different ways to find the square root and none worked.

I can and have given up on doing that in proc iml so I created two variables in the data step and read that dataset into proc iml but I don't think that I should need to do this.

Super User

## Re: How to ask a question

Post you question here . and calling out @Rick_SAS
SAS Super FREQ

## How to use a formula or expression in a matrix cell

I suspect you need to read the article "How to build a vector from expressions," which explains what you can and cannot do with matrix literals. Based on your description, it sounds like you tried something like this:

``````proc iml;
val = -sqrt(2);
/* you can't put a variable inside a matrix literal.
For example, this DOES NOT work: */
A = {1   val,
val 2};   /* ERROR: Mixing character with numeric in matrix literal */
``````

Instead, use the matrix concatenation operators to build your 2x2 matrix:

``````proc iml;
val = -sqrt(2);
A = (1   || val) //
(val || 2);
print A;
``````

Obsidian | Level 7

## Re: How to ask a question

Thank you Rick.

Here are my attempts which didn't work:

``````proc iml;
reset print;

B={5 -sqrt(2), -sqrt(2) 3};
C={5 -2##0.5, -2##0.5 3};
D={5 -1*sqrt(2), -1*sqrt(2) 3};
E={5 (-1*sqrt(2)), (-1*sqrt(2)) 3};
quit;
``````

Fortunately, there is always an way to get things done so I used this method.

``````
data one;
input x1 x2;
if x1=-2 then x1=-sqrt(2);
if x2=-2 then x2=-sqrt(2);
datalines;
5 -2
-2 2
;
run;

proc print;
run;

proc iml;
reset print;  * I don't typically use this option but set it for this example;
use work.one;
read all var _num_ into X;

quit;
``````

Barite | Level 11

## Re: How to ask a question

Expressions are allowed when creating a list, so I thought that another way to get what you want is to use a helper function to extract the numeric data from a list, and convert it into a single matrix.  Essentially this is generalizing the shape function to a list.  For example:

``````proc iml;
/* Concatenate all numeric items in a list and return the reshaped data in the form
of a nr*nc matrix. Sublists upto a depth of maxdepth are searched for data. */
start ListShape(L, nr, nc);
if type(L) ^= 'L' then return;
maxdepth = 20;
/* idx used as loop variable at each depth, ni is the list length at each depth */
idx = j(1, maxdepth, 0);
ni = j(1, maxdepth, 0);
d = 1;  /* the current depth in the list */
do until( d = 0 );
if idx[d] = 0
then if d = 1
then ni[d] = ListLen( L );
else ni[d] = ListLen( ListGetSubItem( L, idx[1:(d-1)]) );
idx[d] = idx[d] + 1;
if idx[d] <= ni[d] then do;
x = ListGetSubItem( L, idx[1:d] );
if type(x) = 'N' then do;
/* glue all data together into a column vector y */
y = y // shape(x, nrow(x)#ncol(x) );
end; else if type(x) = 'L' then d = d + 1; /* item is a list so move deeper */
end; else do;
idx[d] = 0;
d = d - 1; /* move up the list one level */
end;
end;
return(shape(y, nr, nc));
finish;

z = ListShape( [5##2, -sqrt(2), -sqrt(2), 1:3], 3, 2);
print z;
quit;``````

which produces:

``````         z

25 -1.414214
-1.414214         1
2         3``````

The ListShape function is effectively using concatenation within a loop, which will not be efficient with large amounts of data, but should be fine for the small examples given above.

Obsidian | Level 7

## Re: How to ask a question

Interesting.

John

Barite | Level 11

## Re: How to ask a question

Because ListShape handles lists of lists, you can even specify each row of the matrix that you want to construct with it own list - this may seem a more natural syntax.  For example:

``````z = ListShape( [ [5, -sqrt(2)], [-sqrt(2), 3] ], 2, 2);
``````

will give

``````         z

5 -1.414214
-1.414214         3``````
From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
• 10 replies
• 718 views
• 2 likes
• 6 in conversation