On 7 April 2016 at 17:42, Aaron Meurer <[email protected]> wrote:
> You can see how mpmath works here
> http://mpmath.org/doc/current/technical.html#representation-of-numbers.
> It basically uses man*2**exp binary representation. For instance
>
> In [249]: Float("0.1")._mpf_
> Out[249]: (0, 3602879701896397, -55, 52)

Yeah this is what I found yesterday...

>> Exactly sin(Rational) won't be auto-evaluated because it's not clear
> how many digits to use until someone later calls .evalf(). I think it
> should be the same for sin(Float). It shouldn't really matter whether
> the user does S("0.1") or S("1/10").
>
> I think most users don't care about precision beyond the default 15.

Well actually this thread was started by a user who ended up with zero
correct digits because many more than 15 digits may be needed for
intermediate calculations in order to ensure that the end result is
correct to 15 digits.

Consider this:

    >>> S("1e20 + 0.1 - 1e20")
    0.0937500000000000000000

So we're using at least 15 d.p. for each quantity and calculation but
we get almost one correct digit in the output. I think this is
reasonable behaviour for a floating point library but not really from
a CAS like sympy (at least that's not why I use sympy!). I don't have
another CAS to hand but I just noticed that Wolfram Alpha apparently
gives both a wrong and a right answer for this
    https://www.wolframalpha.com/input/?i=%281e20%2B0.1%29-1e20

Really when you do expr.evalf(15) what you want is not for sympy to
use 15 digits of precision internally and compute a result that has an
unspecified number of correct digits. What you want is for sympy to go
do what it takes to get an answer that you can trust to 15 digits.
Making that happen generally means going to a higher precision
internally.

For example if c = a*b and I want c to 15 digits I should compute a
and b to 16 digits, multiply them using 16 digits, and then round to
15 digits. Likewise if I want to compute a%b to 15 digits then I need
to compute a and b to something like ceil(log10(a/b))+15+1 digits
calculate the modulo and then round to 15 digits *at the end*. It is
possible to make something that will recursively compute the
expression tree in such a way that the end result of the computation
is trustable to the specified number of digits.

> For them, auto-evaluating functions like sin at floating point values
> is a useful feature. It's also easy to work around this, either
> provide the precision when you create the float (like Float('0.1',
> 100)), or use a symbol, and substitute it at the end with evalf(100,
> subs={x: '0.1'}).

I think I'll avoid using Floats altogether. I don't like the
possibility that any approximations occur implicitly and I don't
really feel like I know enough about how sympy works with floats to
trust it. Even the way floats are displayed is misleading:

    >>> a = S("1e20")
    >>> a
    100000000000000000000.
    >>> b = S("0.1")
    >>> a
    100000000000000000000.
    >>> (a+b)
    100000000000000000000.
    >>> a == (a+b)
    False
    >>> str(a) == str(a+b)
    True

> The thing that bugs me is that, for instance in this example,
> (x**6000%400).evalf(950, subs={x:"1.4142"}) doesn't work. You have to
> provide the precision twice, like (x**6000%400).evalf(950,
> subs={x:Float("1.4142", 950)}). So perhaps the default precision
> shouldn't be 15, but rather some kind of "auto" flag that uses the
> precision that's provided elsewhere (or 15 if no other precision is
> provided). Or maybe evalf with the subs flag should just override the
> precision for the float inputs with the precision argument of evalf.

The problem is that S("1.4142") throws away the string and stores a 53
bit binary approximation. The only way to increase the precision
retrospectively is to store the number in decimal/rational somewhere
(or just store the string itself).

--
Oscar

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/CAHVvXxT1c3HxzPz%2B6Gkd%2BSZOUaQMnnQz76FcGZpbR2mEs3VXeg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to