Skip to content

Copulas API

predict(...) also supports:

  • given={0: 0.4} for conditional generation in pseudo-observation space
  • horizon='current'|'next' for SCAR-TM predictive mixtures
  • predict_config=PredictConfig(...) for explicit prediction options
  • rng=np.random.default_rng(seed) for reproducible Monte Carlo output

See Prediction Semantics for the mathematical meaning of these options.

Top-level API

pyscarcopula.api.fit(copula, data, method='scar-tm-ou', to_pobs=False, config=None, **kwargs)

Fit a copula to data.

Parameters:

Name Type Description Default
copula object

Exact registered built-in copula to fit. The fitted result and training data are also stored on the instance for its stateful convenience methods.

required
data array_like of shape (n_observations, n_dimensions)

Raw observations or pseudo-observations. Bivariate strategies require two columns; multivariate and vine models determine their own width.

required
method str

Estimation strategy name, such as "mle", "scar-tm-ou", "scar-tm-jacobi", or "gas".

'scar-tm-ou'
to_pobs bool

If true, rank-transform each data column before fitting.

False
config NumericalConfig or None

Numerical and optimizer settings. None selects library defaults.

None
**kwargs Any

Strategy-specific fitting options.

{}

Returns:

Type Description
FitResult

Immutable result object appropriate for the selected strategy.

Raises:

Type Description
ValueError

If the data shape or values are invalid.

TypeError

If the selected strategy is incompatible with copula.

NotImplementedError

If the requested strategy/model combination is recognized but not implemented.

pyscarcopula.api.sample(copula, data, result, n, config=None, **kwargs)

Generate n observations reproducing the fitted model.

Simulates a path of length n with time-varying parameter: MLE: r = const for all t SCAR-TM: r(t) = Psi(x(t)), x(t) simulated from OU process SCAR-TM-JACOBI: r(t) from the fitted discrete Jacobi Markov model GAS: r(t) = Psi(g(t)), g(t) via score-driven recursion

fit(copula, sample(...)) should recover similar parameters.

Parameters:

Name Type Description Default
copula object

Fitted copula family or vine model.

required
data array_like of shape (n_observations, n_dimensions)

Used by non-vine strategies where model reproduction requires fitted data. Vine objects retain their fitted edge state and ignore this stateless-dispatch argument.

required
result FitResult

Result returned by :func:fit. Vine models retain their edge results internally.

required
n int

Number of observations to generate.

required
config NumericalConfig or None

Numerical and optimizer settings. VineCopula post-fit dispatch does not support this argument and accepts only None.

None

Returns:

Type Description
ndarray

Simulated pseudo-observations of shape (n, n_dimensions).

pyscarcopula.api.predict(copula, data, result, n, config=None, given=None, horizon='next', predict_config=None, **kwargs)

Sample n observations from the predictive copula distribution.

For edge models, the predictive parameter semantics are: MLE: r = theta_mle (constant) SCAR-TM: mixture sampling from p(x_T | data) or p(x_{T+1} | data) GAS: point estimate Psi(g_T) or Psi(g_{T+1})

given is a conditional sampling argument in pseudo-observation space. For bivariate copulas it may fix coordinate 0 or 1; for vines it fixes vine-level coordinates. For VineCopula, exact conditional generation requires the fixed variables to be representable at the end of the R-vine variable order, either in the fitted matrix itself or after rebuilding an equivalent natural-order matrix. If the model was fitted with given_vars=..., that target set is the advertised fit-time contract for the current exact sampler.

Parameters:

Name Type Description Default
copula object

Fitted copula family or vine model.

required
data array_like

Pseudo-observations used as prediction history. Passed to regular-vine runtimes as their canonical u history.

required
result FitResult

Ignored for vine copulas, which hold fitted edge state internally.

required
given dict[int, float] or None

Fixed pseudo-observation coordinates.

None
horizon ('current', 'next')

Predictive state timing for GAS and SCAR-TM.

'current'
n int

Number of samples.

required
config NumericalConfig or None

Numerical and optimizer settings. VineCopula post-fit dispatch does not support this argument and accepts only None.

None
predict_config PredictConfig or None

Bundled prediction options. Explicit non-default arguments override corresponding fields in this object. dynamic_conditioning, return_diagnostics, mcmc_steps and mcmc_burnin are vine-only options. Non-vine models reject these direct keywords and non-default values in predict_config.

None
**kwargs Any

Strategy- or vine-specific prediction options.

{}

Returns:

Type Description
ndarray or (ndarray, dict)

Predictive pseudo-observations of shape (n, n_dimensions). When diagnostics are requested by a supporting vine model, returns the samples together with a diagnostics mapping.

pyscarcopula.api.predictive_mean(copula, data, result, config=None, **kwargs)

Predictive mean of the time-varying copula parameter.

For MLE: constant array. For SCAR-TM-OU: E[Psi(x_k) | u_{1:k-1}] via transfer matrix. For SCAR-TM-JACOBI: E[theta(tau_k) | u_{1:k-1}]. For GAS: Psi(g_t) along filtered path.

Parameters:

Name Type Description Default
copula object

Fitted copula family.

required
data array_like of shape (n_observations, n_dimensions)

Prediction history in pseudo-observation space.

required
result FitResult

Result returned by :func:fit.

required
config NumericalConfig or None

Numerical and optimizer settings.

None

Returns:

Type Description
ndarray

Predictive parameter path of shape (n_observations,).

pyscarcopula.api.log_likelihood(copula, data, result, config=None, **kwargs)

Evaluate log-likelihood at fitted parameters.

Parameters:

Name Type Description Default
copula object

Copula associated with result.

required
data array_like of shape (n_observations, n_dimensions)

Pseudo-observations at which to evaluate the fitted model.

required
result FitResult

Result returned by :func:fit.

required
config NumericalConfig or None

Numerical and optimizer settings. VineCopula post-fit dispatch does not support this argument and accepts only None.

None
**kwargs Any

Forwarded to the strategy constructor when applicable.

{}

Returns:

Type Description
float

Total log-likelihood over all observations.

pyscarcopula.api.mixture_h(copula, data, result, config=None, **kwargs)

h-function for vine pseudo-observation propagation.

MLE: h_{2|1}(u2 | u1; theta_mle) SCAR: E[h_{2|1}(u2 | u1; Psi(x_k)) | u_{1:k-1}] using predictive weights GAS: h_{2|1}(u2 | u1; Psi(g_t))

The conditional direction uses the original copula's variable order, including for asymmetric 90/270-degree rotations.

Parameters:

Name Type Description Default
copula object

Fitted bivariate copula family.

required
data array_like of shape (n_observations, 2)

Pair pseudo-observations.

required
result FitResult

Result returned by :func:fit.

required
config NumericalConfig or None

Numerical and optimizer settings.

None

Returns:

Type Description
ndarray

Conditional CDF values of shape (n_observations,).

Raises:

Type Description
NotImplementedError

If copula does not provide pair-copula h-functions.

The following complete example evaluates both fitted likelihood and the conditional CDF used by pair-copula and vine calculations:

import numpy as np
from pyscarcopula import GumbelCopula
from pyscarcopula.api import fit, log_likelihood, mixture_h

rng = np.random.default_rng(2026)
source = GumbelCopula(rotate=180)
u = source.sample_at_parameter(200, np.full(200, 1.7), rng=rng)

copula = GumbelCopula(rotate=180)
result = fit(copula, u, method="mle")
fitted_log_likelihood = log_likelihood(copula, u, result)
conditional_cdf = mixture_h(copula, u, result)

BivariateCopula (base class)

BivariateCopula.predict(...) mirrors the top-level API and accepts given, horizon, and predict_config.

BivariateCopula.sample(n, u=None, ...) reproduces the fitted model, matching the multivariate and vine APIs. Use BivariateCopula.sample_at_parameter(n, r, ...) for generation at an explicit copula parameter.

Clayton, Gumbel, Frank and Joe sampling uses native conditional inversion. Their conditional CDFs and inverses use logarithmic formulas in the tails; Gumbel and Joe use safeguarded monotone root solving. Reflected inverse functions preserve small probabilities without first forming 1 - q. These corrections can change fixed-seed results relative to 0.20.1.

Conditional CDFs and inverse CDFs can reach the mathematical endpoints 0 and 1. Unconditional sampling keeps its output in the open unit interval: if an interior result rounds to an endpoint, only that endpoint is moved to the nearest interior float64 value. There is no artificial 1e-10 sampling floor. A failed inverse is reported as an error rather than accepted as a clipped finite sample. This does not guarantee an arbitrarily small CDF residual when the exact inverse lies between adjacent representable float64 values.

pobs(data) computes ordinal ranks in C++ using the standard library: rows are sorted by value and then by their original row index. Equal values receive successive ranks in input order; the ranks are divided by n + 1. Integer comparisons retain their original precision, and NaNs sort last. The optional ties_method="ordinal" selects the same behavior explicitly. Use ties_method="legacy" for the historical 0.20.1 ordering within ties. This mode uses a separate native implementation of the historical ordering rules; it does not require Numba. Equal values still receive different ranks, but their input order is not preserved. Compare versions using the same precomputed pseudo-observations when exact input agreement matters.

All built-in bivariate families share the same fitting surface:

from pyscarcopula import (
    BivariateGaussianCopula,
    ClaytonCopula,
    FrankCopula,
    IndependentCopula,
    JoeCopula,
)

models = [
    ClaytonCopula(),
    FrankCopula(),
    JoeCopula(),
    BivariateGaussianCopula(),
    IndependentCopula(),
]
results = [model.fit(u, method="mle") for model in models]

Kendall-tau dynamic fitting with method='scar-tm-jacobi' requires tau_to_param and param_to_tau. These mappings are implemented for GumbelCopula, ClaytonCopula, FrankCopula, JoeCopula, and BivariateGaussianCopula.

pyscarcopula.copula.base.BivariateCopula

Bases: CopulaBase

Base class for bivariate copulas (dim=2).

Provides copula evaluation, sampling, and backward-compatible object methods for fitting and prediction. The object methods delegate to the stateless functions in pyscarcopula.api and store fit_result for convenience.

Built-in families use the shared native adapter for density, derivatives, transforms, conditional distributions, inverse conditionals, and grids. Subclasses retain family metadata and Kendall-tau behavior. Python owns RNG draws; the fixed-draw sampling transform is native.

Estimation methods (via .fit()): 'mle' — constant parameter (1 param) 'scar-tm-ou' — transfer matrix (3 params: kappa, mu, nu) 'scar-tm-jacobi' - TM for Jacobi Kendall-tau dynamics 'gas' — GAS score-driven (3 params: omega, gamma, beta)

Parameters:

Name Type Description Default
rotate int

Copula rotation: 0, 90, 180, or 270 degrees.

0

pdf(u1, u2, r)

log_pdf(u1, u2, r)

h(u, v, r)

h_inverse(u, v, r)

sample_at_parameter(n, r, rng=None)

Sample at an explicitly supplied copula parameter.

This is the low-level counterpart of :meth:sample, which reproduces a fitted model.

r: scalar or array (n,). Returns (n, 2).

tau_to_param(tau)

Map Kendall's tau to the copula parameter.

param_to_tau(r)

Map the copula parameter to Kendall's tau.

transform(x)

Map latent values to the copula parameter domain.

inv_transform(r)

Map copula parameters to the model's latent convention.

For softplus and Gaussian transforms this is a numerical inverse. For xtanh it is the established modulus-based positive-branch approximation; because x * tanh(x) is even, no globally unique inverse exists and a transform/inverse round trip is not guaranteed.

GumbelCopula

pyscarcopula.copula.gumbel.GumbelCopula

ClaytonCopula

pyscarcopula.copula.clayton.ClaytonCopula

FrankCopula

pyscarcopula.copula.frank.FrankCopula

Frank copula. Rotation is unsupported because it is symmetric.

JoeCopula

pyscarcopula.copula.joe.JoeCopula

IndependentCopula

pyscarcopula.copula.independent.IndependentCopula

Independence copula: C(u1, u2) = u1 * u2.

This is a zero-parameter copula with c(u1, u2) = 1. It serves as the null model for vine edge selection: edges where no parametric copula beats independence by AIC are set to independent, eliminating all fit/forward-pass cost.

BivariateGaussianCopula

pyscarcopula.copula.elliptical.BivariateGaussianCopula

Bivariate Gaussian copula with native numerical operations.

Parameters:

Name Type Description Default
rotate int

Gaussian rotation. Only the unrotated value 0 is supported.

0
transform_type (softplus, xtanh)

Compatibility-only constructor argument used by shared copula and vine configuration flows. It does not select the Gaussian parameter transform: Gaussian models always use the bounded GaussianTanh mapping. The supplied value is retained as configuration metadata but must not be interpreted as applying softplus or xtanh mathematics.

'softplus'