If I understand you correctly (??) you want to generate random samples with the distribution whose density function is given by f(x)
. One way to do this is to generate a random sample from a uniform distribution, U[0,1]
, and then transform this sample to your density. This is done using the inverse cdf of f
, a methodology which has been described before, here.
So, let
f(x) = your density function,
F(x) = cdf of f(x), and
F.inv(y) = inverse cdf of f(x).
In R code:
f <- function(x) {((x-1)^2) * exp(-(x^3/3-2*x^2/2+x))}
F <- function(x) {integrate(f,0,x)$value}
F <- Vectorize(F)
F.inv <- function(y){uniroot(function(x){F(x)-y},interval=c(0,10))$root}
F.inv <- Vectorize(F.inv)
x <- seq(0,5,length.out=1000)
y <- seq(0,1,length.out=1000)
par(mfrow=c(1,3))
plot(x,f(x),type="l",main="f(x)")
plot(x,F(x),type="l",main="CDF of f(x)")
plot(y,F.inv(y),type="l",main="Inverse CDF of f(x)")
In the code above, since f(x)
is only defined on [0,Inf]
, we calculate F(x)
as the integral of f(x)
from 0 to x. Then we invert that using the uniroot(...)
function on F-y
. The use of Vectorize(...)
is needed because, unlike almost all R functions, integrate(...)
and uniroot(...)
do not operate on vectors. You should look up the help files on these functions for more information.
Now we just generate a random sample X
drawn from U[0,1]
and transform it with Z = F.inv(X)
X <- runif(1000,0,1) # random sample from U[0,1]
Z <- F.inv(X)
Finally, we demonstrate that Z
is indeed distributed as f(x)
.
par(mfrow=c(1,2))
plot(x,f(x),type="l",main="Density function")
hist(Z, breaks=20, xlim=c(0,5))