Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

default show for Arb might be confusing #84

Open
kalmarek opened this issue Oct 31, 2020 · 7 comments
Open

default show for Arb might be confusing #84

kalmarek opened this issue Oct 31, 2020 · 7 comments
Labels
question Further information is requested

Comments

@kalmarek
Copy link
Owner

kalmarek commented Oct 31, 2020

This is an interval containing 0:

julia> let x = sin(Arb(π))
           @info "" x contains(x, 0) Arblib.midref(x) Float64(Arblib.radref(x))
       end
┌ Info: 
│   x = [+/- 2.83e-77]
│   contains(x, 0) = true
│   Arblib.midref(x) = 1.0969174409793520767073235159733943661910882381141135060401716459409529154108e-77Float64(Arblib.radref(x)) = 1.730607217577946e-77

This is an interval containing 1:

julia> let x = sin(Arb(π)/2)
           @info "sin(Arb(π))" x contains(x, 1) Arblib.midref(x) Float64(Arblib.radref(x))
       end
┌ Info: sin(Arb(π))
│   x = [1.000000000000000000000000000000000000000000000000000000000000000000000000000 +/- 1.74e-77]
│   contains(x, 1) = true
│   Arblib.midref(x) = 0.99999999999999999999999999999999999999999999999999999999999999999999999999999Float64(Arblib.radref(x)) = 8.737900781332737e-78

This is an interval containing 1.5:

julia> let x = 1.5sin(Arb(π)/2)
           @info "1.5sin(Arb(π)/2)" x contains(2x, 3) Arblib.midref(x) Float64(Arblib.radref(x))
       end
┌ Info: 1.5sin(Arb(π)/2)
│   x = [1.5000000000000000000000000000000000000000000000000000000000000000000000000000 +/- 4.77e-77]
│   contains(2x, 3) = true
│   Arblib.midref(x) = 1.5Float64(Arblib.radref(x)) = 3.0379188354575523e-77

let's try the same with set_interval!:

julia> let x = Arblib.set_interval!(Arb(), Arf(-0.5), Arf(0.5))
           @info "[-0.5, 0.5]" x contains(x, 0) Arblib.midref(x) Float64(Arblib.radref(x))
       end
┌ Info: [-0.5, 0.5]
│   x = [+/- 0.501]
│   contains(x, 0) = true
│   Arblib.midref(x) = 0Float64(Arblib.radref(x)) = 0.5000000009313226

julia> let x = Arblib.set_interval!(Arb(), Arf(0.5), Arf(1.5))
           @info "[0.5, 1.5]" x contains(x, 1) Arblib.midref(x) Float64(Arblib.radref(x))
       end
┌ Info: [0.5, 1.5]
│   x = [1e+0 +/- 0.501]
│   contains(x, 1) = true
│   Arblib.midref(x) = 1Float64(Arblib.radref(x)) = 0.5000000009313226

julia> let x = Arblib.set_interval!(Arb(), Arf(1.0), Arf(2.0))
           @info "[1.0, 2.0]" x contains(2x, 3) Arblib.midref(x) Float64(Arblib.radref(x))
       end
┌ Info: [1.0, 2.0]
│   x = [+/- 2.01]               this is unexpected
│   contains(2x, 3) = true
│   Arblib.midref(x) = 1.5Float64(Arblib.radref(x)) = 0.5000000009313226

moreover:

julia> let x = Arblib.set_interval!(Arb(), Arf(1.0), Arf(2.0))
           @info "[1.0, 2.0]" Arblib.string_decimal(x) Arblib.string_nice(x)
       end
┌ Info: [1.0, 2.0]
│   Arblib.string_decimal(x) = "1.5 +/- 0.5"
└   Arblib.string_nice(x) = "[+/- 2.01]"
@kalmarek kalmarek added the Arblib bug? The issue might be potentially in Arb c library label Oct 31, 2020
@saschatimme
Copy link
Collaborator

What is exactly the bug? My hunch is that in the second and third case the midpoint is not exactly what is printed. Printed is the rounded version. The first I guess is a concise printing. In the other cases the midpoint has an exact representation and is therefore abbreviated.

@kalmarek
Copy link
Owner Author

kalmarek commented Oct 31, 2020

the bug is that

julia> Arblib.set_interval!(Arb(), Arf(-2.0), Arf(2.0))
[+/- 2.01]

julia> Arblib.set_interval!(Arb(), Arf(1.0), Arf(2.0))
[+/- 2.01]

julia> Arblib.string_decimal(Arblib.set_interval!(Arb(), Arf(1.0), Arf(2.0)))
"1.5 +/- 0.5"

julia> Arblib.string_decimal(Arblib.set_interval!(Arb(), Arf(-2.0), Arf(2.0)))
"0 +/- 2"

the interval [-2.0, 2.0] has the same string_nice (which is used for show) as [1.0, 2.0]

@saschatimme
Copy link
Collaborator

oh I see

@Joel-Dahne
Copy link
Collaborator

I don't think this is a bug but a result of the fact that string_nice only shows correct digits. The Interval [1.0, 2.0] contains both 1 and 2 so not a single digit of the number is known, hence it give anything before the +/- and has to resort to using the radius alone for the result. We get the same result with for example

julia> Arblib.set_interval!(Arb(), Arf(80000), Arf(90000))
[+/- 9.01e+4]

@kalmarek
Copy link
Owner Author

thanks for the explanation @Joel-Dahne; I found it confusing, but it makes perfect sense after explanation; however: given that this requires an explanation should we switch to string_decimal for show?

@kalmarek kalmarek changed the title wrong printing for some Arbs? default show for Arb might be confusing Oct 31, 2020
@kalmarek kalmarek removed the Arblib bug? The issue might be potentially in Arb c library label Oct 31, 2020
@Joel-Dahne
Copy link
Collaborator

That is a good point actually! I have actually been bitten a couple of times by this behaviour myself. The main risk I see with this is that reading that string back with arb_get_str is not guaranteed to give an enclosure since for string_decimal, as written in the documentation, "The printed value of the radius is not adjusted to compensate for the fact that the binary-to-decimal conversion of both the midpoint and the radius introduces additional error."

@kalmarek
Copy link
Owner Author

kalmarek commented Nov 1, 2020

I see, but given the problems with string_nice users should be discouraged from parsing the readable string representation of Arbs:

julia> x = Arblib.set_interval!(Arb(), Arf(1.0), Arf(2.0))
[+/- 2.01]

julia> y = Arb(Arblib.string_nice(x))
[+/- 2.02]

julia> Arblib.midref(y)
0

julia> z = Arb(Arblib.string_decimal(x)) # ← but not guaranteed to enclose x...
[+/- 2.01]

julia> Arblib.midref(z)
1.5

the functions for loading and storing are dump_string and load_string!. This requires additional entry in the docs though.

EDIT:
is there a function in julia for serialization into strings? I thought about repr, but reading the docs it doesn't seem to be the one...

@kalmarek kalmarek added the question Further information is requested label Dec 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants