1"""Python wrappers around C++ copula objects.
3The classes in this module provide a small, Pythonic API over the C++ statistical
4copula implementations. Copulas operate on the unit hypercube: samples returned
5by :meth:`Copula.sample_u` are dependent uniforms, and :meth:`Copula.log_density`
6evaluates the copula density contribution ``log c(u)``.
9from pyhyperiso.core.Statistic.CopulaConfig
import (
13 GaussianCopulaConfigPy,
14 StudentTCopulaConfigPy,
17from typing
import Any, List, Optional, Sequence, Union, cast
18from pyhyperiso.phyperiso.pyhyperiso
import statistic
as st
22 """Base Python wrapper for a bound C++ copula.
24 The wrapper intentionally stores the C++ object as an opaque implementation
25 detail. Use :class:`CopulaFactoryWrapper` to create instances from Python
26 configuration objects.
29 cpp_obj: Bound C++ copula instance.
32 __slots__ = (
"_cpp_obj",)
35 """Store the bound C++ copula object."""
40 """Wrap a bound C++ copula with the most specific Python class.
43 cpp_obj: Bound C++ copula instance.
46 ``GaussianCopula`` for Gaussian C++ objects,
47 ``StudentTCopula`` for Student-t C++ objects, otherwise the generic
50 if isinstance(cpp_obj, st.GaussianCopula):
52 if isinstance(cpp_obj, st.StudentTCopula):
56 def sample_u(self, n: Optional[int] =
None) -> Union[List[float], List[List[float]]]:
57 """Draw one or more dependent uniform samples.
60 n: Number of samples. When omitted, returns a single vector of
61 dependent uniforms. When provided, returns a list of ``n``
65 A single ``list[float]`` if ``n`` is ``None``; otherwise a
66 ``list[list[float]]`` with shape ``n x dim``.
69 ValueError: If ``n`` is negative.
72 >>> cop = CopulaFactoryWrapper.gaussian([[1.0, 0.5], [0.5, 1.0]], seed=123)
73 >>> u = cop.sample_u()
76 >>> U = cop.sample_u(3)
82 return [float(x)
for x
in u]
84 raise ValueError(
"n must be >= 0")
86 return [[float(x)
for x
in row]
for row
in U]
89 """Evaluate the copula log-density at a point in the unit hypercube.
92 u: Uniform coordinates. Each component is expected to lie in
93 ``[0, 1]`` and the length must match the copula dimension.
96 The scalar value ``log c(u)``.
100 def density(self, u: Sequence[float]) -> float:
101 """Evaluate the copula density at a point in the unit hypercube.
104 u: Uniform coordinates passed to :meth:`log_density`.
107 The density value ``c(u)``.
109 return float(pow(2.718281828459045, self.
log_density(u)))
113 """Wrapper for the Gaussian copula backend.
115 The underlying C++ implementation samples a correlated Gaussian latent
116 vector and maps it component-wise through the standard normal CDF.
123 """Wrapper for the Student-t copula backend.
125 The Student-t copula follows the same interface as the Gaussian copula but
126 can model stronger tail dependence through its degrees of freedom.
133 """Factory helpers for creating Python copula wrappers.
135 This class forwards to the C++ ``CopulaFactory`` and wraps the returned C++
136 object in the appropriate Python class.
140 def create(kind: CopulaKind, config: CopulaConfigPy, seed: Optional[int] =
None) -> Copula:
141 """Create a copula from an explicit family and configuration.
144 kind: Copula family to instantiate.
145 config: Python configuration object compatible with ``kind``.
146 seed: Optional random seed passed to the C++ RNG.
149 A Python wrapper around the newly created C++ copula.
151 cpp_kind = kind.to_cpp()
152 cpp_cfg = config.to_cpp()
153 cpp_obj = st.CopulaFactory.create(cpp_kind, cpp_cfg, seed)
154 return Copula.from_cpp(cpp_obj)
157 def gaussian(R: MatrixLike, seed: Optional[int] =
None) -> GaussianCopula:
158 """Create a Gaussian copula from a correlation matrix.
161 R: Square correlation matrix.
162 seed: Optional random seed.
165 A ``GaussianCopula`` instance.
168 >>> cop = CopulaFactoryWrapper.gaussian([[1.0, 0.3], [0.3, 1.0]], seed=7)
169 >>> isinstance(cop.sample_u(), list)
172 cop = CopulaFactoryWrapper.create(
173 CopulaKind.GAUSSIAN, GaussianCopulaConfigPy(R=R), seed=seed
175 return cast(GaussianCopula, cop)
178 def student_t(R: MatrixLike, nu: int = 4, seed: Optional[int] =
None) -> StudentTCopula:
179 """Create a Student-t copula from a correlation matrix.
182 R: Square correlation matrix.
183 nu: Degrees of freedom of the latent Student-t vector.
184 seed: Optional random seed.
187 A ``StudentTCopula`` instance.
189 cop = CopulaFactoryWrapper.create(
190 CopulaKind.STUDENT_T, StudentTCopulaConfigPy(R=R, nu=nu), seed=seed
192 return cast(StudentTCopula, cop)
197 "GaussianCopulaConfigPy",
198 "StudentTCopulaConfigPy",
203 "CopulaFactoryWrapper",
StudentTCopula student_t(MatrixLike R, int nu=4, Optional[int] seed=None)
Copula create(CopulaKind kind, CopulaConfigPy config, Optional[int] seed=None)
GaussianCopula gaussian(MatrixLike R, Optional[int] seed=None)
float density(self, Sequence[float] u)
__init__(self, Any cpp_obj)
float log_density(self, Sequence[float] u)
"Copula" from_cpp(cls, Any cpp_obj)
Union[List[float], List[List[float]]] sample_u(self, Optional[int] n=None)
Student-t copula with correlation matrix and degrees of freedom.