Unreasonable slow speed in numerical integration

Thanks for your help. I finally understand your approach. I haven’t known that do with nested integration can speed up functions until now and it reduce allocations drastically. In my practice, I found that defining two nested functions has the similar timing as your method:


using QuadGK,HCubature,BenchmarkTools,Richardson

function Sigma1(η)

    hcubature((0.0,0.0),(2*pi,4*pi/sqrt(3))) do (kx, ky)

        ϵ = spinonenergy(kx, ky)

        quadgk(-Inf, Inf) do ω

            -1/pi*sqrt(3)/2*1/(2*pi)^2 * imag(inv(ω - ϵ + im*η))

        end[1]

    end[1]

end

function Sigma2(η)

    function intergrand1(kx,ky)

        ϵ = spinonenergy(kx, ky);

        -1/pi*sqrt(3)/2*1/(2*pi)^2 * quadgk(-Inf, Inf) do ω

            imag(inv(ω - ϵ + im*η))

        end[1]

    end

    int=hcubature((0.0,0.0),(2*pi,4*pi/sqrt(3))) do (kx, ky)

    intergrand1(kx,ky)

    end[1];

    return(int)

end

 

@btime Sigma1(0.001)

  219.100 μs (71 allocations: 29.78 KiB)

1.0000000000000029

@btime Sigma2(0.001)

  213.100 μs (71 allocations: 29.78 KiB)

1.0000000000000027

However, I still cannot understand why integration order influencing radically. Since I have to integrate frequency first then integrate over (kx,ky) in further codes. I guess you already know that this order add huge allocations, do you have some idea to reduce this?


function Sigma4(η)

    function intergrand1(ω)

        -1/pi*sqrt(3)/2*1/(2*pi)^2 * hcubature((0.0,0.0),(2*pi,4*pi/sqrt(3)),rtol=1e-4,atol=1e-4) do (kx, ky)

            imag(inv(ω - spinonenergy(kx, ky) + im*η))

        end[1]

    end

    int=quadgk(-Inf, Inf,rtol=1e-4,atol=1e-4) do ω

        intergrand1(ω)

    end[1]

    return(int)

end

@btime Sigma4(0.001)

  9.222 s (157371111 allocations: 5.71 GiB)

0.999984450612222