I would like to differentiate through a two-dimensional integral.

- seems to be not possible for c++ wrappers (e.g. with the great Cuba.jl)
- Julia native integrators are way slower (HCubature.jl, NIntegration.jl)
- nested QuadGK.jl is also not fast enough.

Therefore, two questions:

- Are there tricks to differentiate
`Cuba`

? - Is there a way to speed up Julia native implementations?

Here is MWE and tests

```
using BenchmarkTools
using HCubature
using NIntegration
using QuadGK
using Cuba
function model(cosĪø,Ļ; pars)
Ī±1 = Ī±2 = pars[1]-1
v = (exp(-Ī±1*(cosĪø+1)) + exp(-Ī±2*(1-cosĪø)))*(1+sin(Ļ))^(1.2)
return abs2(v)
end
#
# using Plots
# plot(cosĪø -> model(cosĪø,Ļ/4; pars = [2.3]), -1, 1)
#
I_quadgk(pars) = quadgk(cosĪø->quadgk(Ļ->model(cosĪø,Ļ;pars=pars),-Ļ,Ļ)[1],-1.0, 1.0)[1]
I_nintegration(pars) = nintegrate((cosĪø,Ļ,z)->model(cosĪø,Ļ;pars=pars), (-1.0, -Ļ, 0.0), (1.0, Ļ, 1.0))[1]
I_hcubature(pars) = hcubature(x->model(x[1],x[2]; pars= pars), [-1.0, -Ļ], [1.0, Ļ])[1]
I_cuba(pars) = cuhre((x,f)->f[1]=model(2x[1]-1, Ļ*(2x[2]-1);pars=pars),2,1).integral[1]*(4Ļ)
#
@btime I_cuba([2.3])
@btime I_quadgk([2.3])
@btime I_hcubature([2.3])
@btime I_nintegration([2.3])
```

Results are:

```
1) Cuba: 72.500 Ī¼s (1305 allocations: 61.28 KiB)
2) 2x QuadGK: 160.800 Ī¼s (827 allocations: 19.44 KiB)
3) NIntegration: 303.800 Ī¼s (209 allocations: 9.91 KiB)
4) HCubature: 2.215 ms (23787 allocations: 850.86 KiB)
```

I found it quite surprising with respect to the number of github stars on the packages

EDIT: replaced parameters to a vector.