For tuples, it seems mapreduce
has poorer type inference than map
+ reduce
.
julia> using FillArrays, Infinities, InfiniteArrays, Test
julia> ax = Ones{Int}(InfiniteCardinal{0}());
julia> y = (ax,ax);
julia> @inferred (t -> mapreduce(sum, *, t))(y)
ERROR: return type InfiniteCardinal{0} does not match inferred return type Any
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] top-level scope
@ REPL[6]:1
julia> @inferred (t -> reduce(*, map(sum, t)))(y)
ℵ₀
This is perhaps because map
is specialized for tuples. Is this an instance where code_warntype isn’t accurate, and the result is correctly inferred in both cases? Or is it better to replace mapreduce
by map
+ reduce
?
Ran into a similar problem when constructing a Turing.jl model. Has anyone resolved why this is the case. I created another example where it can arise (but note that this does not match the “red” result on @code_warntype I recieved during the model run)
using Random
function test_arr_fn(n)
y = map(i -> rand(1:100, n), 1:n)
z = mapreduce(x -> x.^2, hcat, y)
return z
end
@code_warntype test_arr_fn(10)
function test_arr_fn2(n)
y = map(i -> rand(1:100, n), 1:n)
z = reduce(hcat, map(x -> x.^2, y))
return z
end
@code_warntype test_arr_fn2(10)
using OrdinaryDiffEq
function lorenz!(du, u, p, t)
du[1] = 10.0 * (u[2] - u[1])
du[2] = u[1] * (28.0 - u[3]) - u[2]
du[3] = u[1] * u[2] - (8 / 3) * u[3]
end
u0 = [1.0; 0.0; 0.0]
tspan = (0.0, 100.0)
function test_ode_fn(model, u0, tspan)
prob = ODEProblem{true}(model, u0, tspan)
sol = solve(prob)
sol_red = mapreduce(x -> x .+ 2, hcat, sol.u)
return sol_red
end
@code_warntype test_ode_fn(lorenz!, u0, tspan)
function test_ode_fn2(model, u0, tspan)
prob = ODEProblem{true}(model, u0, tspan)
sol = solve(prob)
sol_red = reduce(hcat, map(x -> x .+ 2, sol.u))
return sol_red
end
@code_warntype test_ode_fn2(lorenz!, u0, tspan)
Perhaps this is because hcat could return objects of different shapes?