-
Notifications
You must be signed in to change notification settings - Fork 71
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
New macro for guaranteed operations #627
Conversation
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #627 +/- ##
==========================================
- Coverage 82.98% 82.86% -0.13%
==========================================
Files 26 27 +1
Lines 2181 2206 +25
==========================================
+ Hits 1810 1828 +18
- Misses 371 378 +7 ☔ View full report in Codecov by Sentry. |
ForwardDiff seems to not complain julia> using IntervalArithmetic
julia> using ForwardDiff: derivative
julia> @exact f(x) = 3*sin(10x) - 2.2/x
f (generic function with 1 method)
julia> derivative(f, 1.2)
26.843396539752543
julia> derivative(f, interval(1.2, 1.2))
[26.8433, 26.8435]_com Except when it uses comparisons of course julia> @exact g(x) = x^2
g (generic function with 1 method)
julia> derivative(g, 1.2)
2.4
julia> derivative(g, interval(1.2, 1.2))
ERROR: ArgumentError: `==` is purposely not supported for intervals. See instead `isequal_interval` |
Had a bit of fun and found a way to make the floating point input problem apparent: julia> x = interval(0, 1)
[0.0, 1.0]_com
julia> @exact 0.5x + 0.1
┌ Warning: Float64 displayed as 0.1 is equal to 0.1000000000000000055511151231257827021181583404541015625
└ @ IntervalArithmetic ~/.julia/dev/IntervalArithmetic/src/intervals/exact_numbers.jl:33
[0.0999999, 0.600001]_com The same trick should probably be used with |
This is very very nice! 🚀 Let me begin with the following (side) remark: we can use the same trick to find the actual rounding (up or down) when converting a real number julia> x = 0.1
0.1
julia> ExactNumber(x)
ExactNumber{Float64}(0.1000000000000000055511151231257827021181583404541015625)
julia> string(x) < string(ExactNumber(x)) # so 0.1::Float64 is rounded up!
true
# A tight interval representation of the real 0.1 is:
julia> interval(prevfloat(x), x)
Interval{Float64}(0.09999999999999999, 0.1, com)
julia> x = 0.3
0.3
julia> ExactNumber(x)
ExactNumber{Float64}(0.299999999999999988897769753748434595763683319091796875)
julia> string(x) > string(ExactNumber(x)) # 0.3::Float64 is rounded down!
true
# A tight interval representation of the real 0.3 is:
julia> interval(x, nextfloat(x))
Interval{Float64}(0.3, 0.30000000000000004, com) (I guess certain changes are required for negative numbers, but the idea is similar.) The above raises the question: Do we want to "operate" with |
Aside from the comment above, and knowing this is still a prototype, what about other numeric formats ( |
Unfortunately, not quite, because we never know what the user did input. Anything that is parsed as julia> @exact 0.1
┌ Warning: Float64 displayed as 0.1 is equal to 0.1000000000000000055511151231257827021181583404541015625
└ @ IntervalArithmetic ~/.julia/dev/IntervalArithmetic/src/intervals/exact_numbers.jl:33
ExactNumber{Float64}(0.1000000000000000055511151231257827021181583404541015625)
julia> @exact 0.09999999999999999999782
┌ Warning: Float64 displayed as 0.1 is equal to 0.1000000000000000055511151231257827021181583404541015625
└ @ IntervalArithmetic ~/.julia/dev/IntervalArithmetic/src/intervals/exact_numbers.jl:33
ExactNumber{Float64}(0.1000000000000000055511151231257827021181583404541015625)
julia> @exact 0.1000000000000000055511151231257827021181583404541015625
┌ Warning: Float64 displayed as 0.1 is equal to 0.1000000000000000055511151231257827021181583404541015625
└ @ IntervalArithmetic ~/.julia/dev/IntervalArithmetic/src/intervals/exact_numbers.jl:33
ExactNumber{Float64}(0.1000000000000000055511151231257827021181583404541015625)
If we agree this is the way to go I'll add the required methods for Rational, BigFloat and the basic arithmetic operations. |
b17291b
to
a6b1222
Compare
So the purpose of the macro EDIT: sorry I did not follow the discussion at the time. My understanding of the macro is that "whatever is typed in, is guaranteed". In this regard, we should not use an atomic interval for floats; for instance, |
Looking back at the current implementation, I find the goal of I thought the purpose was to allow us to write general code (code used for both floating-points arithmetic and interval arithmetic), and avoid propagating the "NG" flag. To be concrete, suppose I have a function Now if I define This means that an operation involving I think this would be a very powerful feature. One situation I have in mind is rigorously computing a specific zero of a function |
I think this PR is roughly where we want it to be. The formulation of the doc would probably benefit from the review. Once think that this PR is not doing is to deal with conversion of |
The CI failure seems to be due to broken tests introduced in #619, which now pass on nightly. One tiny note: I am trying to think of a single word for the name of the macro. How about |
@Kolaru Lastly I ran into issues when the expression contained Also, I do not understand how the display works. Is the string being prompted truly the exact mathematical number? |
The most descriptive name would probably be
Yes. I ask the Ryu library (I have no idea what it is, but that's what Base uses) to write the number with 2000 decimals and truncate the extra 0s. According to my tests and estimation, 2000 decimals is more than enough to have the exact decimal representation of any Float64.
I fixed the constructor for complex such that PS: |
Looks good to merge, once the tests are successful. I glanced at it but I am not sure what went wrong. |
I forgot to rename the macro. |
I don't know what is going on with nightly or the doctests. Do the doctests use nightly julia ? It may be the same problem. |
It seems that the problem with the doctests is due to the printing of the intervals. Somehow it expects |
c4fc3f6
to
374d33f
Compare
I discussed with Luis and I put up a quick prototype on how we could extend the current
@interval
macro.The strategy drafted here is to convert every literals into
ExactNumber
with the@exact
macro.An
ExactNumber
promote to real when mixed with reals, and to a guaranteed interval when interacting with intervals.The
@exact
macro works on both expression and function definition (thanks to MacroTools.jl)I haven't yet checked how it would play out with IntervalRootFinding or ForwardDiff.