BookmarkSubscribeRSS Feed
aya123
Calcite | Level 5
How can I inform SAS that my decision variable is K inside the following nonlinear programming model ? what is missing in this code in order to give me optimal value of K? where lambda, g, estvar, col11,col2,col3 are stored vectors

Proc iml;
start fun(K);
sumf=0;
do i = 1 to 3;
sumf = sumf + (estvar*lambda)+ (g* k)**2 /(lambda+ k)**2;
end;
return (sumf);
finish fun;
start con(k);
c=j(4,1,0);
sumc1=0;
do i = 1 to 3;
sumc1 = sumc1 + (col1**2 *lambda/(lambda+k)**2);
end;
c[1]= 10-sumc1;
sumc2=0;
do i= 1 to 3;
sumc2 = sumc2 + (col2**2 *lambda/(lambda+k)**2);
end;
c[2]= 10-sumc2;
sumc3=0;
do i= 1 to 3;
sumc3 = sumc3 + (col3**2 *lambda/(lambda+k)**2);
end;
c[3]= 10-sumc3;
c[4]=(max(lambda)/min(lambda))-(max(lambda)+k)/(min(lambda)+k);
return (c);
finish con;
optn=j(1,11,.); optn[4]=1; optn[6]=2; optn[11]=0; optn[10]=4;
call nlpqn (rc, kres, "fun", k, optn) nlc="con";
11 REPLIES 11
Hutch_sas
SAS Employee
IML knows that k is the decision variable, from your specification of the objective function module fun(K). However, in the nlpqr call you need to give it an initial starting point for the optimization, in the 4th parameter, i.e.:

k0 = 1;
call nlpqn (rc, kres, "fun", k0, optn) nlc="con";

If your initial point is infeasible, IML will find one for you. Also, you need to pass in the values of your global parameters to your objective and constraint modules, via a global() clause in the START statement, i. e. :

start fun(K)global(lambda, estvar, g);

start con(k)global(lambda, col1, col2, col3);

Of course you will also need statements to set the values of lambda, estvar, g, col1, col2, and col3 before you call nlpqn.
aya123
Calcite | Level 5
what is the optimal k value? is it kres in my code?
Hutch_sas
SAS Employee
Yes. Also, if you set the print option to 2 (optn[2] = 2) you will get an informative printout of the iteration history and constraint satisfaction.
aya123
Calcite | Level 5
Is there any option to increase the decimal places of k optimal inside call statement?
aya123
Calcite | Level 5
Another question, I want c[1], c[2], c[3], and c[4] which are my 4 constraints to be greater than or equal zero, is this correct in my code?
Hutch_sas
SAS Employee
to : "Another question, I want c[1], c[2], c[3], and c[4] which are my 4 constraints to be greater than or equal zero, is this correct in my code?"

Your code appears to be correct.
aya123
Calcite | Level 5
I want my code using proc iml (code1) to be the same as the one using proc optmodel (code2), Is they are the same ? as they give me different results for K. If they are not the same, What is missing in code 1 to be the same as code 2? moreover, in code 2 we can tell SAS that K is positive (var k >=0;) so, I want to put K as positive variable in code 1 as well, How can I do so?



code1:

Proc iml;
start fun(K);
sumf=0;
do i = 1 to 3;
sumf = sumf + (estvar*lambda)+ (g* k)**2 /(lambda+ k)**2;
end;
return (sumf);
finish fun;
start con(k);
c=j(4,1,0);
sumc1=0;
do i = 1 to 3;
sumc1 = sumc1 + (col1**2 *lambda/(lambda+k)**2);
end;
c[1]= 10-sumc1;
sumc2=0;
do i= 1 to 3;
sumc2 = sumc2 + (col2**2 *lambda/(lambda+k)**2);
end;
c[2]= 10-sumc2;
sumc3=0;
do i= 1 to 3;
sumc3 = sumc3 + (col3**2 *lambda/(lambda+k)**2);
end;
c[3]= 10-sumc3;
c[4]=(max(lambda)/min(lambda))-(max(lambda)+k)/(min(lambda)+k);
return (c);
finish con;
optn=j(1,11,.); optn[4]=1; optn[6]=2; optn[11]=0; optn[10]=4;
call nlpqn (rc, kres, "fun", k, optn) nlc="con";



code2:

proc optmodel;
var k >=0;
set ISET;
num lambda {ISET};
num g {ISET};
num col1 {ISET};
num col2 {ISET};
num col3 {ISET};
num min_lamb = min {i in ISET} lambda;
num max_lamb = max {i in ISET} lambda;
read data sasdata.sxlamb2 into ISET = [_n_] lambda g;
read data work.datavif into ISET = [_n_] col1 col2 col3;
num estvar ;
read data sasdata.m3data into estvar;
min f = sum {i in ISET}((estvar*lambda)+(k**2 *g **2)/(lambda+k)**2);
con co1: sum {i in ISET}(col1**2 *lambda/(lambda+k)**2)<=10;
con co2: sum {i in ISET}(col2**2 *lambda/(lambda+k)**2)<=10;
con co3: sum {i in ISET}(col3**2 *lambda/(lambda+k)**2)<=10;
con co4: (max_lamb+k)/(min_lamb+k)<= max_lamb/min_lamb;
solve with nlpc / tech =qne;
print k ;
aya123
Calcite | Level 5
I want my code using proc iml (code1) to be the same as the one using proc optmodel (code2), Is they are the same ? as they give me different results for K. If they are not the same, What is missing in code 1 to be the same as code 2? moreover, in code 2 we can tell SAS that K is positive (var k >=0;) so, I want to put K as positive variable in code 1 as well, How can I do so?

code1:

Proc iml;
start fun(K);
sumf=0;
do i = 1 to 3;
sumf = sumf + (estvar*lambda)+ (g* k)**2 /(lambda+ k)**2;
end;
return (sumf);
finish fun;
start con(k);
c=j(4,1,0);
sumc1=0;
do i = 1 to 3;
sumc1 = sumc1 + (col1**2 *lambda/(lambda+k)**2);
end;
c[1]= 10-sumc1;
sumc2=0;
do i= 1 to 3;
sumc2 = sumc2 + (col2**2 *lambda/(lambda+k)**2);
end;
c[2]= 10-sumc2;
sumc3=0;
do i= 1 to 3;
sumc3 = sumc3 + (col3**2 *lambda/(lambda+k)**2);
end;
c[3]= 10-sumc3;
c[4]=(max(lambda)/min(lambda))-(max(lambda)+k)/(min(lambda)+k);
return (c);
finish con;
optn=j(1,11,.); optn[4]=1; optn[6]=2; optn[11]=0; optn[10]=4;
call nlpqn (rc, kres, "fun", k, optn) nlc="con";

code2:

proc optmodel;
var k >=0;
set ISET;
num lambda {ISET};
num g {ISET};
num col1 {ISET};
num col2 {ISET};
num col3 {ISET};
num min_lamb = min {i in ISET} lambda;
num max_lamb = max {i in ISET} lambda;
read data sasdata.sxlamb2 into ISET = [_n_] lambda g;
read data work.datavif into ISET = [_n_] col1 col2 col3;
num estvar ;
read data sasdata.m3data into estvar;
min f = sum {i in ISET}((estvar*lambda)+(k**2 *g **2)/(lambda+k)**2);
con co1: sum {i in ISET}(col1**2 *lambda/(lambda+k)**2)<=10;
con co2: sum {i in ISET}(col2**2 *lambda/(lambda+k)**2)<=10;
con co3: sum {i in ISET}(col3**2 *lambda/(lambda+k)**2)<=10;
con co4: (max_lamb+k)/(min_lamb+k)<= max_lamb/min_lamb;
solve with nlpc / tech =qne;
print k ;
aya123
Calcite | Level 5
the rest of code 2:

con co1: sum {i in ISET}(col1**2 *lambda/(lambda+k)**2)<=10;
con co2: sum {i in ISET}(col2**2 *lambda/(lambda+k)**2)<=10;
con co3: sum {i in ISET}(col3**2 *lambda/(lambda+k)**2)<=10;
con co4: (max_lamb+k)/(min_lamb+k)<= max_lamb/min_lamb;
solve with nlpc / tech =qne;
print k ;
aya123
Calcite | Level 5
the rest of code2:

con c1: sum {i in ISET}(col1**2 *lambda/(lambda+k)**2)<=10;
con c2: sum {i in ISET}(col2**2 *lambda/(lambda+k)**2)<=10; con c3: sum {i in ISET}(col3**2 *lambda/(lambda+k)**2)<=10; con c4: (max_lamb+k)/(min_lamb+k)<= max_lamb/min_lamb;
solve with nlpc / tech =qne;
print k ;
Hutch_sas
SAS Employee
The algorithm used by NLPQN does not by design generate a sequence of closer and closer approximations to the x value, and therefore you can't use the difference in x between iterations as a convergence criteria. However, if you use NLPNMS (Nelder-Meade-Simplex), you can specify a value for for termination criteria tc[9] (ABSXCONV) that will terminate the optimization when x is changes by less than that amount, i.e.:

t = j(10,1,.);
t[9] = 1e-9;
call nlpnms (rc, kres, "fun", k0, optn) nlc="con" tc = t;

If you change your optn[2] value to 3, you will get a detailed printout of the x and objective value at each iteration of the optimization process. Look at the IML doc under "Nonlinear Optimization Examples"-> "Details"->"Termination Criteria" for a full explanation of the termination criteria available with NLPNMS

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 11 replies
  • 2582 views
  • 0 likes
  • 2 in conversation