Skip to content

Transform Functions

Overview

The transform function \(\Psi(x)\) maps the latent OU process \(x(t)\) to the copula parameter domain. For example, Gumbel requires \(\theta \ge 1\), so \(\Psi: \mathbb{R} \to [1, \infty)\).

For Archimedean copulas, pyscarcopula provides four selectable transforms. The default is softplus.

Name Formula Properties
softplus \(\log(1 + \exp(x)) + \texttt{offset}\) Default; asymmetric, floor at offset
xtanh \(x \tanh(x) + \texttt{offset}\) Symmetric, linear growth at large \(\lvert x\rvert\)
exp \(\exp(x) + \texttt{offset}\) Positive, asymmetric, exponential growth
logistic \(\texttt{offset} + 20\,\sigma(x/2)\) Bounded to (offset, offset + 20)

Gaussian copulas are different: their correlation parameter always uses the bounded Gaussian tanh mapping. Although BivariateGaussianCopula accepts transform_type='softplus' or 'xtanh', that argument exists only so common copula and vine configuration can be passed to every candidate constructor. It does not change Gaussian mathematics and emits no warning.

Inverse-transform semantics

For softplus, exp, logistic, and the fixed Gaussian tanh transform, inv_transform is a numerical inverse in the interior of the transform range. The exp and logistic links reject finite parameters outside their declared ranges. At an exact range endpoint, inv_transform returns a finite capped latent value for optimizer initialization rather than an infinity; transforming that capped value approaches the endpoint to floating-point precision.

xtanh is deliberately different. The forward function \(x\tanh(x)+\texttt{offset}\) is even, so positive and negative latent values produce the same copula parameter and no globally unique inverse exists. For initialization, pyscarcopula uses the established positive-branch modulus approximation

\[ \operatorname{inv\_transform}(r) = |r| + \texttt{offset}. \]

This is an initialization convention rather than a mathematical inverse. Consequently, transform(inv_transform(r)) == r is not guaranteed for xtanh.

Choosing a transform

This choice applies to Archimedean families such as Gumbel, Clayton, Frank, and Joe. It does not select the transform for Gaussian copulas.

from pyscarcopula import GumbelCopula
from pyscarcopula.api import fit

# Default: softplus
copula = GumbelCopula(rotate=180)

# Explicit softplus
copula = GumbelCopula(rotate=180, transform_type='softplus')
result = fit(copula, u, method='scar-tm-ou')

# Bounded dependence parameter in (1.0001, 21.0001)
bounded = GumbelCopula(rotate=180, transform_type='logistic')

softplus advantages

The softplus transform has a natural floor: the copula parameter cannot go below a minimum value. For Gumbel, \(\theta = 1\) corresponds to independence. Unlike xtanh, softplus is not symmetric around zero and grows linearly only on its positive branch.

xtanh advantages

This transform is even: latent values x and -x produce the same copula parameter. Its inv_transform follows the approximation described above and must not be used when an exact latent round trip is required.

exp advantages

The exponential link is one-to-one and has the same lower limit as softplus, but grows exponentially instead of approximately linearly for large positive states. It is useful only when that stronger response is intended; extreme positive states can overflow and are rejected by the finite-output boundary.

logistic advantages

The logistic link is one-to-one and caps the distance from offset at 20. It can prevent extreme latent states from producing arbitrarily large Archimedean parameters. The bounded range is part of the fitted model and should therefore be selected deliberately rather than treated as a numerical optimization option.

Using with vine

The transform_type parameter propagates through the common constructor flow to all edge copulas in a vine:

from pyscarcopula import VineCopula

vine = VineCopula.cvine(d=u.shape[1])
vine.fit(u, method='scar-tm-ou', transform_type='softplus')

Archimedean edges use the selected transform. Gaussian edges accept only softplus and xtanh as configuration labels and always use GaussianTanh. The default candidate pool includes Gaussian, so it cannot be used with exp or logistic. Select an Archimedean-only pool explicitly:

from pyscarcopula import ClaytonCopula, FrankCopula, GumbelCopula, JoeCopula

bounded_vine = VineCopula.dvine(
    d=u.shape[1],
    candidates=[ClaytonCopula, FrankCopula, GumbelCopula, JoeCopula],
).fit(u, method="mle", transform_type="logistic")

The same restriction applies to fixed edge specifications passed with copulas=. Gaussian edges in a mixed family pool require softplus or xtanh; these labels leave their correlation mapping unchanged.