#' Hermite Polynomials
#'
#' Computes univariate and multivariate Hermite polynomials.
#'
#' @param order the order of the Hermite polynomial.
#' @param sigma the covariance \code{matrix} of the Gaussian kernel.
#' @param var \code{character} vector giving the variables of the polynomial.
#' @param transform \code{character} vector representing a change of variables. See details.
#'
#' @details Hermite polynomials are obtained by differentiation of the Gaussian kernel:
#'
#' \deqn{H_{\nu}(x,\Sigma) = exp \Bigl( \frac{1}{2} x_i \Sigma_{ij} x_j \Bigl) (- \partial_x )^\nu exp \Bigl( -\frac{1}{2} x_i \Sigma_{ij} x_j \Bigl)}
#'
#' where \eqn{\Sigma} is a \eqn{d}-dimensional square matrix and
#' \eqn{\nu=(\nu_1 \dots \nu_d)} is the vector representing the order of
#' differentiation for each variable \eqn{x = (x_1\dots x_d)}.
#' In the case where \eqn{\Sigma=1} and \eqn{x=x_1} the formula reduces to the
#' standard univariate Hermite polynomials:
#'
#' \deqn{H_{\nu}(x) = e^{\frac{x^2}{2}}(-1)^\nu \frac{d^\nu}{dx^\nu}e^{-\frac{x^2}{2}}}
#'
#' If \code{transform} is not \code{NULL}, the variables \code{var} \eqn{x} are replaced with
#' \code{transform} \eqn{f(x)} to compute the polynomials \eqn{H_{\nu}(f(x),\Sigma)}
#'
#' @return
#' \code{list} of Hermite polynomials with components:
#' \describe{
#' \item{f}{the Hermite polynomial.}
#' \item{order}{the order of the Hermite polynomial.}
#' \item{terms}{\code{data.frame} containing the variables, coefficients and degrees of each term in the Hermite polynomial.}
#' }
#'
#' @examples
#' ### univariate Hermite polynomials up to order 3
#' hermite(3)
#'
#' ### multivariate Hermite polynomials up to order 2
#' hermite(order = 2,
#' sigma = matrix(c(1,0,0,1), nrow = 2),
#' var = c('z1', 'z2'))
#'
#' ### multivariate Hermite polynomials with transformation of variables
#' hermite(order = 2,
#' sigma = matrix(c(1,0,0,1), nrow = 2),
#' var = c('z1', 'z2'),
#' transform = c('z1+z2','z1-z2'))
#'
#' @family polynomials
#'
#' @references
#' Guidotti E (2022). "calculus: High-Dimensional Numerical and Symbolic Calculus in R." Journal of Statistical Software, 104(5), 1-37. \doi{10.18637/jss.v104.i05}
#'
#' @export
#'
hermite <- function(order, sigma = 1, var = 'x', transform = NULL){
sigma <- as.matrix(sigma)
if(length(var)==1 && var=='x' && ncol(sigma)>1)
var <- paste0('x', 1:ncol(sigma))
if(any(dim(sigma)!=length(var)))
stop("sigma must be a square matrix with ncol and nrow equal to the length of var")
if(!is.null(transform)) if(any(dim(var)!=dim(transform)))
stop("parameters transform and var must be of the same length")
# cache
H <- list()
# kernel
kernel <- sprintf('exp(%s)', (-0.5 * sigma) %inner% (var %outer% var))
nu <- partitions(n = order, length = length(var), fill = TRUE, perm = TRUE, equal = FALSE)
for(i in 1:ncol(nu)){
v <- nu[,i]
prev <- 1
expr <- kernel
if(length(H)>0){
prev <- which(apply(v - nu, 2, function(x) sum(x)==1 & all(x>=0)))[[1]]
expr <- H[[prev]]$f
expr <- paste0(wrap(expr), " * " , kernel)
}
expr <- parse(text = expr)
h <- derivative(f = expr, var = var, order = v - nu[,prev], deparse = FALSE)
h <- paste0((-1)^sum(v - nu[,prev]), " * ", wrap(e2c(h)))
h <- gsub(x = h, pattern = kernel, replacement = '1', fixed = T)
H[[paste(v, collapse = ',')]] <- taylor(h, var = var, order = sum(v))
}
if(!is.null(transform)){
d <- length(var)
var.reg <- paste0("\\b",var,"\\b")
var.tmp <- paste0("#",var,"#")
var.new <- wrap(transform)
H <- lapply(H, function(h){
for(i in 1:d) h$f <- gsub(x = h$f, pattern = var.reg[i], replacement = var.tmp[i])
for(i in 1:d) h$f <- gsub(x = h$f, pattern = var.tmp[i], replacement = var.new[i], fixed = TRUE)
taylor(h$f, var = var, order = h$order)
})
}
return(H)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.