Accurate integration of this kind of function will require you to work in log-space, which means that you will use the $\text{logsumexp}$ function for sums of terms. You can then use any standard method of numerical integration (e.g., quadrature, importance sampling, etc.)
To give you a more specific idea of how to implement this technique, I will construct a simple method using an arbitrary weighting on the terms for the numerical integration, and working in log-space. For simplicity, I will assume you have a continuous distribution where you have a known quantile function $Q$ that you can compute. On this basis, we choose some odd value $n$ and split the unit interval into $n$ equal sub-intervals, and look at the midpoints of these sub-intervals. We consider the points $b_1,...,b_n$ (which are the values at the quantiles equal to those sub-interval midpoints) given by:
$$b_i \equiv Q \bigg( \frac{2i-1}{2n} \bigg).$$
Suppose we take some corresponding positive weights $w_1,...,w_n$ with mean $\bar{w} \equiv \sum w_i / n$, and we define the coefficients $\ell_{i*} \equiv \ell(\theta,b_i) + \log w_i$. The integral can be approximated (using these weights) as:
$$\begin{equation} \begin{aligned}
\log \ell_m(\theta)
&= \log \int \exp \left( \ell(\theta,b) \right) \ dF(b) \\[6pt]
&= \log \int \limits_0^1 \exp \left( \ell(\theta,Q(p)) \right) \ dp \\[6pt]
&\approx \log \Bigg( \sum_{i=1}^n \frac{w_i}{n \bar{w}} \cdot \exp \left( \ell(\theta,b_i) \right) \Bigg) \\[6pt]
&= -\log(n \bar{w}) + \log \Bigg( \sum_{i=1}^n \exp \left( \ell(\theta,b_i) + \log w_i \right) \Bigg) \\[6pt]
&= -\log(n \bar{w}) + \log \Bigg( \sum_{i=1}^n \exp \left( \ell_{i*} \right) \Bigg) \\[6pt]
&= -\log(n \bar{w}) + \text{logsumexp} \left( \ell_{1*}, ..., \ell_{n*} \right). \\[6pt]
\end{aligned} \end{equation}$$
Now, we will generally choose the weights $w_1,...,w_n$ to correspond to some appropriate quadrature rules. For example, we could implement the numerical integration using Simpson's rule by taking the weights to be $w_1,...,w_n = 1, 4, 2, 4, ..., 4, 2, 4, 1$.
We can program this method in R
as follows. (Note that this is not a particularly efficient method. I am including it for purposes of exposition rather than recommending it as a method. There are much better numerical integration algorithms already programmed into R
.) Here we program a function INTEGRATE
that takes your function l
and your quantile function Q
and computes the integral using Simpson's rule with n
terms. The option log
specifies whether you want the logarithm of the integral as the output (or the actual integral).
INTEGRATE <- function(l, Q, n = 100001, log.out = TRUE) {
#Check the input n
if (length(n) != 1) { stop('Error: n should be a single value') }
if (n < 1) { stop('Error: n should be a positive integer') }
n <- as.integer(n);
if (n%%2 == 0) { n <- n+1; }
#Set Simpson weights
WW <- rep(0, n);
for (i in 1:n) { WW[i] <- ifelse(i%%2 == 0, 4, 2); }
WW[1] <- 1;
WW[n] <- 1;
#Set numerical terms
BB <- rep(0, n);
TT <- rep(-Inf, n);
for (i in 1:n) {
PROB <- (2*i-1)/(2*n);
BB[i] <- Q(PROB);
TT[i] <- l(BB[i]) + log(WW[i]); }
#Perform numerical integration
LOG_INT <- - log(sum(WW)) + matrixStats::logSumExp(TT);
#Give output
if (log.out) { LOG_INT } else { exp(LOG_INT) } }
We will implement this with an example where the true value of the integral is known. Taking $\ell(\theta, b) = \theta \cdot b$ means that the integral is just the moment generating function of the random variable $B$, evaluated at $\theta$. We can compute this integral numerically for the standard normal distribution and compare the result to the known value of the MGF. Taking $\theta = 2$ and using the standard normal distribution, the log-MGF value should be $\theta^2/2 = 2$. Our computation below shows that we get a numerical integral that is somewhat near this value by taking a sufficiently large value for $n$.
#Set an example function
theta <- 2;
l <- function(z) { theta*z; }
#Set the quantile function (standard normal)
Q <- function(p) { qnorm(p, 0, 1); }
#Compute the integral numerically
LOG_INT <- INTEGRATE(l, Q, n = 10^7, log.out = TRUE);
LOG_INT;
[1] 1.999567
We can see that our numerical integration in this case comes close to the true value of the integral. Note that this is not a particularly efficient numerical integration algorithm, and there are better numerical integration algorithms in R
. Nevertheless, hopefully this illustrates a broad class of methods for integrating this kind of function in log-space.