1

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;
Joe
  • 62,789
  • 6
  • 49
  • 67
Mizzle
  • 747
  • 4
  • 14

1 Answers1

2

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.

Joe
  • 62,789
  • 6
  • 49
  • 67
  • This is definitely not an "ideal IML" solution - just one that should work, at least. Hopefully Rick will see this and post the correct way to do it. I wouldn't recommend accepting the answer for a few days to give him time to see the question. – Joe Jul 20 '22 at 18:19
  • This is a perfectly acceptable solution. Since each problem is independent, you have to solve 10 problems. I'd use ncol(x0) in the DO loop, but otherwise this is how I would solve it. Be aware that the function is very flat, so some guesses might not converge if they are far from the minimum at x=0.73. – Rick Jul 21 '22 at 10:59