Rick, an interesting idea to pre-compute the matrices and use a list. I have come up with a recursive direct product algorithm that is well suited to this.
proc iml;
n = 5;
L = ListCreate( n );
L$1 = {0, 1};
do i = 1 to n - 1;
L$(i+1) = ( L$1 @ j(2##i, 1) ) || ( {1,1} @ L$i );
end;
do i = 1 to n;
print (L$i);
end;
The code uses the list syntax that came in with SAS/IML 14.3.
Very clever, Ian. I like it. As I have said in the past, you are the master of the Kronecker product.
For those who (like) me, need to deconstruct Ian's magic, here is an alternative computation if the inner loop, which might be more enlightening. You can also print A and B at each iteration.
do i = 1 to n - 1;
A = {0,1} @ j(2##i, 1);
B = {1,1} @ L$i;
L$(i+1) = A || B;
end;
And for those who have not used lists in SAS/IML, see the article "Create lists by using a natural syntax in SAS/IML" or watch this video on the list syntax.
For a discussion and example of storing matrices in a list, see "Store pre-computed matrices in a list".
I tried to run your code but its giving the following error messages:
746 proc iml;
NOTE: IML Ready
747
748 n = 5;
749 L = ListCreate(n);
ERROR: Invocation of unresolved module LISTCREATE.
statement : ASSIGN at line 749 column 1
750 L$1 = {0, 1};
-
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
751 do i = 1 to n - 1;
752 L$(i+1) = ( L$1 @ j(2**i, 1) ) || ( {1,1} @ L$i );
-
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
753 end;
ERROR: END does not occur within DO group at line=753 col=1.
754
755 do i = 1 to n;
756 print (L$i);
-
22
76
ERROR 22-322: Syntax error, expecting one of the following: #, ##, &, (, (|, ), *, **, +, -, /,
//, :, <, <=, <>, =, >, ><, >=, @, [, ^=, `, |, ||.
ERROR 76-322: Syntax error, statement will be ignored.
757 end;
ERROR: END does not occur within DO group at line=757 col=1
You are running an old version of SAS/IML. Don't worry about it. Ian's suggestion was tangential to the discussion and isn't required to solve the problem.
Hi Rick,
I just want to know if its possible to edit the following code to have the matrix as a character matrix instead of numeric.
proc iml;
start AllZeroOneComb(n);
if n=1 then return ( {0,1} );
cmd = "m = expandgrid(";
do i = 1 to n-1;
cmd = cmd + "0:1, ";
end;
cmd = cmd + "0:1);";
*print cmd;
CALL EXECUTE(cmd);
return (m);
finish;
do n = 1 to 3;
m = AllZeroOneComb(n);
print m;
end;
For example for n=2 I should get:
"1"
"A"
"B"
"A B"
Thanks,
DJ
Sure. Index each numerical column into the character matrix {"A" "B"}. If you can't figure it out, open a new thread.
Expandgrid can accept character arguments, so it could also be done like this.
proc iml;
start XAllLetterComb(n);
if n=1 then return ( {'1','A'} );
cmd = "m = expandgrid(";
do i = 1 to n;
cmd = cmd + cat("{' ','", byte(65+n-i)," '}");
if i < n then cmd = cmd + ",";
end;
cmd = cmd + ");";
*print cmd;
CALL EXECUTE(cmd);
m[1]='1';
return ( compbl ( left( reverse( rowcat( m )))));
finish;
c = XAllLetterComb(5);
print c;
To see the expandgrid syntax, then uncomment the print statement.
Thanks alot.
This is exactly what I wanted.
thanks again,
DJ
thanks for your reply. I will just use Ian's.
thanks,
DJ
@DJ20 wrote:
I need to put them in a matrix form so I can use it in further calculations.
I need to combine my code so it depends on the number of factors. I.e if I have 3 factors it will calculate the number of combination swhich is 2**3 = 8 and output the matrix of 0's and 1's as well!!
If you want them in a matrix, you could create a SAS data set using PROC FACTEX of your factorial design, and then read that into IML. A factorial combination with letters A B C D is less useful than a matrix of 0s and 1s that would be produced by PROC FACTEX.
And even if you don't have PROC FACTEX in your SAS license, a DO loop in PROC IML creating a matrix of zeros and ones would be much easier to produce and would be much more usable than a matrix containing combinations of letters ABCD.
Unfortunately my task is to write it in SAS/IML. Otherwise I would have used the FACTEX procedure for sure.
thank you very much.
I am going to use for the output of the ANOVA table only. For the calculations I will be using the numerical version.
Thanks,
DJ
Since you are new to SAS. you might want to share what you are actually trying to accomplish (other than to create a binary matrix), we might have additional advice. For example, if you are trying to compute all possible linear regression models on a set of k regressors, there are better ways
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.