List comprehension `no method matching zero` issue

Hello, good morning,

I had a following code block failing when I’m doing a loop for get a vector of results in a monte carlo simulation. Can’t understand why I got the issue above:
in line below:

mc_estimate = sum([in(sample(omega), union(A, B)) for x in 1:i if x % 1000 == 0]) / i;
ERROR: LoadError: MethodError: no method matching zero(::Type{Any})
Closest candidates are:
  zero(::Type{Union{Missing, T}}) where T at missing.jl:105
  zero(::Union{Type{P}, P}) where P<:Dates.Period at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Dates\src\periods.jl:53       
  zero(::Histogram{T, N, E}) where {T, N, E} at C:\Users\jcbritobr\.julia\packages\StatsBase\Q76Ni\src\hist.jl:538
  ...
Stacktrace:
  [1] zero(#unused#::Type{Any})
    @ Base .\missing.jl:106
  [2] reduce_empty(#unused#::typeof(+), #unused#::Type{Any})
    @ Base .\reduce.jl:311
  [3] reduce_empty(#unused#::typeof(Base.add_sum), #unused#::Type{Any})
    @ Base .\reduce.jl:320
  [4] mapreduce_empty(#unused#::typeof(identity), op::Function, T::Type)
    @ Base .\reduce.jl:343
  [5] reduce_empty(op::Base.MappingRF{typeof(identity), typeof(Base.add_sum)}, #unused#::Type{Any})
    @ Base .\reduce.jl:329
  [6] reduce_empty_iter
    @ .\reduce.jl:355 [inlined]
  [7] mapreduce_empty_iter(f::Function, op::Function, itr::Vector{Any}, ItrEltype::Base.HasEltype)
    @ Base .\reduce.jl:351
  [8] _mapreduce(f::typeof(identity), op::typeof(Base.add_sum), #unused#::IndexLinear, A::Vector{Any})
    @ Base .\reduce.jl:400
  [9] _mapreduce_dim
    @ .\reducedim.jl:318 [inlined]
 [10] #mapreduce#672
    @ .\reducedim.jl:310 [inlined]
 [11] mapreduce
    @ .\reducedim.jl:310 [inlined]
 [12] #_sum#682
    @ .\reducedim.jl:878 [inlined]
 [13] _sum
    @ .\reducedim.jl:878 [inlined]
 [14] #_sum#681
    @ .\reducedim.jl:877 [inlined]
 [15] _sum
    @ .\reducedim.jl:877 [inlined]
 [16] #sum#679
    @ .\reducedim.jl:873 [inlined]
 [17] sum(a::Vector{Any})
    @ Base .\reducedim.jl:873
 [18] top-level scope
    @ c:\Workspace\julia\statistics\samples.jl:49
in expression starting at c:\Workspace\julia\statistics\samples.jl:48

The code below:

# %% Monte Carlo simulation for above problem
using StatsBase, Plots

N=10^4;
omega = collect(Ω);

simulations = Vector(undef, N);
mc_estimate = 0;
for i in 1:N
    mc_estimate = sum([in(sample(omega), union(A, B)) for x in 1:i if x % 1000 == 0]) / i;
    simulations[i] = mc_estimate;
end

println("The result of monte carlo simulation is $mc_estimate");
plot(1:N, simulations);
plot!(x -> 0.6, 1:N)

It looks like the element type of the comprehension is inferred as Any, and, from the stacktrace, it looks like it is empty, so Julia errors when you call sum on it:

julia> x = Any[];

julia> sum(x)
ERROR: MethodError: no method matching zero(::Type{Any})

If you know what element type you expect (e.g. Int), then you can use a typed comprehension: Int[...] instead, but perhaps there is a bug in your code since I am guessing you didn’t expect it to be empty in the first place.

2 Likes

It solves de error, but the results now I got is wrong. What I’m trying to do is optimize this list towards 10^4 or more.

image

What I was expecting is a plot like the below:
image

I’m just trying to skip some simulations, because I want to approximate Monte Carlo to 10^6 and get better results and plot them.

The comprehension must generate a result list for sum only if x % 1000 == 0, but its not working what we can see in plot. Algorithm is wrong. I cant skip the samples because this will lead to less aproximate results.

I think got what I want with the code below:

# %% Monte Carlo simulation for above problem
using StatsBase, Plots

N=10^4;
step = 1;
omega = collect(Ω);

size = Int(N/step)

simulations = Vector(undef, size);
mc_estimate = 0;
for i in 1:step:N
    println("\rSimulation $i of $N");
    mc_estimate = sum(Int[in(sample(omega), union(A, B)) for _ in 1:i]) / i;
    index =Int(round(i/step));
    simulations[index] = mc_estimate;
end

println("The result of monte carlo simulation is $mc_estimate");
plot(1:size, simulations, xlabel="Samples", ylabel="Result", label="Result");
plot!(x -> result, 1:size, label="Solution ($result)")

Plot:
image