From 5f101f722a9a366361c3b4e0270a4e9fa211bc45 Mon Sep 17 00:00:00 2001 From: Thibault Vatter Date: Tue, 12 Nov 2024 11:03:19 +0100 Subject: [PATCH] RVineCDF via Monte Carlo (#97) * RVineCDF * Less like a VineCopula nOOb * Remove the quasi- * Bump version to satisfy CRAN check --- DESCRIPTION | 2 +- NAMESPACE | 1 + NEWS.md | 7 +++ R/RVineLogLik.R | 102 ++++++++++++++++++++++++++++++++++++++++++ README.md | 4 +- man/RVineCDF.Rd | 83 ++++++++++++++++++++++++++++++++++ tests/other/na_test.R | 2 + 7 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 man/RVineCDF.Rd diff --git a/DESCRIPTION b/DESCRIPTION index abe2662..12959c7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: VineCopula Type: Package Title: Statistical Inference of Vine Copulas -Version: 2.5.1 +Version: 2.5.2 Description: Provides tools for the statistical analysis of regular vine copula models, see Aas et al. (2009) and Dissman et al. (2013) . diff --git a/NAMESPACE b/NAMESPACE index 6b8b477..ce46b63 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -60,6 +60,7 @@ export(BiCopKDE) export(RVineLogLik) export(RVinePDF) +export(RVineCDF) export(RVineAIC) export(RVineBIC) export(RVineMatrix) diff --git a/NEWS.md b/NEWS.md index 72b4982..92c9ac6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +VineCopula 2.5.0 +---------------------------------------------------------------- + +NEW FEATURES + +* add `RVineCDF()` function for cumulative distribution of vine copulas models (#97). + VineCopula 2.5.1 ---------------------------------------------------------------- diff --git a/R/RVineLogLik.R b/R/RVineLogLik.R index d120ee2..e5ae4ed 100644 --- a/R/RVineLogLik.R +++ b/R/RVineLogLik.R @@ -339,3 +339,105 @@ RVineLogLik <- function(data, RVM, par = RVM$par, par2 = RVM$par2, RVinePDF <- function(newdata, RVM, verbose = TRUE) { exp(RVineLogLik(newdata, RVM, separate = TRUE, calculate.V = FALSE, verbose = verbose)$loglik) } + +#' CDF of an R-Vine Copula Model +#' +#' This function calculates the cumulative distribution +#' function of a d-dimensional R-vine copula. +#' +#' The cumulative distribution function of a \eqn{d}-dimensional R-vine copula +#' cannot be expressed in closed form. +#' However, it can be calculated by numerical integration. The function uses +#' the \code{\link[=RVineSim]{RVineSim()}} function to +#' simulate a grid of points and then computes the CDF via Monte Carlo. +#' +#' @param data An N x d data matrix that specifies where +#' the CDF shall be evaluated. +#' @param RVM An [RVineMatrix()] object including the +#' structure and the pair-copula families and parameters. +#' @param N Number of points to simulate for the Monte +#' Carlo integration (default: `n = 1000`). +#' +#' @return A vector of length N with the CDF values. +#' +#' @author Thibault Vatter +#' +#' @seealso [RVineSim()], [RVineMatrix()], [RVineLogLik()], [RVinePDF()] +#' +#' @examples +#' # define 5-dimensional R-vine tree structure matrix +#' Matrix <- c( +#' 5, 2, 3, 1, 4, +#' 0, 2, 3, 4, 1, +#' 0, 0, 3, 4, 1, +#' 0, 0, 0, 4, 1, +#' 0, 0, 0, 0, 1 +#' ) +#' Matrix <- matrix(Matrix, 5, 5) +#' +#' # define R-vine pair-copula family matrix +#' family <- c( +#' 0, 1, 3, 4, 4, +#' 0, 0, 3, 4, 1, +#' 0, 0, 0, 4, 1, +#' 0, 0, 0, 0, 3, +#' 0, 0, 0, 0, 0 +#' ) +#' family <- matrix(family, 5, 5) +#' +#' # define R-vine pair-copula parameter matrix +#' par <- c( +#' 0, 0.2, 0.9, 1.5, 3.9, +#' 0, 0, 1.1, 1.6, 0.9, +#' 0, 0, 0, 1.9, 0.5, +#' 0, 0, 0, 0, 4.8, +#' 0, 0, 0, 0, 0 +#' ) +#' par <- matrix(par, 5, 5) +#' +#' # define second R-vine pair-copula parameter matrix +#' par2 <- matrix(0, 5, 5) +#' +#' # define RVineMatrix object +#' RVM <- RVineMatrix( +#' Matrix = Matrix, family = family, +#' par = par, par2 = par2, +#' names = c("V1", "V2", "V3", "V4", "V5") +#' ) +#' +#' # compute the CDF at (0.1, 0.2, 0.3, 0.4, 0.5) +#' RVineCDF(c(0.1, 0.2, 0.3, 0.4, 0.5), RVM) +#' +RVineCDF <- function(data, RVM, N = 1000) { + # Preprocess arguments + args <- preproc( + c(as.list(environment()), call = match.call()), + check_data, + fix_nas, + check_if_01, + check_RVMs, + prep_RVMs + ) + list2env(args, environment()) + + # Simulate N random numbers from the vine model + u_sim <- RVineSim(N, RVM) + + # Initialize output vector + n <- nrow(data) + vine_distribution <- numeric(n) + + # Compute the cumulative distribution + for (i in seq_len(n)) { + temp <- data[i, ] + + # Calculate the maximum difference row-wise between u_sim and temp + x <- apply(u_sim, 1, function(row) max(row - temp)) + + # Count occurrences where all differences are <= 0 + vine_distribution[i] <- sum(x <= 0) + } + + # Return normalized cumulative distribution + return(vine_distribution / N) +} \ No newline at end of file diff --git a/README.md b/README.md index 2d56c14..e5b8b73 100644 --- a/README.md +++ b/README.md @@ -160,8 +160,8 @@ specifying `family`, `par` and `par2` manually. * `RVinePar2Tau`, `RVinePar2Beta`: Calculate dependence measures corresponding to a vine copula model. - * `RVinePDF`, `RVineLogLik`, `RVineAIC`, `RVineBIC`: Calculate the density, - log-likelihood, AIC, and BIC of a vine copula. +* `RVinePDF`, `RVineCDF`, `RVineLogLik`, `RVineAIC`, `RVineBIC`: Calculate the density, + cumulative distribution, log-likelihood, AIC, and BIC of a vine copula. ### Additional features diff --git a/man/RVineCDF.Rd b/man/RVineCDF.Rd new file mode 100644 index 0000000..c3314a0 --- /dev/null +++ b/man/RVineCDF.Rd @@ -0,0 +1,83 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/RVineLogLik.R +\name{RVineCDF} +\alias{RVineCDF} +\title{CDF of an R-Vine Copula Model} +\usage{ +RVineCDF(data, RVM, N = 1000) +} +\arguments{ +\item{data}{An N x d data matrix that specifies where +the CDF shall be evaluated.} + +\item{RVM}{An \code{\link[=RVineMatrix]{RVineMatrix()}} object including the +structure and the pair-copula families and parameters.} + +\item{N}{Number of points to simulate for the Monte +Carlo integration (default: \code{n = 1000}).} +} +\value{ +A vector of length N with the CDF values. +} +\description{ +This function calculates the cumulative distribution +function of a d-dimensional R-vine copula. +} +\details{ +The cumulative distribution function of a \eqn{d}-dimensional R-vine copula +cannot be expressed in closed form. +However, it can be calculated by numerical integration. The function uses +the \code{\link[=RVineSim]{RVineSim()}} function to +simulate a grid of points and then computes the CDF via Monte Carlo. +} +\examples{ +# define 5-dimensional R-vine tree structure matrix +Matrix <- c( + 5, 2, 3, 1, 4, + 0, 2, 3, 4, 1, + 0, 0, 3, 4, 1, + 0, 0, 0, 4, 1, + 0, 0, 0, 0, 1 +) +Matrix <- matrix(Matrix, 5, 5) + +# define R-vine pair-copula family matrix +family <- c( + 0, 1, 3, 4, 4, + 0, 0, 3, 4, 1, + 0, 0, 0, 4, 1, + 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0 +) +family <- matrix(family, 5, 5) + +# define R-vine pair-copula parameter matrix +par <- c( + 0, 0.2, 0.9, 1.5, 3.9, + 0, 0, 1.1, 1.6, 0.9, + 0, 0, 0, 1.9, 0.5, + 0, 0, 0, 0, 4.8, + 0, 0, 0, 0, 0 +) +par <- matrix(par, 5, 5) + +# define second R-vine pair-copula parameter matrix +par2 <- matrix(0, 5, 5) + +# define RVineMatrix object +RVM <- RVineMatrix( + Matrix = Matrix, family = family, + par = par, par2 = par2, + names = c("V1", "V2", "V3", "V4", "V5") +) + +# compute the CDF at (0.1, 0.2, 0.3, 0.4, 0.5) +RVineCDF(c(0.1, 0.2, 0.3, 0.4, 0.5), RVM) + +} +\seealso{ +\code{\link[=RVineSim]{RVineSim()}}, \code{\link[=RVineMatrix]{RVineMatrix()}}, \code{\link[=RVineLogLik]{RVineLogLik()}}, \code{\link[=RVinePDF]{RVinePDF()}} +} +\author{ +Thibault Vatter +} diff --git a/tests/other/na_test.R b/tests/other/na_test.R index 03c71da..ada2dc6 100644 --- a/tests/other/na_test.R +++ b/tests/other/na_test.R @@ -418,6 +418,7 @@ stopifnot(inherits(e, "try-error")) e <- try(RVineBIC(simdata, RVM)) stopifnot(inherits(e, "try-error")) + ## RVineClarkeTest/ RVineVuongTest --------------- data(daxreturns) RVM <- RVineMatrix(Matrix = Matrix, family = family, par = par, par2 = par2) @@ -432,6 +433,7 @@ simdata <- RVineSim(10, RVM) simdata[2, 2] <- NA RVineLogLik(simdata, RVM, separate = TRUE) RVineLogLik(simdata, RVM, separate = FALSE) +RVineCDF(simdata, RVM) ## RVineCopSelect ---------------------------- RVM <- RVineMatrix(Matrix = Matrix, family = family, par = par, par2 = par2)