Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Gauss-Turán quadrature implementation #254

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions ext/IntegralsGaussTuran.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module IntegralsGaussTuran
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
module IntegralsGaussTuran
module IntegralsGaussTuranExt

This file should be renamed to IntegralsGaussTuranExt.jl and the Project.toml file is missing a line IntegralsGaussTuranExt = "ForwardDiff" in the [extensions] section


using ForwardDiff
using Integrals
# Defining the GaussTuran struct
struct GaussTuran{B} <: SciMLBase.AbstractIntegralAlgorithm
n::Int # number of points
s::Int # order of derivative
ad_backend::B # for now ForwardDiff
end
Comment on lines +6 to +10
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct can be deleted since it is already defined in Integrals.jl


const xgt51 = [0.171573532582957e-02,
0.516674690067835e-01,
0.256596242621252e+00,
0.614259881077552e+00,
0.929575800557533e+00]

const agt51 = [(0.121637123277610E-01, 0.283102654629310E-04, 0.214239866660517E-07),
(0.114788544658756E+00, 0.141096832290629E-02, 0.357587075122775E-04),
(0.296358604286158E+00, 0.391442503354071E-02, 0.677935112926019E-03),
(0.373459975331693E+00, -0.111299945126195E-02, 0.139576858045244E-02),
(0.203229163395632E+00, -0.455530407798230E-02, 0.226019273068948E-03)]

# Gauss-Turán quadrature (gt51) function
function gt51(f, a, b)
res = zero(eltype(f(a))) # Initializing result

# Transformation factor
factor = b - a

for i in 1:5
# Map the nodes to the interval [a, b]
xi = xgt51[i] * factor + a

# Compute function value and derivatives at xi using ForwardDiff
fi = f(xi)
dfi = ForwardDiff.derivative(f, xi) * factor
d2fi = ForwardDiff.derivative(x -> ForwardDiff.derivative(f, x), xi) * factor^2

# Get the weights
Ai1, Ai2, Ai3 = agt51[i]

# Accumulate the result
res += Ai1 * fi + Ai2 * dfi + Ai3 * d2fi
end

return res * factor
end

# Integrals.__solvebp_call for GaussTuran
function Integrals.__solvebp_call(prob::IntegralProblem,
alg::GaussTuran,
sensealg, domain, p;
reltol=nothing, abstol=nothing,
maxiters=nothing)
integrand = prob.f
a, b = domain
return gt51((x) -> integrand(x, p), a, b)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should return a SciMLBase.jl solution, such as SciMLBase.build_solution(prob, alg, val, nothing, retcode = ReturnCode.Success)

end

end # module
10 changes: 10 additions & 0 deletions src/algorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,13 @@ struct QuadratureRule{Q} <: SciMLBase.AbstractIntegralAlgorithm
end
end
QuadratureRule(q; n = 250) = QuadratureRule(q, n)


"""
Gauss Turan Quadrature using xgt51 and agt51
"""
struct GaussTuran{B} <: SciMLBase.AbstractIntegralAlgorithm
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export GaussTuran is missing from src/Integrals.jl

n::Int # number of points
s::Int # order of derivative
ad_backend::B # for now ForwardDiff
end
13 changes: 13 additions & 0 deletions test/gaussturan_tests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Test
using ForwardDiff
using Integrals

a, b = 0.0, π

result = solve(IntegralProblem((x, p) -> sin(x), (0, π)), GaussTuran(5, 2, ForwardDiff))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result = solve(IntegralProblem((x, p) -> sin(x), (0, π)), GaussTuran(5, 2, ForwardDiff))
result = solve(IntegralProblem((x, p) -> sin(x), (0, π)), GaussTuran(5, 2, ForwardDiff)).u


expected_result = 2.0

@test isapprox(result, expected_result, atol=1e-6)

println("Test passed, result of integration: ", result)