Very large scale projects such as modeling of atomic interactions with time-dependent fields, or FEM (finite element) analysis of electric and magnetic field geometries require computations of vast numbers of similar integrals with each iteration of the main relaxation loop. You can construct fast integration schemes given the types of functions that must be integrated that are specifically tailored to speed up your analysis.
Suppose that we we need to integrate linear functions only as a trivial example. We assume that for a first order polynomial, the formula
is exact. Next compute the integral exactly
and solve for the coefficients
and we arrive at
which we can iterate by gluing together many intervals to build up the domain from segments, with
This is a very good approximation if the function is linear on all of the little intervals
that we have chained together.
Next assume that is quadratic on the interval .
and construct the coefficients and from the resulting algebraic equations
This results in
or
We have obtained Simpson’s rule, which is better than trapezoid for larger intervals
which is exact for any second order . Differentiate with respect to and we get the variant of Simpson’s rule that we used in the Adams-Bashford-Milne integration algorithm
Rename:
and if is quadratice on then
and you can chain together adjacent intervals upon which satisfies this. You can see that the resulting formulas are very similar to Gaussian quadrature schemes in which we evaluate the integral with a weighted sum of the function values at selected points on the interval.
Integrals such as can be handled by mapping and then using Gaussian quadrature http://abadonna.physics.wisc.edu/2021/08/01/algorithms-for-numerical-integration/ or Clenshaw-Curtis: let , for some well-chosen (in most cases works well)
In julia…
Clenshaw2sided=function(f,N,L)
abscissas=(k*π/N for k in 1:(N-1))
weights=sin.(abscissas)
weights=weights.^(-2)
args=f.(L*cot.(abscissas))
(L*π/N)*sum(weights .* args)
end
For Gaussian quadrature of using Chebyshev polynomials:
quad=function(f,N)
abscissas=((2.0*k+1)*π/(4.0*N+2) for k in 0:N)
weights=abs.(sin.(abscissas))
args=f.(cos.(abscissas))
(π/(N+1.0))*sum(weights .* args)
end