Copulas API¶
predict(...) also supports:
given={0: 0.4}for conditional generation in pseudo-observation spacehorizon='current'|'next'for SCAR-TM predictive mixturespredict_config=PredictConfig(...)for explicit prediction optionsrng=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 |
'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
|
**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 |
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: |
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
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Simulated pseudo-observations of shape |
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 |
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
|
predict_config
|
PredictConfig or None
|
Bundled prediction options. Explicit non-default arguments override
corresponding fields in this object.
|
None
|
**kwargs
|
Any
|
Strategy- or vine-specific prediction options. |
{}
|
Returns:
| Type | Description |
|---|---|
ndarray or (ndarray, dict)
|
Predictive pseudo-observations of shape |
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: |
required |
config
|
NumericalConfig or None
|
Numerical and optimizer settings. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Predictive parameter path of shape |
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 |
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: |
required |
config
|
NumericalConfig or None
|
Numerical and optimizer settings. VineCopula post-fit dispatch does
not support this argument and accepts only |
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: |
required |
config
|
NumericalConfig or None
|
Numerical and optimizer settings. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Conditional CDF values of shape |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If |
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
|
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 |
'softplus'
|