-
Notifications
You must be signed in to change notification settings - Fork 37
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
one(measurement) should return 1, not 1 ± 0 #134
Comments
Uhm, if I define Base.one(::Type{Measurement{T}}) where T = one(T)
Base.one(::Type{Complex{Measurement{T}}}) where T = one(Complex{T}) then some operations are no longer inferred correctly:
which breaks tests at Measurements.jl/test/runtests.jl Lines 288 to 289 in daa1ad2
Measurements.jl/test/runtests.jl Line 732 in daa1ad2
|
And the accuracy of a bunch of QuadGK tests gets worse:
although the prospect of deleting the |
I presume the problem with the complex power is the use of Edit: no, or not only that: replacing |
Actually, that's independent from this change, accuracy got worse in v2.8.1 of QuadGK, it's restored if I downgraded it to v2.8.0. |
In particular, with 2.8.0: julia> QuadGK.quadgk(t -> cos(3 - t), 0, 2pi)
(6.106226635438361e-16, 0.0) with 2.8.1: julia> QuadGK.quadgk(t -> cos(3 - t), 0, 2pi)
(-1.0625509660110193e-13, 1.1749641421160047e-23) This has nothing to do with |
This regressed in v2.8.1: <#134 (comment)>.
@stevengj Additionally, v2.6.0 of QuadGK broke another test here: Measurements.jl/test/runtests.jl Lines 925 to 930 in daa1ad2
julia> using Unitful, Measurements, QuadGK
julia> f(x) = x^2
f (generic function with 1 method)
julia> F(x) = x^3 / 3
F (generic function with 1 method)
julia> a = (5 ± 0.1)u"m"
5.0 ± 0.1 m
julia> b = (10 ± 1)u"m"
10.0 ± 1.0 m
julia> QuadGK.quadgk(f, a, b)
ERROR: MethodError: no method matching Float64(::Measurement{Float64})
Closest candidates are:
(::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat at rounding.jl:200
(::Type{T})(::T) where T<:Number at boot.jl:772
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
...
Stacktrace:
[1] convert(#unused#::Type{Float64}, x::Measurement{Float64})
@ Base ./number.jl:7
[2] setindex!(A::Vector{Float64}, x::Measurement{Float64}, i1::Int64)
@ Base ./array.jl:966
[3] eignewt(b::Vector{Measurement{Float64}}, m::Int64, n::Int64)
@ QuadGK ~/.julia/packages/QuadGK/BYxcx/src/gausskronrod.jl:43
[4] kronrod(#unused#::Type{Measurement{Float64}}, n::Int64)
@ QuadGK ~/.julia/packages/QuadGK/BYxcx/src/gausskronrod.jl:197
[5] macro expansion
@ ~/.julia/packages/QuadGK/gxzkm/src/gausskronrod.jl:259 [inlined]
[6] _cachedrule(#unused#::Type{Measurement{Float64}}, n::Int64)
@ QuadGK ~/.julia/packages/QuadGK/BYxcx/src/gausskronrod.jl:259
[7] cachedrule
@ ~/.julia/packages/QuadGK/gxzkm/src/gausskronrod.jl:264 [inlined]
[8] do_quadgk(f::typeof(f), s::Tuple{Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}, Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}, n::Int64, atol::Nothing, rtol::Nothing, maxevals::Int64, nrm::typeof(LinearAlgebra.norm), segbuf::Nothing)
@ QuadGK ~/.julia/packages/QuadGK/BYxcx/src/adapt.jl:7
[9] #46
@ ~/.julia/packages/QuadGK/gxzkm/src/adapt.jl:219 [inlined]
[10] handle_infinities(workfunc::QuadGK.var"#46#47"{Nothing, Nothing, Int64, Int64, typeof(LinearAlgebra.norm), Nothing}, f::typeof(f), s::Tuple{Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}, Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}})
@ QuadGK ~/.julia/packages/QuadGK/BYxcx/src/adapt.jl:118
[11] quadgk(::Function, ::Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}, ::Vararg{Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}; atol::Nothing, rtol::Nothing, maxevals::Int64, order::Int64, norm::Function, segbuf::Nothing)
@ QuadGK ~/.julia/packages/QuadGK/BYxcx/src/adapt.jl:218
[12] quadgk(::Function, ::Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}, ::Quantity{Measurement{Float64}, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}})
@ QuadGK ~/.julia/packages/QuadGK/BYxcx/src/adapt.jl:216
[13] top-level scope
@ REPL[36]:1 Although this would be fixed in #135 by defining the |
* Use more `@inferred` in tests * Reduce required accuracy of some QuadGK integrals This regressed in v2.8.1: <#134 (comment)>. * Skip test broken upstream by QuadGK * [CI] Use newer versions of `actions/checkout` workflow * Do not test `@inferred` on `logabsbeta`
The basic problem with this test is that you are asking it to compute an integral that is zero to a relative tolerance of The solution, as explained in the QuadGK manual, is that whenever you have an integral that might be zero, you should pass in a nonzero
and 2.8.0:
though the answers are very slightly different due to changes in roundoff. |
For powers, The alternative would be to define some other method to get the "scalar" type from a numeric type. Maybe call it |
I would suggest defining:
which still a correct answer since it is still a multiplicative identity for a
Measurement
(type promotion takes care of the rest). In general,one(x)
need not return the same type asx
in Julia — if the caller wants the same type, they should useoneunit(x)
.one(x)
is commonly used to "strip the units" from a quantity, and it would provide a nice generic way to extract the underlying scalar type from a measurement. For example, this code in QuadGK.jl should work as-is forMeasurement
if you defineone
, and you should no longer need to implement specialized QuadGK methods. (Hopefully you can eliminate your QuadGK dependency completely and it will just work.)The text was updated successfully, but these errors were encountered: