On Tue, Feb 8, 2022 at 1:07 PM Luke Hartman <[email protected]> wrote: > > When you use evalf, you can provide an argument n, which is "the number of > digits of precision" that you want > > One straightforward interpretation of this is that Sympy's evalf interface > always returns a number whose nth significant digit is within 1 of the true > answer (in either direction). > > The only examples I have seen this break are around zero. In particular, if > you have the wrong sign, then tweaking the nth significant digit is not going > to help > > Here is a simple example where sp.core.evalf.evalf gives a different sign > with different precision (so at least one of them has the wrong sign) > ``` > expr = sp.fibonacci(27) - (sp.GoldenRatio**27)/sp.sqrt(5) > re, _, re_acc, _ = sp.core.evalf.evalf(expr, prec=1, options={"strict": True}) > sign, man, exp, bc = re > print([1, -1][sign]*man*2**exp) > print(float(expr)) > ``` > prints > ``` > -128 > 1.0182366178305287e-06 > ``` > > I also dug into the code a bit to see what I could find, when you use > "strict=True", behind the scenes, Sympy basically just checks that > sp.core.evalf.evalf's returned re_acc (only concerned with) is at least as > high as the desired precision. (Where re_acc seems to be the number of > accurate bits in the number that re is a rounded version of) > > So it isn't really clear to me what the interpretation of n/prec/re_acc is > for these cases around zero > > In a perfect world, I would like to have a function which takes the > input/output of evalf and returns an upper and lower bound for the true value > of the expression.
What you want is something that uses interval arithmetic. mpmath is based on significance arithmetic which makes this harder. There is an interval module in mpmath, but it isn't integrated into evalf. There are also libraries like arb which are alternatives to mpmath that are built on interval semantics. > > As a related question, I would like to know how rigorous Sympy tries to be > with adhering to a specific precision guarantee (for example mpmath has [this > page](https://mpmath.org/doc/current/technical.html#correctness-guarantees)) SymPy tries to go a step above mpmath by increasing the working precision internally. However, it is limited in how far it will try this. In general you might have something like this >>> (sin(1)**2 + cos(1)**2 - 1).evalf() -0.e-124 this means that it tried increasing the working precision to 124 digits until it gave up. This can be controlled by the maxn parameter. However, in this case, it could increase the working precision indefinitely and never be able to determine the true value, because it's exactly 0, but the algorithm for computing the expression will never give exactly 0 in finitely many steps. If you use strict=True for this example, you instead get an error. > > -- > 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 view this discussion on the web visit > https://groups.google.com/d/msgid/sympy/d93886b7-b89e-4c2f-b07c-92d450d6676an%40googlegroups.com. -- 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 view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAKgW%3D6LC5cNECb9wYn%3D9Mf201Z%2BvLfrz304%3DZTCBrfRSDzb1ZQ%40mail.gmail.com.
