Tinflex.setup {Tinflex}R Documentation

Create Tinflex Generator Object

Description

Create a generator object of class "Tinflex".

Usage

Tinflex.setup(lpdf, dlpdf, d2lpdf, ib, cT=0, rho=1.1, max.intervals=1001)

Arguments

lpdf

log-density of targent distribution. (function)

dlpdf

first derivative of log-density. (function)

d2lpdf

second derivative of log-density. (function)

ib

break points for partition of domain of log-density. (numeric vector of length greater than 1)

cT

parameter for transformation Tc. (numeric vector of length 1 or of length length(ib)-1)

rho

performance parameter: requested upper bound for ratio of area below hat to area below squeeze. (numeric)

max.intervals

maximal numbers of intervals. (numeric)

Details

Algorithm Tinflex is a flexible algorithm that works (in theory) for all distributions that have a piecewise twice differentiable density function. The algorithm is based on the transformed density rejection algorithm which is a variant of the acceptance-rejection algorithm where the density of the targent distribution is transformed by means of some transformation Tc. Hat and squeeze functions of the density are then constructed by means of tangents and secants.

The algorithm uses family Tc of transformations, where

T0 = log(x) for c=0
Tc = sign(x) xc for c!=0

Parameter c is given by argument cT.

The algorithm requires the following input from the user:

The starting partition of the domain of the target distribution into non-overlapping intervals has to satisfy the following conditions:

Parameter cT is either a single numeric, that is, the same transformation Tc is used for all subintervals of the domain, or it can be set independently for each of these intervals. In the latter case length(cT) must be equal to the number of intervals, that is, equal to length(ib)-1. For the choice of cT the following should be taken into consideration:

Parameter rho is a performance parameter. It defines an upper bound for ratio of the area below the hat function to the area below the squeeze function. This parameter is an upper bound of the rejection constant. More importantly, it provides an approximation to the number of (time consuming) evalutions of the log-density function lpdf. For rho=1.01, the log-density function is evaluated once for a sample of 300 random points. However, values of rho close to 1 also increase the table size and thus make the setup more expensive.

Parameter max.intervals defines the maximal number of subintervals and thus the maximal table size. Putting an upper bound on the table size prevents the algorithm from accidentally exhausting all of the computer memory due to invalid input. It is very unlikely that one has to increase the default value.

Value

Object of class "Tinflex" that stores the random variate generator (density, hat and squeeze functions, cumulated areas below hat). For details see sources of the algorithm or execute print(gen,debug=TRUE) with an object gen of class "Tinflex".

Warning

It is very important to note that the user is responsible for the correctness of the supplied arguments. Since the algorithm works (in theory) for all distributions with piecewise twice differentiable density functions, it is not possible to detect improper arguments. It is thus recommended that the user inspect the generator object visually by means of the plot method (see plot.Tinflex for details).

Package rvgtest provides a test suite for non-uniform random number generators. (Approximate distribution functions are available through method pinv.new in package Runuran.)

Author(s)

Josef Leydold josef.leydold@wu.ac.at, Carsten Botts and Wolfgang Hörmann.

References

C. Botts, W. Hörmann, and J. Leydold (2013), Transformed Density Rejection with Inflection Points, Statistics and Computing 23(2), 251–260, DOI: 10.1007/s11222-011-9306-4 (see also Research Report Series / Department of Statistics and Mathematics Nr. 110, Department of Statistics and Mathematics, WU Wien, http://epub.wu.ac.at/).

See Also

See Tinflex.sample for drawing random samples, plot.Tinflex and print.Tinflex for printing and plotting objects of class "Tinflex".

Examples

## Example 1: Bimodal density
##   Density  f(x) = exp( -|x|^alpha + s*|x|^beta + eps*|x|^2 )
##   with alpha > beta >= 2 and s, eps > 0

alpha <- 4.2
beta <- 2.1
s <- 1
eps <- 0.1

## Log-density and its derivatives.
lpdf   <- function(x) { -abs(x)^alpha + s*abs(x)^beta + eps*abs(x)^2 }
dlpdf  <- function(x) { (sign(x) * (-alpha*abs(x)^(alpha-1)
                           + s*beta*abs(x)^(beta-1) + 2*eps*abs(x))) }
d2lpdf <- function(x) { (-alpha*(alpha-1)*abs(x)^(alpha-2)
                          + s*beta*(beta-1)*abs(x)^(beta-2) + 2*eps) }

## Parameter cT=0 (default):
##   There are two inflection points on either side of 0.
ib <- c(-Inf, 0, Inf)

## Create generator object.
gen <- Tinflex.setup(lpdf, dlpdf, d2lpdf, ib=c(-Inf,0,Inf), rho=1.1)

## Print data about generator object.
print(gen)

## Draw a random sample
Tinflex.sample(gen, n=10)

## Inspect hat and squeeze visually in original scale
plot(gen, from=-2.5, to=2.5)
## ... and in transformed (log) scale.
plot(gen, from=-2.5, to=2.5, is.trans=TRUE)

## -------------------------------------------------------------------
## Example 2: Exponential Power Distribution
##   Density  f(x) = exp( -|x|^alpha )
##   with alpha > 0  [ >= 0.015 due to limitations of FPA ]

alpha <- 0.5

## Log-density and its derivatives.
lpdf   <- function(x) { -abs(x)^alpha }
dlpdf  <- function(x) { if (x==0) {0} else {-sign(x) * alpha*abs(x)^(alpha-1)}}
d2lpdf <- function(x) { -alpha*(alpha-1)*abs(x)^(alpha-2) }

## Parameter cT=-0.5:
##   There are two inflection points on either side of 0 and
##   a cusp at 0. Thus we need a partition point that separates
##   the inflection points from the cusp.
ib <- c(-Inf, -(1-alpha)/2, 0, (1-alpha)/2, Inf)

## Create generator object with c = -0.5.
gen <- Tinflex.setup(lpdf, dlpdf, d2lpdf, ib=ib, cT=-0.5, rho=1.1)

## Print data about generator object.
print(gen)

## Draw a random sample.
Tinflex.sample(gen, n=10)

## Inspect hat and squeeze visually in original scale
plot(gen, from=-4, to=4)
## ... and in transformed (log) scale.
plot(gen, from=-4, to=4, is.trans=TRUE)

## -------------------------------------------------------------------
## Example 3: Generalized Inverse Gaussian Distribution
##   Density  f(x) = x^(lambda-1) * exp(-omega/2 * (x+1/x))   x>= 0
##   with 0 < lambda < 1 and 0 < omega <= 0.5

la <- 0.4     ## lambda
om <- 1.e-7   ## omega

## Log-density and its derivatives.
lpdf   <- function(x) { ifelse (x==0., -Inf, ((la - 1) * log(x) - om/2*(x+1/x))) }
dlpdf  <- function(x) { if (x==0) { Inf} else {(om + 2*(la-1)*x-om*x^2)/(2*x^2)} }
d2lpdf <- function(x) { if (x==0) {-Inf} else {-(om - x + la*x)/x^3} }

## Parameter cT=0 near 0 and cT=-0.5 at tail:
ib <- c(0, (3/2*om/(1-la) + 2/9*(1-la)/om), Inf)
cT <- c(0,-0.5)

## Create generator object.
gen <- Tinflex.setup(lpdf, dlpdf, d2lpdf, ib=ib, cT=cT, rho=1.1)

## Print data about generator object.
print(gen)

## Draw a random sample.
Tinflex.sample(gen, n=10)

## Inspect hat and squeeze visually in original scale
plot(gen, from=0, to=5)

[Package Tinflex version 1.5 Index]