Concepts

A self-contained tour of the ideas behind pyvinecopulib. The emphasis is on the formulas you’ll see in docstrings and the API classes that implement them. Skimming this page first should make the rest of the documentation much easier to navigate; revisit it whenever a docstring throws an unfamiliar symbol your way.

Sklar’s theorem and pseudo-observations

A copula is a multivariate distribution with uniform-\([0, 1]\) marginals. By Sklar’s theorem (Sklar, 1959), every joint distribution \(F\) on \(\mathbb{R}^d\) factorises as

\[F(x_1, \ldots, x_d) \;=\; C\bigl(F_1(x_1), \ldots, F_d(x_d)\bigr),\]

where \(F_1, \ldots, F_d\) are the marginal CDFs and \(C : [0, 1]^d \to [0, 1]\) is the copula. When the marginals are continuous \(C\) is unique. Differentiating both sides gives the corresponding density factorisation

\[f(x_1, \ldots, x_d) \;=\; c\bigl(F_1(x_1), \ldots, F_d(x_d)\bigr) \, \prod_{j=1}^{d} f_j(x_j),\]

so the log-likelihood splits cleanly into a sum of marginal log-likelihoods and a copula log-likelihood:

\[\log f(\mathbf x) \;=\; \log c\bigl(F_1(x_1), \ldots, F_d(x_d)\bigr) \;+\; \sum_{j=1}^{d} \log f_j(x_j).\]

This justifies a two-step inference-functions-for-margins estimator (Joe & Xu, 1996): first fit the \(d\) univariate marginals; then fit the copula on the pseudo-observations

\[\hat u_{ij} \;=\; \hat F_j(x_{ij}), \qquad i = 1, \ldots, n, \; j = 1, \ldots, d.\]

The univariate side is well-trodden — pyvinecopulib uses pyvinecopulib.utils.Kde1d (a boundary-corrected 1-d KDE that also handles ordered-discrete data) for the marginals. Two convenience helpers convert raw data to pseudo-observations and measure dependence on them:

  • pyvinecopulib.utils.to_pseudo_obs() ranks each column to \((0, 1)\), the canonical input shape for the copula classes.

  • pyvinecopulib.utils.wdm() computes weighted versions of Kendall’s \(\tau\), Spearman’s \(\rho\), Blomqvist’s \(\beta\), Hoeffding’s \(D\), and Pearson correlation — margin-free dependence measures that drive both diagnostics and Dissmann’s structure-selection heuristic.

The interesting part is \(c\), and the rest of this page is about how pyvinecopulib represents and fits it.

Bivariate copulas

The atomic object is the bivariate copula pyvinecopulib.core.Bicop. It exposes the standard surface expected from a \(d = 2\) distribution on \([0, 1]^2\):

Pair copulas inside a vine also need h-functions, the partial conditional CDFs

\[\begin{split}h_1(u_1, u_2) \;&=\; \mathbb{P}(U_2 \le u_2 \mid U_1 = u_1) \;=\; \frac{\partial C(u_1, u_2)}{\partial u_1}, \\[4pt] h_2(u_1, u_2) \;&=\; \mathbb{P}(U_1 \le u_1 \mid U_2 = u_2) \;=\; \frac{\partial C(u_1, u_2)}{\partial u_2},\end{split}\]

and their inverses \(h_1^{-1}\), \(h_2^{-1}\). These map to

H-functions are the workhorse of vine evaluation: they turn the \([0, 1]^2\) outputs of one tree into the conditional pseudo-observations consumed by the next, and their inverses drive pyvinecopulib.core.Vinecop.simulate() and pyvinecopulib.core.Vinecop.inverse_rosenblatt().

Every Bicop belongs to one of the families catalogued in Available families below; switch families via pyvinecopulib.core.FitControlsBicop.

Vine structures

Estimating a fully-flexible \(d\)-dimensional copula directly is hard once \(d\) is larger than a handful. Pair-copula constructions (Joe, 1996; Bedford & Cooke, 2001, 2002) sidestep that by decomposing the joint copula density into a product of \(d(d-1)/2\) bivariate building blocks. The order of conditioning is encoded by a graphical object called a vine.

Definition (regular vine)

A regular vine (R-vine) on \(d\) variables is a sequence of trees \((V_t, E_t)\), \(t = 1, \ldots, d - 1\), with

  • \(V_1 = \{1, \ldots, d\}\),

  • \(V_t = E_{t-1}\) for \(t \ge 2\),

  • the proximity condition: two nodes in \((V_{t+1}, E_{t+1})\) are connected only if the corresponding edges in \((V_t, E_t)\) share a node.

A vine copula labels each edge \(e \in E_t\) with a conditioned set \(\{j_e, k_e\}\) and a conditioning set \(D_e \subset \{1, \ldots, d\} \setminus \{j_e, k_e\}\), plus a bivariate pair-copula \(c_{j_e, k_e \mid D_e}\) describing the conditional dependence between \(U_{j_e}\) and \(U_{k_e}\) given \(\mathbf U_{D_e}\). See Czado & Nagler (2022) for a textbook treatment.

In pyvinecopulib the structure object is pyvinecopulib.core.RVineStructure, with the two well-known specialisations

Both can be passed anywhere an R-vine is accepted, and simulate() draws structures uniformly at random (Joe, 2011) — the basis of the Structure selection section below.

Pair-copula construction

With the structure fixed, the vine-copula density factorises as

\[c(\mathbf u) \;=\; \prod_{t = 1}^{d - 1} \prod_{e \in E_t} c_{j_e, k_e \mid D_e}\!\bigl( u_{j_e \mid D_e}, \; u_{k_e \mid D_e} \,\big|\, \mathbf u_{D_e} \bigr),\]

where the conditional pseudo-observations \(u_{j_e \mid D_e} = C_{j_e \mid D_e}(u_{j_e} \mid \mathbf u_{D_e})\) are obtained tree-by-tree from h-functions of the lower-tree pair copulas. Concretely, if an edge in tree \(t + 1\) has conditioned set \(\{j, k\}\) and conditioning set \(D \cup \{\ell\}\), then

\[u_{j \mid D \cup \{\ell\}} \;=\; h_1\!\bigl(u_{j \mid D}, \; u_{\ell \mid D};\; c_{j, \ell \mid D}\bigr),\]

i.e. the conditional pseudo-obs at level \(t + 1\) is an h-function of the pair-copula one level down. This recursive structure is what pyvinecopulib.core.Vinecop.rosenblatt() evaluates forward (data \(\to\) independent uniforms) and what pyvinecopulib.core.Vinecop.inverse_rosenblatt() evaluates backward (uniforms \(\to\) data — used by pyvinecopulib.core.Vinecop.simulate()).

CDF evaluation is harder: there is no closed form for \(C(\mathbf u)\) in general, so pyvinecopulib.core.Vinecop.cdf() uses Monte-Carlo integration with the quasi-random uniforms produced by pyvinecopulib.utils.simulate_uniform() (sobol() or ghalton() sequences). Increase N to trade compute for accuracy.

The same factorisation backs the PyTorch port pyvinecopulib.torch.TorchVinecop (every pair copula is a pyvinecopulib.torch.TorchBicop); its cascade matches the C++ evaluator byte-for-byte and additionally offers a batched=True fast path (one stacked bicop call per tree level).

Simplifying assumption

The conditional pair-copulas in the previous section may, in principle, depend on the conditioning value \(\mathbf u_{D_e}\). The simplifying assumption states that they do not:

\[c_{j_e, k_e \mid D_e}(u, v \mid \mathbf u_{D_e}) \;\equiv\; c_{j_e, k_e \mid D_e}(u, v), \qquad \forall \mathbf u_{D_e}.\]

Under this assumption the model reduces to a collection of two-dimensional copulas, which is what makes vines practical. The choice of vine structure becomes load-bearing — different structures yield different approximations of the same true density. See Stoeber, Joe & Czado (2013), Spanhel & Kurz (2019) and Nagler (2025) for the theoretical discussion. Every fit in pyvinecopulib.core.Vinecop (and hence the sklearn / torch wrappers) uses the simplified model; pyvinecopulib.core.FitControlsVinecop controls which families to consider, which structures to search, and how to truncate the model in higher dimensions.

The backend-neutral VinecopBase can go further: a ConditioningContext lets each pair copula also depend on its conditioning value \(\mathbf u_{D_e}\) (and on external covariates), giving a genuinely non-simplified, conditional vine. This is an advanced extension point (see Extending: custom and conditional pair copulas) — the built-in fit stays simplified.

Available families

Every pair-copula in pyvinecopulib belongs to one of the families below. The first column links the family constant, which lives on pyvinecopulib.families and can be passed to pyvinecopulib.core.FitControlsBicop.family_set (or the same attribute on pyvinecopulib.core.FitControlsVinecop) to restrict the fit-time search space.

Parameter ranges below are the conventional textbook ones; the exact bounds the C++ library enforces are visible via pyvinecopulib.core.Bicop.get_parameters_lower_bounds() and pyvinecopulib.core.Bicop.get_parameters_upper_bounds(). The “Kendall’s \(\tau\)” column lists the closed-form mapping where one exists; otherwise pyvinecopulib.core.Bicop.parameters_to_tau() (and its inverse tau_to_parameters()) implement the numerical conversion.

Family

Identifier

Type

Pars

Range

Rotations

Tail dep.

Kendall’s \(\tau\)

Independence

pyvinecopulib.families.indep

0

none

none

\(0\)

Gaussian

pyvinecopulib.families.gaussian

elliptical

1

\(\rho \in (-1, 1)\)

rotationless

none

\((2/\pi) \arcsin \rho\)

Student

pyvinecopulib.families.student

elliptical

2

\(\rho \in (-1, 1)\), \(\nu > 2\)

rotationless

symmetric

\((2/\pi) \arcsin \rho\)

Clayton

pyvinecopulib.families.clayton

Archimedean

1

\(\theta > 0\)

0° / 90° / 180° / 270°

lower

\(\theta / (\theta + 2)\)

Gumbel

pyvinecopulib.families.gumbel

Arch. / EV

1

\(\theta \ge 1\)

0° / 90° / 180° / 270°

upper

\(1 - 1/\theta\)

Frank

pyvinecopulib.families.frank

Archimedean

1

\(\theta \in \mathbb{R} \setminus \{0\}\)

rotationless

none

via Debye function

Joe

pyvinecopulib.families.joe

Archimedean

1

\(\theta \ge 1\)

0° / 90° / 180° / 270°

upper

series expansion

BB1

pyvinecopulib.families.bb1

Arch. (2-par)

2

\(\theta > 0\), \(\delta \ge 1\)

0° / 90° / 180° / 270°

lower + upper

closed form

BB6

pyvinecopulib.families.bb6

Arch. (2-par)

2

\(\theta \ge 1\), \(\delta \ge 1\)

0° / 90° / 180° / 270°

upper

closed form

BB7

pyvinecopulib.families.bb7

Arch. (2-par)

2

\(\theta \ge 1\), \(\delta > 0\)

0° / 90° / 180° / 270°

lower + upper

closed form

BB8

pyvinecopulib.families.bb8

Arch. (2-par)

2

\(\theta \ge 1\), \(\delta \in (0, 1]\)

0° / 90° / 180° / 270°

upper

closed form

Tawn

pyvinecopulib.families.tawn

extreme-value

3

bounded; see C++ bounds

0° / 90° / 180° / 270°

upper (asymmetric)

via Pickands \(A\)

TLL

pyvinecopulib.families.tll

nonparametric

data-driven

data-driven

rank-based

The non-elliptical, non-radially-symmetric parametric families are labelled with a rotation in \(\{0°, 90°, 180°, 270°\}\); rotation 0° is the base form (positive dependence, lower-tail-heavy for Clayton, upper-tail-heavy for Gumbel / Joe, …), 180° is the survival copula (covers the opposite tail), and 90° / 270° provide negative dependence variants. pyvinecopulib.core.Bicop.flip() flips between rotations 0° \(\leftrightarrow\) 180° and 90° \(\leftrightarrow\) 270°. Each fitted pair copula also reports its tail-dependence coefficients in the four corners of the unit square as the read-only taildep matrix (NaN for tll) and Blomqvist’s \(\beta = 4\,C(0.5, 0.5) - 1\) as beta; the maps parameters_to_taildep() and parameters_to_beta() evaluate them at arbitrary parameters.

Family-group constants (also in pyvinecopulib.families) are pre-built lists you can pass directly to family_set:

  • all — every family listed above.

  • parametric — every family except tll.

  • nonparametricindep and tll.

  • one_par / two_par / three_par — grouped by parameter count (one-parameter parametric / two-parameter parametric / three-parameter parametric).

  • ellipticalgaussian, student.

  • archimedeanclayton, gumbel, frank, joe, bb1, bb6, bb7, bb8.

  • extreme_valuetawn, gumbel.

  • bbbb1, bb6, bb7, bb8.

  • rotationless — families that already cover both positive and negative dependence (indep, gaussian, student, frank, tll).

  • lt / ut — families with lower- / upper-tail dependence.

  • itau — families that support estimation by Kendall’s-\(\tau\) inversion (indep, gaussian, student, clayton, gumbel, frank, joe).

The notebook examples/01_bivariate_copulas.ipynb walks through a fit on synthetic data for several of these families. pyvinecopulib.utils.benchmark() compares several families on standard test problems.

Estimation

Vine fitting is a two-step procedure inherited from Sklar’s theorem and pseudo-observations:

  1. Marginals. Each \(F_j\) is estimated independently — pyvinecopulib.utils.Kde1d (a boundary-corrected 1-d KDE) is the default both for the sklearn estimators and the notebook examples. Kde1d supports continuous, ordered-discrete, and unordered-categorical input via its type argument.

  2. Copula. Given pseudo-observations \(\hat U_{i \cdot} = (\hat F_1(X_{i,1}), \ldots, \hat F_d(X_{i,d}))\), the joint copula is fit by pyvinecopulib.core.Vinecop.from_data() (or pyvinecopulib.core.Vinecop.select() for in-place re-fitting).

The pair-copula estimator on each edge depends on the chosen family. Three regimes are available via pyvinecopulib.core.FitControlsBicop:

  • Maximum likelihood (parametric_method="mle") — the default for parametric families; numerically optimises the per-edge log-likelihood under the family’s parameter constraints.

  • Kendall’s :math:`tau` inversion (parametric_method="itau") — restricted to families in the itau group; uses tau_to_parameters() to back out the parameters from the empirical \(\hat\tau\). Cheaper than MLE and the conventional choice for very high-dimensional vines.

  • Nonparametric TLL (family tllpyvinecopulib.families.tll) — Transformed Local Likelihood (Geenens, 2014; Nagler, 2018). The copula density is estimated on a grid in the inverse-normal-transformed space \((z_1, z_2) = (\Phi^{-1}(u_1), \Phi^{-1}(u_2))\), where local-likelihood machinery is well-behaved at the boundary of the unit square. Bandwidth selection is automatic; the nonparametric_method and nonparametric_mult knobs on FitControlsBicop tune the kernel order and the bandwidth multiplier respectively.

TLL is the default family for both the C++ and PyTorch backends because it captures arbitrary non-Gaussian-like dependence (heavy tails, asymmetry) without committing to a parametric form, and because its density-grid representation is exactly what pyvinecopulib.torch.TorchBicop consumes for GPU and autograd evaluation.

Family selection across the parametric set runs by AIC / BIC / mBIC inside pyvinecopulib.core.Bicop.select(); choose the selection criterion via pyvinecopulib.core.FitControlsBicop.selection_criterion.

For asymptotics on a parametric fit, both Bicop and Vinecop expose the log-likelihood score (scores), its observation-average (gradient), the Hessian (hessian), and the score covariance (scores_cov) at the fitted parameters; on Vinecop these accept an optional per-observation parameters matrix for evaluation off the fitted point.

Structure selection

The vine structure \(\mathcal V\) is rarely known in advance, and the number of regular vines on \(d\) variables grows as \(2^{(d-3)(d-2)/2 - 1} d!\) (Morales-Napoles, 2011; Joe, 2011) — super-exponential, so exhaustive search is infeasible beyond a handful of variables. Two algorithms are exposed via pyvinecopulib.core.FitControlsVinecop.tree_algorithm:

  • "mst_prim" — Dissmann’s greedy heuristic (Dissmann et al., 2013), which is the default. Builds the trees one at a time as maximum-spanning-trees weighted by absolute Kendall’s \(\tau\) (or the criterion of your choice — see tree_criterion). It is fast and remains the de-facto standard (Czado & Nagler, 2022).

  • "random_weighted" — Wilson-weighted random spanning trees; draws a random structure with edge probabilities proportional to the absolute dependence on each candidate edge. Used to seed the random search ensembles below.

Selection is further tunable through FitControlsVinecop: supply a custom edge weight via tree_criterion_function (any callable (data, weights) -> float returning a scalar dependence measure), make random searches reproducible with seeds, and toggle whether rotated families are considered with allow_rotations.

When better accuracy matters more than runtime, the sklearn forest estimators do a Bayesian-style hold-out random search over a set of candidate structures and combine the survivors via a model confidence set (MCS) — see Vine forests and regression. The underlying algorithm is described in Vatter & Nagler (2026).

Vine truncation

For sparse models in higher dimensions, set pyvinecopulib.core.FitControlsVinecop.trunc_lvl to an integer \(T < d - 1\): pair copulas in trees \(T + 1, \ldots, d - 1\) are forced to indep, reducing both fit time and statistical degrees of freedom. The same effect can be triggered automatically via the mBIC criterion (Nagler, 2019).

Conditional sampling and conditioning-aware vines

A fitted vine can sample from the conditional distribution of a subset of variables given fixed values of the rest, via pyvinecopulib.core.Vinecop.simulate_conditional(). The conditioning variables are the last k of the vine order (order): each row of u_cond is one conditioning point and the corresponding output row is drawn from the remaining variables’ distribution conditional on that point (implemented as a Rosenblatt transform of the conditioning variables followed by an inverse Rosenblatt transform, so discrete conditioning variables are supported too).

Because conditioning acts on the order tail, it is most efficient when the conditioning set already sits there. Two tools arrange that:

These operate on the simplified vine’s exact conditional. For fully non-simplified / conditional pair copulas on a custom (e.g. neural) backend, see the extending guide (example notebook 11) instead. A fitted vine’s tree-by-tree decomposition — the conditioned pairs, conditioning sets, and pair-copulas — is available as nested lists through pyvinecopulib.core.Vinecop.get_trees(), and a bare structure round-trips through pyvinecopulib.core.RVineStructure.get_trees() / pyvinecopulib.core.RVineStructure.from_trees().

Vine forests and regression

When a single greedy fit is not enough, pyvinecopulib offers ensemble estimators in pyvinecopulib.sklearn. The recipe is:

  1. Generate \(M\) candidate structures \(\Theta = \{\mathcal V_1, \ldots, \mathcal V_M\}\) — either uniformly at random (Joe’s algorithm) or by Wilson-weighted local random walks around the Dissmann structure.

  2. Fit a vine on each candidate.

  3. Score each candidate on a held-out validation split with a loss \(L\) (negative log-likelihood for density estimation; conditional log-likelihood for regression).

  4. Run a model-confidence-set selector (Hansen, Lunde & Nason, 2011) on the loss matrix to retain only candidates statistically indistinguishable from the best one. The implementation uses the dual-argmin (DA) test of Kim, Ramdas & Tibshirani (2025); see pyvinecopulib.sklearn for method="da_mcs_marg" (per-model coverage; default) vs method="da_mcs_unif" (familywise coverage).

  5. Combine the survivors \(\hat\Theta\) into the MCS mixture

    \[\hat f_{\hat\Theta}(\mathbf z) \;=\; \frac{1}{|\hat\Theta|} \sum_{\mathcal V \in \hat\Theta} \hat f_{\mathcal V, \mathcal D}(\mathbf z).\]

This is what pyvinecopulib.sklearn.VineForestDensity does for joint-density estimation. The single-vine variant pyvinecopulib.sklearn.VineDensity skips steps 1–4 and fits one structure (Dissmann by default).

Vine regression

For conditional inference, fix one variable as the response \(Y\) and stack it with the predictors to model the joint distribution \((Y, \mathbf X)\). Any conditional summary of interest is then solved out of the estimating equation (Nagler, 2018)

\[\int \psi_\beta(y) \, \hat f_{\hat\Theta}(y \mid \mathbf x) \, dy \;=\; 0,\]

with \(\psi_\beta(y) = y - \beta\) recovering the conditional mean \(\beta(\mathbf x) = \mathbb E[Y \mid \mathbf X = \mathbf x]\) and \(\psi_\beta(y) = \mathbb 1\{y < \beta(\mathbf x)\} - \tau\) recovering the conditional \(\tau\)-quantile. In practice the integral is replaced by a weighted sum over a grid \(\{y_1, \ldots, y_G\}\):

\[\sum_{g = 1}^G \psi_\beta(y_g) \, \hat f_Y(y_g) \sum_{\mathcal V \in \hat\Theta} \hat c_{\mathcal V, \mathcal D}\!\bigl( \hat F_Y(\mathbf x), \, \hat F_Y(y_g) \bigr) \;\approx\; 0,\]

which pyvinecopulib.sklearn.VineRegressor (single vine) and pyvinecopulib.sklearn.VineForestRegressor (MCS ensemble) solve numerically. Pass the quantile levels you want via the quantiles= constructor argument; the predicted conditional mean is always returned when mean=True.

The forest classes share the same MCS plumbing as the density forest, and parallelise over candidates via joblib (n_jobs=).

Where to next

The examples/04_discrete_variables.ipynb notebook covers the discrete-margin extension (Panagiotelis, Czado & Joe, 2012; Funk, Nagler & Czado, 2025), which replaces the marginal CDF derivatives in Sklar’s theorem and pseudo-observations by finite differences (transparent to the user — pass var_types=["d", ...] to pyvinecopulib.core.Vinecop.from_data() or set type="d" on pyvinecopulib.utils.Kde1d).

Extending: custom and conditional pair copulas

The evaluators pyvinecopulib.core.Bicop / Vinecop and their PyTorch counterparts pyvinecopulib.torch.TorchBicop / TorchVinecop are concrete implementations of two backend-neutral contracts, evaluated on either NumPy or PyTorch arrays:

  • BicopLike — a pair copula, exposing pdf / cdf / hfunc1 / hfunc2 / hinv1 / hinv2 / simulate;

  • VinecopLike — a fitted vine, exposing pdf / cdf / rosenblatt / inverse_rosenblatt / simulate on an RVineStructure.

You can plug your own pair copula into a vine by implementing the contract — most easily by subclassing the canonical partial implementations BicopBase / VinecopBase, which fill in almost everything from a few primitives. A BicopBase subclass need only define pdf / hfunc1 / hfunc2 and inherits numerical hinv1 / hinv2, simulate, loglik, and plot; a VinecopBase subclass need only return its pairs from _get_pair_copula and inherits the whole tree-by-tree cascade. The bases are pure Python (no PyTorch), so custom pairs also work in a torch-less environment.

Every method carries an optional trailing conditioning matrix x. For the common simplified, unconditional vine it is None everywhere (the default SimplifiedContext). To lift the simplifying assumption, host the pairs under a NonSimplifiedContext: the cascade then assembles each edge’s conditioning-set values \(\mathbf u_{D_e}\) (and any external covariates) into x and threads them to the pair copula, giving a non-simplified / conditional vine. pyvinecopulib.core.VinecopBase.fit() is the seam for fitting such a vine edge by edge.

The examples/11_extending_pyvinecopulib.ipynb notebook is a worked, end-to-end walk-through: a custom Gaussian pair copula hosted first in a simplified vine (matching pyvinecopulib.core.Vinecop.from_structure()) and then made non-simplified and conditional.

References

  • Sklar (1959). Fonctions de répartition à n dimensions et leurs marges. Publ. Inst. Statist. Univ. Paris 8, 229–231.

  • Bedford & Cooke (2001, 2002). Probability density decomposition for conditionally dependent random variables modeled by vines / Vines — a new graphical model for dependent random variables. Annals of Mathematics and Artificial Intelligence 32, 245–268 / Annals of Statistics 30(4), 1031–1068.

  • Joe (1996). Families of m-variate distributions with given margins and m(m-1)/2 bivariate dependence parameters. In: Distributions with Fixed Marginals and Related Topics (IMS Lecture Notes 28), 120–141.

  • Joe & Xu (1996). The estimation method of inference functions for margins for multivariate models. Technical Report 166, Department of Statistics, University of British Columbia.

  • Aas, Czado, Frigessi & Bakken (2009). Pair-copula constructions of multiple dependence. Insurance: Mathematics and Economics 44(2), 182–198.

  • Dissmann, Brechmann, Czado & Kurowicka (2013). Selecting and estimating regular vine copulae and application to financial returns. Computational Statistics & Data Analysis 59, 52–69.

  • Joe (2011). Dependence comparisons of vine copulae with four or more variables. In: Dependence Modeling: Vine Copula Handbook, 139–164.

  • Geenens (2014). Probit Transformation for Kernel Density Estimation on the Unit Interval. JASA 109(505), 346–358.

  • Hansen, Lunde & Nason (2011). The Model Confidence Set. Econometrica 79(2), 453–497.

  • Nagler (2018). A Generic Approach to Nonparametric Function Estimation with Mixed Data. Statistics & Probability Letters 137, 326–330.

  • Nagler, Schepsmeier, Stoeber, Brechmann, Graeler & Erhardt (2018). VineCopula: Statistical inference of vine copulas. R package.

  • Nagler (2019). Model selection in sparse high-dimensional vine copula models with an application to portfolio risk. Journal of Multivariate Analysis 172, 180–198.

  • Spanhel & Kurz (2019). Simplified vine copula models: approximations based on the simplifying assumption. Electronic Journal of Statistics 13(1), 1254–1291.

  • Czado & Nagler (2022). Vine Copula Based Modeling. Annual Review of Statistics and Its Application 9, 453–477.

  • Panagiotelis, Czado & Joe (2012). Pair Copula Constructions for Multivariate Discrete Data. JASA 107(499), 1063–1072.

  • Funk, Nagler & Czado (2025). Discrete and mixed pair-copula constructions revisited. (In press.)

  • Kim, Ramdas & Tibshirani (2025). Locally simultaneous inference for the model confidence set. arXiv:2410.16092.

  • Vatter & Nagler (2026). Throwing Vines at the Wall: Structure Learning via Random Search. (Preprint.)