First, I have no idea wether the professor gave the wrong question. Anyway, I tried to generate F(x)~U(0,1)
, where CDF F(x)=1-(1+x)exp(-x)
(For this CDF, you could not calculate x=g(F(x))
by hand). And then calculate the root of F(x)
to achieve what the question want.
Because the root range from 0
to INF
, uniroot()
is out of question. Therefore, I use Newton Method to write one.
Then, my code is like this:
f=function(x) {
ifelse(x>=0,x*exp(-x),0)
}
in.C=function(n) {
a=runif(n)
G=NULL
for(i in 1:n) {
del=1
x=2
while(abs(del)>1e-12){
del=(1-(1+x)*exp(-x)-a[i])/f(x)
x=x-del
}
G[i]=x
}
G
}
system.time(tt<-in.C(100000))
However, if the F(x)
is too small, and one step in Newton Method, the result may be less than zero, then errors will happen. Further, I revised my code like this:
f=function(x) {
ifelse(x>=0,x*exp(-x),0)
}
in.C=function(n) {
a=runif(n)
G=NULL
for(i in 1:n) {
del=1
x=2
while(abs(del)>1e-12){
if(x>=0){ del=(1-(1+x)*exp(-x)-a[i])/f(x)
x=x-del
}
else break
}
if(x>=0) G[i]=x
}
G[!is.na(G)]
}
system.time(tt<-in.C(100000))
hist(tt, breaks=70, right=F, freq=F)
curve(f(x),from=0,to=20,add=T)
Clearly, the code is wrong, because I rejected the result near zero.
So, my quetion is whether my code can be revised to calculate right, if not, whether there is another way to do it. Any assitance is appreciated.