BookmarkSubscribeRSS Feed
acsb
Calcite | Level 5

Hi - I am a very new IML user and I'd appreciate any help.  I'm trying to optimize a system of pricing equations subject to a set of nonlinear constraints.  Setting this up, I wrote a module to calculate the total profit, which will be my objective function.  That code (below) when called with my initial values for the objective function returns the value I expect.  However, when I try to call NLPQN, I get an error (below) directing me to the calculation of A, the average prices.  It reports that I'm trying to multiply a 186 x 558 matrix by a 1 x 558 vector, which obviously won't work.  However, the vector X should be 558 x 1.  Can anybody shed any light on this for me?  I've tried transposing the vector, but I get the same error.

proc iml;

**INITIAL VALUES FOR PRICES;

  use &OPT_DATA.;

  read all var{PRICE1,PRICE2,PRICE3} into prices;

  X0 = prices[,1]//prices[,2]//prices[,3];

start PROFIT(X);

**READING IN THE RAW DATA;

  use &OPT_INTCRS.(keep=EFF:);

  read all var _ALL_ into CI;

  use &OPT_EXTCRS.(keep=EXT_COEF EXT_FIXED);

  read all var _ALL_ into CX;

  use &OPT_DATA.;

  read all var{A1,A2,A3,A4} into param;

**CREATING PARAMETERS USED IN OBJECTIVE FUNCTION;

  S = (j(&N.,2*&N.,0)||I(&N.)); *Selection Matrix;

  A = S*X; *Average Prices;

  M = A - param[,4]; *Margin;

  C = param[,1]#I(&N.)||param[,2]#I(&N.)||(T(CI) + (CX[,1]#I(&N.))); *Coefficients on Prices;

  F = CX[,2] + param[,3]; *Fixed Effect;

  Q = exp(C*log(X) + F); *Total Quantity;

**OBJECTIVE FUNCTION;

  P = T(M)*Q; *Profit;

  return(P);

finish PROFIT;

**When I run this bit of code it reports the expected value;

z = PROFIT(X0);

print z;

**However, when I try to optimize (even without the constraints), I get the following error;

call NLPQN(rc,xres,"PROFIT",X0,optn) nlc="CONSTRAINTS";

ERROR: (execution) Matrices do not conform to the operation.

operation : * at line 33514 column 12

operands  : S, X

S    186 rows    558 cols    (numeric)

X      1 row     558 cols    (numeric)

2 REPLIES 2
Rick_SAS
SAS Super FREQ

The documentation for the NLP functions states that "the argument x0 specifies a row vector," so your objective function should expect a row vector. The easiest way to do that without rewriting the code is to define the function as

start PROFIT(TX); /* argument is row vector */

X = T(TX); /* transpose to column vector */

...

finish;

Here's an unsolicited tip for efficiency. Currently you are reading three data sets for each call to the objective function. This will be GLACIALLY slow!  Instead, read the data sets OUTSIDE the objective function and use a GLOBAL statement to pass in those parameters:

start PROFIT(TX) global(CI, CX, param);

Another tip: The matrix multiplication S*X is merely extracting the bottom 62 (=&N.) elements of the X vector.

A more efficient way to get that data is to extract it with subscripts:

A = X[(2*&N.+1):(3*&N.)];

If you want to look at an online examples of optimization, see  Maximum likelihood estimation in SAS/IML - The DO Loop

acsb
Calcite | Level 5

Thanks so much - all your suggestions are very helpful!

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

Multiple Linear Regression in SAS

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.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 2 replies
  • 916 views
  • 3 likes
  • 2 in conversation