# Failure of Zygote.jl on function with integration by HCubature.jl

**URL:** https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856
**Category:** General Usage
**Tags:** question, package, autodiff
**Created:** [October 11, 2023, 2:02pm UTC](https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856 "2023-10-11T14:02:30Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![swish47](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swish47/32/43921_2.png) [@swish47](https://discourse.julialang.org/u/swish47)
#### Post date: [October 11, 2023, 2:02pm UTC](https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856/1 "2023-10-11T14:02:30Z")

</div>

I need to perform automatic differentiation on a function constructed by numerical integration. I choose `HCubature.jl` on integral and `Zygote.jl` on AD. However, there is an error as following:

```julia
using HCubature,Zygote

const kb::Float64=1;

const tem::Float64=1/9600;

nf(e,tem)=inv(expm1(e/(kb*tem))+2.0)

spinonenergy(kx,ky,h,mu)=(-2*(cos(kx)+cos(ky)))-h-mu

SD_spinon(omega,kx,ky,h,mu)=
-1/pi*imag(inv(omega+1e-2*im-spinonenergy(kx,ky,h,mu)))

function GSE(mu,h)
        integrand_spinon(omega,kx,ky)=
        omega*SD_spinon(omega,kx,ky,h,mu)*nf(omega,tem)

        int_spinon=hcubature(x->integrand_spinon(x[1],x[2],x[3]), (-5,-pi,-pi), (5,pi,pi),maxevals=Int(2e+7),rtol=1e-4, atol=1e-4)[1]

        return 1/(2*pi)^2*(int_spinon)
end

let
energy(x) = GSE(-0.5,x[1])

Zygote.gradient(energy,[1.0])[1]

end

ArgumentError: new: too few arguments (expected 1)

```

What cause this error and how could I fix it?

---

<div class="post-metadata">

### Author: ![swish47](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swish47/32/43921_2.png) [@swish47](https://discourse.julialang.org/u/swish47)
#### Post date: [October 11, 2023, 2:31pm UTC](https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856/2 "2023-10-11T14:31:02Z")

</div>

If I turn to use `Cubature`, the error would become to

```julia
using Cubature, Zygote
#Everything is the same as above mentioned
let
energy(x) = GSE(-0.5,x)

Zygote.gradient(energy,1.0)[1]

end
Compiling Tuple{typeof(Cubature.integrands), Cubature.IntegrandData{var"#3#5"{var"#integrand_spinon#4"{Float64, Float64}}}, Bool, Bool, Bool}: UndefVarError: `spvals` not defined

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [October 11, 2023, 5:09pm UTC](https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856/3 "2023-10-11T17:09:59Z")

</div>

> [@swish47](#):
>
> I need to perform automatic differentiation on a function constructed by numerical integration. I choose `HCubature.jl` on integral and `Zygote.jl` on AD.

For this sort of thing, I would recommend using HCubature via [Integrals.jl](https://github.com/SciML/Integrals.jl), which provides a wrapper that has AD chain rules written for it, so that Zygote does not try to differentiate through it “manually”.

---

<div class="post-metadata">

### Author: ![swish47](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swish47/32/43921_2.png) [@swish47](https://discourse.julialang.org/u/swish47)
#### Post date: [October 11, 2023, 5:36pm UTC](https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856/4 "2023-10-11T17:36:09Z")

</div>

Thx for your reply.  
I rewrite the function with integration into `Integrals.jl`, however there is still a problem in `Zygote.jl`

```julia
using Integrals,Zygote
function GSE(mu,h)
    integrand_spinon(u,p)=
    u[1]*SD_spinon(u[1],u[2],u[3],h,mu)*nf(u[1],tem)

    int_spinon = IntegralProblem(integrand_spinon, (-5.0,-pi*1,-pi*1), (5.0,pi*1,pi*1))
    
    sol_spinon = solve(int_spinon, HCubatureJL(); reltol = 1e-3, abstol = 1e-3)
    
    return 1/(2*pi)^2*(sol_spinon.u)
end

let
energy(x) = GSE(-0.5,x)

Zygote.gradient(energy,1.0)[1]

end
MethodError: no method matching length(::SciMLBase.NullParameters)
An arithmetic operation was performed on a NullParameters object. This means no parameters were passed
into the AbstractSciMLProblem (e.x.: ODEProblem) but the parameters object `p` was used in an arithmetic
expression. Two common reasons for this issue are:

1. Forgetting to pass parameters into the problem constructor. For example, `ODEProblem(f,u0,tspan)` should
be `ODEProblem(f,u0,tspan,p)` in order to use parameters.

2. Using the wrong function signature. For example, with `ODEProblem`s the function signature is always
`f(du,u,p,t)` for the in-place form or `f(u,p,t)` for the out-of-place form. Note that the `p` argument
will always be in the function signature reguardless of if the problem is defined with parameters!

```

---

<div class="post-metadata">

### Author: ![swish47](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swish47/32/43921_2.png) [@swish47](https://discourse.julialang.org/u/swish47)
#### Post date: [October 11, 2023, 5:46pm UTC](https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856/5 "2023-10-11T17:46:02Z")

</div>

BTW, functions by `Integrals.jl` support `ForwardDiff.jl` and the results are correct. Actually, my final goal is minimize the function `GSE` through `Optim.jl` with some derivative dependent algorithms, but only errors I received.

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [October 11, 2023, 8:58pm UTC](https://discourse.julialang.org/t/failure-of-zygote-jl-on-function-with-integration-by-hcubature-jl/104856/6 "2023-10-11T20:58:11Z")

</div>

I think you might have some errors in the way parameters are handled (see [this tutorial](https://docs.sciml.ai/Integrals/stable/tutorials/differentiating_integrals/)). The following should work but I’m missing some functions so I can’t test:

```julia
using Integrals, Zygote

function integrand_spinon(u, p)
    mu, h = p[1], p[2]
    return u[1]*SD_spinon(u[1],u[2],u[3],h,mu)*nf(u[1],tem)
end

function GSE(mu, h)
    lb = (-5.0,-pi*1,-pi*1)
    ub = (5.0,pi*1,pi*1)
    p = [mu, h]
    int_spinon = IntegralProblem(integrand_spinon, lb, ub, p)
    sol_spinon = solve(int_spinon, HCubatureJL(); reltol = 1e-3, abstol = 1e-3)
    return 1/(2*pi)^2*(sol_spinon.u)
end

energy(x) = GSE(-0.5, x)
Zygote.gradient(energy, 1.0)[1]

```

However the tutorial says Zygote is broken, not sure what’s going on there
