6 votos

Problemas generando una muestra de una distribución personalizada con registro

Estoy tratando de generar un ejemplo de una familia de distribuciones. En particular, me gustaría ser capaz de obtener una muestra de la supervivencia de la función:

$$1-F(x) = c x^{-a} \log^b(x)$$ con un dominio adecuado de modo que F está definida y es una función de sobrevivencia, a partir de diferentes valores de $c$, $b$ y $a$.

Por ejemplo: $$1-F(x) \approx \tfrac{\log(x)}{x^2}, x>\sqrt{e}$$

Roughly speaking I need a function $F$ such that the distribution is heavy tailed and behaves like $1-F(x) = c x^{-a} \log^b(x)$, as $x$ goes to $+ \infty$.

He tratado de muchas maneras, porque he encontrado varios ejemplos:

Pero en cualquier momento, incluso para el más simple de la función de con $b=1$ $a=2$ errores vienen de fuera. Yo creo que es porque tal vez, debido a que el registro, algunos de los algoritmos de trabajo con todos los números reales, y no se limita a los números positivos.

Que es la forma más fácil para un pdf/cdf con un registro? Es difícil debido al hecho de que es difícil invertir la función xlogx?

Si tengo que usar algunos de los métodos anteriores puedo mostrar mis logros y donde me quedé atrapado!

EDICIÓN 1 Gracias a whuber I sucedido en la construcción del código, aquí están:

# Simulating data from G(x) = 1-F(x) = c * x^(-a) * (log(x))^b
# Case: b > 0
pxlog <- function(x, a=5, b=2, c=(a*exp(1)/b)^b) {((1-c*x^(-a)*(log(x))^b))}                 # G
dxlog <- function(x, a=5, b=2, c=(a*exp(1)/b)^b) {c*(x^(-1-a))*((log(x))^(-1+b))*(-b+a*log(x))}
qxlog <- function(y, a=5, b=2, c=(a*exp(1)/b)^b) {exp(-(b/a)*lambert_Wm1(-(a/b)*((1-y)/c)^(1/b)))}   # inversa di G

# Domain for the functions: x > exp(b/a)

# Generating Samples
rxlog <- function(n, a=5, b=2, c=(a*exp(1)/b)^b) qxlog(runif(n),a,b,c)

# Testing Samples
hist(rxlog(10000, 2, 10), breaks=50, freq = F, col="grey", label=F)
curve(dxlog(x, 2, 10), exp(10/2), add= TRUE, col="red")

El resultado es que funciona... casi! Si yo uso los valores de $b$ mayor que $a$, o en general, si $b-a>-1$, el ajuste de la densidad/histograma crea problema.

Por ejemplo, $a=2, b=10$ enter image description here

o con $a=3, b=4$ (ajuste de la rompe en hist)

enter image description here

Cual es el problema? Y la segunda pregunta, ¿cómo puedo incluir, si es posible, el dominio de la información sobre $F$ en la definición de $F$ sí? Gracias!

EDIT 2 Por $b>0$ la distribución que yo estoy buscando, puede ser asumido como el registro de la distribución gamma. Usted puede encontrar en el Actuar de la biblioteca en R. Pruebas de "mi" de la distribución (el uno con el código de EDITAR 1) con que hay algunas diferencias... pero creo que es sólo porque he cometido algunos errores!

5voto

jldugger Puntos 7490

Podemos generar variables aleatorias a partir de esta distribución con la inversión.

Esto significa que la solución de $1 - F(x) = q$ (que se encuentra entre el$0$$1$, lo que implica la $a\gt 0$)$x$. Observe que $\log^b(x)$ será indefinido o negativo (que no funciona), a menos que $x \gt 1$. Dejar de lado el caso de $b=0$ por el momento. Las soluciones son ligeramente diferentes dependiendo del signo de $b$. Cuando $b \lt 0$, $$x=\exp(y)$$ and solve for $y \gt 0$:

$$q^{1/b} = (c \log^b(x) x^{-a})^{1/b} = c^{1/b} y\exp(-\frac{a}{b} y),$$

whence

$$-\frac{b}{a} W\left(-\frac{a}{b} \left(\frac{q}{c}\right)^{1/b}\right)= y.$$

$W$ is the primary branch of the Lambert $W$ function: when $w = u \exp(u)$ for $u \ge -1$, $W(w)=u$. The solid lines in the figure show this branch.

![Figure: Plots of the inverse of W and W itself

When $b\gt 0$, let $$x = \exp(-y)$$ and solve as before, yielding

$$\frac{b}{a} W\left(-\frac{a}{b} \left(\frac{q}{c}\right)^{1/b}\right)= y.$$

Because we are interested in the behavior as $x\to \infty$, which corresponds to $s\- \infty$, the relevant branch is the one shown with the dashed lines in the figure. Notice that the argument of $W$ must lie in the interval $[-1/e, 0]$. This will happen only when $c$ is sufficiently large. Since $0 \le q \le 1$, this implies

$$c \ge \left(\frac{e a}{b}\right)^b.$$

Values along either branch of $W$ are readily computed using Newton-Raphson. Depending on the values of $a,b,$ and $c$ chosen, between one and a dozen iterations will be needed.

Finally, when $b=0$ the logarithmic term is $1$ and we can readily solve

$$x = \left(\frac{c}{q}\right)^{1/a} = \exp\left(-\frac{1}{a}\log\left(\frac{q}{c}\right)\right).$$

(In some sense the limiting value of $(q/c)^{1/b}/b$ gives the natural logarithm, as we would hope.)

In either case, to generate variates from this distribution, stipulate $a$, $b$, and $c$, then generate uniform variates in the range $[0,1]$ and substitute their values for $q$ in the appropriate formula.


Here are examples with $a=5$ and $b=\pm 2$ to illustrate. $10,000$ independent variates were drawn and summarized with histograms of $y$ and $x$. For negative $b$ (top), I chose a value of $c$ that gives a picture that is not terribly skewed. For positive $b$ (bottom), the most extreme possible value of $c$ was chosen. Shown for comparison are solid curves graphing the derivative of the distribution function $F$. The match is excellent in both cases.

Negative $b$

Figure: Negative b

Positive $b$

Figure: Positive b


Here is working code to compute $W$ in R, with an example showing its use. It is vectorized to perform Newton-Raphson steps in parallel for a large number of values of the argument, which is ideal for efficient generation of random variates.

(Mathematica, which generated the figures here, implements $W$ as ProductLog. The negative branch used here is the one with index $-1$ en Mathematica's de numeración. Devuelve los mismos valores en los ejemplos dados aquí, que se calculan en menos de 12 cifras significativas.)

W <- function(q, tol.x2=1e-24, tol.W2=1e-24, iter.max=15, verbose=FALSE) {
  #
  # Define the function and its derivative.
  #
  W.inverse <- function(z) z * exp(z)
  W.inverse.prime <- function(z) exp(z) + W.inverse(z)
  #
  # Functions to take one Newton-Raphson step.
  #
  NR <- function(x, f, f.prime) x - f(x) / f.prime(x)
  step <- function(x, q) NR(x, function(y) W.inverse(y) - q, W.inverse.prime)
  #
  # Pick a good starting value.  Use the principal branch for positive
  # arguments and its continuation (to large negative values) for 
  # negative arguments.
  #
  x.0 <- ifelse(q < 0, log(-q), log(q + 1))
  #
  # True zeros must be handled specially.
  #
  i.zero <- q == 0
  q.names <- q
  q[i.zero] <- NA
  #
  # Newton-Raphson iteration.
  #
  w.1 <- W.inverse(x.0)
  i <- 0
  if (verbose) x <- x.0
  if (any(!i.zero, na.rm=TRUE)) {
    while (i < iter.max) {
      i <- i + 1
      x.1 <- step(x.0, q)
      if (verbose) x <- rbind(x, x.1)
      if (mean((x.0/x.1 - 1)^2, na.rm=TRUE) <= tol.x2) break
      w.1 <- W.inverse(x.1)
      if (mean(((w.1 - q)/(w.1 + q))^2, na.rm=TRUE) <= tol.W2) break
      x.0 <- x.1
    }
  }
  x.0[i.zero] <- 0
  w.1[i.zero] <- 0
  rv <- list(W=x.0,                              # Values of Lambert W
             W.inverse=w.1,                      # W * exp(W)
             Iterations=i,
             Code=ifelse(i < iter.max, 0, -1),   # 0 for success
             Tolerances=c(x2=tol.x2, W2=tol.W2))
  names(rv$W) <- q.names                         # $
  if (verbose) {
    rownames(x) <- 1:nrow(x) - 1
    rv$Steps <- x                                # $
  }
  return (rv)
}
#
# Test on both positive and negative arguments
#
q <- rbind(Positive = 10^seq(-3, 3, length.out=7), 
           Negative = -exp(seq(-(1+1e-15), -600, length.out=7)))
for (i in 1:nrow(q)) {
  rv <- W(q[i, ], verbose=TRUE)
  cat(rv$Iterations, " steps:", rv$W, "\n")
  #print(rv$Steps, digits=13)                     # Shows the steps
      #print(rbind(q[i, ], rv$W.inverse), digits=12)  # Checks correctness
}

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X