Beginner tutorial · copulas · JDistlib 0.7.0+

Keep each outcome simple; model their dependence separately

A copula joins marginal distributions through uniform probabilities. Change a margin without rewriting the dependence model, or compare dependence families without changing the margins.

Copula feature · available from 0.7.0

The idea

Margins answer “what”; the copula answers “together how?”

Correlation alone does not describe tail co-movement or asymmetric dependence. Copula families make those choices explicit.

First model · 0.7.0+

Join two continuous margins

import jdistlib.Copula;
import jdistlib.CopulaDistribution;
import jdistlib.Exponential;
import jdistlib.GaussianCopula;
import jdistlib.Normal;

Copula dependence = GaussianCopula.fromKendallsTau(
    new double[][] {{1.0, 0.45}, {0.45, 1.0}});

CopulaDistribution joint = new CopulaDistribution(
    dependence,
    new Normal(10.0, 2.0),
    new Exponential(3.0));

double jointCdf = joint.cumulative(new double[] {11.0, 2.0});
double logDensity = joint.logDensity(new double[] {11.0, 2.0});
double[] repeatableDraw = joint.random(20260826L);

The matrix passed to fromKendallsTau expresses rank dependence. JDistlib converts it to a valid Gaussian-copula correlation representation and rejects invalid inputs.

Discrete and mixed margins · 0.7.0+

Declare which coordinates have jumps

A usual copula density times marginal densities is valid only when every margin is continuous. For counts or categories, use MixedCopulaDistribution; it computes exact CDF rectangle differences for discrete coordinates.

MixedCopulaDistribution mixed = new MixedCopulaDistribution(
    new ClaytonCopula(2, 1.2),
    CopulaMarginal.continuous(new Normal()),
    CopulaMarginal.discrete(new Binomial(1, 0.35)));

CopulaMeasureResult at = mixed.measure(
    new double[] {0.3, 1.0});
if (!at.isSuccess()) {
    throw new ArithmeticException(at.getMessage());
}

CopulaLogLikelihoodResult likelihood =
    mixed.logLikelihoodResult(new double[][] {{0.3, 1.0}});
if (!likelihood.hasEstimate()) {
    throw new ArithmeticException(likelihood.getMessage());
}

measure returns a density with respect to continuous coordinates and probability mass with respect to discrete ones, plus a status and error information when numerical differentiation is needed. From 0.7.2, logLikelihoodResult also retains every row contribution, evaluation cost, numerical error estimate, and the first problematic observation. The original scalar logLikelihood remains available.

Dependence fitting · 0.7.0+

Let criteria compare plausible families

double[][] observations = mixed.random(250, 20260826L);

CopulaSelectionResult choice = CopulaSelector.selectMixed(
    observations,
    new CopulaMarginal[] {
        CopulaMarginal.continuous(new Normal()),
        CopulaMarginal.discrete(new Binomial(1, 0.35))
    },
    new CopulaFitOptions(),
    CopulaSelectionCriterion.BIC,
    CopulaFamily.INDEPENDENCE,
    CopulaFamily.GAUSSIAN,
    CopulaFamily.CLAYTON,
    CopulaFamily.FRANK);

CopulaFitResult selected = choice.getSelected();
CopulaLikelihoodDiagnostics diagnostics = selected.getDiagnostics();
int boundaryHeavyRows = diagnostics.countNearBoundary(1e-6);

Selection ranks only the candidates you provide. Treat AIC or BIC as comparative evidence, then inspect the row-level diagnostics and whether each family's tail behavior makes sense for the domain. Pass a long seed when randomized discrete transforms are desired; the overload above uses deterministic jump midpoints.

More than two dimensions · 0.7.0+

Use vines for pair-by-pair structure

CVineCopula and DVineCopula assemble simplified vines from PairCopula objects. VineFitter estimates sequential trees and can select pair families. A C-vine emphasizes hub variables; a D-vine emphasizes an ordering or chain. Start with an interpretable ordering and remember that the simplified-vine assumption keeps conditional copula parameters constant.

For a first three-dimensional model, read the complete copula contract alongside the JavaDoc.

Before trusting a result

Diagnose boundaries, margins, and identifiability

Unit-cube boundaries

Copula densities are defined on the open unit cube. Inspect CopulaLikelihoodDiagnostics before interpreting boundary-heavy fits.

Marginal fit matters

A copula cannot repair a poor marginal model. Check every margin first.

Discrete data carry less information

Coarse discrete margins can make the underlying copula weakly identifiable. Report uncertainty and compare families.

Own random streams

Use explicit engines or seed overloads for reproducibility and do not share a mutable engine across threads.

Next · still 0.7.0+

Follow a mixed-marginal analysis

The insurance-claims vignette puts composition, simulation, family selection, and interpretation into one workflow.