RE: RE:Working Precision
- To: mathgroup at smc.vnet.net
- Subject: [mg24047] RE: [mg23928] RE:Working Precision
- From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
- Date: Wed, 21 Jun 2000 02:20:07 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
I want to clear up some things.
The only problem I have with the examples based on
x=1.11111111111111111111;
Do[x=2*x-x, {100}];
is that a message is never posted warning that the results are not reliable
due to lose of precision in the value of (x). I suspect many users would
want to know when arbitrary precision arithmetic gives results with very low
precision.
------------------------
I also thought members of the MathGroup would
be interested to know that a definition for
f[x]
apply to a wide range of values when (x) is a numeric value with precision
near zero and even more so when (x) has negative precision. I didn't mean to
suggest that this is a bug. I agree the results are correct.
-------------------------
Now lets take another look at a new variation of my second example using the
default setting of $MinPrecision.
In[1]:=
lst={Pi, Sqrt[2], 11, -10.749999999999999`4.28, -0.25`20};
b1=Plus@@lst
Out[2]=
4.55580621596289
In[3]:=
Precision[b1]
Out[3]=
15
How could we know the value of (b1) with 15 decimal places of precision when
the value of
-10.7499 ....
is only good to 4.28 decimal places?
(*------------------------------*)
I suspect it is possible to write a Plus routine that would give the answer
I expect in cases like the one above (without needing $MinPrecision <0 ). I
suggest that when
evaluating Plus[args__] and all of the following are True
1) None of (args) are machine precision
2) Each args is numeric
3) One or more of (args) is arbitrary precision
4) Length[{args}]>2
then we should be sure not to add terms with opposite sign until everything
else is added together. The method below seems to work well.
In[4]:=
quad1 = Select[lst, (0 <= Arg[#1] < Pi/2)& ];
quad2 = Select[lst, (Pi/2 <= Arg[#1] < Pi)& ];
quad3 = Select[lst, (Pi <= Arg[#1] < 3*Pi/2)& ];
quad4 = Complement[lst, quad1, quad2, quad3];
a1=Complement[Accuracy/@lst,{Infinity}];
accur=Min[Max[a1],Min[a1]+100];
q1=quad1/.z_?(Accuracy[#]===Infinity&):>SetAccuracy[z,accur];
q2=quad2/.z_?(Accuracy[#]===Infinity&):>SetAccuracy[z,accur];
q3=quad3/.z_?(Accuracy[#]===Infinity&):>SetAccuracy[z,accur];
q4=quad4/.z_?(Accuracy[#]===Infinity&):>SetAccuracy[z,accur];
b1=Plus@@{Plus@@q1,Plus@@q2,Plus@@q3,Plus@@q4}
Out[14]=
4.556
In[15]:=
Precision[b1]
Out[15]=
4
Of course I would like to see something like this built-in to the kernel's
(Plus) routine where it would be transparent to the user and run much
faster. Perhaps I overlooked something when I came up with the above
method. In any case I think this is a step in the right direction.
--------------------
Regards,
Ted Ersek
Download Mathematica tips, tricks at
http://www.verbeia.com/mathematica/tips/Tricks.html