# Nested QuadGK: Long compilation time gets short when plotting the argument beforehand, but not when calling it

Hey everyone, I stumbled upon a weird behaviour of compilation time.
I have the following function definitions:

using QuadGK
g(t) = t^2
f(t) = integrate(g,t)


Now if I call quadgk(f,0,1), it takes over two minutes to compile:

julia> @time quadgk(f,0,1);
142.877898 seconds (305.06 M allocations: 23.536 GiB, 4.36% gc time)

0.000242 seconds (552 allocations: 13.219 KiB)


If instead I plot f before, the compilation time is only half a second:

julia> @time using Plots; @time plot(f,0,1);
4.834115 seconds (9.95 M allocations: 550.155 MiB, 4.37% gc time)
22.190020 seconds (56.53 M allocations: 2.786 GiB, 7.81% gc time)

0.598319 seconds (1.36 M allocations: 83.927 MiB, 6.51% gc time)

0.000156 seconds (537 allocations: 12.984 KiB)


Just calling e.g f(0.1) does not have an impact on the compilation time.
Can anyone explain to me whatâ€™s going on here? What does plot(f,0,1) do that f(0.1) doesnâ€™t?

I am using Julia 1.1.0

2 Likes

I am also surprised the first compilation @time quadgk(f,0,1) takes 140 seconds (150 on my machine).

I donâ€™t have an explanation for the compilation time â€” you might file an issue at JuliaLang/julia â€” but I would strongly recommend against using nested 1d adaptive quadrature, which can easily waste a lot of time trying to refine 1d integrals in regions that donâ€™t contribute much to the overall integral.

Instead, you should use a â€ścubatureâ€ť routine (like in HCubature.jl, Cubature.jl, or Cuba.jl) that knows how to do multiple integrals in a holistic way. Even though these routines typically integrate over box domains, you can integrate over other domains with a change of variables. For example, your problem is a triangular domain, which can be mapped to a box with:

\int_0^1 dx \int_0^x dy \, F(x,y) = \int_0^1 dx \int_0^1 du \, xF(x,ux)

via the change of variables y = ux.

5 Likes