Set initial values for solving nonlinear equation by SAS proc IML

102 views Asked by At

I am using SAS proc IML to solve the nonlinear equation (x-0.11)(x-0.32)(x-0.98) = 0. I have to provide initial values for the proc IML. I would like to use 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 as initial values. The SAS program for initial value 0.1 is below. Now I have to repeat the SAS program below for each of the initial values. I am wondering if there is an elegant way to do it.

proc iml;
start Fun(var);
   x = var[1];
   f = j(1, 1, .);         /* return a ROW VECTOR */
   f[1] = (x-0.11)*(x-0.32)*(x-0.98);
return (f);
finish;
 
/*     x constraints. Lower bounds in 1st row; upper bounds in 2nd row */
con = {1e-6,   /* x > 0*/
         . };
x0 = {0.1};           /* initial guess */
optn = {1               /* solve least square problem that has 1 components */
        1};             /* amount of printing */
call nlphqn(rc, Soln, "Fun", x0, optn) blc=con;  /* or use NLPLM */
print Soln;
create root var {Soln}; /** create data set **/
append;       /** write data in vectors **/
close root; /** close the data set **/
quit;
1

There are 1 answers

2
Joe On BEST ANSWER

I don't know anything about the kind of nonlinear solving you're doing, but at minimum you can loop it:

proc iml;
start Fun(var);
   x = var[1];
   f = j(1, 1, .);         /* return a ROW VECTOR */
   f[1] = (x-0.11)*(x-0.32)*(x-0.98);
return (f);
finish;
 
/*     x constraints. Lower bounds in 1st row; upper bounds in 2nd row */
con = {1e-6,   /* x > 0*/
         . };
x0 = {0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0};           /* initial guesses */
optn = {1               /* solve least square problem that has 1 components */
        1};             /* amount of printing */
create root var {Soln}; /** create data set **/
       do i = 1 to 10;
            call nlphqn(rc, Soln, "Fun", x0[i], optn) blc=con;  /* or use NLPLM */
            print Soln;

            append;       /** write data in vectors **/
            
        end;
close root; /** close the data set **/

quit;

You might be able to pass the whole vector and do it more optimally that way, but not to the call nlphqn as you have it at least. You'd probably have to rewrite the function at least to accept the vector, and I'm not sure what that would do at that point - it may or may not work with nlphqn, I'm not sure.