<?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: Numeric precision and discontinuity in Mathematical Optimization, Discrete-Event Simulation, and OR</title>
    <link>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51508#M379</link>
    <description>Hi:&lt;BR /&gt;
  Perhaps these will shed some light on how operating systems can have different precision issues:&lt;BR /&gt;
&lt;A href="http://support.sas.com/documentation/cdl/en/lrcon/59522/HTML/default/a000695157.htm" target="_blank"&gt;http://support.sas.com/documentation/cdl/en/lrcon/59522/HTML/default/a000695157.htm&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/kb/31/560.html" target="_blank"&gt;http://support.sas.com/kb/31/560.html&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/techsup/technote/ts654.pdf" target="_blank"&gt;http://support.sas.com/techsup/technote/ts654.pdf&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/documentation/cdl/en/connref/59593/HTML/default/implications.htm" target="_blank"&gt;http://support.sas.com/documentation/cdl/en/connref/59593/HTML/default/implications.htm&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/kb/20/587.html" target="_blank"&gt;http://support.sas.com/kb/20/587.html&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/kb/30/534.html" target="_blank"&gt;http://support.sas.com/kb/30/534.html&lt;/A&gt;&lt;BR /&gt;
 &lt;BR /&gt;
cynthia</description>
    <pubDate>Fri, 03 Oct 2008 14:04:36 GMT</pubDate>
    <dc:creator>Cynthia_sas</dc:creator>
    <dc:date>2008-10-03T14:04:36Z</dc:date>
    <item>
      <title>Numeric precision and discontinuity</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51507#M378</link>
      <description>Hi.&lt;BR /&gt;
&lt;BR /&gt;
This isn't specifically on O.R. question, but it has to do with a kind of numerical computing that perhaps you'll have some expertise with.&lt;BR /&gt;
&lt;BR /&gt;
I'm looking for advice / feedback / abuse concerning a numerical computation issue.  Briefly, I'm trying to solve the equation y=f(x) for the value of x, given the function f() and the value y.&lt;BR /&gt;
&lt;BR /&gt;
I have provided some code below for a function that depends on three parameters, N, M, and r, with a target value of G.  I have fixed N = 730 and M = 1, and want to find the value of r that gives G = 730.  (The code is designed to look at a range of values of N, with G changing proportionally, but in this example I didn't vary N.)  The function has monotonicity properties that guarantee the value of r will fall between 0 and 1; when r = 0, G = 0, and G increases as r increases until G ~ 2**N when r = 1.  The solution method is a simple bisection that moves r down if G is above the target, and moves r up if G is below the target, until either the difference between the computed G and the target is within a certain tolerance level, or an upper limit of iterations is reached.&lt;BR /&gt;
&lt;BR /&gt;
I have run the code below in SAS 9.1.3 on both Windows XP and HP-UX.  I get slightly different results on the two systems, but in both cases there is a discontinuity near the solution; as the value of r converges to 0.00929, the value of G flip-flops between 753 and 540, but never seems to get any closer to the target value of 730.&lt;BR /&gt;
&lt;BR /&gt;
This is a tricky function.  It is a sum of about N terms (recall N = 730), and each term involves the product of a very large number (comb(N,k)) with a very small number.&lt;BR /&gt;
&lt;BR /&gt;
Is there a better way to do this computation to converge on the target value, or is this just too much to ask of SAS?&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
************************************************************************&lt;BR /&gt;
&lt;BR /&gt;
%let	Nlo	=	730	;&lt;BR /&gt;
%let	Nhi	=	730	;&lt;BR /&gt;
%let	Ninc	=	10	;&lt;BR /&gt;
%let	N0	=	1000	;&lt;BR /&gt;
%let	G0	=	1000	;&lt;BR /&gt;
%let	M0	=	1	;&lt;BR /&gt;
%let	rstart	=	0.5	;&lt;BR /&gt;
%let	gtol	=	0.0001	;&lt;BR /&gt;
%let	ntries	=	100	;&lt;BR /&gt;
%let	bouncelim	=	4	;&lt;BR /&gt;
%let	vnum	=	01	;&lt;BR /&gt;
%*let	vnum	=	%sysfunc(putn(%sysevalf(&amp;amp;vnum.	+	1),z2.))	;&lt;BR /&gt;
%put	vnum	=	&amp;amp;vnum.	;&lt;BR /&gt;
%let	dnum	=	01	;&lt;BR /&gt;
%*let	dnum	=	%sysfunc(putn(%sysevalf(&amp;amp;dnum.	+	1),z2.))	;&lt;BR /&gt;
%put	dnum	=	&amp;amp;dnum.	;&lt;BR /&gt;
&lt;BR /&gt;
*	trial and error to find r that fits N, M, G for several scaled N, G, with debug info	;&lt;BR /&gt;
data	rbyn_&amp;amp;vnum._d&amp;amp;dnum.	;&lt;BR /&gt;
	keep	N	M	G	r	rfound	i	rhi	rlo	groups	gdif	rdif	mingdif	rmingdif	gmingdif	GBOUNCE	;&lt;BR /&gt;
	array	combnk{2:&amp;amp;N0.}	;&lt;BR /&gt;
	M	=	&amp;amp;M0.	;&lt;BR /&gt;
	do	N	=	&amp;amp;Nlo.	to	&amp;amp;Nhi.	by	&amp;amp;Ninc.	;&lt;BR /&gt;
		G	=	N	*	%sysevalf(&amp;amp;G0.	/	&amp;amp;N0.)	;&lt;BR /&gt;
		do	k	=	2	to	N	;&lt;BR /&gt;
			combnk{k}	=	comb(N,k)	;&lt;BR /&gt;
		end	;	*	k	;&lt;BR /&gt;
		rfound	=	0	;&lt;BR /&gt;
		r		=	&amp;amp;rstart.	;&lt;BR /&gt;
		rhi		=	1	;&lt;BR /&gt;
		rlo		=	0	;&lt;BR /&gt;
		pgdif	=	.	;&lt;BR /&gt;
		mingdif	=	.	;&lt;BR /&gt;
		rmingdif	=	.	;&lt;BR /&gt;
		gmingdif	=	.	;&lt;BR /&gt;
		gbounce	=	0	;&lt;BR /&gt;
		do	i	=	1	to	&amp;amp;ntries.	while	(rfound	=	0)	;&lt;BR /&gt;
			groups	=	0	;&lt;BR /&gt;
			do	k	=	2	to	N	;&lt;BR /&gt;
				qk			=	(1	-	r**k)**M	;&lt;BR /&gt;
				pk			=	1	-	qk	;&lt;BR /&gt;
				groups_k	=	combnk{k}	*	pk	;&lt;BR /&gt;
				groups		+	groups_k	;&lt;BR /&gt;
			end	;	*	k	;&lt;BR /&gt;
			gdif	=	(groups	-	G)	;&lt;BR /&gt;
			absgdif	=	abs(gdif)	;&lt;BR /&gt;
			rdif	=	(rhi	-	rlo)	;&lt;BR /&gt;
			output	;&lt;BR /&gt;
			if			(absgdif	&amp;lt;	abs(mingdif))	or	missing(mingdif)	then	do	;&lt;BR /&gt;
				if	abs(sum(gdif,-mingdif))	&amp;lt;	%sysevalf(0.5	*	&amp;amp;gtol.)	then	do	;&lt;BR /&gt;
					gbounce	+	1	;&lt;BR /&gt;
				end	;&lt;BR /&gt;
				else	do	;&lt;BR /&gt;
					gbounce	=	0	;&lt;BR /&gt;
				end	;&lt;BR /&gt;
				mingdif		=	gdif	;&lt;BR /&gt;
				rmingdif	=	r	;&lt;BR /&gt;
				gmingdif	=	groups	;&lt;BR /&gt;
			end	;&lt;BR /&gt;
			else	if	((absgdif	&amp;gt;	abs(mingdif))	and	(gdif	*	mingdif	&amp;gt;	0))	or	(gbounce	ge	&amp;amp;bouncelim.)	then	do	;	*	should be impossible	;&lt;BR /&gt;
				rfound	=	-1	;&lt;BR /&gt;
				r		=	rmingdif	;&lt;BR /&gt;
				groups	=	gmingdif	;&lt;BR /&gt;
			end	;&lt;BR /&gt;
			if	absgdif	&amp;lt;	&amp;amp;gtol.	then	do	;&lt;BR /&gt;
				rfound	=	1	;&lt;BR /&gt;
			end	;&lt;BR /&gt;
			else	if	groups	&amp;gt;	G	then	do	;&lt;BR /&gt;
				rhi	=	r	;&lt;BR /&gt;
				if	.	&amp;lt;	pgdif	&amp;lt;	0	then	do	;&lt;BR /&gt;
					sumdiff	=	(gdif	-	pgdif)	;&lt;BR /&gt;
					r	=	((gdif	*	rlo)	-	(pgdif	*	rhi))	/	sumdiff	;&lt;BR /&gt;
				end	;&lt;BR /&gt;
				else	do	;&lt;BR /&gt;
					r	=	0.5	*	(rhi	+	rlo)	;&lt;BR /&gt;
				end	;&lt;BR /&gt;
			end	;&lt;BR /&gt;
			else	if	groups	&amp;lt;	G	then	do	;&lt;BR /&gt;
				rlo	=	r	;&lt;BR /&gt;
				if	pgdif	&amp;gt;	0	then	do	;&lt;BR /&gt;
					sumdiff	=	(pgdif	-	gdif)	;&lt;BR /&gt;
					r	=	((pgdif	*	rlo)	-	(gdif	*	rhi))	/	sumdiff	;&lt;BR /&gt;
				end	;&lt;BR /&gt;
				else	do	;&lt;BR /&gt;
					r	=	0.5	*	(rlo	+	rhi)	;&lt;BR /&gt;
				end	;&lt;BR /&gt;
			end	;&lt;BR /&gt;
			pgdif	=	gdif	;&lt;BR /&gt;
*			output	;&lt;BR /&gt;
		end	;	*	i	;&lt;BR /&gt;
		output	;&lt;BR /&gt;
	end	;	*	N	;&lt;BR /&gt;
run	;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
************************************************************************&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
Thanks!&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
--  TMK  --&lt;BR /&gt;
"The Macro Klutz"</description>
      <pubDate>Fri, 03 Oct 2008 04:09:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51507#M378</guid>
      <dc:creator>topkatz</dc:creator>
      <dc:date>2008-10-03T04:09:09Z</dc:date>
    </item>
    <item>
      <title>Re: Numeric precision and discontinuity</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51508#M379</link>
      <description>Hi:&lt;BR /&gt;
  Perhaps these will shed some light on how operating systems can have different precision issues:&lt;BR /&gt;
&lt;A href="http://support.sas.com/documentation/cdl/en/lrcon/59522/HTML/default/a000695157.htm" target="_blank"&gt;http://support.sas.com/documentation/cdl/en/lrcon/59522/HTML/default/a000695157.htm&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/kb/31/560.html" target="_blank"&gt;http://support.sas.com/kb/31/560.html&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/techsup/technote/ts654.pdf" target="_blank"&gt;http://support.sas.com/techsup/technote/ts654.pdf&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/documentation/cdl/en/connref/59593/HTML/default/implications.htm" target="_blank"&gt;http://support.sas.com/documentation/cdl/en/connref/59593/HTML/default/implications.htm&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/kb/20/587.html" target="_blank"&gt;http://support.sas.com/kb/20/587.html&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://support.sas.com/kb/30/534.html" target="_blank"&gt;http://support.sas.com/kb/30/534.html&lt;/A&gt;&lt;BR /&gt;
 &lt;BR /&gt;
cynthia</description>
      <pubDate>Fri, 03 Oct 2008 14:04:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51508#M379</guid>
      <dc:creator>Cynthia_sas</dc:creator>
      <dc:date>2008-10-03T14:04:36Z</dc:date>
    </item>
    <item>
      <title>Re: Numeric precision and discontinuity</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51509#M380</link>
      <description>Thank you, Cynthia@sas.  I also posted this question on SAS-L and got a couple of interesting responses there (); one of them cited one document that's the same as the first one on your list, and cited another one that's referred to in ts654.&lt;BR /&gt;
&lt;BR /&gt;
By the way, in related investigations, I've found that the ** exponentiation operator sacrifices some accuracy; even x**1 is not quite the same as x, so if you have x**n and n is an integer, you'll be slower but more accurate if you do x*x*...*x.&lt;BR /&gt;
&lt;BR /&gt;
--  TMK  --&lt;BR /&gt;
"The Macro Klutz"</description>
      <pubDate>Mon, 06 Oct 2008 14:07:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51509#M380</guid>
      <dc:creator>topkatz</dc:creator>
      <dc:date>2008-10-06T14:07:51Z</dc:date>
    </item>
    <item>
      <title>Re: Numeric precision and discontinuity</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51510#M381</link>
      <description>My guess is that your numerical difficulty is caused by the computation of &lt;BR /&gt;
&lt;BR /&gt;
1- (1-r**k)**M&lt;BR /&gt;
&lt;BR /&gt;
because (1-r**k)**M is very close to 1, and  the difference gets los in the numerical precision. Perhaps you can expand (1-r**k)**M in a binomial series and cancel out the 1 to get better accuracy?</description>
      <pubDate>Mon, 06 Oct 2008 15:09:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51510#M381</guid>
      <dc:creator>Hutch_sas</dc:creator>
      <dc:date>2008-10-06T15:09:26Z</dc:date>
    </item>
    <item>
      <title>Re: Numeric precision and discontinuity</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51511#M382</link>
      <description>In fact, for your specific case, where M = 1, if you make the following modification to your program to simplify the expression, you converge to an answer in about 24 iterations to r = 0.0090868548:&lt;BR /&gt;
&lt;BR /&gt;
	/*&lt;BR /&gt;
                                qk                      =       (1      -       r**k)**M        ;&lt;BR /&gt;
                                pk                      =       1       -       qk      ;&lt;BR /&gt;
                */&lt;BR /&gt;
		pk = r ** k; /* true if M == 1 */</description>
      <pubDate>Mon, 06 Oct 2008 16:14:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51511#M382</guid>
      <dc:creator>Hutch_sas</dc:creator>
      <dc:date>2008-10-06T16:14:09Z</dc:date>
    </item>
    <item>
      <title>Re: Numeric precision and discontinuity</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51512#M383</link>
      <description>Thank you, that was a really useful suggestion.  In fact, rearranging 1 - (1 - r**k)**M as r**k * (1 + (1 - r**k) + ... + (1 - r**k)**(M-1)) works better for M &amp;gt; 1, too.  It looks like it's better to add a bunch of small numbers than it is to subtract two (relatively) large ones, at least in this case.</description>
      <pubDate>Tue, 07 Oct 2008 21:04:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Numeric-precision-and-discontinuity/m-p/51512#M383</guid>
      <dc:creator>topkatz</dc:creator>
      <dc:date>2008-10-07T21:04:03Z</dc:date>
    </item>
  </channel>
</rss>

