Skip to content

Broken inplace integrand for HCubatureJL #169

Description

@lxvm

Hi,
I was writing a quadrature code with inplace integrands and I noticed that Integrals.jl has the same problem I noticed. Depending on how the quadrature library allocates arrays, it is possible that multiple integrand evaluations are made before they are summed together. When the result is overwritten to the same array this means some of the quadrature nodes are overwritten by the values of another. For example, integrating sin(x) on [-1,1] as below should give zero on the initial segment, but the inplace evaluator seems to integrate sin(abs(x)) on that segment.

julia> using Integrals

julia> prob = IntegralProblem((x,p) -> sin(p*x), -1, 1, 3.0)
IntegralProblem. In-place: false


julia> inplaceprob = IntegralProblem((y,x,p) -> y .= sin(p*x), -1.0, 1.0, 3.0)
IntegralProblem. In-place: true


julia> solve(prob, HCubatureJL(), maxiters=15)
u: 0.0

julia> solve(inplaceprob, HCubatureJL(), maxiters=15)
u: 1-element Vector{Float64}:
 1.3044979103237169

The problem is in the definition of the integrand wrapper

dx = zeros(eltype(lb), prob.nout)
f = x -> (prob.f(dx, x, prob.p); dx)

An issue with dx is that it may have the wrong type, since the user's function could return complex values at real nodes, for example. A fix is to allow the user to pass in the output array. The second issue in the example above can be fixed by returning a new array at each integrand evaluation, which can be done by returning one(eltype(lb))*dx. The downside to this last fix is that most of the array operations aren't inplace, but the only way to achieve this is if the library supports them (e.g. see quadgk! in QuadGK.jl for an implementation).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions