Error taking derivative of QuadratureProblem() with NullParameters()


I am trying to use Quadrature.jl to calculate the expected values of some random variables (code pasted below). This function works fine and it gives me the values I would expected; however, when I try and take the derivative of this function with Zygote (a supported feature per the docs) I get an error:

MethodError: no method matching length(::SciMLBase.NullParameters)

I can paste more of the stack trace in if necessary but this only comes up when trying to take the derivative of my function. I think this has something to do with me not passing parameters to the QuadratureProblem() but I don’t know if I’m doing something wrong or if the library is.

The result should be 0.5 for all temperatures and I have verified this by evaluating the function at two temperatures and calculating the central difference.

using Quadrature

function expected_value_U(T::Float64, U::Function)

    numerator_integrand(x,p) = U(x)*exp(-U(x)/T)
    denominator_integrand(x,p) = exp(-U(x)/T)

    numerator = QuadratureProblem(numerator_integrand, -Inf, Inf)
    numerator_val = solve(numerator,QuadGKJL(),reltol=1e-7,abstol=1e-7)

    denominator = QuadratureProblem(denominator_integrand, -Inf, Inf)
    denominator_val = solve(denominator,QuadGKJL(),reltol=1e-7,abstol=1e-7)

    return numerator_val[1]/denominator_val[1]


function U_harmonic(x)
    return 2.0*x + 40.0*(x^2)

temp = 2.0
Cv_harmonic = Zygote.gradient( (T) -> expected_value_U(T, U_harmonic), temp)

Quadrature.jl is deprecated and was replaced with Integrals.jl. The documentation of the packagte is here:

The tutorial on this is a bit light:

but it’s all there (we are improving these docs this month).

Indeed, there are no parameters, so there are no parameters to take the derivative of. You should use the parameters.

using Integrals

function expected_value_U(T::Float64, U::Function)

    numerator_integrand(x,p) = U(x)*exp(-U(x)/p[1])
    denominator_integrand(x,p) = exp(-U(x)/p[1])

    numerator = IntegralProblem(numerator_integrand, -Inf, Inf, [T])
    numerator_val = solve(numerator,QuadGKJL(),reltol=1e-7,abstol=1e-7)

    denominator = IntegralProblem(denominator_integrand, -Inf, Inf, [T])
    denominator_val = solve(denominator,QuadGKJL(),reltol=1e-7,abstol=1e-7)

    return numerator_val[1]/denominator_val[1]

should work (I didn’t check)

1 Like

ah thank you, I thought it would just take the derivative w.r.t what I passed into .gradient() I guess it makes sense that you’d have to tell the QuadratureProblem that as well.

also it worked