<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Solve non-linear equation system in SAS Procedures</title>
    <link>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/544044#M74213</link>
    <description>I've tried solving this using PROC MODEL. But I can't figure it out.&lt;BR /&gt;&lt;BR /&gt;Any pointers?</description>
    <pubDate>Mon, 18 Mar 2019 17:11:09 GMT</pubDate>
    <dc:creator>invalid</dc:creator>
    <dc:date>2019-03-18T17:11:09Z</dc:date>
    <item>
      <title>Solve non-linear equation system</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/542776#M74186</link>
      <description>&lt;P&gt;Hi!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a data set with a column&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;f&lt;/STRONG&gt;&lt;/EM&gt; with many rows&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I want to find a value&amp;nbsp;&lt;EM&gt;b&amp;nbsp;&lt;/EM&gt;so that when taking sum over all &lt;EM&gt;i&amp;nbsp;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;c1 = SUM_i(MAX(b*f_i,c2))&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;c1 and c2 are constants.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;CODE class=" language-sas"&gt;Here is example data (in reality I have much more than 100 rows)&lt;/CODE&gt;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let c1 = 40000;
%let c2 = 100;

data mydata;
call streaminit(123);       /* set random number seed */
do i = 1 to 100;
   f=rand("Lognormal");
   output;
end;
run;&lt;/CODE&gt;&lt;CODE class=" language-sas"&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;By exporting &lt;EM&gt;mydata&lt;/EM&gt; to excel and using goal seek i've found that b=245 solves my example (see attachment).&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;But I cant figure out how to find b using SAS. I think it should be doable using proc model?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I think i am on version 9.4&lt;/P&gt;</description>
      <pubDate>Wed, 13 Mar 2019 13:23:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/542776#M74186</guid>
      <dc:creator>invalid</dc:creator>
      <dc:date>2019-03-13T13:23:27Z</dc:date>
    </item>
    <item>
      <title>Re: Solve non-linear equation system</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/542904#M74189</link>
      <description>&lt;P&gt;You want to find the root (zero) of the equation&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;F(b) = SUM_i(MAX(b*f_i,c2)) - c1&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;If you have SAS/IML, I recommend &lt;A href="A%20simple way to find the root of a function of one variable" target="_self"&gt;using the FROOT function to find the root.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc iml;
use mydata;  read all var "f";  close;

/* find the zero of this function */
start Func(b) global(f);
   v = (b#f &amp;lt;&amp;gt; &amp;amp;c2);  /* v[i] = max(b*f[i], &amp;amp;c2) */
   return &amp;amp;c1 - sum(v);
finish;

b = froot("Func", {0 1000});  
print b;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Region Capture.png" style="width: 76px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/28161iD4672B0876B893CC/image-size/small?v=v2&amp;amp;px=200" role="button" title="Region Capture.png" alt="Region Capture.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you&amp;nbsp;don't have SAS/IML,&amp;nbsp;there are other ways to solve for the root of a nonlinear equation. Which of the following do you have licensed?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SAS/ETS (PROC MODEL)&lt;/P&gt;
&lt;P&gt;SAS/OR (PROC OPTMODEL)&lt;/P&gt;
&lt;P&gt;SAS/STAT (PROC NLIN)&lt;/P&gt;</description>
      <pubDate>Mon, 25 Mar 2019 00:13:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/542904#M74189</guid>
      <dc:creator>Rick_SAS</dc:creator>
      <dc:date>2019-03-25T00:13:27Z</dc:date>
    </item>
    <item>
      <title>Re: Solve non-linear equation system</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/543059#M74193</link>
      <description>&lt;P&gt;I have&amp;nbsp;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;SPAN&gt;SAS/ETS (PROC MODEL)&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;SAS/STAT (PROC NLIN)&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;SPAN&gt;The other two I don't have.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 14 Mar 2019 09:23:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/543059#M74193</guid>
      <dc:creator>invalid</dc:creator>
      <dc:date>2019-03-14T09:23:04Z</dc:date>
    </item>
    <item>
      <title>Re: Solve non-linear equation system</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/544044#M74213</link>
      <description>I've tried solving this using PROC MODEL. But I can't figure it out.&lt;BR /&gt;&lt;BR /&gt;Any pointers?</description>
      <pubDate>Mon, 18 Mar 2019 17:11:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/544044#M74213</guid>
      <dc:creator>invalid</dc:creator>
      <dc:date>2019-03-18T17:11:09Z</dc:date>
    </item>
    <item>
      <title>Re: Solve non-linear equation system</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/545623#M74318</link>
      <description>&lt;P&gt;Hello&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/177512"&gt;@invalid&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Sorry for the late reply. I don't have a SAS/ETS license, so can't help you with PROC MODEL. But your problem can be solved with Base SAS alone, at least if c2&amp;gt;=0. Here is how:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want(keep=b);
if &amp;amp;c2&amp;lt;0 then do;
  put "WAR" "NING: This algorithm doesn't handle the case c2&amp;lt;0!";
  stop;
end;
else if &amp;amp;c1&amp;lt;n*&amp;amp;c2 then do;
  put 'No solution exists because c1 &amp;lt; n*c2.';
  stop;
end;
if _n_=1 then do;
  if 0 then set mydata nobs=n;
  dcl hash h(dataset: 'mydata(keep=f)', multidata: 'y', ordered: 'y');
  h.definekey('f');
  h.definedone();
  dcl hiter hi('h');
  hi.first();
  minf=f;
  hi.last();
  maxf=f;
  rc=hi.next();
end;
if &amp;amp;c1=n*&amp;amp;c2 then do;
  if minf then lb=&amp;amp;c2/minf;
  if maxf then ub=&amp;amp;c2/maxf;
  if .z&amp;lt;maxf&amp;lt;0 | .z&amp;lt;minf&amp;lt;0=maxf then do;
    b=lb; output;
    put 'All b &amp;gt;= ' lb :best16. '(and only these) are solutions.';
  end;
  else if maxf=0 then do; /* In this case all f_i=0. */
    b=0; output;
    put 'All real numbers b are solutions.';
  end;
  else if maxf&amp;gt;0 then do;
    if minf&amp;gt;=0 then do;
      b=ub; output;
      put 'All b &amp;lt;= ' ub :best16. '(and only these) are solutions.';
    end;
    else if &amp;amp;c2&amp;gt;0 then do;
      b=lb; output; b=ub; output;
      put 'All b in the interval [' lb :best16. +(-1) ', ' ub :best16. +(-1) '] (and only these) are solutions.';
    end;
    else do; /* i.e. minf&amp;lt;&amp;amp;c2=0 */
      b=0; output;
      put 'b=0 is the only solution.';
    end;
  end;
end;
/* Main case: &amp;amp;c1&amp;gt;n*&amp;amp;c2 */
else if minf=maxf=0 then put 'No solution exists because c1 &amp;gt; n*c2 &amp;gt;= 0, but all f_i are zero.';
else do;
  if .z&amp;lt;minf&amp;lt;0&amp;lt;maxf then put 'There are exactly two solutions:';
  else put 'There is only one solution:';
  if .z&amp;lt;minf&amp;lt;0 then do;
    /* Determine a solution b&amp;lt;0 */
    hi.first();
    s=f;
    do m=1 to n;
      b=(&amp;amp;c1-(n-m)*&amp;amp;c2)/s;
      if hi.next()=0 &amp;amp; b*f&amp;gt;&amp;amp;c2 then s+f;
      else leave;
    end;
    put +3 b= best16.;
    output;
  end;
  if maxf&amp;gt;0 then do;
    /* Determine a solution b&amp;gt;0 */
    hi.last();
    s=f;
    do m=n to 1 by -1;
      b=(&amp;amp;c1-(m-1)*&amp;amp;c2)/s;
      if hi.prev()=0 &amp;amp; b*f&amp;gt;&amp;amp;c2 then s+f;
      else leave;
    end;
    put +3 b= best16.;
    output;
  end;
end;
stop;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Again, the above solution requires &lt;STRONG&gt;c2&amp;gt;=0&lt;/STRONG&gt;&amp;nbsp;-- I hope that this is consistent with your real c2 values -- and assumes that all f_i, i.e. the values of F in dataset MYDATA, are non-missing. (I haven't spent much time on the case c2&amp;lt;0, but I know that it is substantially different.) Run times were less than 3 seconds for n=10,000,000 observations on my machine.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The algorithm is based on a sorted sequence of the F values (sorted ascending or descending). To avoid a PROC SORT step I use a sorted hash table and a hash iterator, which is also convenient because the latter can traverse the table in both directions. But the algorithm could also be implemented without a hash object, especially if MYDATA was already sorted by F.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I've tested the program with &lt;EM&gt;integer&lt;/EM&gt; values of c1 and c2. Please note that in case of non-integer values the tests of &lt;FONT face="courier new,courier"&gt;&amp;amp;c1&amp;lt;n*&amp;amp;c2&lt;/FONT&gt; etc. could be affected by numerical accuracy issues. In this case appropriate rounding should be applied.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In some situations there are infinitely many solutions, e.g. an entire interval (which is then indicated in the log). In this case the output dataset WANT contains only the finite interval boundaries (or 0 if all real numbers are solutions).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Of course, it's easy to verify solutions in a simple data step and I would recommend doing so. (Note, for example, the potential risk of numerical accuracy issues in the tests of&amp;nbsp;&lt;FONT face="courier new,courier"&gt;b*f&amp;gt;&amp;amp;c2&lt;/FONT&gt;.)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Feel free to ask if you have questions about the program.&lt;/P&gt;</description>
      <pubDate>Sun, 24 Mar 2019 19:56:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/Solve-non-linear-equation-system/m-p/545623#M74318</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2019-03-24T19:56:56Z</dc:date>
    </item>
  </channel>
</rss>

