\name{mtruncnorm}
\alias{dmtruncnorm}
\alias{pmtruncnorm}
\alias{rmtruncnorm}

\title{The multivariate truncated normal distribution}

\description{
  The probability density function, the distribution function and random
  number generation for the \code{d}-dimensional truncated normal (Gaussian)
  random variable.
}
\usage{
dmtruncnorm(x, mean, varcov, lower, upper, log = FALSE, ...)
pmtruncnorm(x, mean, varcov, lower, upper, ...)
rmtruncnorm(n, mean, varcov, lower, upper, start, burnin=5, thinning=1)
}
 
\arguments{
  \item{x}{either a vector of length \code{d} or a matrix with \code{d}
    columns,representing  the coordinates of the point(s) where the density 
    must be evaluated.  
    Here we denote \code{d=ncol(varcov)}; see \sQuote{Details} for restrictions.}
  \item{mean}{a \code{d}-vector representing the mean value of the pre-truncation 
    normal distribution.}
  \item{varcov}{a symmetric positive definite matrix with dimensions \code{(d,d)} 
    representing the variance matrix of the pre-truncation normal distribution.}
  \item{lower}{a \code{d}-vector representing the lower truncation values of the   
    component variables; \code{-Inf} values are allowed. 
    If missing, it is set equal to \code{rep(-Inf, d)}.}
  \item{upper}{a \code{d}-vector representing the upper truncation values of the 
    component variables; \code{Inf} values are allowed.
    If missing, it is set equal to \code{rep(Inf, d)}.}

  \item{log}{a logical value (default value is \code{FALSE});
    if \code{TRUE}, the logarithm of the density is computed.}

  \item{\dots}{arguments passed to \code{sadmvn}, 
    among \code{maxpts}, \code{abseps}, \code{releps}.}
    
  \item{n}{the number of (pseudo) random vectors to be generated.}
  
  \item{start}{an optional vector of initial values; see \sQuote{Details}.}
  
  \item{burnin}{the number of burnin iterations of the Gibbs sampler 
    (default: \code{5}); see \sQuote{Details}.}
    
  \item{thinning}{a positive integer representing the thinning factor of the 
    internally generated Gibbs sequence (default: \code{1}); see \sQuote{Details}.} 
}

\details{For \code{dmtruncnorm} and \code{pmtruncnorm},  
the dimension \code{d} cannot exceed \code{20}.
If this threshold is exceeded, \code{NA}s are returned. 
The constraint originates from the underlying function  \code{\link{sadmvn}}.

If \code{d>1}, \code{rmtruncnorm} uses a Gibbs sampling scheme as described by
Breslaw (1994) and by Kotecha & Djurić (1999), 
Detailed algebraic expressions are provided by Wilhelm (2022).
After some initial settings in \R, the core iteration is performed by 
a compiled \acronym{FORTRAN 77} subroutine, for numerical efficiency. 

If the \code{start} vector is not supplied, the mean value of the truncated
distribution is used. This choice should provide a good starting point for the
Gibbs iteration, which explains why the default value for the \code{burnin}
stage is so small. Since successive random vectors generated by a Gibbs
sampler are not independent, which can be a problem in certain applications.
This dependence is typically ameliorated by generating a larger-than-required
number of random vectors, followed by a  \sQuote{thinning} stage; this can
be obtained by setting the \code{thinning} argument larger that \code{1}.
The overall number of generated points is \code{burnin+n*thinning}, and the 
returned object is formed by those with index in \code{burnin+(1:n)*thinning}.

If \code{d=1}, the values are sampled using a non-iterative procedure, 
essentially as in equation (4) of Breslaw (1994), except that in this case 
the  mean and the variance do not refer to a conditional distribution, 
but are the arguments supplied in the calling statement. 
}
  
\value{
  \code{dmtruncnorm} and \code{pmtruncnorm} return a numeric vector;
  \code{rmtruncnorm} returns a matrix, unless either \code{n=1} or \code{d=1}, 
  in which case it returns a vector.
}

\author{Adelchi Azzalini}
 
\seealso{\code{\link{plot_fxy}} for additional plotting examples,
\code{\link{sadmvn}} for regulating accuracy via \code{...}}

\examples{
# example with d=2
m2 <- c(0.5, -1)
V2 <- matrix(c(3, 3, 3, 6), 2, 2)
low <- c(-1, -2.8)
up <- c(1.5, 1.5)
# plotting truncated normal density using 'dmtruncnorm' and 'contour' functions 
plot_fxy(dmtruncnorm, xlim=c(-2, 2), ylim=c(-3, 2), mean=m2, varcov=V2, 
      lower=low, upper=up,  npt=101)   
set.seed(1)    
x <-  rmtruncnorm(n=500, mean=m2, varcov=V2, lower=low, upper=up) 
points(x, cex=0.2, col="red")
#------
# example with d=1
set.seed(1) 
low <- -4
hi <- 3
x <- rmtruncnorm(1e5, mean=2, varcov=5, lower=low, upper=hi)
hist(x, prob=TRUE, xlim=c(-8, 12), main="Truncated univariate N(2, sqrt(5))")
rug(c(low, hi), col=2)
x0 <- seq(-8, 12, length=251)
pdf <- dnorm(x0, 2, sqrt(5))
p <- pnorm(c(low, hi), 2, sqrt(5))
lines(x0, pdf/diff(p), col=4, lty=2)
lines(x0, dmtruncnorm(x0, 2, 5, low, hi), col=2, lwd=2)
}

\references{
Breslaw, J.A. (1994)
Random sampling from a truncated multivariate normal distribution.
\emph{Appl. Math. Lett.}  vol.7, pp.1-6.

Kotecha, J.H. and  Djurić, P.M. (1999).
Gibbs sampling approach for generation of truncated multivariate 
Gaussian random variables.
In \emph{ICASSP'99: Proceedings of IEEE International Conference on 
Acoustics, Speech, and Signal Processing}, 
vol.3, pp.1757-1760. \doi{10.1109/ICASSP.1999.756335}. 
  
Wilhelm, S. (2022).
Gibbs sampler for the truncated multivariate normal distribution.
Vignette of R package \url{https://cran.r-project.org/package=tmvtnorm}, 
version 1.5.
}
%--- 
\keyword{distribution}
\keyword{multivariate}
\concept{multivariate truncated normal distribution}
 
