From 96c3edd151fe85cf85f2cdf55bfa02491698a016 Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Thu, 15 Feb 2024 20:21:37 -0500
Subject: [PATCH 1/9] add useful error for unloaded extensions

---
 src/Integrals.jl | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/Integrals.jl b/src/Integrals.jl
index d717251..076df7f 100644
--- a/src/Integrals.jl
+++ b/src/Integrals.jl
@@ -64,6 +64,22 @@ end
 # Give a layer to intercept with AD
 __solvebp(args...; kwargs...) = __solvebp_call(args...; kwargs...)
 
+function __solvebp_call(prob::IntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm, args...; kws...)
+    if alg isa AbstractCubatureJLAlgorithm
+        error("algorithm $(nameof(typeof(alg))) requires `using Cubature`")
+    elseif alg isa AbstractCubaAlgorithm
+        error("algorithm $(nameof(typeof(alg))) requires `using Cuba`")
+    elseif alg isa VEGASMC
+        error("algorithm $(nameof(typeof(alg))) requires `using MCIntegration`")
+    elseif alg isa GaussLegendre
+        error("algorithm $(nameof(typeof(alg))) requires `using FastGaussQuadrature`")
+    elseif alg isa ArblibJL
+        error("algorithm $(nameof(typeof(alg))) requires `using Arblib`")
+    else
+        throw(MethodError(__solvebp_call, (prob, alg, args...)))
+    end
+end
+
 function quadgk_prob_types(f, lb::T, ub::T, p, nrm) where {T}
     DT = float(T)   # we need to be careful to infer the same result as `evalrule`
     RT = Base.promote_op(*, DT, Base.promote_op(f, DT, typeof(p)))    # kernel

From 685f621daea3803f052c2c1a8e6e8953f3881634 Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Thu, 15 Feb 2024 20:22:03 -0500
Subject: [PATCH 2/9] add stated Cubature norm defaults

---
 src/algorithms.jl | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/algorithms.jl b/src/algorithms.jl
index 5a7b75a..7205b28 100644
--- a/src/algorithms.jl
+++ b/src/algorithms.jl
@@ -330,7 +330,7 @@ CubaCuhre(; flags = 0, minevals = 0, key = 0) = CubaCuhre(flags, minevals, key)
 
 abstract type AbstractCubatureJLAlgorithm <: SciMLBase.AbstractIntegralAlgorithm end
 """
-    CubatureJLh()
+    CubatureJLh(; norm=Cubature.INDIVIDUAL)
 
 Multidimensional h-adaptive integration from Cubature.jl.
 `error_norm` specifies the convergence criterion  for vector valued integrands.
@@ -353,9 +353,10 @@ publisher={Elsevier}
 struct CubatureJLh <: AbstractCubatureJLAlgorithm
     error_norm::Int32
 end
+CubatureJLh(; norm=0) = CubatureJLh(norm)
 
 """
-    CubatureJLp()
+    CubatureJLp(; norm=Cubature.INDIVIDUAL)
 
 Multidimensional p-adaptive integration from Cubature.jl.
 This method is based on repeatedly doubling the degree of the cubature rules,
@@ -368,6 +369,8 @@ Defaults to `Cubature.INDIVIDUAL`, other options are
 struct CubatureJLp <: AbstractCubatureJLAlgorithm
     error_norm::Int32
 end
+CubatureJLp(; norm=0) = CubatureJLp(norm)
+
 
 
 """

From 89c2247de7abd6d1e2558532e9bccf4e60c739bd Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Sat, 17 Feb 2024 12:11:56 -0500
Subject: [PATCH 3/9] put sampled algorithms in separate file

---
 src/algorithms.jl         | 44 ---------------------------------------
 src/algorithms_sampled.jl | 43 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 44 deletions(-)
 create mode 100644 src/algorithms_sampled.jl

diff --git a/src/algorithms.jl b/src/algorithms.jl
index 7205b28..ace7fe3 100644
--- a/src/algorithms.jl
+++ b/src/algorithms.jl
@@ -127,50 +127,6 @@ function GaussLegendre(; n = 250, subintervals = 1, nodes = nothing, weights = n
     return GaussLegendre(nodes, weights, subintervals)
 end
 
-"""
-    TrapezoidalRule
-
-Struct for evaluating an integral via the trapezoidal rule.
-
-
-Example with sampled data:
-
-```
-using Integrals
-f = x -> x^2
-x = range(0, 1, length=20)
-y = f.(x)
-problem = SampledIntegralProblem(y, x)
-method = TrapezoidalRule()
-solve(problem, method)
-```
-"""
-struct TrapezoidalRule <: SciMLBase.AbstractIntegralAlgorithm
-end
-
-"""
-    SimpsonsRule
-
-Struct for evaluating an integral via the Simpson's composite 1/3-3/8
-rule over `AbstractRange`s (evenly spaced points) and 
-Simpson's composite 1/3 rule for non-equidistant grids.
-
-
-Example with equidistant data:
-
-```
-using Integrals 
-f = x -> x^2
-x = range(0, 1, length=20)
-y = f.(x)
-problem = SampledIntegralProblem(y, x)
-method = SimpsonsRule()
-solve(problem, method)
-```
-"""
-struct SimpsonsRule <: SciMLBase.AbstractIntegralAlgorithm
-end
-
 
 """
   QuadratureRule(q; n=250)
diff --git a/src/algorithms_sampled.jl b/src/algorithms_sampled.jl
new file mode 100644
index 0000000..6cd5dd5
--- /dev/null
+++ b/src/algorithms_sampled.jl
@@ -0,0 +1,43 @@
+abstract type AbstractSampledIntegralAlgorithm <: SciMLBase.AbstractIntegralAlgorithm end
+
+"""
+    TrapezoidalRule
+
+Struct for evaluating an integral via the trapezoidal rule.
+
+
+Example with sampled data:
+
+```
+using Integrals
+f = x -> x^2
+x = range(0, 1, length=20)
+y = f.(x)
+problem = SampledIntegralProblem(y, x)
+method = TrapezoidalRule()
+solve(problem, method)
+```
+"""
+struct TrapezoidalRule <: AbstractSampledIntegralAlgorithm end
+
+"""
+    SimpsonsRule
+
+Struct for evaluating an integral via the Simpson's composite 1/3-3/8
+rule over `AbstractRange`s (evenly spaced points) and
+Simpson's composite 1/3 rule for non-equidistant grids.
+
+
+Example with equidistant data:
+
+```
+using Integrals
+f = x -> x^2
+x = range(0, 1, length=20)
+y = f.(x)
+problem = SampledIntegralProblem(y, x)
+method = SimpsonsRule()
+solve(problem, method)
+```
+"""
+struct SimpsonsRule <: AbstractSampledIntegralAlgorithm end

From b6578aa49910bae166f23434625719849862d0df Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Sat, 17 Feb 2024 12:14:10 -0500
Subject: [PATCH 4/9] move extension algorithms to new file

---
 src/algorithms.jl           | 220 -----------------------------------
 src/algorithms_extension.jl | 221 ++++++++++++++++++++++++++++++++++++
 2 files changed, 221 insertions(+), 220 deletions(-)
 create mode 100644 src/algorithms_extension.jl

diff --git a/src/algorithms.jl b/src/algorithms.jl
index ace7fe3..9f1bef7 100644
--- a/src/algorithms.jl
+++ b/src/algorithms.jl
@@ -148,223 +148,3 @@ struct QuadratureRule{Q} <: SciMLBase.AbstractIntegralAlgorithm
     end
 end
 QuadratureRule(q; n = 250) = QuadratureRule(q, n)
-
-## Extension Algorithms
-
-abstract type AbstractCubaAlgorithm <: SciMLBase.AbstractIntegralAlgorithm end
-"""
-    CubaVegas()
-
-Multidimensional adaptive Monte Carlo integration from Cuba.jl.
-Importance sampling is used to reduce variance.
-
-## References
-
-@article{lepage1978new,
-title={A new algorithm for adaptive multidimensional integration},
-author={Lepage, G Peter},
-journal={Journal of Computational Physics},
-volume={27},
-number={2},
-pages={192--203},
-year={1978},
-publisher={Elsevier}
-}
-"""
-struct CubaVegas <: AbstractCubaAlgorithm
-    flags::Int
-    seed::Int
-    minevals::Int
-    nstart::Int
-    nincrease::Int
-    gridno::Int
-end
-"""
-    CubaSUAVE()
-
-Multidimensional adaptive Monte Carlo integration from Cuba.jl.
-Suave stands for subregion-adaptive VEGAS.
-Importance sampling and subdivision are thus used to reduce variance.
-
-## References
-
-@article{hahn2005cuba,
-title={Cuba—a library for multidimensional numerical integration},
-author={Hahn, Thomas},
-journal={Computer Physics Communications},
-volume={168},
-number={2},
-pages={78--95},
-year={2005},
-publisher={Elsevier}
-}
-"""
-struct CubaSUAVE{R} <: AbstractCubaAlgorithm where {R <: Real}
-    flags::Int
-    seed::Int
-    minevals::Int
-    nnew::Int
-    nmin::Int
-    flatness::R
-end
-"""
-    CubaDivonne()
-
-Multidimensional adaptive Monte Carlo integration from Cuba.jl.
-Stratified sampling is used to reduce variance.
-
-## References
-
-@article{friedman1981nested,
-title={A nested partitioning procedure for numerical multiple integration},
-author={Friedman, Jerome H and Wright, Margaret H},
-journal={ACM Transactions on Mathematical Software (TOMS)},
-volume={7},
-number={1},
-pages={76--92},
-year={1981},
-publisher={ACM New York, NY, USA}
-}
-"""
-struct CubaDivonne{R1, R2, R3, R4} <:
-       AbstractCubaAlgorithm where {R1 <: Real, R2 <: Real, R3 <: Real, R4 <: Real}
-    flags::Int
-    seed::Int
-    minevals::Int
-    key1::Int
-    key2::Int
-    key3::Int
-    maxpass::Int
-    border::R1
-    maxchisq::R2
-    mindeviation::R3
-    xgiven::Matrix{R4}
-    nextra::Int
-    peakfinder::Ptr{Cvoid}
-end
-"""
-    CubaCuhre()
-
-Multidimensional h-adaptive integration from Cuba.jl.
-
-## References
-
-@article{berntsen1991adaptive,
-title={An adaptive algorithm for the approximate calculation of multiple integrals},
-author={Berntsen, Jarle and Espelid, Terje O and Genz, Alan},
-journal={ACM Transactions on Mathematical Software (TOMS)},
-volume={17},
-number={4},
-pages={437--451},
-year={1991},
-publisher={ACM New York, NY, USA}
-}
-"""
-struct CubaCuhre <: AbstractCubaAlgorithm
-    flags::Int
-    minevals::Int
-    key::Int
-end
-
-function CubaVegas(; flags = 0, seed = 0, minevals = 0, nstart = 1000, nincrease = 500,
-        gridno = 0)
-    CubaVegas(flags, seed, minevals, nstart, nincrease, gridno)
-end
-function CubaSUAVE(; flags = 0, seed = 0, minevals = 0, nnew = 1000, nmin = 2,
-        flatness = 25.0)
-    CubaSUAVE(flags, seed, minevals, nnew, nmin, flatness)
-end
-function CubaDivonne(; flags = 0, seed = 0, minevals = 0,
-        key1 = 47, key2 = 1, key3 = 1, maxpass = 5, border = 0.0,
-        maxchisq = 10.0, mindeviation = 0.25,
-        xgiven = zeros(Cdouble, 0, 0),
-        nextra = 0, peakfinder = C_NULL)
-    CubaDivonne(flags, seed, minevals, key1, key2, key3, maxpass, border, maxchisq,
-        mindeviation, xgiven, nextra, peakfinder)
-end
-CubaCuhre(; flags = 0, minevals = 0, key = 0) = CubaCuhre(flags, minevals, key)
-
-abstract type AbstractCubatureJLAlgorithm <: SciMLBase.AbstractIntegralAlgorithm end
-"""
-    CubatureJLh(; norm=Cubature.INDIVIDUAL)
-
-Multidimensional h-adaptive integration from Cubature.jl.
-`error_norm` specifies the convergence criterion  for vector valued integrands.
-Defaults to `Cubature.INDIVIDUAL`, other options are
-`Cubature.PAIRED`, `Cubature.L1`, `Cubature.L2`, or `Cubature.LINF`.
-
-## References
-
-@article{genz1980remarks,
-title={Remarks on algorithm 006: An adaptive algorithm for numerical integration over an N-dimensional rectangular region},
-author={Genz, Alan C and Malik, Aftab Ahmad},
-journal={Journal of Computational and Applied mathematics},
-volume={6},
-number={4},
-pages={295--302},
-year={1980},
-publisher={Elsevier}
-}
-"""
-struct CubatureJLh <: AbstractCubatureJLAlgorithm
-    error_norm::Int32
-end
-CubatureJLh(; norm=0) = CubatureJLh(norm)
-
-"""
-    CubatureJLp(; norm=Cubature.INDIVIDUAL)
-
-Multidimensional p-adaptive integration from Cubature.jl.
-This method is based on repeatedly doubling the degree of the cubature rules,
-until convergence is achieved.
-The used cubature rule is a tensor product of Clenshaw–Curtis quadrature rules.
-`error_norm` specifies the convergence criterion  for vector valued integrands.
-Defaults to `Cubature.INDIVIDUAL`, other options are
-`Cubature.PAIRED`, `Cubature.L1`, `Cubature.L2`, or `Cubature.LINF`.
-"""
-struct CubatureJLp <: AbstractCubatureJLAlgorithm
-    error_norm::Int32
-end
-CubatureJLp(; norm=0) = CubatureJLp(norm)
-
-
-
-"""
-    ArblibJL(; check_analytic=false, take_prec=false, warn_on_no_convergence=false, opts=C_NULL)
-
-One-dimensional adaptive Gauss-Legendre integration using rigorous error bounds and
-precision ball arithmetic. Generally this assumes the integrand is holomorphic or
-meromorphic, which is the user's responsibility to verify. The result of the integral is not
-guaranteed to satisfy the requested tolerances, however the result is guaranteed to be
-within the error estimate.
-
-[Arblib.jl](https://github.com/kalmarek/Arblib.jl) only supports integration of univariate
-real- and complex-valued functions with both inplace and out-of-place forms. See their
-documentation for additional details the algorithm arguments and on implementing
-high-precision integrands. Additionally, the error estimate is included in the return value
-of the integral, representing a ball.
-"""
-struct ArblibJL{O} <: SciMLBase.AbstractIntegralAlgorithm
-    check_analytic::Bool
-    take_prec::Bool
-    warn_on_no_convergence::Bool
-    opts::O
-end
-function ArblibJL(; check_analytic=false, take_prec=false, warn_on_no_convergence=false, opts=C_NULL)
-    return ArblibJL(check_analytic, take_prec, warn_on_no_convergence, opts)
-end
-
-"""
-    VEGASMC(; kws...)
-
-Markov-chain based Vegas algorithm from MCIntegration.jl
-
-Refer to
-[`MCIntegration.integrate`](https://numericaleft.github.io/MCIntegration.jl/dev/lib/montecarlo/#MCIntegration.integrate-Tuple{Function})
-for documentation on the keywords, which are passed directly to the solver with a set of
-defaults that works for conforming integrands.
-"""
-struct VEGASMC{K<:NamedTuple} <: SciMLBase.AbstractIntegralAlgorithm
-    kws::K
-end
-VEGASMC(; kws...) = VEGASMC(NamedTuple(kws))
diff --git a/src/algorithms_extension.jl b/src/algorithms_extension.jl
new file mode 100644
index 0000000..2740dfa
--- /dev/null
+++ b/src/algorithms_extension.jl
@@ -0,0 +1,221 @@
+## Extension Algorithms
+
+abstract type AbstractIntegralExtensionAlgorithm <: SciMLBase.AbstractIntegralAlgorithm end
+
+abstract type AbstractCubaAlgorithm <: AbstractIntegralExtensionAlgorithm end
+"""
+    CubaVegas()
+
+Multidimensional adaptive Monte Carlo integration from Cuba.jl.
+Importance sampling is used to reduce variance.
+
+## References
+
+@article{lepage1978new,
+title={A new algorithm for adaptive multidimensional integration},
+author={Lepage, G Peter},
+journal={Journal of Computational Physics},
+volume={27},
+number={2},
+pages={192--203},
+year={1978},
+publisher={Elsevier}
+}
+"""
+struct CubaVegas <: AbstractCubaAlgorithm
+    flags::Int
+    seed::Int
+    minevals::Int
+    nstart::Int
+    nincrease::Int
+    gridno::Int
+end
+"""
+    CubaSUAVE()
+
+Multidimensional adaptive Monte Carlo integration from Cuba.jl.
+Suave stands for subregion-adaptive VEGAS.
+Importance sampling and subdivision are thus used to reduce variance.
+
+## References
+
+@article{hahn2005cuba,
+title={Cuba—a library for multidimensional numerical integration},
+author={Hahn, Thomas},
+journal={Computer Physics Communications},
+volume={168},
+number={2},
+pages={78--95},
+year={2005},
+publisher={Elsevier}
+}
+"""
+struct CubaSUAVE{R} <: AbstractCubaAlgorithm where {R <: Real}
+    flags::Int
+    seed::Int
+    minevals::Int
+    nnew::Int
+    nmin::Int
+    flatness::R
+end
+"""
+    CubaDivonne()
+
+Multidimensional adaptive Monte Carlo integration from Cuba.jl.
+Stratified sampling is used to reduce variance.
+
+## References
+
+@article{friedman1981nested,
+title={A nested partitioning procedure for numerical multiple integration},
+author={Friedman, Jerome H and Wright, Margaret H},
+journal={ACM Transactions on Mathematical Software (TOMS)},
+volume={7},
+number={1},
+pages={76--92},
+year={1981},
+publisher={ACM New York, NY, USA}
+}
+"""
+struct CubaDivonne{R1, R2, R3, R4} <:
+       AbstractCubaAlgorithm where {R1 <: Real, R2 <: Real, R3 <: Real, R4 <: Real}
+    flags::Int
+    seed::Int
+    minevals::Int
+    key1::Int
+    key2::Int
+    key3::Int
+    maxpass::Int
+    border::R1
+    maxchisq::R2
+    mindeviation::R3
+    xgiven::Matrix{R4}
+    nextra::Int
+    peakfinder::Ptr{Cvoid}
+end
+"""
+    CubaCuhre()
+
+Multidimensional h-adaptive integration from Cuba.jl.
+
+## References
+
+@article{berntsen1991adaptive,
+title={An adaptive algorithm for the approximate calculation of multiple integrals},
+author={Berntsen, Jarle and Espelid, Terje O and Genz, Alan},
+journal={ACM Transactions on Mathematical Software (TOMS)},
+volume={17},
+number={4},
+pages={437--451},
+year={1991},
+publisher={ACM New York, NY, USA}
+}
+"""
+struct CubaCuhre <: AbstractCubaAlgorithm
+    flags::Int
+    minevals::Int
+    key::Int
+end
+
+function CubaVegas(; flags = 0, seed = 0, minevals = 0, nstart = 1000, nincrease = 500,
+        gridno = 0)
+    CubaVegas(flags, seed, minevals, nstart, nincrease, gridno)
+end
+function CubaSUAVE(; flags = 0, seed = 0, minevals = 0, nnew = 1000, nmin = 2,
+        flatness = 25.0)
+    CubaSUAVE(flags, seed, minevals, nnew, nmin, flatness)
+end
+function CubaDivonne(; flags = 0, seed = 0, minevals = 0,
+        key1 = 47, key2 = 1, key3 = 1, maxpass = 5, border = 0.0,
+        maxchisq = 10.0, mindeviation = 0.25,
+        xgiven = zeros(Cdouble, 0, 0),
+        nextra = 0, peakfinder = C_NULL)
+    CubaDivonne(flags, seed, minevals, key1, key2, key3, maxpass, border, maxchisq,
+        mindeviation, xgiven, nextra, peakfinder)
+end
+CubaCuhre(; flags = 0, minevals = 0, key = 0) = CubaCuhre(flags, minevals, key)
+
+abstract type AbstractCubatureJLAlgorithm <: AbstractIntegralExtensionAlgorithm end
+"""
+    CubatureJLh(; norm=Cubature.INDIVIDUAL)
+
+Multidimensional h-adaptive integration from Cubature.jl.
+`error_norm` specifies the convergence criterion  for vector valued integrands.
+Defaults to `Cubature.INDIVIDUAL`, other options are
+`Cubature.PAIRED`, `Cubature.L1`, `Cubature.L2`, or `Cubature.LINF`.
+
+## References
+
+@article{genz1980remarks,
+title={Remarks on algorithm 006: An adaptive algorithm for numerical integration over an N-dimensional rectangular region},
+author={Genz, Alan C and Malik, Aftab Ahmad},
+journal={Journal of Computational and Applied mathematics},
+volume={6},
+number={4},
+pages={295--302},
+year={1980},
+publisher={Elsevier}
+}
+"""
+struct CubatureJLh <: AbstractCubatureJLAlgorithm
+    error_norm::Int32
+end
+CubatureJLh(; norm=0) = CubatureJLh(norm)
+
+"""
+    CubatureJLp(; norm=Cubature.INDIVIDUAL)
+
+Multidimensional p-adaptive integration from Cubature.jl.
+This method is based on repeatedly doubling the degree of the cubature rules,
+until convergence is achieved.
+The used cubature rule is a tensor product of Clenshaw–Curtis quadrature rules.
+`error_norm` specifies the convergence criterion  for vector valued integrands.
+Defaults to `Cubature.INDIVIDUAL`, other options are
+`Cubature.PAIRED`, `Cubature.L1`, `Cubature.L2`, or `Cubature.LINF`.
+"""
+struct CubatureJLp <: AbstractCubatureJLAlgorithm
+    error_norm::Int32
+end
+CubatureJLp(; norm=0) = CubatureJLp(norm)
+
+
+
+"""
+    ArblibJL(; check_analytic=false, take_prec=false, warn_on_no_convergence=false, opts=C_NULL)
+
+One-dimensional adaptive Gauss-Legendre integration using rigorous error bounds and
+precision ball arithmetic. Generally this assumes the integrand is holomorphic or
+meromorphic, which is the user's responsibility to verify. The result of the integral is not
+guaranteed to satisfy the requested tolerances, however the result is guaranteed to be
+within the error estimate.
+
+[Arblib.jl](https://github.com/kalmarek/Arblib.jl) only supports integration of univariate
+real- and complex-valued functions with both inplace and out-of-place forms. See their
+documentation for additional details the algorithm arguments and on implementing
+high-precision integrands. Additionally, the error estimate is included in the return value
+of the integral, representing a ball.
+"""
+struct ArblibJL{O} <: AbstractIntegralExtensionAlgorithm
+    check_analytic::Bool
+    take_prec::Bool
+    warn_on_no_convergence::Bool
+    opts::O
+end
+function ArblibJL(; check_analytic=false, take_prec=false, warn_on_no_convergence=false, opts=C_NULL)
+    return ArblibJL(check_analytic, take_prec, warn_on_no_convergence, opts)
+end
+
+"""
+    VEGASMC(; kws...)
+
+Markov-chain based Vegas algorithm from MCIntegration.jl
+
+Refer to
+[`MCIntegration.integrate`](https://numericaleft.github.io/MCIntegration.jl/dev/lib/montecarlo/#MCIntegration.integrate-Tuple{Function})
+for documentation on the keywords, which are passed directly to the solver with a set of
+defaults that works for conforming integrands.
+"""
+struct VEGASMC{K<:NamedTuple} <: AbstractIntegralExtensionAlgorithm
+    kws::K
+end
+VEGASMC(; kws...) = VEGASMC(NamedTuple(kws))

From d3ba020b24145329130220bb269f3e89762596f6 Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Sat, 17 Feb 2024 12:14:30 -0500
Subject: [PATCH 5/9] remove errors  at solve time

---
 src/Integrals.jl | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/src/Integrals.jl b/src/Integrals.jl
index 076df7f..baa01ea 100644
--- a/src/Integrals.jl
+++ b/src/Integrals.jl
@@ -64,21 +64,6 @@ end
 # Give a layer to intercept with AD
 __solvebp(args...; kwargs...) = __solvebp_call(args...; kwargs...)
 
-function __solvebp_call(prob::IntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm, args...; kws...)
-    if alg isa AbstractCubatureJLAlgorithm
-        error("algorithm $(nameof(typeof(alg))) requires `using Cubature`")
-    elseif alg isa AbstractCubaAlgorithm
-        error("algorithm $(nameof(typeof(alg))) requires `using Cuba`")
-    elseif alg isa VEGASMC
-        error("algorithm $(nameof(typeof(alg))) requires `using MCIntegration`")
-    elseif alg isa GaussLegendre
-        error("algorithm $(nameof(typeof(alg))) requires `using FastGaussQuadrature`")
-    elseif alg isa ArblibJL
-        error("algorithm $(nameof(typeof(alg))) requires `using Arblib`")
-    else
-        throw(MethodError(__solvebp_call, (prob, alg, args...)))
-    end
-end
 
 function quadgk_prob_types(f, lb::T, ub::T, p, nrm) where {T}
     DT = float(T)   # we need to be careful to infer the same result as `evalrule`

From 43aa0ecf59db301e40721d14a3f335215d799d42 Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Sat, 17 Feb 2024 21:17:52 -0500
Subject: [PATCH 6/9] include new files

---
 src/Integrals.jl | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/Integrals.jl b/src/Integrals.jl
index baa01ea..ca58af1 100644
--- a/src/Integrals.jl
+++ b/src/Integrals.jl
@@ -10,6 +10,8 @@ using LinearAlgebra
 
 include("common.jl")
 include("algorithms.jl")
+include("algorithms_sampled.jl")
+include("algorithms_extension.jl")
 include("infinity_handling.jl")
 include("quadrules.jl")
 include("sampled.jl")

From 67d2d82fa133a2db75e38423cefa5f604a78b5b0 Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Sat, 17 Feb 2024 21:28:17 -0500
Subject: [PATCH 7/9] add error messages for unloaded extensions in constructor

---
 src/algorithms_extension.jl | 38 ++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/algorithms_extension.jl b/src/algorithms_extension.jl
index 2740dfa..f25f30d 100644
--- a/src/algorithms_extension.jl
+++ b/src/algorithms_extension.jl
@@ -3,6 +3,7 @@
 abstract type AbstractIntegralExtensionAlgorithm <: SciMLBase.AbstractIntegralAlgorithm end
 
 abstract type AbstractCubaAlgorithm <: AbstractIntegralExtensionAlgorithm end
+
 """
     CubaVegas()
 
@@ -30,6 +31,7 @@ struct CubaVegas <: AbstractCubaAlgorithm
     nincrease::Int
     gridno::Int
 end
+
 """
     CubaSUAVE()
 
@@ -58,6 +60,7 @@ struct CubaSUAVE{R} <: AbstractCubaAlgorithm where {R <: Real}
     nmin::Int
     flatness::R
 end
+
 """
     CubaDivonne()
 
@@ -93,6 +96,7 @@ struct CubaDivonne{R1, R2, R3, R4} <:
     nextra::Int
     peakfinder::Ptr{Cvoid}
 end
+
 """
     CubaCuhre()
 
@@ -119,23 +123,33 @@ end
 
 function CubaVegas(; flags = 0, seed = 0, minevals = 0, nstart = 1000, nincrease = 500,
         gridno = 0)
-    CubaVegas(flags, seed, minevals, nstart, nincrease, gridno)
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsCubaExt)) && error("CubaVegas requires `using Cuba`")
+    return CubaVegas(flags, seed, minevals, nstart, nincrease, gridno)
 end
+
 function CubaSUAVE(; flags = 0, seed = 0, minevals = 0, nnew = 1000, nmin = 2,
         flatness = 25.0)
-    CubaSUAVE(flags, seed, minevals, nnew, nmin, flatness)
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsCubaExt)) && error("CubaSUAVE requires `using Cuba`")
+    return CubaSUAVE(flags, seed, minevals, nnew, nmin, flatness)
 end
+
 function CubaDivonne(; flags = 0, seed = 0, minevals = 0,
         key1 = 47, key2 = 1, key3 = 1, maxpass = 5, border = 0.0,
         maxchisq = 10.0, mindeviation = 0.25,
         xgiven = zeros(Cdouble, 0, 0),
         nextra = 0, peakfinder = C_NULL)
-    CubaDivonne(flags, seed, minevals, key1, key2, key3, maxpass, border, maxchisq,
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsCubaExt)) && error("CubaDivonne requires `using Cuba`")
+    return CubaDivonne(flags, seed, minevals, key1, key2, key3, maxpass, border, maxchisq,
         mindeviation, xgiven, nextra, peakfinder)
 end
-CubaCuhre(; flags = 0, minevals = 0, key = 0) = CubaCuhre(flags, minevals, key)
+
+function CubaCuhre(; flags = 0, minevals = 0, key = 0)
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsCubaExt)) && error("CubaCuhre requires `using Cuba`")
+    return CubaCuhre(flags, minevals, key)
+end
 
 abstract type AbstractCubatureJLAlgorithm <: AbstractIntegralExtensionAlgorithm end
+
 """
     CubatureJLh(; norm=Cubature.INDIVIDUAL)
 
@@ -160,7 +174,10 @@ publisher={Elsevier}
 struct CubatureJLh <: AbstractCubatureJLAlgorithm
     error_norm::Int32
 end
-CubatureJLh(; norm=0) = CubatureJLh(norm)
+function CubatureJLh(; norm=0)
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsCubatureExt)) && error("CubatureJLh requires `using Cubature`")
+    return CubatureJLh(norm)
+end
 
 """
     CubatureJLp(; norm=Cubature.INDIVIDUAL)
@@ -176,7 +193,10 @@ Defaults to `Cubature.INDIVIDUAL`, other options are
 struct CubatureJLp <: AbstractCubatureJLAlgorithm
     error_norm::Int32
 end
-CubatureJLp(; norm=0) = CubatureJLp(norm)
+function CubatureJLp(; norm=0)
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsCubatureExt)) && error("CubatureJLp requires `using Cubature`")
+    return CubatureJLp(norm)
+end
 
 
 
@@ -202,6 +222,7 @@ struct ArblibJL{O} <: AbstractIntegralExtensionAlgorithm
     opts::O
 end
 function ArblibJL(; check_analytic=false, take_prec=false, warn_on_no_convergence=false, opts=C_NULL)
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsArblibExt)) && error("ArblibJL requires `using Arblib`")
     return ArblibJL(check_analytic, take_prec, warn_on_no_convergence, opts)
 end
 
@@ -218,4 +239,7 @@ defaults that works for conforming integrands.
 struct VEGASMC{K<:NamedTuple} <: AbstractIntegralExtensionAlgorithm
     kws::K
 end
-VEGASMC(; kws...) = VEGASMC(NamedTuple(kws))
+function VEGASMC(; kws...)
+    isnothing(Base.get_extension(@__MODULE__, :IntegralsMCIntegrationExt)) && error("VEGASMC requires `using MCIntegration`")
+    return VEGASMC(NamedTuple(kws))
+end

From 96cb1f0f5a2c91ab6103149b06346243047f5f66 Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Sat, 17 Feb 2024 21:28:38 -0500
Subject: [PATCH 8/9] remove error message

---
 ext/IntegralsCubatureExt.jl | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/ext/IntegralsCubatureExt.jl b/ext/IntegralsCubatureExt.jl
index 5bb68d7..9033291 100644
--- a/ext/IntegralsCubatureExt.jl
+++ b/ext/IntegralsCubatureExt.jl
@@ -2,13 +2,7 @@ module IntegralsCubatureExt
 
 using Integrals, Cubature
 
-import Integrals: transformation_if_inf,
-    scale_x, scale_x!, CubatureJLh, CubatureJLp,
-    AbstractCubatureJLAlgorithm
-import Cubature: INDIVIDUAL, PAIRED, L1, L2, LINF
-
-Integrals.CubatureJLh(; error_norm = Cubature.INDIVIDUAL) = CubatureJLh(error_norm)
-Integrals.CubatureJLp(; error_norm = Cubature.INDIVIDUAL) = CubatureJLp(error_norm)
+using Integrals: scale_x, scale_x!, CubatureJLh, CubatureJLp, AbstractCubatureJLAlgorithm
 
 function Integrals.__solvebp_call(prob::IntegralProblem,
         alg::AbstractCubatureJLAlgorithm,

From 4b0a887eaeca9fbed1d98348d284a21b169dbcec Mon Sep 17 00:00:00 2001
From: lxvm <lorenzo@vanmunoz.com>
Date: Sat, 17 Feb 2024 21:38:49 -0500
Subject: [PATCH 9/9] restore error_norm keyword for Cubature algs

---
 src/algorithms_extension.jl | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/algorithms_extension.jl b/src/algorithms_extension.jl
index f25f30d..b79eaa8 100644
--- a/src/algorithms_extension.jl
+++ b/src/algorithms_extension.jl
@@ -151,7 +151,7 @@ end
 abstract type AbstractCubatureJLAlgorithm <: AbstractIntegralExtensionAlgorithm end
 
 """
-    CubatureJLh(; norm=Cubature.INDIVIDUAL)
+    CubatureJLh(; error_norm=Cubature.INDIVIDUAL)
 
 Multidimensional h-adaptive integration from Cubature.jl.
 `error_norm` specifies the convergence criterion  for vector valued integrands.
@@ -174,13 +174,13 @@ publisher={Elsevier}
 struct CubatureJLh <: AbstractCubatureJLAlgorithm
     error_norm::Int32
 end
-function CubatureJLh(; norm=0)
+function CubatureJLh(; error_norm=0)
     isnothing(Base.get_extension(@__MODULE__, :IntegralsCubatureExt)) && error("CubatureJLh requires `using Cubature`")
-    return CubatureJLh(norm)
+    return CubatureJLh(error_norm)
 end
 
 """
-    CubatureJLp(; norm=Cubature.INDIVIDUAL)
+    CubatureJLp(; error_norm=Cubature.INDIVIDUAL)
 
 Multidimensional p-adaptive integration from Cubature.jl.
 This method is based on repeatedly doubling the degree of the cubature rules,
@@ -193,9 +193,9 @@ Defaults to `Cubature.INDIVIDUAL`, other options are
 struct CubatureJLp <: AbstractCubatureJLAlgorithm
     error_norm::Int32
 end
-function CubatureJLp(; norm=0)
+function CubatureJLp(; error_norm=0)
     isnothing(Base.get_extension(@__MODULE__, :IntegralsCubatureExt)) && error("CubatureJLp requires `using Cubature`")
-    return CubatureJLp(norm)
+    return CubatureJLp(error_norm)
 end