funcsim 0.2.4__tar.gz → 0.2.6__tar.gz
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.
- {funcsim-0.2.4/funcsim.egg-info → funcsim-0.2.6}/PKG-INFO +2 -2
- {funcsim-0.2.4 → funcsim-0.2.6}/README.md +1 -1
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/__init__.py +4 -2
- funcsim-0.2.6/funcsim/copcompare.py +116 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/copfit.py +26 -6
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/dependence.py +402 -9
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/nearby.py +2 -2
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/shrinkage.py +26 -11
- {funcsim-0.2.4 → funcsim-0.2.6/funcsim.egg-info}/PKG-INFO +2 -2
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim.egg-info/SOURCES.txt +1 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/setup.py +1 -1
- {funcsim-0.2.4 → funcsim-0.2.6}/LICENSE +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/MANIFEST.in +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/addist.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/conversions.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/core.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/cpt.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/cvmdist.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/distfit.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/ecdfgof.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/edf.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/eut.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/imanconover.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/kde.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/ksdist.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/multicore.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/plotting.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/rdarrays.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/screen.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/shapiro.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/testsim.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/utests.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim/vect.py +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim.egg-info/dependency_links.txt +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim.egg-info/requires.txt +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/funcsim.egg-info/top_level.txt +0 -0
- {funcsim-0.2.4 → funcsim-0.2.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: funcsim
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: functional, simple stochastic simulation
|
|
5
5
|
Home-page: https://github.com/h-bryant/funcsim
|
|
6
6
|
Author: Henry Bryant
|
|
@@ -54,7 +54,7 @@ Features:
|
|
|
54
54
|
- stratified/Latin hypercube sampling
|
|
55
55
|
- painless multi-core simulations
|
|
56
56
|
- fitting and comparison of univariate distributions, kernel density estimates, and goodness-of-fit tests
|
|
57
|
-
- multivariate normal and KDE distributions; Gaussian, Student's t, Clayton, Gumbel, and Frank copulas (implemented natively, no additional packages required); Iman-Conover
|
|
57
|
+
- multivariate normal (fitted to data or specified by a mean vector and covariance matrix) and multivariate KDE distributions; Gaussian, Student's t, Clayton, Gumbel, and Frank copulas, fitted to pseudo-observations or specified by their parameters (implemented natively, no additional packages required); information-criterion comparison of copula families; Iman-Conover; covariance shrinkage
|
|
58
58
|
- expected utility and cumulative prospect theory calculations
|
|
59
59
|
- plotly-based fan charts and diagnostic plots
|
|
60
60
|
- highly flexible, and as simple as possible (but no more)
|
|
@@ -9,7 +9,7 @@ Features:
|
|
|
9
9
|
- stratified/Latin hypercube sampling
|
|
10
10
|
- painless multi-core simulations
|
|
11
11
|
- fitting and comparison of univariate distributions, kernel density estimates, and goodness-of-fit tests
|
|
12
|
-
- multivariate normal and KDE distributions; Gaussian, Student's t, Clayton, Gumbel, and Frank copulas (implemented natively, no additional packages required); Iman-Conover
|
|
12
|
+
- multivariate normal (fitted to data or specified by a mean vector and covariance matrix) and multivariate KDE distributions; Gaussian, Student's t, Clayton, Gumbel, and Frank copulas, fitted to pseudo-observations or specified by their parameters (implemented natively, no additional packages required); information-criterion comparison of copula families; Iman-Conover; covariance shrinkage
|
|
13
13
|
- expected utility and cumulative prospect theory calculations
|
|
14
14
|
- plotly-based fan charts and diagnostic plots
|
|
15
15
|
- highly flexible, and as simple as possible (but no more)
|
|
@@ -10,6 +10,8 @@ from .dependence import CopulaClayton
|
|
|
10
10
|
from .dependence import CopulaGumbel
|
|
11
11
|
from .dependence import CopulaFrank
|
|
12
12
|
|
|
13
|
+
from .copcompare import copcompare
|
|
14
|
+
|
|
13
15
|
from .imanconover import imanconover
|
|
14
16
|
|
|
15
17
|
from .shrinkage import shrink
|
|
@@ -46,6 +48,6 @@ def version():
|
|
|
46
48
|
Returns
|
|
47
49
|
-------
|
|
48
50
|
str
|
|
49
|
-
The version string of the package (e.g., '0.2.
|
|
51
|
+
The version string of the package (e.g., '0.2.6').
|
|
50
52
|
"""
|
|
51
|
-
return "0.2.
|
|
53
|
+
return "0.2.6"
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Information-criteria comparison of funcsim's copula families.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pandas as pd
|
|
9
|
+
|
|
10
|
+
from . import conversions
|
|
11
|
+
from . import copfit
|
|
12
|
+
from .dependence import (CopulaGauss, CopulaStudent, CopulaClayton,
|
|
13
|
+
CopulaGumbel, CopulaFrank)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _fmt(x: float) -> str:
|
|
17
|
+
return f"{x:.3f}"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _rho_label(rho: np.ndarray) -> str:
|
|
21
|
+
# a scalar for two variables, otherwise just the matrix size
|
|
22
|
+
K = rho.shape[0]
|
|
23
|
+
if K == 2:
|
|
24
|
+
return f"rho={_fmt(rho[0, 1])}"
|
|
25
|
+
return f"rho: {K}x{K} matrix"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def copcompare(udata: conversions.ArrayLike) -> pd.DataFrame:
|
|
29
|
+
"""
|
|
30
|
+
Compare fits of funcsim's copula families to pseudo-observations.
|
|
31
|
+
|
|
32
|
+
Each family (Gaussian, Student's t, Clayton, Gumbel, Frank) is fitted
|
|
33
|
+
to `udata` exactly as the corresponding copula class would fit it, its
|
|
34
|
+
copula log-likelihood (the pseudo-likelihood of Genest, Ghoudi, and
|
|
35
|
+
Rivest, 1995) is evaluated at those fitted parameters, and the Akaike
|
|
36
|
+
and Bayesian information criteria are computed from it.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
udata : ArrayLike
|
|
41
|
+
Pseudo-observations (marginal CDF values) with variables in columns
|
|
42
|
+
and observations in rows; every value must lie in (0, 1).
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
pd.DataFrame
|
|
47
|
+
One row per family, indexed by family name and sorted by BIC from
|
|
48
|
+
best (smallest) to worst, with columns ``parameters`` (the fitted
|
|
49
|
+
values as text), ``n_params``, ``loglik``, ``AIC``, and ``BIC``.
|
|
50
|
+
|
|
51
|
+
Notes
|
|
52
|
+
-----
|
|
53
|
+
The parameters are the ones the copula classes use: normal-scores
|
|
54
|
+
correlation for the Gaussian copula, Kendall's-tau inversion plus a
|
|
55
|
+
profile likelihood for the degrees of freedom for the Student's t copula,
|
|
56
|
+
and maximum pseudo-likelihood for the Archimedean families. The
|
|
57
|
+
Gaussian and Student's t log-likelihoods are therefore evaluated at
|
|
58
|
+
moment-type estimates rather than at the exact maximum, so their
|
|
59
|
+
criteria are conservative by a small amount. Standard information
|
|
60
|
+
criteria applied to pseudo-likelihoods are approximate (Grønneberg and
|
|
61
|
+
Hjort, 2014); treat differences of a few points as ties. Warnings
|
|
62
|
+
issued while fitting a family (for example, negative dependence in data
|
|
63
|
+
handed to an Archimedean family that represents only positive
|
|
64
|
+
dependence) are passed through.
|
|
65
|
+
|
|
66
|
+
References
|
|
67
|
+
----------
|
|
68
|
+
Genest, C., Ghoudi, K., & Rivest, L.-P. (1995). A semiparametric
|
|
69
|
+
estimation procedure of dependence parameters in multivariate families
|
|
70
|
+
of distributions. Biometrika, 82(3), 543-552.
|
|
71
|
+
|
|
72
|
+
Grønneberg, S., & Hjort, N. L. (2014). The copula information criteria.
|
|
73
|
+
Scandinavian Journal of Statistics, 41(2), 436-459.
|
|
74
|
+
|
|
75
|
+
Examples
|
|
76
|
+
--------
|
|
77
|
+
>>> table = fs.copcompare(uh)
|
|
78
|
+
>>> print(table.round(2))
|
|
79
|
+
"""
|
|
80
|
+
u = conversions.alToArray(udata)
|
|
81
|
+
if u.ndim != 2 or u.shape[1] < 2:
|
|
82
|
+
raise ValueError("udata must have at least two columns (variables)")
|
|
83
|
+
(M, K) = u.shape
|
|
84
|
+
npair = K * (K - 1) // 2
|
|
85
|
+
|
|
86
|
+
def row(name, parameters, n_params, loglik):
|
|
87
|
+
return {"copula": name,
|
|
88
|
+
"parameters": parameters,
|
|
89
|
+
"n_params": n_params,
|
|
90
|
+
"loglik": loglik,
|
|
91
|
+
"AIC": 2.0 * n_params - 2.0 * loglik,
|
|
92
|
+
"BIC": n_params * math.log(M) - 2.0 * loglik}
|
|
93
|
+
|
|
94
|
+
cg = CopulaGauss(u)
|
|
95
|
+
rho_g = cg.rho.to_numpy()
|
|
96
|
+
ct = CopulaStudent(u)
|
|
97
|
+
rho_t = ct.rho.to_numpy()
|
|
98
|
+
cc = CopulaClayton(u)
|
|
99
|
+
cgu = CopulaGumbel(u)
|
|
100
|
+
cf = CopulaFrank(u)
|
|
101
|
+
uc = copfit._clipu(u)
|
|
102
|
+
|
|
103
|
+
rows = [
|
|
104
|
+
row("Gaussian", _rho_label(rho_g), npair,
|
|
105
|
+
copfit.gauss_loglik(rho_g, u)),
|
|
106
|
+
row("Student", f"{_rho_label(rho_t)}, nu={_fmt(ct.nu)}", npair + 1,
|
|
107
|
+
copfit.student_loglik(rho_t, ct.nu, u)),
|
|
108
|
+
row("Clayton", f"theta={_fmt(cc.theta)}", 1,
|
|
109
|
+
copfit.clayton_loglik(cc.theta, uc)),
|
|
110
|
+
row("Gumbel", f"theta={_fmt(cgu.theta)}", 1,
|
|
111
|
+
copfit.gumbel_loglik(cgu.theta, uc)),
|
|
112
|
+
row("Frank", f"theta={_fmt(cf.theta)}", 1,
|
|
113
|
+
copfit.frank_loglik(cf.theta, uc)),
|
|
114
|
+
]
|
|
115
|
+
table = pd.DataFrame(rows).set_index("copula")
|
|
116
|
+
return table.sort_values("BIC")
|
|
@@ -267,6 +267,31 @@ def fit_frank(u: np.ndarray) -> Tuple[float, float, bool]:
|
|
|
267
267
|
return (theta, tb, False)
|
|
268
268
|
|
|
269
269
|
|
|
270
|
+
def gauss_loglik(R: np.ndarray, u: np.ndarray) -> float:
|
|
271
|
+
# total Gaussian copula log-density over the rows of u for the
|
|
272
|
+
# correlation matrix R:
|
|
273
|
+
# log c(u) = -0.5 log|R| - 0.5 z' (R^-1 - I) z, with z = Phi^-1(u)
|
|
274
|
+
uc = _clipu(u)
|
|
275
|
+
z = stats.norm.ppf(uc)
|
|
276
|
+
(M, d) = z.shape
|
|
277
|
+
(sign, logdet) = np.linalg.slogdet(R)
|
|
278
|
+
if sign <= 0:
|
|
279
|
+
raise ValueError("R must be positive definite")
|
|
280
|
+
quad = np.einsum("ij,jk,ik->i", z, np.linalg.inv(R) - np.eye(d), z)
|
|
281
|
+
return float(-0.5 * M * logdet - 0.5 * np.sum(quad))
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def student_loglik(R: np.ndarray, nu: float, u: np.ndarray) -> float:
|
|
285
|
+
# total Student's t copula log-density over the rows of u for the
|
|
286
|
+
# correlation matrix R and degrees of freedom nu:
|
|
287
|
+
# log c(u) = log t_{nu,R}(x) - sum_k log t_nu(x_k), with x = t_nu^-1(u)
|
|
288
|
+
uc = _clipu(u)
|
|
289
|
+
x = stats.t.ppf(uc, df=nu)
|
|
290
|
+
d = R.shape[0]
|
|
291
|
+
joint = stats.multivariate_t(loc=np.zeros(d), shape=R, df=nu).logpdf(x)
|
|
292
|
+
return float(np.sum(joint) - np.sum(stats.t.logpdf(x, df=nu)))
|
|
293
|
+
|
|
294
|
+
|
|
270
295
|
def fit_student(u: np.ndarray) -> Tuple[np.ndarray, float]:
|
|
271
296
|
# fit a Student's t copula; returns (correlation matrix, deg. of freedom).
|
|
272
297
|
# stage 1: pairwise Kendall's tau -> rho_ij = sin(pi tau_ij / 2),
|
|
@@ -281,17 +306,12 @@ def fit_student(u: np.ndarray) -> Tuple[np.ndarray, float]:
|
|
|
281
306
|
R = R / np.outer(s, s) # renormalize to unit diagonal
|
|
282
307
|
np.fill_diagonal(R, 1.0)
|
|
283
308
|
|
|
284
|
-
mvt_dim = R.shape[0]
|
|
285
|
-
|
|
286
309
|
def negll(lognu):
|
|
287
310
|
nu = math.exp(lognu)
|
|
288
311
|
try:
|
|
289
312
|
with np.errstate(divide="ignore", invalid="ignore",
|
|
290
313
|
over="ignore"):
|
|
291
|
-
|
|
292
|
-
ll = (stats.multivariate_t(loc=np.zeros(mvt_dim), shape=R,
|
|
293
|
-
df=nu).logpdf(x).sum()
|
|
294
|
-
- stats.t.logpdf(x, df=nu).sum())
|
|
314
|
+
ll = student_loglik(R, nu, uc)
|
|
295
315
|
except Exception:
|
|
296
316
|
return np.inf
|
|
297
317
|
return -ll if np.isfinite(ll) else np.inf
|
|
@@ -2,7 +2,7 @@ import math
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
import pandas as pd
|
|
4
4
|
from scipy import stats
|
|
5
|
-
from typing import Generator, Optional, Tuple
|
|
5
|
+
from typing import Generator, Optional, Sequence, Tuple
|
|
6
6
|
import warnings
|
|
7
7
|
from . import conversions
|
|
8
8
|
from . import copfit
|
|
@@ -24,6 +24,75 @@ def _checkcov(cov, name):
|
|
|
24
24
|
return cov
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def _cop_names(K: int,
|
|
28
|
+
names: Optional[Sequence[str]],
|
|
29
|
+
source: Optional[pd.Index] = None,
|
|
30
|
+
) -> pd.Index:
|
|
31
|
+
# variable names for a copula built from parameters rather than data:
|
|
32
|
+
# the explicit `names` if given, else the labels carried by the
|
|
33
|
+
# parameter object (`source`, e.g. a DataFrame's columns), else v0, v1, ...
|
|
34
|
+
if names is not None:
|
|
35
|
+
nms = pd.Index(list(names))
|
|
36
|
+
elif source is not None:
|
|
37
|
+
nms = pd.Index(source)
|
|
38
|
+
else:
|
|
39
|
+
nms = pd.Index([f"v{k}" for k in range(K)])
|
|
40
|
+
if len(nms) != K:
|
|
41
|
+
raise ValueError(f"names must have length {K}; got {len(nms)}")
|
|
42
|
+
return nms
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _corr_from_params(rho: conversions.ArrayLike) -> np.ndarray:
|
|
46
|
+
# validate a user-supplied correlation matrix for an elliptical copula:
|
|
47
|
+
# square, symmetric, unit diagonal. If it is not positive definite the
|
|
48
|
+
# nearest positive definite matrix (Higham, 1988) is substituted and
|
|
49
|
+
# renormalized to a unit diagonal
|
|
50
|
+
if isinstance(rho, (list, tuple)):
|
|
51
|
+
R = np.asarray(rho, dtype=float)
|
|
52
|
+
else:
|
|
53
|
+
R = np.asarray(conversions.alToArray(rho), dtype=float)
|
|
54
|
+
if R.ndim != 2 or R.shape[0] != R.shape[1]:
|
|
55
|
+
raise ValueError(f"rho must be a square matrix; got shape {R.shape}")
|
|
56
|
+
if not np.allclose(R, R.T):
|
|
57
|
+
raise ValueError("rho must be symmetric")
|
|
58
|
+
if not np.allclose(np.diag(R), 1.0):
|
|
59
|
+
raise ValueError("rho must have ones on its diagonal")
|
|
60
|
+
Rpd = nearby.nearestpd(0.5 * (R + R.T))
|
|
61
|
+
s = np.sqrt(np.diag(Rpd))
|
|
62
|
+
Rn = Rpd / np.outer(s, s)
|
|
63
|
+
np.fill_diagonal(Rn, 1.0)
|
|
64
|
+
Rn = 0.5 * (Rn + Rn.T)
|
|
65
|
+
# Higham's projection of an indefinite matrix has a zero eigenvalue at
|
|
66
|
+
# machine precision, and rescaling can push it slightly negative, so the
|
|
67
|
+
# Cholesky factorization used for draws may fail. Shrink toward the
|
|
68
|
+
# identity by the smallest power of ten that restores positive
|
|
69
|
+
# definiteness; the convex combination keeps the unit diagonal exactly
|
|
70
|
+
Id = np.eye(R.shape[0])
|
|
71
|
+
candidates = ((1.0 - eps) * Rn + eps * Id
|
|
72
|
+
for eps in (0.0, *(10.0 ** p for p in range(-14, -3))))
|
|
73
|
+
Rout = next(filter(nearby.is_positive_definite, candidates), None)
|
|
74
|
+
if Rout is None:
|
|
75
|
+
raise ValueError("rho could not be repaired to a positive definite "
|
|
76
|
+
"correlation matrix")
|
|
77
|
+
return Rout
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _param_labels(rho: conversions.ArrayLike) -> Optional[pd.Index]:
|
|
81
|
+
# column labels carried by a parameter matrix, if any
|
|
82
|
+
if isinstance(rho, pd.DataFrame):
|
|
83
|
+
return rho.columns
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _positive_scalar(x: float, what: str, minimum: float = 0.0) -> float:
|
|
88
|
+
# validate a scalar copula parameter that must exceed `minimum`
|
|
89
|
+
xf = float(x)
|
|
90
|
+
if not (math.isfinite(xf) and xf > minimum):
|
|
91
|
+
raise ValueError(f"{what} must be a finite number greater than "
|
|
92
|
+
f"{minimum}; got {x}")
|
|
93
|
+
return xf
|
|
94
|
+
|
|
95
|
+
|
|
27
96
|
def _rand_int(u, M):
|
|
28
97
|
# given a standard uniform draw "u", select a
|
|
29
98
|
# random integer from a length "M" sequece: 0, 1, ..., M-1
|
|
@@ -284,10 +353,12 @@ class MvKde():
|
|
|
284
353
|
|
|
285
354
|
class MvNorm():
|
|
286
355
|
"""
|
|
287
|
-
A multivariate normal distribution object.
|
|
288
|
-
and a covariance matrix are computed from the input
|
|
289
|
-
|
|
290
|
-
|
|
356
|
+
A multivariate normal distribution object. Constructed from data, a
|
|
357
|
+
vector of means and a covariance matrix are computed from the input.
|
|
358
|
+
Constructed with :meth:`from_params`, the mean vector and covariance
|
|
359
|
+
matrix are supplied directly. Either way, if the covariance matrix is
|
|
360
|
+
not positive definite, the Higham method is used to calculate the
|
|
361
|
+
nearest positive definite matrix.
|
|
291
362
|
|
|
292
363
|
Parameters
|
|
293
364
|
----------
|
|
@@ -323,10 +394,80 @@ class MvNorm():
|
|
|
323
394
|
swp = shapiro.swtest(self._data[:, k])[1]
|
|
324
395
|
if not swp > 0.05:
|
|
325
396
|
msg = (f"variable '{self._names[k]}' may not be "
|
|
326
|
-
f"
|
|
397
|
+
f"normally distributed. (Shapiro-Wilk p-value"
|
|
327
398
|
f"={swp:.3f})")
|
|
328
399
|
warnings.warn(msg, UserWarning)
|
|
329
400
|
|
|
401
|
+
@classmethod
|
|
402
|
+
def from_params(cls,
|
|
403
|
+
mu: conversions.VectorLike,
|
|
404
|
+
sigma: conversions.ArrayLike,
|
|
405
|
+
names: Optional[Sequence[str]] = None,
|
|
406
|
+
) -> "MvNorm":
|
|
407
|
+
"""
|
|
408
|
+
Create a multivariate normal distribution object from a mean vector
|
|
409
|
+
and a covariance matrix, rather than from data.
|
|
410
|
+
|
|
411
|
+
Parameters
|
|
412
|
+
----------
|
|
413
|
+
mu : VectorLike
|
|
414
|
+
Mean vector of length K.
|
|
415
|
+
sigma : ArrayLike
|
|
416
|
+
K-by-K covariance matrix (a nested list is also accepted). It
|
|
417
|
+
must be symmetric. If it is not positive definite, the nearest
|
|
418
|
+
positive definite matrix (Higham, 1988) is substituted with a
|
|
419
|
+
warning.
|
|
420
|
+
names : sequence of str, optional
|
|
421
|
+
Variable names, length K. If omitted, the index of `mu` (if it
|
|
422
|
+
is a pandas Series) or the column labels of `sigma` (if it is a
|
|
423
|
+
pandas DataFrame) are used; otherwise the variables are named
|
|
424
|
+
'v0', 'v1', ....
|
|
425
|
+
|
|
426
|
+
Returns
|
|
427
|
+
-------
|
|
428
|
+
MvNorm
|
|
429
|
+
A distribution object whose :meth:`draw` method returns joint
|
|
430
|
+
draws with the given means and covariances.
|
|
431
|
+
|
|
432
|
+
Notes
|
|
433
|
+
-----
|
|
434
|
+
No normality check is performed, since there are no data to check.
|
|
435
|
+
|
|
436
|
+
Examples
|
|
437
|
+
--------
|
|
438
|
+
>>> dist = fs.MvNorm.from_params([3.0, 4.0], [[1.0, 0.5], [0.5, 1.0]])
|
|
439
|
+
"""
|
|
440
|
+
muA = np.asarray(conversions.vlToArray(mu), dtype=float)
|
|
441
|
+
if isinstance(sigma, (list, tuple)):
|
|
442
|
+
sigmaA = np.asarray(sigma, dtype=float)
|
|
443
|
+
else:
|
|
444
|
+
sigmaA = np.asarray(conversions.alToArray(sigma), dtype=float)
|
|
445
|
+
K = muA.shape[0]
|
|
446
|
+
if sigmaA.shape != (K, K):
|
|
447
|
+
raise ValueError(f"sigma must be {K}-by-{K} to match mu; "
|
|
448
|
+
f"got shape {sigmaA.shape}")
|
|
449
|
+
if not np.allclose(sigmaA, sigmaA.T):
|
|
450
|
+
raise ValueError("sigma must be symmetric")
|
|
451
|
+
if names is not None:
|
|
452
|
+
nms = pd.Index(list(names))
|
|
453
|
+
elif isinstance(mu, pd.Series):
|
|
454
|
+
nms = pd.Index(mu.index)
|
|
455
|
+
elif isinstance(sigma, pd.DataFrame):
|
|
456
|
+
nms = pd.Index(sigma.columns)
|
|
457
|
+
else:
|
|
458
|
+
nms = pd.Index([f"v{k}" for k in range(K)])
|
|
459
|
+
if len(nms) != K:
|
|
460
|
+
raise ValueError(f"names must have length {K}; got {len(nms)}")
|
|
461
|
+
|
|
462
|
+
obj = cls.__new__(cls)
|
|
463
|
+
obj._data = None
|
|
464
|
+
obj._names = nms
|
|
465
|
+
(obj._M, obj._K) = (0, K)
|
|
466
|
+
obj._mu = muA
|
|
467
|
+
obj._sigma = nearby.nearestpd(sigmaA)
|
|
468
|
+
obj._A = np.linalg.cholesky(obj._sigma)
|
|
469
|
+
return obj
|
|
470
|
+
|
|
330
471
|
def draw(self,
|
|
331
472
|
ugen: Generator[float, None, None]
|
|
332
473
|
) -> pd.Series:
|
|
@@ -344,9 +485,9 @@ class MvNorm():
|
|
|
344
485
|
A pandas Series representing a joint draw from the multivariate
|
|
345
486
|
normal distribution. The index values are the variable names,
|
|
346
487
|
and the values are the random values. If no variable names were
|
|
347
|
-
provided
|
|
348
|
-
|
|
349
|
-
|
|
488
|
+
provided (as column labels of the input data, or through the
|
|
489
|
+
`names` argument of :meth:`from_params`), the variables are
|
|
490
|
+
named 'v0', 'v1', ..., in column order.
|
|
350
491
|
"""
|
|
351
492
|
uvec = [next(ugen) for i in range(self._K)]
|
|
352
493
|
retA = self._mu + np.dot(self._A, stats.norm.ppf(uvec))
|
|
@@ -410,6 +551,57 @@ class CopulaGauss():
|
|
|
410
551
|
# cholesky decomposition of the correlation matrix, for draws
|
|
411
552
|
self._A = np.linalg.cholesky(self._rho)
|
|
412
553
|
|
|
554
|
+
@classmethod
|
|
555
|
+
def from_params(cls,
|
|
556
|
+
rho: conversions.ArrayLike,
|
|
557
|
+
names: Optional[Sequence[str]] = None,
|
|
558
|
+
) -> "CopulaGauss":
|
|
559
|
+
"""
|
|
560
|
+
Create a Gaussian copula object from a correlation matrix, rather
|
|
561
|
+
than from pseudo-observations.
|
|
562
|
+
|
|
563
|
+
Parameters
|
|
564
|
+
----------
|
|
565
|
+
rho : ArrayLike
|
|
566
|
+
K-by-K correlation matrix (a nested list is also accepted). It
|
|
567
|
+
must be symmetric with ones on its diagonal. If it is not
|
|
568
|
+
positive definite, the nearest positive definite matrix
|
|
569
|
+
(Higham, 1988) is substituted and rescaled to a unit diagonal.
|
|
570
|
+
names : sequence of str, optional
|
|
571
|
+
Variable names, length K. If omitted, the column labels of
|
|
572
|
+
`rho` (if it is a pandas DataFrame) are used; otherwise the
|
|
573
|
+
variables are named 'v0', 'v1', ....
|
|
574
|
+
|
|
575
|
+
Returns
|
|
576
|
+
-------
|
|
577
|
+
CopulaGauss
|
|
578
|
+
A copula object whose :meth:`draw` method returns joint standard
|
|
579
|
+
uniform draws with the given Gaussian dependence.
|
|
580
|
+
|
|
581
|
+
Examples
|
|
582
|
+
--------
|
|
583
|
+
>>> cop = fs.CopulaGauss.from_params([[1.0, 0.9], [0.9, 1.0]])
|
|
584
|
+
"""
|
|
585
|
+
R = _corr_from_params(rho)
|
|
586
|
+
K = R.shape[0]
|
|
587
|
+
obj = cls.__new__(cls)
|
|
588
|
+
obj._data = None
|
|
589
|
+
obj._z = None
|
|
590
|
+
obj._names = _cop_names(K, names, _param_labels(rho))
|
|
591
|
+
(obj._M, obj._K) = (0, K)
|
|
592
|
+
obj._rho = R
|
|
593
|
+
obj._A = np.linalg.cholesky(obj._rho)
|
|
594
|
+
return obj
|
|
595
|
+
|
|
596
|
+
@property
|
|
597
|
+
def rho(self) -> pd.DataFrame:
|
|
598
|
+
"""
|
|
599
|
+
The copula's correlation matrix parameter, as a DataFrame whose
|
|
600
|
+
index and columns are the variable names.
|
|
601
|
+
"""
|
|
602
|
+
return pd.DataFrame(self._rho.copy(), index=self._names,
|
|
603
|
+
columns=self._names)
|
|
604
|
+
|
|
413
605
|
def draw(self,
|
|
414
606
|
ugen: Generator[float, None, None]
|
|
415
607
|
) -> pd.Series:
|
|
@@ -480,6 +672,66 @@ class CopulaStudent():
|
|
|
480
672
|
# cholesky decomposition of the correlation matrix, for draws
|
|
481
673
|
self._A = np.linalg.cholesky(self._rho)
|
|
482
674
|
|
|
675
|
+
@classmethod
|
|
676
|
+
def from_params(cls,
|
|
677
|
+
rho: conversions.ArrayLike,
|
|
678
|
+
nu: float,
|
|
679
|
+
names: Optional[Sequence[str]] = None,
|
|
680
|
+
) -> "CopulaStudent":
|
|
681
|
+
"""
|
|
682
|
+
Create a Student's t copula object from a correlation matrix and a
|
|
683
|
+
degrees-of-freedom parameter, rather than from pseudo-observations.
|
|
684
|
+
|
|
685
|
+
Parameters
|
|
686
|
+
----------
|
|
687
|
+
rho : ArrayLike
|
|
688
|
+
K-by-K correlation matrix (a nested list is also accepted). It
|
|
689
|
+
must be symmetric with ones on its diagonal. If it is not
|
|
690
|
+
positive definite, the nearest positive definite matrix
|
|
691
|
+
(Higham, 1988) is substituted and rescaled to a unit diagonal.
|
|
692
|
+
nu : float
|
|
693
|
+
Degrees of freedom, greater than zero. As `nu` grows the copula
|
|
694
|
+
approaches the Gaussian copula with the same `rho`.
|
|
695
|
+
names : sequence of str, optional
|
|
696
|
+
Variable names, length K. If omitted, the column labels of
|
|
697
|
+
`rho` (if it is a pandas DataFrame) are used; otherwise the
|
|
698
|
+
variables are named 'v0', 'v1', ....
|
|
699
|
+
|
|
700
|
+
Returns
|
|
701
|
+
-------
|
|
702
|
+
CopulaStudent
|
|
703
|
+
A copula object whose :meth:`draw` method returns joint standard
|
|
704
|
+
uniform draws with the given Student's t dependence.
|
|
705
|
+
|
|
706
|
+
Examples
|
|
707
|
+
--------
|
|
708
|
+
>>> cop = fs.CopulaStudent.from_params([[1.0, 0.9], [0.9, 1.0]], nu=4)
|
|
709
|
+
"""
|
|
710
|
+
R = _corr_from_params(rho)
|
|
711
|
+
K = R.shape[0]
|
|
712
|
+
obj = cls.__new__(cls)
|
|
713
|
+
obj._data = None
|
|
714
|
+
obj._names = _cop_names(K, names, _param_labels(rho))
|
|
715
|
+
(obj._M, obj._K) = (0, K)
|
|
716
|
+
obj._rho = R
|
|
717
|
+
obj._nu = _positive_scalar(nu, "nu")
|
|
718
|
+
obj._A = np.linalg.cholesky(obj._rho)
|
|
719
|
+
return obj
|
|
720
|
+
|
|
721
|
+
@property
|
|
722
|
+
def rho(self) -> pd.DataFrame:
|
|
723
|
+
"""
|
|
724
|
+
The copula's correlation matrix parameter, as a DataFrame whose
|
|
725
|
+
index and columns are the variable names.
|
|
726
|
+
"""
|
|
727
|
+
return pd.DataFrame(self._rho.copy(), index=self._names,
|
|
728
|
+
columns=self._names)
|
|
729
|
+
|
|
730
|
+
@property
|
|
731
|
+
def nu(self) -> float:
|
|
732
|
+
"""The copula's degrees-of-freedom parameter."""
|
|
733
|
+
return float(self._nu)
|
|
734
|
+
|
|
483
735
|
def draw(self,
|
|
484
736
|
ugen: Generator[float, None, None]
|
|
485
737
|
) -> pd.Series:
|
|
@@ -565,6 +817,53 @@ class CopulaClayton():
|
|
|
565
817
|
f"representation for your data.",
|
|
566
818
|
UserWarning)
|
|
567
819
|
|
|
820
|
+
@classmethod
|
|
821
|
+
def from_params(cls,
|
|
822
|
+
theta: float,
|
|
823
|
+
K: int = 2,
|
|
824
|
+
names: Optional[Sequence[str]] = None,
|
|
825
|
+
) -> "CopulaClayton":
|
|
826
|
+
"""
|
|
827
|
+
Create a Clayton copula object from its dependence parameter,
|
|
828
|
+
rather than from pseudo-observations.
|
|
829
|
+
|
|
830
|
+
Parameters
|
|
831
|
+
----------
|
|
832
|
+
theta : float
|
|
833
|
+
Dependence parameter, greater than zero. Kendall's tau is theta / (theta + 2).
|
|
834
|
+
K : int, optional
|
|
835
|
+
Number of variables. Default is 2. Ignored when `names` is
|
|
836
|
+
given, in which case K is the number of names.
|
|
837
|
+
names : sequence of str, optional
|
|
838
|
+
Variable names. If omitted, the variables are named 'v0',
|
|
839
|
+
'v1', ....
|
|
840
|
+
|
|
841
|
+
Returns
|
|
842
|
+
-------
|
|
843
|
+
CopulaClayton
|
|
844
|
+
A copula object whose :meth:`draw` method returns joint standard
|
|
845
|
+
uniform draws with the given Clayton dependence.
|
|
846
|
+
|
|
847
|
+
Examples
|
|
848
|
+
--------
|
|
849
|
+
>>> cop = fs.CopulaClayton.from_params(theta=2.0)
|
|
850
|
+
"""
|
|
851
|
+
th = _positive_scalar(theta, "theta", 0.0)
|
|
852
|
+
k = len(names) if names is not None else int(K)
|
|
853
|
+
if k < 2:
|
|
854
|
+
raise ValueError("a copula needs at least two variables")
|
|
855
|
+
obj = cls.__new__(cls)
|
|
856
|
+
obj._data = None
|
|
857
|
+
obj._names = _cop_names(k, names)
|
|
858
|
+
(obj._M, obj._K) = (0, k)
|
|
859
|
+
obj._theta = th
|
|
860
|
+
return obj
|
|
861
|
+
|
|
862
|
+
@property
|
|
863
|
+
def theta(self) -> float:
|
|
864
|
+
"""The copula's dependence parameter."""
|
|
865
|
+
return float(self._theta)
|
|
866
|
+
|
|
568
867
|
def _Ftilde(self, t):
|
|
569
868
|
return (1.0 + t)**(-1.0 / self._theta)
|
|
570
869
|
|
|
@@ -655,6 +954,53 @@ class CopulaGumbel():
|
|
|
655
954
|
f"representation for your data.",
|
|
656
955
|
UserWarning)
|
|
657
956
|
|
|
957
|
+
@classmethod
|
|
958
|
+
def from_params(cls,
|
|
959
|
+
theta: float,
|
|
960
|
+
K: int = 2,
|
|
961
|
+
names: Optional[Sequence[str]] = None,
|
|
962
|
+
) -> "CopulaGumbel":
|
|
963
|
+
"""
|
|
964
|
+
Create a Gumbel copula object from its dependence parameter,
|
|
965
|
+
rather than from pseudo-observations.
|
|
966
|
+
|
|
967
|
+
Parameters
|
|
968
|
+
----------
|
|
969
|
+
theta : float
|
|
970
|
+
Dependence parameter, greater than one (one is independence, which this sampler cannot represent). Kendall's tau is 1 - 1 / theta.
|
|
971
|
+
K : int, optional
|
|
972
|
+
Number of variables. Default is 2. Ignored when `names` is
|
|
973
|
+
given, in which case K is the number of names.
|
|
974
|
+
names : sequence of str, optional
|
|
975
|
+
Variable names. If omitted, the variables are named 'v0',
|
|
976
|
+
'v1', ....
|
|
977
|
+
|
|
978
|
+
Returns
|
|
979
|
+
-------
|
|
980
|
+
CopulaGumbel
|
|
981
|
+
A copula object whose :meth:`draw` method returns joint standard
|
|
982
|
+
uniform draws with the given Gumbel dependence.
|
|
983
|
+
|
|
984
|
+
Examples
|
|
985
|
+
--------
|
|
986
|
+
>>> cop = fs.CopulaGumbel.from_params(theta=2.0)
|
|
987
|
+
"""
|
|
988
|
+
th = _positive_scalar(theta, "theta", 1.0)
|
|
989
|
+
k = len(names) if names is not None else int(K)
|
|
990
|
+
if k < 2:
|
|
991
|
+
raise ValueError("a copula needs at least two variables")
|
|
992
|
+
obj = cls.__new__(cls)
|
|
993
|
+
obj._data = None
|
|
994
|
+
obj._names = _cop_names(k, names)
|
|
995
|
+
(obj._M, obj._K) = (0, k)
|
|
996
|
+
obj._theta = th
|
|
997
|
+
return obj
|
|
998
|
+
|
|
999
|
+
@property
|
|
1000
|
+
def theta(self) -> float:
|
|
1001
|
+
"""The copula's dependence parameter."""
|
|
1002
|
+
return float(self._theta)
|
|
1003
|
+
|
|
658
1004
|
def _Ftilde(self, t):
|
|
659
1005
|
return math.exp(-(t**(1.0/self._theta)))
|
|
660
1006
|
|
|
@@ -743,6 +1089,53 @@ class CopulaFrank():
|
|
|
743
1089
|
f"representation for your data.",
|
|
744
1090
|
UserWarning)
|
|
745
1091
|
|
|
1092
|
+
@classmethod
|
|
1093
|
+
def from_params(cls,
|
|
1094
|
+
theta: float,
|
|
1095
|
+
K: int = 2,
|
|
1096
|
+
names: Optional[Sequence[str]] = None,
|
|
1097
|
+
) -> "CopulaFrank":
|
|
1098
|
+
"""
|
|
1099
|
+
Create a Frank copula object from its dependence parameter,
|
|
1100
|
+
rather than from pseudo-observations.
|
|
1101
|
+
|
|
1102
|
+
Parameters
|
|
1103
|
+
----------
|
|
1104
|
+
theta : float
|
|
1105
|
+
Dependence parameter, greater than zero. Kendall's tau is 1 - 4 (1 - D_1(theta)) / theta, with D_1 the first Debye function.
|
|
1106
|
+
K : int, optional
|
|
1107
|
+
Number of variables. Default is 2. Ignored when `names` is
|
|
1108
|
+
given, in which case K is the number of names.
|
|
1109
|
+
names : sequence of str, optional
|
|
1110
|
+
Variable names. If omitted, the variables are named 'v0',
|
|
1111
|
+
'v1', ....
|
|
1112
|
+
|
|
1113
|
+
Returns
|
|
1114
|
+
-------
|
|
1115
|
+
CopulaFrank
|
|
1116
|
+
A copula object whose :meth:`draw` method returns joint standard
|
|
1117
|
+
uniform draws with the given Frank dependence.
|
|
1118
|
+
|
|
1119
|
+
Examples
|
|
1120
|
+
--------
|
|
1121
|
+
>>> cop = fs.CopulaFrank.from_params(theta=5.0)
|
|
1122
|
+
"""
|
|
1123
|
+
th = _positive_scalar(theta, "theta", 0.0)
|
|
1124
|
+
k = len(names) if names is not None else int(K)
|
|
1125
|
+
if k < 2:
|
|
1126
|
+
raise ValueError("a copula needs at least two variables")
|
|
1127
|
+
obj = cls.__new__(cls)
|
|
1128
|
+
obj._data = None
|
|
1129
|
+
obj._names = _cop_names(k, names)
|
|
1130
|
+
(obj._M, obj._K) = (0, k)
|
|
1131
|
+
obj._theta = th
|
|
1132
|
+
return obj
|
|
1133
|
+
|
|
1134
|
+
@property
|
|
1135
|
+
def theta(self) -> float:
|
|
1136
|
+
"""The copula's dependence parameter."""
|
|
1137
|
+
return float(self._theta)
|
|
1138
|
+
|
|
746
1139
|
def draw(self,
|
|
747
1140
|
ugen: Generator[float, None, None]
|
|
748
1141
|
) -> pd.Series:
|
|
@@ -72,7 +72,7 @@ def nearestpd(array):
|
|
|
72
72
|
|
|
73
73
|
if is_positive_definite(A3):
|
|
74
74
|
msg = ("Higham's (1988) first method was employed to compute "
|
|
75
|
-
"the
|
|
75
|
+
"the positive definite matrix nearest to the input matrix.")
|
|
76
76
|
warnings.warn(msg, UserWarning)
|
|
77
77
|
return repackage(array, A3)
|
|
78
78
|
|
|
@@ -94,6 +94,6 @@ def nearestpd(array):
|
|
|
94
94
|
A3 += Id * (-mineig * k ** 2 + spacing)
|
|
95
95
|
k += 1
|
|
96
96
|
msg = ("Higham's (1988) second method was employed to compute "
|
|
97
|
-
|
|
97
|
+
"the positive definite matrix nearest to the input matrix.")
|
|
98
98
|
warnings.warn(msg, UserWarning)
|
|
99
99
|
return repackage(array, A3)
|
|
@@ -6,6 +6,7 @@ Genetics and Molecular Biology//, vol 4(2005), issue 1.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import itertools
|
|
9
|
+
from typing import Tuple, Union
|
|
9
10
|
import numpy as np
|
|
10
11
|
import pandas as pd
|
|
11
12
|
import xarray as xr
|
|
@@ -207,7 +208,10 @@ def _target_f(x):
|
|
|
207
208
|
|
|
208
209
|
|
|
209
210
|
def shrink(data: conversions.ArrayLike,
|
|
210
|
-
target: str
|
|
211
|
+
target: str,
|
|
212
|
+
return_intensity: bool = False
|
|
213
|
+
) -> Union[conversions.ArrayLike,
|
|
214
|
+
Tuple[conversions.ArrayLike, float]]:
|
|
211
215
|
"""
|
|
212
216
|
Covariance shrinkage estimator.
|
|
213
217
|
|
|
@@ -229,11 +233,18 @@ def shrink(data: conversions.ArrayLike,
|
|
|
229
233
|
Targets 'B', 'E', and 'F' originate in Ledoit and Wolf (2003,
|
|
230
234
|
2004). The shrinkage intensity is estimated analytically in each
|
|
231
235
|
case.
|
|
236
|
+
return_intensity : bool, optional
|
|
237
|
+
If True, also return the estimated shrinkage intensity. Default is
|
|
238
|
+
False.
|
|
232
239
|
|
|
233
240
|
Returns
|
|
234
241
|
-------
|
|
235
|
-
ArrayLike
|
|
236
|
-
The estimated covariance matrix, with a type matching the data
|
|
242
|
+
ArrayLike or tuple
|
|
243
|
+
The estimated covariance matrix, with a type matching the data
|
|
244
|
+
array. If `return_intensity` is True, a tuple ``(sigma, lam)``,
|
|
245
|
+
where ``lam`` is the shrinkage intensity, a float in [0, 1]: 0
|
|
246
|
+
leaves the sample covariance matrix unchanged and 1 replaces it
|
|
247
|
+
with the target.
|
|
237
248
|
|
|
238
249
|
Raises
|
|
239
250
|
------
|
|
@@ -259,26 +270,30 @@ def shrink(data: conversions.ArrayLike,
|
|
|
259
270
|
'E': _target_e,
|
|
260
271
|
'F': _target_f}
|
|
261
272
|
|
|
262
|
-
sig = target_map[target](a_np)
|
|
273
|
+
sig, lam = target_map[target](a_np)
|
|
263
274
|
|
|
264
275
|
# return the same type of array that was passed. the result is a
|
|
265
276
|
# p-by-p covariance matrix, so both axes are labeled with the
|
|
266
277
|
# variable (column) labels of the input, not the observation index
|
|
267
278
|
if isinstance(data, pd.DataFrame):
|
|
268
|
-
|
|
269
|
-
|
|
279
|
+
result = pd.DataFrame(data=sig, index=data.columns,
|
|
280
|
+
columns=data.columns)
|
|
270
281
|
elif isinstance(data, xr.DataArray):
|
|
271
282
|
coldim = str(data.dims[-1])
|
|
272
283
|
if coldim in data.coords:
|
|
273
284
|
varnames = np.asarray(data.coords[coldim].values)
|
|
274
285
|
else:
|
|
275
286
|
varnames = np.arange(sig.shape[0])
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
287
|
+
result = xr.DataArray(sig,
|
|
288
|
+
dims=(coldim, coldim + "_"),
|
|
289
|
+
coords={coldim: varnames,
|
|
290
|
+
coldim + "_": varnames})
|
|
280
291
|
else:
|
|
281
|
-
|
|
292
|
+
result = sig
|
|
293
|
+
|
|
294
|
+
if return_intensity:
|
|
295
|
+
return result, float(lam)
|
|
296
|
+
return result
|
|
282
297
|
|
|
283
298
|
|
|
284
299
|
if __name__ == '__main__':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: funcsim
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: functional, simple stochastic simulation
|
|
5
5
|
Home-page: https://github.com/h-bryant/funcsim
|
|
6
6
|
Author: Henry Bryant
|
|
@@ -54,7 +54,7 @@ Features:
|
|
|
54
54
|
- stratified/Latin hypercube sampling
|
|
55
55
|
- painless multi-core simulations
|
|
56
56
|
- fitting and comparison of univariate distributions, kernel density estimates, and goodness-of-fit tests
|
|
57
|
-
- multivariate normal and KDE distributions; Gaussian, Student's t, Clayton, Gumbel, and Frank copulas (implemented natively, no additional packages required); Iman-Conover
|
|
57
|
+
- multivariate normal (fitted to data or specified by a mean vector and covariance matrix) and multivariate KDE distributions; Gaussian, Student's t, Clayton, Gumbel, and Frank copulas, fitted to pseudo-observations or specified by their parameters (implemented natively, no additional packages required); information-criterion comparison of copula families; Iman-Conover; covariance shrinkage
|
|
58
58
|
- expected utility and cumulative prospect theory calculations
|
|
59
59
|
- plotly-based fan charts and diagnostic plots
|
|
60
60
|
- highly flexible, and as simple as possible (but no more)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|