-
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
API for choosing power function #355
Comments
Could we choose one at pre-compile time based on a specific key in the That's already what we do to determine whether or not to do validity checks. I think it is good unless there is a reason one would like to switch the default during a computation, but I can't see any use case (as long as both versions are available at all time through specific function names). |
Since
How is that supposed to be used? The following obviously doesn't work, because julia> using IntervalArithmetic
julia> haskey(ENV, "IA_VALID")
false
julia> Interval(3, 2)
[3, 2]
julia> ENV["IA_VALID"] = true
true
julia> Interval(3, 2)
[3, 2]
I agree; mixing different power methods in the same program seems like a rare use case. |
Best I found is the following (starting with IA set with the validity check): julia> using IntervalArithmetic
julia> Interval(3, 2)
ERROR: ArgumentError: Interval of form [3.0, 2.0] not allowed. Must have a ≤ b to construct interval(a, b).
Stacktrace:
[1] Interval at /home/benoit/.julia/dev/IntervalArithmetic/src/intervals/intervals.jl:28 [inlined]
[2] Interval at /home/benoit/.julia/dev/IntervalArithmetic/src/intervals/intervals.jl:42 [inlined]
[3] Interval(::Int64, ::Int64) at /home/benoit/.julia/dev/IntervalArithmetic/src/intervals/intervals.jl:49
[4] top-level scope at REPL[2]:1
julia> haskey(ENV, "IA_VALID")
false
julia> Base.compilecache(Base.PkgId(IntervalArithmetic))
[ Info: Precompiling IntervalArithmetic [d1acc4aa-44c8-5952-acd4-ba5d80a2a253]
"/home/benoit/.julia/compiled/v1.3/IntervalArithmetic/Gjmwo_x70GE.ji"
julia> exit() Then after restarting julia: julia> using IntervalArithmetic
julia> Interval(3, 2)
[3, 2] Apparently the package manager |
Cool, |
I fully agree! Surely, not ideal, but we could exploit the already existing |
Here's a possible solution / workaround using julia> using IRTools: @dynamo, recurse!, IR
julia> @dynamo function fast_powers(a...)
ir = IR(a...)
ir == nothing && return
recurse!(ir)
return ir
end
julia> fast_powers(::typeof(^), a, b) = pow(a, b);
julia> x = 1.1..2.2
Interval(1.0999999999999999, 2.2)
julia> x^10
Interval(2.5937424600999965, 2655.9922791424024)
julia> pow(x, 10)
Interval(2.593742460099994, 2655.992279142405)
julia> fast_powers() do
x^10
end
Interval(2.593742460099994, 2655.992279142405) |
Given this, I would suggest making fast powers the default, and having an |
Here's the same using Cassette.jl instead: using Cassette, IntervalArithmetic
Cassette.@context FastPowersCtx
const fast_powers_ctx = Cassette.disablehooks(FastPowersCtx())
Cassette.overdub(::FastPowersCtx, ::typeof(^), a, b) = pow(a,b)
fast_powers(f) = Cassette.overdub(fast_powers_ctx, f)
x = 1.1..2.2
fast_powers() do
x^10
end |
Very nice and very impressive! I cannot comment about which approach to follow, but I think the default should use accurate_powers as default, simply because it is the one that complies with the standard. |
As long as we don't introduce a new (mutable) global variables I'm fine with any API, but I must admit the use of context is very fancy =D. Also the standard doesn't require anything about naming convention and iirc the function it defines must ensure correctness, but they are not required to be as tight as possible. |
Thanks for sharing the different solutions with IRTools and Cassette. This illuminated me about some code transformations we wanted to do in LazySets, which seem to be achievable with this technology :) Contextual dispatch avoids the more traditional/verbose |
Great! Cassette is really super powerful. Yes it has to be inside a I I think what you're effectively asking is "can I set a global context to use with Cassette". I think this will end up being equivalent to the kind of global manipulations we are already doing? Hmm, actually maybe that's a neater way of doing what we are trying to do. This is related to #352. |
I don't think we need the ability to set a global context. As far as i can see, the worst case scenario would be to have the whole program inside a do block (which can easily be done by putting everything in a single function and calling this one inside a do block). To me this doesn't justifies taking the risk to have a global option possibly causing unexpected side effects. |
Done in PR #593. Let us see if the proposed API holds up to our expectations. |
We need to decide on an API for how to specify whether powers will use the slow but accurate version (via MPFR) or the fast but less accurate version (via power_by_squaring).
Maybe something like
Any other suggestions @lbenet @mforets @Kolaru?
The text was updated successfully, but these errors were encountered: