Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

runif with .Machine$double.xmax as boundaries

I wanted to generate a random real (I guess rational) number.

To do this I wanted to use runif(1, min = m, max = M) and my thoughts were to set m; M (absolute) as large as possible in order to make the interval as large as possible. Which brings me to my question:

M <- .Machine$double.xmax
m <- -M
runif(1, m, M)
## which returns
[1] Inf

Why is it not returning a number? Is the chosen interval simply too large?

PS

> .Machine$double.xmax
[1] 1.797693e+308
like image 916
niko Avatar asked Mar 18 '18 09:03

niko


1 Answers

As hinted by mt1022 the reason is in runif C source:

double runif(double a, double b)
{
    if (!R_FINITE(a) || !R_FINITE(b) || b < a)  ML_ERR_return_NAN;

    if (a == b)
    return a;
    else {
    double u;
    /* This is true of all builtin generators, but protect against
       user-supplied ones */
    do {u = unif_rand();} while (u <= 0 || u >= 1);
    return a + (b - a) * u;
    }
}

In the return argument you can see the formula a + (b - a) * u which transoform uniformly [0, 1] generated random value in the user supplied interval [a, b]. In your case it will be -M + (M + M) * u. So M + M in case it 1.79E308 + 1.79E308 generates Inf. I.e. finite + Inf * finite = Inf:

M + (M - m) * runif(1, 0, 1)
# Inf
like image 149
Artem Avatar answered Nov 06 '22 23:11

Artem