How to generate random numbers from density function if it's known that if $X_i$ are iid and $X_i \sim F$, then $F(x_i) \sim U[0,1]$

67 Views Asked by At

The given density function: $$f(x) = \frac{1}{2}\phi(x, 0, 1) + \frac{1}{10}\sum^4_{j=0}\phi(x; (j/2)-1, 1/10) $$ where $\phi$ is normal distribution.

f <- function(x){
  dnorm(x)/2 +
    dnorm(x,- 1, 1/10)/10 +
    dnorm(x, 1/2 - 1, 1/10)/10 +
    dnorm(x, 2/2 - 1, 1/10)/10 +
    dnorm(x, 3/2 - 1, 1/10)/10 +
    dnorm(x, 4/2 - 1, 1/10)/10
}

It is known that if random variables $X_i$ are iid, and $X_i \sim F$, then $F(X_i)\sim U[0,1]$ I tried to define the cumulative function:

F <- function(x){integrate(f, lower = -Inf, upper = x)}$value

And then to find zeroes of function $F(x)-\text{runif}(x)$

zeros <- function(x){uniroot(F(x)-runif(x), c(-10,10))}

But the program R gives me an error:

Error in uniroot(F(x) - runif(x), c(-10, 10)) : 
  f() values at end points not of opposite sign

Anyway, I am at loss as to the way, this problem could be possibly solved. Does anybody got any insights?

2

There are 2 best solutions below

5
On BEST ANSWER

You didn't show how you are calling the function zeros, so I am not sure how to explain why you get this error. Probably, when you are calling zeros, it tries to evaluate runif(x) where x is a number between 0 and 1 and that is the source of the problem.

Try this.

f <- function(x){
  dnorm(x)/2 +
    dnorm(x,- 1, 1/10)/10 +
    dnorm(x, 1/2 - 1, 1/10)/10 +
    dnorm(x, 2/2 - 1, 1/10)/10 +
    dnorm(x, 3/2 - 1, 1/10)/10 +
    dnorm(x, 4/2 - 1, 1/10)/10
}
integrate(f,lower=-Inf,upper = Inf)
F <- function(x){integrate(f, lower = -Inf, upper = x)}$value
Finv <- function(t) uniroot(function(x,t) F(x)-t,c(-10,10),t=t)$root
(u=runif(1))
F(Finv(u))
Finv(F(u))

This verifies that Finv is the inverse of F.
Then, you can simulate a random variable with distribution $F$ by using Finv(runf(1)).

0
On

Looks to me as if you have a mixture with six different densities, mixing coefficients $\pi_k$ where $\pi_1 = 1/2$ and the other five are $1/10$. What you might want to do to generate $X$ is to select one of these densities at random, using these probabilities, then generate $X$ from that one:

  1. Select $i$ from $\{1, 2, 3, 4, 5, 6\}$ with probabilities $\{1/2, 1/10, 1/10, 1/10, 1/10, 1/10 \}$.
  2. Return $X$ from $f_i$.