I think there is a fundamental mistake in your code:
mc <- function(lambda, f, B){
x <- rexp(B, lambda)
f(x[x<pi]) / dexp(x[x<pi], lambda)
}
since it produces a sample of an exponential truncated to $(0,\pi)$, with a random size. Therefore, the importance weight should be the inverse of the density of the truncated Exponential,$$\lambda\exp\{-\lambda x\}\big/1-\exp\{-\lambda\pi\}$$that is
md <- function(lambda, f, B){
x <- rexp(B, lambda)
pexp(pi,lambda)*f(x[x<pi]) / dexp(x[x<pi], lambda)
}
Comparing the outputs shows why one md
works and the other mc
does not:
> integrate(f,0,pi)$val
[1] 1.581188
> lambda=.1;mean(mc(lambda,f,B));mean(md(lambda,f,B))
[1] 5.800769
[1] 1.556356
> lambda=.5;mean(mc(lambda,f,B));mean(md(lambda,f,B))
[1] 1.991859
[1] 1.588999
> lambda=2;mean(mc(lambda,f,B));mean(md(lambda,f,B))
[1] 1.566827
[1] 1.597629
The alternative to the truncation is to return the entire Exponential sample while taking $f(x)=0$ for $x>\pi$:
me <- function(lambda, f, B){
x <- rexp(B, lambda)
f(x)*(x<pi) / dexp(x, lambda)
}
> lambda=.1;mean(mc(lambda,f,B));mean(md(lambda,f,B));mean(me(lambda,f,B));
[1] 5.869764
[1] 1.575606
[1] 1.574132
This being fixed, looking for the optimal value of $\lambda$ can be operated by minimising the Monte Carlo variance over $\lambda$ with the very same Exponential sample, in order to avoid Monte Carlo variability
expone=rexp(B,1) #standard Exponential
target <- function(lambda,expone,B){
explambda=expone/lambda
fexplambda=f(explambda)*(explambda<pi)/dexp(explambda,lambda)
return(var(fexplambda))}
which leads to
> optimise(target,c(.01,5),expone=expone,B=1e6)
$minimum
[1] 0.9462493
$objective
[1] 0.2354651
B
is not declared in your code, so the code doesn't run. Please fix your code (it's presumably the number of MC samples). $\endgroup$