-
Notifications
You must be signed in to change notification settings - Fork 113
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
extrapolation fails with MethodError: Cannot convert an object of type Missing #424
Comments
Try this: julia> f64m = Union{Float64, Missing}
Union{Missing, Float64}
julia> interpolant = LinearInterpolation([1.0, 2.0, 3.0], f64m[1.0, 2.0, 3.0], extrapolation_bc=missing)
3-element extrapolate(interpolate((::Vector{Float64},), ::Vector{Union{Missing, Float64}}, Gridded(Linear())), missing) with element type Union{Missing, Float64}:
1.0
2.0
3.0
julia> interpolant(4.0)
missing |
Indeed, it works, julia> eltype(y)
Float64
julia> extrap = missing;
julia> Union{eltype(y), typeof(extrap)}
Union{Missing, Float64}
julia> extrap = 0.0;
julia> Union{eltype(y), typeof(extrap)}
Float64 Or it should be documented in the extrapolation section. |
Isn't type stability about having an output entirely determined by the type of the arguments, and not their value ? |
In this case, we narrow down the possible return types to |
But I was using
(L1 = 32768, L2 = 524288, L3 = 16777216) The memory usage of an ODE kernel: # 6 arrays of n Float64 used in time_evolution
memory_usage(n) = 6 * Base.summarysize(zeros(Float64, n)) Then the limits of cache filling are evaluated as: function N_filling_caches()
interpolant = LinearInterpolation(memory_usage.(N_points_), N_points_)
caches = machine_caches()
min = memory_usage(first(N_points_))
max = memory_usage(last(N_points_))
NamedTuple(name => convert(Float64, interpolant(caches[name]))
for name in keys(caches)
if min <= caches[name] <= max # avoid extrapolation
)
end In an ideal world, I'd have mapped the interpolant on |
How about this: julia> Np = 1:1000.0:100001.0
julia> interpolant = LinearInterpolation(memory_usage.(Np), Np; extrapolation_bc=NaN);
julia> interpolated = NamedTuple{ keys(caches) }( interpolant.( values(caches) ) )
(L1 = 677.6666666666666, L2 = 10917.666666666668, L3 = NaN)
julia> (; [k => v for (k,v) in pairs(interpolated) if !isnan(v)]...)
(L1 = 677.6666666666666, L2 = 10917.666666666668)
|
Perhaps, I'm missing something, but is this not sufficient: julia> N_points(memory) = ( memory/6 - Base.summarysize(zeros(Float64,0)) ) / sizeof(Float64)
N_points (generic function with 1 method)
julia> caches = machine_caches()
(L1 = 32768, L2 = 524288, L3 = 16777216)
julia> NamedTuple{ keys(caches) }( N_points.( values(caches) ) )
(L1 = 677.6666666666666, L2 = 10917.666666666666, L3 = 349520.3333333333) |
These are all valid, and better. |
Actually, it looks that |
I posted there: julia> function sum_non_nan(X::AbstractArray)
s = zero(eltype(X))
@inbounds @simd for x in X
# simplify the branch so it can SIMD.
s += isnan(x) ? zero(x) : x
end
s
end
julia> function sum_nonmissing(X::AbstractArray)
s = zero(eltype(X))
@inbounds @simd for x in X
s += ismissing(x) ? zero(x) : x
end
s
end
julia> Y1 = rand(10_000_000);
julia> Y2 = Vector{Union{Missing, Float64}}(Y1);
julia> Y3 = ifelse.(rand(length(Y2)) .< 0.9, Y2, missing);
julia> Y3_nan = Array{Float64}(replace(x->ismissing(x) ? NaN : x, Y3));
julia> @btime sum_nonmissing($Y1)
9.132 ms (0 allocations: 0 bytes)
4.999213478955774e6
julia> @btime sum_non_nan($Y1)
10.114 ms (0 allocations: 0 bytes)
4.999213478955774e6
julia> @btime sum_nonmissing($Y2);
17.643 ms (0 allocations: 0 bytes)
julia> @btime sum_nonmissing($Y3);
13.534 ms (0 allocations: 0 bytes)
julia> @btime sum_non_nan($Y3_nan);
10.156 ms (0 allocations: 0 bytes) For me only Note that the conditional structure if important here. Using the ternary operator with If you want to see what the compiler is doing, try |
OK, thanks, I'm convinced for performance-critical code.
But code complexity and maintainability are most important. I have no idea about that. |
Extrapolation is not working.
It might be related to "something is not working well there" comment of #404 (comment) ?
Long story,
after redirection from fonsp/Pluto.jl#1163 (comment)
since using
extrapolation_bc=missing
gave a "Failed to show" error in Pluto(not important, just in case someone else would search here for
isassigned
):julia> interpolant = LinearInterpolation([100, 110, 120], [100, 110, 120], extrapolation_bc=missing)
julia> isassigned(interpolant, 1)
ERROR: MethodError: Cannot
convert
an object of type Missing to an object of type Int64Closest candidates are:
convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
convert(::Type{T}, ::Base.TwicePrecision) where T<:Number at twiceprecision.jl:250
convert(::Type{T}, ::AbstractChar) where T<:Number at char.jl:180
...
Stacktrace:
[1] FilledExtrapolation
@ ~/.julia/packages/Interpolations/GIn2o/src/extrapolation/filled.jl:37 [inlined]
[2] getindex
@ ~/.julia/packages/Interpolations/GIn2o/src/Interpolations.jl:449 [inlined]
[3] isassigned(a::Interpolations.FilledExtrapolation{Union{Missing, Float64}, 1, Interpolations.GriddedInterpolation{Float64, 1, Int64, Gridded{Linear}, Tuple{Vector{Int64}}}, Gridded{Linear}, Missing}, i::Int64)
@ Base ./abstractarray.jl:513
[4] top-level scope
@ REPL[5]:1
and indeed
interpolant[i]
orgetindex(interpolant, 1)
give the same error.getindex
is overridden here:Interpolations.jl/src/Interpolations.jl
Lines 448 to 450 in 4f6f488
The text was updated successfully, but these errors were encountered: