pynumerics 2.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pynumerics/__init__.py +73 -0
- pynumerics/_bin/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- pynumerics/_bin/Microsoft.CodeAnalysis.LICENSE.txt +27 -0
- pynumerics/_bin/Microsoft.CodeAnalysis.dll +0 -0
- pynumerics/_bin/Numerics.dll +0 -0
- pynumerics/_bin/pynumerics.runtimeconfig.json +15 -0
- pynumerics/_coverage.py +3825 -0
- pynumerics/_util.py +237 -0
- pynumerics/_version.py +40 -0
- pynumerics/bootstrap.py +593 -0
- pynumerics/callbacks.py +791 -0
- pynumerics/copulas.py +910 -0
- pynumerics/data.py +2233 -0
- pynumerics/differentiation.py +348 -0
- pynumerics/distributions.py +4043 -0
- pynumerics/download.py +623 -0
- pynumerics/enums.py +119 -0
- pynumerics/errors.py +245 -0
- pynumerics/functions.py +1142 -0
- pynumerics/goodness_of_fit.py +699 -0
- pynumerics/graphs.py +556 -0
- pynumerics/hypothesis_tests.py +445 -0
- pynumerics/identity.py +144 -0
- pynumerics/integration.py +677 -0
- pynumerics/linalg.py +1408 -0
- pynumerics/machine_learning.py +1335 -0
- pynumerics/marshal.py +733 -0
- pynumerics/mathematics.py +1053 -0
- pynumerics/mcmc.py +1406 -0
- pynumerics/multivariate.py +1539 -0
- pynumerics/ode.py +156 -0
- pynumerics/optimization.py +1736 -0
- pynumerics/probability.py +966 -0
- pynumerics/py.typed +0 -0
- pynumerics/regional.py +522 -0
- pynumerics/roots.py +274 -0
- pynumerics/runtime.py +384 -0
- pynumerics/sampling.py +1758 -0
- pynumerics/special.py +1079 -0
- pynumerics/statistics.py +1958 -0
- pynumerics/timeseries.py +1326 -0
- pynumerics-2.3.0.dist-info/METADATA +142 -0
- pynumerics-2.3.0.dist-info/RECORD +46 -0
- pynumerics-2.3.0.dist-info/WHEEL +5 -0
- pynumerics-2.3.0.dist-info/licenses/LICENSE +10 -0
- pynumerics-2.3.0.dist-info/top_level.txt +1 -0
pynumerics/copulas.py
ADDED
|
@@ -0,0 +1,910 @@
|
|
|
1
|
+
"""Bivariate copulas from ``Numerics.Distributions.Copulas``.
|
|
2
|
+
|
|
3
|
+
Every class wraps one .NET copula (``.net``). Paired (u, v) arrays cross once into the
|
|
4
|
+
``(IList<double>, IList<double>)`` overloads of ``BivariateCopula`` where Numerics has them, and
|
|
5
|
+
are evaluated pair by pair with the scalar member otherwise. Parameter estimation
|
|
6
|
+
(``BivariateCopulaEstimation.Estimate``), the factory (``CopulaFactory``) and the XML round trip
|
|
7
|
+
(``ToXElement`` and ``CopulaFactory.CreateCopula(XElement)``) are Numerics calls.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
from pynumerics._util import bind, loop, namespace, net_enum, unwrap
|
|
17
|
+
from pynumerics.distributions import FrozenDistribution, UnivariateDistribution
|
|
18
|
+
from pynumerics.distributions import wrap as wrap_univariate
|
|
19
|
+
from pynumerics.enums import NetEnum
|
|
20
|
+
from pynumerics.errors import translate_public
|
|
21
|
+
from pynumerics.marshal import to_net_doubles, to_numpy_doubles, to_numpy_matrix
|
|
22
|
+
from pynumerics.multivariate import _draw, _message
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _nc() -> Any:
|
|
26
|
+
"""Return the ``Numerics.Distributions.Copulas`` namespace after starting the runtime."""
|
|
27
|
+
return namespace("Numerics.Distributions.Copulas")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CopulaType(NetEnum):
|
|
31
|
+
"""Copula families (``Numerics.Distributions.Copulas.CopulaType``)."""
|
|
32
|
+
|
|
33
|
+
ALI_MIKHAIL_HAQ = "AliMikhailHaq"
|
|
34
|
+
CLAYTON = "Clayton"
|
|
35
|
+
FRANK = "Frank"
|
|
36
|
+
GUMBEL = "Gumbel"
|
|
37
|
+
JOE = "Joe"
|
|
38
|
+
NORMAL = "Normal"
|
|
39
|
+
STUDENT_T = "StudentT"
|
|
40
|
+
INDEPENDENCE = "Independence"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class CopulaEstimationMethod(NetEnum):
|
|
44
|
+
"""Copula estimation methods (``Numerics.Distributions.Copulas.CopulaEstimationMethod``)."""
|
|
45
|
+
|
|
46
|
+
FULL_LIKELIHOOD = "FullLikelihood"
|
|
47
|
+
PSEUDO_LIKELIHOOD = "PseudoLikelihood"
|
|
48
|
+
INFERENCE_FROM_MARGINS = "InferenceFromMargins"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _pairwise(u: Any, v: Any, copula: Any, name: str) -> Any:
|
|
52
|
+
"""Evaluate a (u, v) copula member over broadcast arrays.
|
|
53
|
+
|
|
54
|
+
A scalar pair calls the ``(double, double)`` overload. Arrays cross once into the
|
|
55
|
+
``(IList<double>, IList<double>)`` overload of ``BivariateCopula`` when the member has one, or
|
|
56
|
+
pair by pair otherwise; every value is the scalar member's. Both overloads are bound once per
|
|
57
|
+
copula object.
|
|
58
|
+
"""
|
|
59
|
+
import System # noqa: PLC0415 - the runtime is running (the copula exists)
|
|
60
|
+
from System.Collections.Generic import IList # noqa: PLC0415
|
|
61
|
+
|
|
62
|
+
cache = copula.__dict__.setdefault("_bound", {})
|
|
63
|
+
entry = cache.get(name)
|
|
64
|
+
if entry is None or entry[0] is not copula.net:
|
|
65
|
+
group = getattr(copula.net, name)
|
|
66
|
+
scalar = group.Overloads[System.Double, System.Double]
|
|
67
|
+
try:
|
|
68
|
+
vector = group.Overloads[IList[System.Double], IList[System.Double]]
|
|
69
|
+
except (KeyError, TypeError):
|
|
70
|
+
vector = None
|
|
71
|
+
entry = cache[name] = (copula.net, scalar, vector)
|
|
72
|
+
_, scalar, vector = entry
|
|
73
|
+
uu, vv = np.broadcast_arrays(np.asarray(u, dtype=np.float64), np.asarray(v, dtype=np.float64))
|
|
74
|
+
if uu.ndim == 0:
|
|
75
|
+
return float(scalar(float(uu), float(vv)))
|
|
76
|
+
if vector is not None:
|
|
77
|
+
return to_numpy_doubles(vector(to_net_doubles(uu.ravel()), to_net_doubles(vv.ravel()))).reshape(uu.shape)
|
|
78
|
+
out = np.empty(uu.size, dtype=np.float64)
|
|
79
|
+
for index, (a, b) in enumerate(zip(uu.ravel(), vv.ravel(), strict=True)):
|
|
80
|
+
out[index] = scalar(float(a), float(b))
|
|
81
|
+
return out.reshape(uu.shape)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _marginal_net(distribution: UnivariateDistribution | None) -> Any:
|
|
85
|
+
"""Return the .NET marginal to attach: None, the distribution's object, or a clone of a frozen one.
|
|
86
|
+
|
|
87
|
+
A frozen distribution is read-only, and estimation with the full likelihood refits attached
|
|
88
|
+
marginals in place, so a frozen marginal is attached as a clone.
|
|
89
|
+
"""
|
|
90
|
+
if distribution is None:
|
|
91
|
+
return None
|
|
92
|
+
if isinstance(distribution, FrozenDistribution):
|
|
93
|
+
return distribution.net.Clone()
|
|
94
|
+
return distribution.net
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class BivariateCopula:
|
|
98
|
+
"""A wrapped ``Numerics.Distributions.Copulas.BivariateCopula``.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
net : Numerics.Distributions.Copulas.BivariateCopula
|
|
103
|
+
The .NET copula.
|
|
104
|
+
|
|
105
|
+
Attributes
|
|
106
|
+
----------
|
|
107
|
+
net : Numerics.Distributions.Copulas.BivariateCopula
|
|
108
|
+
The wrapped .NET object.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
def __init__(self, net: Any) -> None:
|
|
112
|
+
self.net = unwrap(net)
|
|
113
|
+
|
|
114
|
+
def _attach(self, marginal_x: UnivariateDistribution | None, marginal_y: UnivariateDistribution | None) -> None:
|
|
115
|
+
"""Attach the marginals given to a constructor, leaving unset ones untouched."""
|
|
116
|
+
if marginal_x is not None or marginal_y is not None:
|
|
117
|
+
self.set_marginals(marginal_x, marginal_y)
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def type(self) -> CopulaType:
|
|
121
|
+
"""The copula family (``Type``)."""
|
|
122
|
+
return CopulaType(str(self.net.Type))
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def display_name(self) -> str:
|
|
126
|
+
"""The Numerics display name."""
|
|
127
|
+
return str(self.net.DisplayName)
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def short_display_name(self) -> str:
|
|
131
|
+
"""The Numerics short display name."""
|
|
132
|
+
return str(self.net.ShortDisplayName)
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def theta(self) -> float:
|
|
136
|
+
"""The dependence parameter θ (ρ for the normal and Student-t copulas); settable."""
|
|
137
|
+
return float(self.net.Theta)
|
|
138
|
+
|
|
139
|
+
@theta.setter
|
|
140
|
+
def theta(self, value: float) -> None:
|
|
141
|
+
self.net.Theta = float(value)
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def theta_minimum(self) -> float:
|
|
145
|
+
"""The smallest admissible θ."""
|
|
146
|
+
return float(self.net.ThetaMinimum)
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def theta_maximum(self) -> float:
|
|
150
|
+
"""The largest admissible θ."""
|
|
151
|
+
return float(self.net.ThetaMaximum)
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def parameter_to_string(self) -> tuple[tuple[str, ...], ...]:
|
|
155
|
+
"""The parameter names and values as Numerics formats them, one (name, value) row per parameter."""
|
|
156
|
+
table = self.net.ParameterToString
|
|
157
|
+
return tuple(tuple(str(table[i, j]) for j in range(table.GetLength(1))) for i in range(table.GetLength(0)))
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def parameter_name_short_form(self) -> str:
|
|
161
|
+
"""The short parameter name (for example θ or ρ)."""
|
|
162
|
+
return str(self.net.ParameterNameShortForm)
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def parameter_property_name(self) -> str:
|
|
166
|
+
"""The name of the parameter property (``GetParameterPropertyName``)."""
|
|
167
|
+
return str(self.net.GetParameterPropertyName)
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def parameters_valid(self) -> bool:
|
|
171
|
+
"""Whether the current parameters are valid (``ParametersValid``)."""
|
|
172
|
+
return bool(self.net.ParametersValid)
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def upper_tail_dependence(self) -> float:
|
|
176
|
+
"""The upper tail dependence coefficient λ_U."""
|
|
177
|
+
return float(self.net.UpperTailDependence)
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def lower_tail_dependence(self) -> float:
|
|
181
|
+
"""The lower tail dependence coefficient λ_L."""
|
|
182
|
+
return float(self.net.LowerTailDependence)
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def number_of_copula_parameters(self) -> int:
|
|
186
|
+
"""The number of copula parameters (0, 1, or 2 for the Student-t copula)."""
|
|
187
|
+
return int(self.net.NumberOfCopulaParameters)
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def copula_parameters(self) -> np.ndarray:
|
|
191
|
+
"""The copula parameters in Numerics order (``GetCopulaParameters``)."""
|
|
192
|
+
return to_numpy_doubles(self.net.GetCopulaParameters)
|
|
193
|
+
|
|
194
|
+
def set_copula_parameters(self, parameters: Any) -> None:
|
|
195
|
+
"""Set the copula parameters in Numerics order (``SetCopulaParameters``).
|
|
196
|
+
|
|
197
|
+
Parameters
|
|
198
|
+
----------
|
|
199
|
+
parameters : array_like
|
|
200
|
+
One value per copula parameter.
|
|
201
|
+
"""
|
|
202
|
+
self.net.SetCopulaParameters(to_net_doubles(parameters))
|
|
203
|
+
|
|
204
|
+
def validate_parameter(self, parameter: float) -> str | None:
|
|
205
|
+
"""Return why a dependence parameter is invalid, or None when it is valid.
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
parameter : float
|
|
210
|
+
Candidate θ.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
str or None
|
|
215
|
+
The Numerics message of ``ValidateParameter(parameter, false)``, or None.
|
|
216
|
+
"""
|
|
217
|
+
return _message(self.net.ValidateParameter(float(parameter), False))
|
|
218
|
+
|
|
219
|
+
def parameter_constraints(self, x: Any, y: Any) -> np.ndarray:
|
|
220
|
+
"""Return the search bounds of each copula parameter for a sample (``ParameterConstraints``).
|
|
221
|
+
|
|
222
|
+
Parameters
|
|
223
|
+
----------
|
|
224
|
+
x : array_like
|
|
225
|
+
Sample of the first variable.
|
|
226
|
+
y : array_like
|
|
227
|
+
Sample of the second variable.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
numpy.ndarray
|
|
232
|
+
Array of shape ``(number_of_copula_parameters, 2)`` of lower and upper bounds.
|
|
233
|
+
"""
|
|
234
|
+
return to_numpy_matrix(self.net.ParameterConstraints(to_net_doubles(x), to_net_doubles(y)))
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def marginal_distribution_x(self) -> UnivariateDistribution | None:
|
|
238
|
+
"""The marginal of the first variable, or None; settable (a frozen marginal is attached as a clone)."""
|
|
239
|
+
net = self.net.MarginalDistributionX
|
|
240
|
+
return None if net is None else wrap_univariate(net)
|
|
241
|
+
|
|
242
|
+
@marginal_distribution_x.setter
|
|
243
|
+
def marginal_distribution_x(self, value: UnivariateDistribution | None) -> None:
|
|
244
|
+
self.net.MarginalDistributionX = _marginal_net(value)
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def marginal_distribution_y(self) -> UnivariateDistribution | None:
|
|
248
|
+
"""The marginal of the second variable, or None; settable (a frozen marginal is attached as a clone)."""
|
|
249
|
+
net = self.net.MarginalDistributionY
|
|
250
|
+
return None if net is None else wrap_univariate(net)
|
|
251
|
+
|
|
252
|
+
@marginal_distribution_y.setter
|
|
253
|
+
def marginal_distribution_y(self, value: UnivariateDistribution | None) -> None:
|
|
254
|
+
self.net.MarginalDistributionY = _marginal_net(value)
|
|
255
|
+
|
|
256
|
+
def set_marginals(self, x: UnivariateDistribution | None, y: UnivariateDistribution | None) -> None:
|
|
257
|
+
"""Set the marginal distributions used by sampling and the likelihoods.
|
|
258
|
+
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
x : UnivariateDistribution or None
|
|
262
|
+
Marginal of the first variable.
|
|
263
|
+
y : UnivariateDistribution or None
|
|
264
|
+
Marginal of the second variable.
|
|
265
|
+
|
|
266
|
+
Notes
|
|
267
|
+
-----
|
|
268
|
+
The copula holds the distribution's own .NET object, so estimation with the full
|
|
269
|
+
likelihood refits it in place; a frozen distribution is attached as a clone.
|
|
270
|
+
"""
|
|
271
|
+
self.net.MarginalDistributionX = _marginal_net(x)
|
|
272
|
+
self.net.MarginalDistributionY = _marginal_net(y)
|
|
273
|
+
|
|
274
|
+
def pdf(self, u: Any, v: Any) -> Any:
|
|
275
|
+
"""Return the copula density c(u, v).
|
|
276
|
+
|
|
277
|
+
Parameters
|
|
278
|
+
----------
|
|
279
|
+
u : float or array_like
|
|
280
|
+
First uniform margin.
|
|
281
|
+
v : float or array_like
|
|
282
|
+
Second uniform margin, broadcast with ``u``.
|
|
283
|
+
|
|
284
|
+
Returns
|
|
285
|
+
-------
|
|
286
|
+
float or numpy.ndarray
|
|
287
|
+
Densities.
|
|
288
|
+
"""
|
|
289
|
+
return _pairwise(u, v, self, "PDF")
|
|
290
|
+
|
|
291
|
+
def log_pdf(self, u: Any, v: Any) -> Any:
|
|
292
|
+
"""Return the log copula density log c(u, v) (``LogPDF``).
|
|
293
|
+
|
|
294
|
+
Parameters
|
|
295
|
+
----------
|
|
296
|
+
u : float or array_like
|
|
297
|
+
First uniform margin.
|
|
298
|
+
v : float or array_like
|
|
299
|
+
Second uniform margin, broadcast with ``u``.
|
|
300
|
+
|
|
301
|
+
Returns
|
|
302
|
+
-------
|
|
303
|
+
float or numpy.ndarray
|
|
304
|
+
Log-densities.
|
|
305
|
+
"""
|
|
306
|
+
return _pairwise(u, v, self, "LogPDF")
|
|
307
|
+
|
|
308
|
+
def cdf(self, u: Any, v: Any) -> Any:
|
|
309
|
+
"""Return the copula C(u, v).
|
|
310
|
+
|
|
311
|
+
Parameters
|
|
312
|
+
----------
|
|
313
|
+
u : float or array_like
|
|
314
|
+
First uniform margin.
|
|
315
|
+
v : float or array_like
|
|
316
|
+
Second uniform margin, broadcast with ``u``.
|
|
317
|
+
|
|
318
|
+
Returns
|
|
319
|
+
-------
|
|
320
|
+
float or numpy.ndarray
|
|
321
|
+
Joint non-exceedance probabilities.
|
|
322
|
+
"""
|
|
323
|
+
return _pairwise(u, v, self, "CDF")
|
|
324
|
+
|
|
325
|
+
def or_joint_exceedance_probability(self, u: Any, v: Any) -> Any:
|
|
326
|
+
"""Return P(U > u or V > v) = 1 − C(u, v) (``ORJointExceedanceProbability``).
|
|
327
|
+
|
|
328
|
+
Parameters
|
|
329
|
+
----------
|
|
330
|
+
u : float or array_like
|
|
331
|
+
First uniform margin.
|
|
332
|
+
v : float or array_like
|
|
333
|
+
Second uniform margin, broadcast with ``u``.
|
|
334
|
+
|
|
335
|
+
Returns
|
|
336
|
+
-------
|
|
337
|
+
float or numpy.ndarray
|
|
338
|
+
Probabilities that either variable exceeds its threshold.
|
|
339
|
+
"""
|
|
340
|
+
return _pairwise(u, v, self, "ORJointExceedanceProbability")
|
|
341
|
+
|
|
342
|
+
def and_joint_exceedance_probability(self, u: Any, v: Any) -> Any:
|
|
343
|
+
"""Return P(U > u and V > v) = 1 − u − v + C(u, v) (``ANDJointExceedanceProbability``).
|
|
344
|
+
|
|
345
|
+
Parameters
|
|
346
|
+
----------
|
|
347
|
+
u : float or array_like
|
|
348
|
+
First uniform margin.
|
|
349
|
+
v : float or array_like
|
|
350
|
+
Second uniform margin, broadcast with ``u``.
|
|
351
|
+
|
|
352
|
+
Returns
|
|
353
|
+
-------
|
|
354
|
+
float or numpy.ndarray
|
|
355
|
+
Probabilities that both variables exceed their thresholds.
|
|
356
|
+
"""
|
|
357
|
+
return _pairwise(u, v, self, "ANDJointExceedanceProbability")
|
|
358
|
+
|
|
359
|
+
def conditional_cdf(self, u: Any, v: Any) -> Any:
|
|
360
|
+
"""Return the conditional CDF ``ConditionalCDF(u, v)``.
|
|
361
|
+
|
|
362
|
+
Parameters
|
|
363
|
+
----------
|
|
364
|
+
u : float or array_like
|
|
365
|
+
First uniform margin.
|
|
366
|
+
v : float or array_like
|
|
367
|
+
Second uniform margin, broadcast with ``u``.
|
|
368
|
+
|
|
369
|
+
Returns
|
|
370
|
+
-------
|
|
371
|
+
float or numpy.ndarray
|
|
372
|
+
Conditional probabilities.
|
|
373
|
+
"""
|
|
374
|
+
return _pairwise(u, v, self, "ConditionalCDF")
|
|
375
|
+
|
|
376
|
+
def inverse_conditional_cdf(self, u: Any, t: Any) -> Any:
|
|
377
|
+
"""Return the inverse conditional CDF ``InverseConditionalCDF(u, t)``.
|
|
378
|
+
|
|
379
|
+
Parameters
|
|
380
|
+
----------
|
|
381
|
+
u : float or array_like
|
|
382
|
+
Conditioning margin.
|
|
383
|
+
t : float or array_like
|
|
384
|
+
Conditional probability.
|
|
385
|
+
|
|
386
|
+
Returns
|
|
387
|
+
-------
|
|
388
|
+
float or numpy.ndarray
|
|
389
|
+
The second margin v.
|
|
390
|
+
"""
|
|
391
|
+
return _pairwise(u, t, self, "InverseConditionalCDF")
|
|
392
|
+
|
|
393
|
+
def inverse_cdf(self, u: float, v: float) -> np.ndarray:
|
|
394
|
+
"""Map two independent uniforms to a dependent pair (``InverseCDF(u, v)``).
|
|
395
|
+
|
|
396
|
+
Parameters
|
|
397
|
+
----------
|
|
398
|
+
u : float
|
|
399
|
+
First independent uniform.
|
|
400
|
+
v : float
|
|
401
|
+
Second independent uniform.
|
|
402
|
+
|
|
403
|
+
Returns
|
|
404
|
+
-------
|
|
405
|
+
numpy.ndarray
|
|
406
|
+
The dependent uniform pair.
|
|
407
|
+
"""
|
|
408
|
+
return to_numpy_doubles(self.net.InverseCDF(float(u), float(v)))
|
|
409
|
+
|
|
410
|
+
def generate_random_values(self, sample_size: int, seed: Any = -1) -> np.ndarray:
|
|
411
|
+
"""Draw a sample (``GenerateRandomValues``; marginal values when both marginals are set).
|
|
412
|
+
|
|
413
|
+
Parameters
|
|
414
|
+
----------
|
|
415
|
+
sample_size : int
|
|
416
|
+
Number of pairs.
|
|
417
|
+
seed : int or MersenneTwister, optional
|
|
418
|
+
Seed (zero or negative seeds from the clock, not reproducible) or a generator.
|
|
419
|
+
|
|
420
|
+
Returns
|
|
421
|
+
-------
|
|
422
|
+
numpy.ndarray
|
|
423
|
+
Array of shape ``(sample_size, 2)``.
|
|
424
|
+
"""
|
|
425
|
+
return _draw(self.net.GenerateRandomValues, sample_size, seed)
|
|
426
|
+
|
|
427
|
+
def pseudo_log_likelihood(self, x: Any, y: Any) -> float:
|
|
428
|
+
"""Return the pseudo log-likelihood Σ log c(xᵢ, yᵢ) (``PseudoLogLikelihood``).
|
|
429
|
+
|
|
430
|
+
Parameters
|
|
431
|
+
----------
|
|
432
|
+
x : array_like
|
|
433
|
+
Plotting positions of the first variable.
|
|
434
|
+
y : array_like
|
|
435
|
+
Plotting positions of the second variable.
|
|
436
|
+
|
|
437
|
+
Returns
|
|
438
|
+
-------
|
|
439
|
+
float
|
|
440
|
+
The log-likelihood; negative infinity when it is not finite.
|
|
441
|
+
"""
|
|
442
|
+
return float(self.net.PseudoLogLikelihood(to_net_doubles(x), to_net_doubles(y)))
|
|
443
|
+
|
|
444
|
+
def ifm_log_likelihood(self, x: Any, y: Any) -> float:
|
|
445
|
+
"""Return the inference-from-margins log-likelihood Σ log c(F(xᵢ), G(yᵢ)) (``IFMLogLikelihood``).
|
|
446
|
+
|
|
447
|
+
Parameters
|
|
448
|
+
----------
|
|
449
|
+
x : array_like
|
|
450
|
+
Sample of the first variable.
|
|
451
|
+
y : array_like
|
|
452
|
+
Sample of the second variable.
|
|
453
|
+
|
|
454
|
+
Returns
|
|
455
|
+
-------
|
|
456
|
+
float
|
|
457
|
+
The log-likelihood with the attached marginals; negative infinity when it is not finite.
|
|
458
|
+
"""
|
|
459
|
+
return float(self.net.IFMLogLikelihood(to_net_doubles(x), to_net_doubles(y)))
|
|
460
|
+
|
|
461
|
+
def log_likelihood(self, x: Any, y: Any) -> float:
|
|
462
|
+
"""Return the full log-likelihood of copula and marginals (``LogLikelihood``).
|
|
463
|
+
|
|
464
|
+
Parameters
|
|
465
|
+
----------
|
|
466
|
+
x : array_like
|
|
467
|
+
Sample of the first variable.
|
|
468
|
+
y : array_like
|
|
469
|
+
Sample of the second variable.
|
|
470
|
+
|
|
471
|
+
Returns
|
|
472
|
+
-------
|
|
473
|
+
float
|
|
474
|
+
Σ [log c(F(xᵢ), G(yᵢ)) + log f(xᵢ) + log g(yᵢ)]; negative infinity when it is not finite.
|
|
475
|
+
"""
|
|
476
|
+
return float(self.net.LogLikelihood(to_net_doubles(x), to_net_doubles(y)))
|
|
477
|
+
|
|
478
|
+
def estimate(self, x: Any, y: Any,
|
|
479
|
+
method: CopulaEstimationMethod | str = CopulaEstimationMethod.PSEUDO_LIKELIHOOD) -> None:
|
|
480
|
+
"""Fit the copula in place (``BivariateCopulaEstimation.Estimate``).
|
|
481
|
+
|
|
482
|
+
Parameters
|
|
483
|
+
----------
|
|
484
|
+
x : array_like
|
|
485
|
+
Sample of the first variable (plotting positions for the pseudo likelihood).
|
|
486
|
+
y : array_like
|
|
487
|
+
Sample of the second variable (plotting positions for the pseudo likelihood).
|
|
488
|
+
method : CopulaEstimationMethod or str, optional
|
|
489
|
+
Default the pseudo likelihood. Inference from margins needs both marginals attached;
|
|
490
|
+
the full likelihood also refits them, so they must support maximum likelihood.
|
|
491
|
+
|
|
492
|
+
Notes
|
|
493
|
+
-----
|
|
494
|
+
One-parameter copulas are fitted with Brent's method over the parameter constraints and
|
|
495
|
+
the Student-t copula with Nelder-Mead; the full likelihood fits the copula and both
|
|
496
|
+
marginals jointly with Nelder-Mead, restarted once. A zero-parameter copula is unchanged.
|
|
497
|
+
"""
|
|
498
|
+
nc = _nc()
|
|
499
|
+
self.net = unwrap(nc.BivariateCopulaEstimation.Estimate(
|
|
500
|
+
self.net, to_net_doubles(x), to_net_doubles(y), net_enum(nc.CopulaEstimationMethod, method)))
|
|
501
|
+
|
|
502
|
+
def clone(self) -> BivariateCopula:
|
|
503
|
+
"""Return a deep copy, marginals included (``Clone``).
|
|
504
|
+
|
|
505
|
+
Returns
|
|
506
|
+
-------
|
|
507
|
+
BivariateCopula
|
|
508
|
+
A wrapper of the cloned .NET copula, of the matching Python class.
|
|
509
|
+
"""
|
|
510
|
+
return wrap(self.net.Clone())
|
|
511
|
+
|
|
512
|
+
def to_xml(self, include_marginals: bool = False) -> str:
|
|
513
|
+
"""Return the copula's ``ToXElement`` as XML text.
|
|
514
|
+
|
|
515
|
+
Parameters
|
|
516
|
+
----------
|
|
517
|
+
include_marginals : bool, optional
|
|
518
|
+
Also write the attached marginals (``ToXElement(true)``).
|
|
519
|
+
|
|
520
|
+
Returns
|
|
521
|
+
-------
|
|
522
|
+
str
|
|
523
|
+
The element as .NET writes it; :func:`copula_from_xml` reads it back.
|
|
524
|
+
"""
|
|
525
|
+
if not include_marginals:
|
|
526
|
+
return str(self.net.ToXElement().ToString())
|
|
527
|
+
import System # noqa: PLC0415 - the runtime is running (self.net exists)
|
|
528
|
+
|
|
529
|
+
return str(self.net.ToXElement.Overloads[System.Boolean](True).ToString())
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
class ArchimedeanCopula(BivariateCopula):
|
|
533
|
+
"""A wrapped ``Numerics.Distributions.Copulas.ArchimedeanCopula`` with its generator φ.
|
|
534
|
+
|
|
535
|
+
Parameters
|
|
536
|
+
----------
|
|
537
|
+
net : Numerics.Distributions.Copulas.ArchimedeanCopula
|
|
538
|
+
The .NET copula.
|
|
539
|
+
|
|
540
|
+
Notes
|
|
541
|
+
-----
|
|
542
|
+
C(u, v) = φ⁻¹(φ(u) + φ(v)). The generator members accept a scalar or an array, evaluated
|
|
543
|
+
element by element with the bound scalar member.
|
|
544
|
+
"""
|
|
545
|
+
|
|
546
|
+
def _generator_member(self, name: str, t: Any) -> Any:
|
|
547
|
+
"""Evaluate a scalar generator member, bound once per copula object."""
|
|
548
|
+
cache = self.__dict__.setdefault("_generators", {})
|
|
549
|
+
entry = cache.get(name)
|
|
550
|
+
if entry is None or entry[0] is not self.net:
|
|
551
|
+
entry = cache[name] = (self.net, bind(getattr(self.net, name)))
|
|
552
|
+
return loop(t, entry[1])
|
|
553
|
+
|
|
554
|
+
def generator(self, t: Any) -> Any:
|
|
555
|
+
"""Return the generator φ(t) (``Generator``).
|
|
556
|
+
|
|
557
|
+
Parameters
|
|
558
|
+
----------
|
|
559
|
+
t : float or array_like
|
|
560
|
+
Arguments in (0, 1].
|
|
561
|
+
|
|
562
|
+
Returns
|
|
563
|
+
-------
|
|
564
|
+
float or numpy.ndarray
|
|
565
|
+
The value φ(t).
|
|
566
|
+
"""
|
|
567
|
+
return self._generator_member("Generator", t)
|
|
568
|
+
|
|
569
|
+
def generator_inverse(self, t: Any) -> Any:
|
|
570
|
+
"""Return the inverse generator φ⁻¹(t) (``GeneratorInverse``).
|
|
571
|
+
|
|
572
|
+
Parameters
|
|
573
|
+
----------
|
|
574
|
+
t : float or array_like
|
|
575
|
+
Arguments in [0, ∞).
|
|
576
|
+
|
|
577
|
+
Returns
|
|
578
|
+
-------
|
|
579
|
+
float or numpy.ndarray
|
|
580
|
+
The value φ⁻¹(t).
|
|
581
|
+
"""
|
|
582
|
+
return self._generator_member("GeneratorInverse", t)
|
|
583
|
+
|
|
584
|
+
def generator_prime(self, t: Any) -> Any:
|
|
585
|
+
"""Return the first derivative φ′(t) (``GeneratorPrime``).
|
|
586
|
+
|
|
587
|
+
Parameters
|
|
588
|
+
----------
|
|
589
|
+
t : float or array_like
|
|
590
|
+
Arguments in (0, 1].
|
|
591
|
+
|
|
592
|
+
Returns
|
|
593
|
+
-------
|
|
594
|
+
float or numpy.ndarray
|
|
595
|
+
The value φ′(t).
|
|
596
|
+
"""
|
|
597
|
+
return self._generator_member("GeneratorPrime", t)
|
|
598
|
+
|
|
599
|
+
def generator_prime2(self, t: Any) -> Any:
|
|
600
|
+
"""Return the second derivative φ″(t) (``GeneratorPrime2``).
|
|
601
|
+
|
|
602
|
+
Parameters
|
|
603
|
+
----------
|
|
604
|
+
t : float or array_like
|
|
605
|
+
Arguments in (0, 1].
|
|
606
|
+
|
|
607
|
+
Returns
|
|
608
|
+
-------
|
|
609
|
+
float or numpy.ndarray
|
|
610
|
+
The value φ″(t).
|
|
611
|
+
"""
|
|
612
|
+
return self._generator_member("GeneratorPrime2", t)
|
|
613
|
+
|
|
614
|
+
def generator_prime_inverse(self, t: Any) -> Any:
|
|
615
|
+
"""Return the inverse of the first derivative, (φ′)⁻¹(t) (``GeneratorPrimeInverse``).
|
|
616
|
+
|
|
617
|
+
Parameters
|
|
618
|
+
----------
|
|
619
|
+
t : float or array_like
|
|
620
|
+
Values of φ′.
|
|
621
|
+
|
|
622
|
+
Returns
|
|
623
|
+
-------
|
|
624
|
+
float or numpy.ndarray
|
|
625
|
+
The argument whose φ′ is ``t``.
|
|
626
|
+
"""
|
|
627
|
+
return self._generator_member("GeneratorPrimeInverse", t)
|
|
628
|
+
|
|
629
|
+
def set_theta_from_tau(self, x: Any, y: Any) -> None:
|
|
630
|
+
"""Set θ by inverting Kendall's tau of a sample (``SetThetaFromTau``).
|
|
631
|
+
|
|
632
|
+
Parameters
|
|
633
|
+
----------
|
|
634
|
+
x : array_like
|
|
635
|
+
Sample of the first variable.
|
|
636
|
+
y : array_like
|
|
637
|
+
Sample of the second variable.
|
|
638
|
+
"""
|
|
639
|
+
self.net.SetThetaFromTau(to_net_doubles(x), to_net_doubles(y))
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def _build(name: str, parameters: tuple[Any, ...]) -> Any:
|
|
643
|
+
"""Construct a .NET copula with its parameters, or with the Numerics defaults when none are given."""
|
|
644
|
+
net_type = getattr(_nc(), name)
|
|
645
|
+
return net_type(*(float(p) for p in parameters)) if parameters else net_type()
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
class NormalCopula(BivariateCopula):
|
|
649
|
+
"""Gaussian copula.
|
|
650
|
+
|
|
651
|
+
Parameters
|
|
652
|
+
----------
|
|
653
|
+
rho : float, optional
|
|
654
|
+
Correlation ρ; default the Numerics default.
|
|
655
|
+
marginal_x : UnivariateDistribution, optional
|
|
656
|
+
Marginal of the first variable.
|
|
657
|
+
marginal_y : UnivariateDistribution, optional
|
|
658
|
+
Marginal of the second variable.
|
|
659
|
+
"""
|
|
660
|
+
|
|
661
|
+
def __init__(self, rho: float | None = None, marginal_x: UnivariateDistribution | None = None,
|
|
662
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
663
|
+
super().__init__(_build("NormalCopula", () if rho is None else (rho,)))
|
|
664
|
+
self._attach(marginal_x, marginal_y)
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
class StudentTCopula(BivariateCopula):
|
|
668
|
+
"""Student-t copula.
|
|
669
|
+
|
|
670
|
+
Parameters
|
|
671
|
+
----------
|
|
672
|
+
rho : float, optional
|
|
673
|
+
Correlation ρ. Give both ``rho`` and ``degrees_of_freedom``, or neither for the Numerics defaults.
|
|
674
|
+
degrees_of_freedom : float, optional
|
|
675
|
+
Degrees of freedom ν.
|
|
676
|
+
marginal_x : UnivariateDistribution, optional
|
|
677
|
+
Marginal of the first variable.
|
|
678
|
+
marginal_y : UnivariateDistribution, optional
|
|
679
|
+
Marginal of the second variable.
|
|
680
|
+
"""
|
|
681
|
+
|
|
682
|
+
def __init__(self, rho: float | None = None, degrees_of_freedom: float | None = None,
|
|
683
|
+
marginal_x: UnivariateDistribution | None = None,
|
|
684
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
685
|
+
if (rho is None) != (degrees_of_freedom is None):
|
|
686
|
+
raise TypeError("Give both rho and degrees_of_freedom, or neither.")
|
|
687
|
+
parameters = () if rho is None else (rho, degrees_of_freedom)
|
|
688
|
+
super().__init__(_build("StudentTCopula", parameters))
|
|
689
|
+
self._attach(marginal_x, marginal_y)
|
|
690
|
+
|
|
691
|
+
@property
|
|
692
|
+
def degrees_of_freedom(self) -> float:
|
|
693
|
+
"""The degrees of freedom ν; settable."""
|
|
694
|
+
return float(self.net.DegreesOfFreedom)
|
|
695
|
+
|
|
696
|
+
@degrees_of_freedom.setter
|
|
697
|
+
def degrees_of_freedom(self, value: float) -> None:
|
|
698
|
+
self.net.DegreesOfFreedom = float(value)
|
|
699
|
+
|
|
700
|
+
def validate_parameters(self, rho: float, degrees_of_freedom: float) -> str | None:
|
|
701
|
+
"""Return why a correlation and degrees of freedom are invalid, or None when they are valid.
|
|
702
|
+
|
|
703
|
+
Parameters
|
|
704
|
+
----------
|
|
705
|
+
rho : float
|
|
706
|
+
Candidate correlation.
|
|
707
|
+
degrees_of_freedom : float
|
|
708
|
+
Candidate degrees of freedom.
|
|
709
|
+
|
|
710
|
+
Returns
|
|
711
|
+
-------
|
|
712
|
+
str or None
|
|
713
|
+
The Numerics message of ``ValidateParameters(rho, nu, false)``, or None.
|
|
714
|
+
"""
|
|
715
|
+
return _message(self.net.ValidateParameters(float(rho), float(degrees_of_freedom), False))
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
class ClaytonCopula(ArchimedeanCopula):
|
|
719
|
+
"""Clayton copula.
|
|
720
|
+
|
|
721
|
+
Parameters
|
|
722
|
+
----------
|
|
723
|
+
theta : float, optional
|
|
724
|
+
Dependence parameter θ; default the Numerics default.
|
|
725
|
+
marginal_x : UnivariateDistribution, optional
|
|
726
|
+
Marginal of the first variable.
|
|
727
|
+
marginal_y : UnivariateDistribution, optional
|
|
728
|
+
Marginal of the second variable.
|
|
729
|
+
"""
|
|
730
|
+
|
|
731
|
+
def __init__(self, theta: float | None = None, marginal_x: UnivariateDistribution | None = None,
|
|
732
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
733
|
+
super().__init__(_build("ClaytonCopula", () if theta is None else (theta,)))
|
|
734
|
+
self._attach(marginal_x, marginal_y)
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
class GumbelCopula(ArchimedeanCopula):
|
|
738
|
+
"""Gumbel copula.
|
|
739
|
+
|
|
740
|
+
Parameters
|
|
741
|
+
----------
|
|
742
|
+
theta : float, optional
|
|
743
|
+
Dependence parameter θ ≥ 1; default the Numerics default.
|
|
744
|
+
marginal_x : UnivariateDistribution, optional
|
|
745
|
+
Marginal of the first variable.
|
|
746
|
+
marginal_y : UnivariateDistribution, optional
|
|
747
|
+
Marginal of the second variable.
|
|
748
|
+
"""
|
|
749
|
+
|
|
750
|
+
def __init__(self, theta: float | None = None, marginal_x: UnivariateDistribution | None = None,
|
|
751
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
752
|
+
super().__init__(_build("GumbelCopula", () if theta is None else (theta,)))
|
|
753
|
+
self._attach(marginal_x, marginal_y)
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
class FrankCopula(ArchimedeanCopula):
|
|
757
|
+
"""Frank copula.
|
|
758
|
+
|
|
759
|
+
Parameters
|
|
760
|
+
----------
|
|
761
|
+
theta : float, optional
|
|
762
|
+
Dependence parameter θ ≠ 0; default the Numerics default.
|
|
763
|
+
marginal_x : UnivariateDistribution, optional
|
|
764
|
+
Marginal of the first variable.
|
|
765
|
+
marginal_y : UnivariateDistribution, optional
|
|
766
|
+
Marginal of the second variable.
|
|
767
|
+
"""
|
|
768
|
+
|
|
769
|
+
def __init__(self, theta: float | None = None, marginal_x: UnivariateDistribution | None = None,
|
|
770
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
771
|
+
super().__init__(_build("FrankCopula", () if theta is None else (theta,)))
|
|
772
|
+
self._attach(marginal_x, marginal_y)
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
class JoeCopula(ArchimedeanCopula):
|
|
776
|
+
"""Joe copula.
|
|
777
|
+
|
|
778
|
+
Parameters
|
|
779
|
+
----------
|
|
780
|
+
theta : float, optional
|
|
781
|
+
Dependence parameter θ ≥ 1; default the Numerics default.
|
|
782
|
+
marginal_x : UnivariateDistribution, optional
|
|
783
|
+
Marginal of the first variable.
|
|
784
|
+
marginal_y : UnivariateDistribution, optional
|
|
785
|
+
Marginal of the second variable.
|
|
786
|
+
"""
|
|
787
|
+
|
|
788
|
+
def __init__(self, theta: float | None = None, marginal_x: UnivariateDistribution | None = None,
|
|
789
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
790
|
+
super().__init__(_build("JoeCopula", () if theta is None else (theta,)))
|
|
791
|
+
self._attach(marginal_x, marginal_y)
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
class AMHCopula(ArchimedeanCopula):
|
|
795
|
+
"""Ali-Mikhail-Haq copula.
|
|
796
|
+
|
|
797
|
+
Parameters
|
|
798
|
+
----------
|
|
799
|
+
theta : float, optional
|
|
800
|
+
Dependence parameter θ in [−1, 1); default the Numerics default.
|
|
801
|
+
marginal_x : UnivariateDistribution, optional
|
|
802
|
+
Marginal of the first variable.
|
|
803
|
+
marginal_y : UnivariateDistribution, optional
|
|
804
|
+
Marginal of the second variable.
|
|
805
|
+
"""
|
|
806
|
+
|
|
807
|
+
def __init__(self, theta: float | None = None, marginal_x: UnivariateDistribution | None = None,
|
|
808
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
809
|
+
super().__init__(_build("AMHCopula", () if theta is None else (theta,)))
|
|
810
|
+
self._attach(marginal_x, marginal_y)
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
class IndependenceCopula(BivariateCopula):
|
|
814
|
+
"""Independence copula C(u, v) = u·v.
|
|
815
|
+
|
|
816
|
+
Parameters
|
|
817
|
+
----------
|
|
818
|
+
marginal_x : UnivariateDistribution, optional
|
|
819
|
+
Marginal of the first variable.
|
|
820
|
+
marginal_y : UnivariateDistribution, optional
|
|
821
|
+
Marginal of the second variable.
|
|
822
|
+
"""
|
|
823
|
+
|
|
824
|
+
def __init__(self, marginal_x: UnivariateDistribution | None = None,
|
|
825
|
+
marginal_y: UnivariateDistribution | None = None) -> None:
|
|
826
|
+
super().__init__(_build("IndependenceCopula", ()))
|
|
827
|
+
self._attach(marginal_x, marginal_y)
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
_CLASSES: dict[str, type[BivariateCopula]] = {
|
|
831
|
+
"NormalCopula": NormalCopula, "StudentTCopula": StudentTCopula, "ClaytonCopula": ClaytonCopula,
|
|
832
|
+
"GumbelCopula": GumbelCopula, "FrankCopula": FrankCopula, "JoeCopula": JoeCopula, "AMHCopula": AMHCopula,
|
|
833
|
+
"IndependenceCopula": IndependenceCopula,
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
def wrap(net: Any) -> BivariateCopula:
|
|
838
|
+
"""Wrap a .NET bivariate copula in the matching Python class.
|
|
839
|
+
|
|
840
|
+
Parameters
|
|
841
|
+
----------
|
|
842
|
+
net : Numerics.Distributions.Copulas.BivariateCopula or IBivariateCopula
|
|
843
|
+
The .NET object.
|
|
844
|
+
|
|
845
|
+
Returns
|
|
846
|
+
-------
|
|
847
|
+
BivariateCopula
|
|
848
|
+
The specific wrapper class when one exists, otherwise the generic wrapper; the .NET object
|
|
849
|
+
is shared, not copied.
|
|
850
|
+
"""
|
|
851
|
+
concrete = unwrap(net)
|
|
852
|
+
cls = _CLASSES.get(str(concrete.GetType().Name), BivariateCopula)
|
|
853
|
+
instance = cls.__new__(cls)
|
|
854
|
+
BivariateCopula.__init__(instance, concrete)
|
|
855
|
+
return instance
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
def create_copula(copula_type: CopulaType | str) -> BivariateCopula:
|
|
859
|
+
"""Create a copula of a family with its default parameters (``CopulaFactory.CreateCopula``).
|
|
860
|
+
|
|
861
|
+
Parameters
|
|
862
|
+
----------
|
|
863
|
+
copula_type : CopulaType or str
|
|
864
|
+
The family.
|
|
865
|
+
|
|
866
|
+
Returns
|
|
867
|
+
-------
|
|
868
|
+
BivariateCopula
|
|
869
|
+
The typed copula.
|
|
870
|
+
"""
|
|
871
|
+
nc = _nc()
|
|
872
|
+
return wrap(nc.CopulaFactory.CreateCopula(net_enum(nc.CopulaType, copula_type)))
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
def copula_from_xml(xml: str, include_marginals: bool = False) -> BivariateCopula:
|
|
876
|
+
"""Rebuild a copula from :meth:`BivariateCopula.to_xml` text (``CopulaFactory.CreateCopula(XElement)``).
|
|
877
|
+
|
|
878
|
+
Parameters
|
|
879
|
+
----------
|
|
880
|
+
xml : str
|
|
881
|
+
The serialized ``Copula`` element.
|
|
882
|
+
include_marginals : bool, optional
|
|
883
|
+
Also restore the serialized marginals (``CreateCopula(XElement, bool)``).
|
|
884
|
+
|
|
885
|
+
Returns
|
|
886
|
+
-------
|
|
887
|
+
BivariateCopula
|
|
888
|
+
The validated typed copula.
|
|
889
|
+
|
|
890
|
+
Raises
|
|
891
|
+
------
|
|
892
|
+
ValueError
|
|
893
|
+
If the element is malformed or its parameters do not define a valid copula.
|
|
894
|
+
"""
|
|
895
|
+
nc = _nc()
|
|
896
|
+
element = namespace("System.Xml.Linq").XElement.Parse(str(xml))
|
|
897
|
+
if not include_marginals:
|
|
898
|
+
return wrap(nc.CopulaFactory.CreateCopula(element))
|
|
899
|
+
import System # noqa: PLC0415 - the runtime is running
|
|
900
|
+
|
|
901
|
+
return wrap(nc.CopulaFactory.CreateCopula.Overloads[type(element), System.Boolean](element, True))
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
__all__ = [
|
|
905
|
+
"AMHCopula", "ArchimedeanCopula", "BivariateCopula", "ClaytonCopula", "CopulaEstimationMethod", "CopulaType",
|
|
906
|
+
"FrankCopula", "GumbelCopula", "IndependenceCopula", "JoeCopula", "NormalCopula", "StudentTCopula",
|
|
907
|
+
"copula_from_xml", "create_copula", "wrap",
|
|
908
|
+
]
|
|
909
|
+
|
|
910
|
+
translate_public(globals())
|