I greatly appreciate the syntax PROC OPTMODEL uses in declaring array and matrics - especially for facilitating cell identification based on flexible and varied index sets. Excellent for subsetting, and visually recognising what combination of dimensions a given cell represents. And the user does not have to worry about reording one matrix to match another, as long as they are based on the same SET dimensions.
BUT below (in the VAR statement at the bottom - note the syntax in red) is how, to the best of my knowledge, one has to generate an X'X sum of squares and cross products from a matrix X.
That's not so bad, but what if I wanted to generate, say, beta=(X'X)-1(X'Y) or something a bit more extensive, yet trivially expressible in matrix form? There would a lot of "sum .. in". expressions and explicit subscripting requred - easy opportunities for typing erros.. How much nicer and more readable it would be to adapt some syntax from proc IML. Something like the violet in:
var beta{cols} init inv(X`*X) * X`*Y;
and have it work as long as X' and Y are compatible in their declared dimensions.
If somebody is aware of such syntax in PROC OPTMODEL, please point me to it. Otherwise, this is a request for adding some IML-like syntax to proc optmodel statements.
** Sample prog **;
data have;
do r=1 to 6;
100*uniform(015981098));
100*uniform(015986783));
100*uniform(015984565));
output;
end;
proc optmodel;
set rows init {1..6};
set cols init {1..3};
num X{rows,cols} ;
read data have into rows=
var XpX{c1 in cols,c2 in cols} init sum{r in 1..6} X[r,c1]*X[r,c2];
You are correct that PROC OPTMODEL does not support such matrix syntax. In particular, there is no INV() function in PROC OPTMODEL, and matrix products are expressed using sums of products, with explicit indices, as you have indicated. There are currently no plans to support IML-like syntax, but thank you for your suggestion.
Rob Pratt
Now that PROC OPTMODEL is officially FCMP-enabled in SAS/OR 13.1, you can access the matrix functions and subroutines that are supplied in PROC FCMP. See Base SAS(R) 9.4 Procedures Guide, Second Edition for a complete list. For example:
proc fcmp outlib=work.myfuncs.test;
function mydet(x[*,*]);
call det(x, result);
return (result);
endsub;
subroutine mytranspose(x[*,*],y[*,*]);
outargs y;
call transpose(x,y);
endsub;
subroutine myinv(x[*,*],y[*,*]);
outargs y;
call inv(x,y);
endsub;
subroutine mymult(x[*,*],y[*,*],z[*,*]);
outargs z;
call mult(x,y,z);
endsub;
quit;
options cmplib = work.myfuncs;
proc optmodel;
/* matrix declaration */
num mat1 {1..3,1..3} = [0.3, -0.78, -0.82, 0.54, 1.74, 1.2, -1.3, 0.25, 1.49];
print mat1;
/* determinant */
print (mydet(mat1));
/* matrix transpose */
num trans {1..3,1..3};
call mytranspose(mat1, trans);
print trans;
/* matrix inversion */
num inv {1..3,1..3};
call myinv(mat1, inv);
print inv;
/* matrix multiplication */
num mat1_dot_inv {1..3,1..3};
call mymult(mat1, inv, mat1_dot_inv);
print mat1_dot_inv;
quit;
/* maximize determinant */
proc optmodel;
num n = 5;
var x {1..n, 1..n} >= -1 <= 1;
max z = mydet(x);
solve with NLP / ms;
print x;
quit;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.