funcsim 0.2.3__tar.gz → 0.2.5__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.3/funcsim.egg-info → funcsim-0.2.5}/PKG-INFO +25 -17
- funcsim-0.2.5/README.md +47 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/__init__.py +2 -2
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/core.py +36 -16
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/cpt.py +2 -2
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/dependence.py +151 -33
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/distfit.py +4 -1
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/ecdfgof.py +21 -9
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/eut.py +2 -2
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/imanconover.py +3 -3
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/nearby.py +2 -2
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/plotting.py +17 -12
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/rdarrays.py +15 -2
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/screen.py +17 -4
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/shrinkage.py +46 -17
- {funcsim-0.2.3 → funcsim-0.2.5/funcsim.egg-info}/PKG-INFO +25 -17
- {funcsim-0.2.3 → funcsim-0.2.5}/setup.py +1 -1
- funcsim-0.2.3/README.md +0 -39
- {funcsim-0.2.3 → funcsim-0.2.5}/LICENSE +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/MANIFEST.in +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/addist.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/conversions.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/copfit.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/cvmdist.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/edf.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/kde.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/ksdist.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/multicore.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/shapiro.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/testsim.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/utests.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim/vect.py +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim.egg-info/SOURCES.txt +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim.egg-info/dependency_links.txt +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim.egg-info/requires.txt +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/funcsim.egg-info/top_level.txt +0 -0
- {funcsim-0.2.3 → funcsim-0.2.5}/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.5
|
|
4
4
|
Summary: functional, simple stochastic simulation
|
|
5
5
|
Home-page: https://github.com/h-bryant/funcsim
|
|
6
6
|
Author: Henry Bryant
|
|
@@ -46,35 +46,43 @@ Dynamic: summary
|
|
|
46
46
|
# funcsim
|
|
47
47
|
Lightweight, functional stochastic simulation
|
|
48
48
|
|
|
49
|
+
Documentation: https://funcsim.readthedocs.io/
|
|
50
|
+
|
|
49
51
|
Features:
|
|
50
|
-
- cross-sectional and recursive
|
|
51
|
-
- pseudo-random numbers (so that results are comparable across
|
|
52
|
+
- static (cross-sectional) and recursive-dynamic simulations from a single user-written function
|
|
53
|
+
- pseudo-random numbers with an explicit seed (so that results are reproducible and comparable across runs or scenarios)
|
|
52
54
|
- stratified/Latin hypercube sampling
|
|
53
55
|
- painless multi-core simulations
|
|
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; covariance shrinkage
|
|
58
|
+
- expected utility and cumulative prospect theory calculations
|
|
59
|
+
- plotly-based fan charts and diagnostic plots
|
|
54
60
|
- highly flexible, and as simple as possible (but no more)
|
|
55
61
|
- functional paradigm
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
- python >= 3.
|
|
59
|
-
- numpy 2.2.0
|
|
60
|
-
- scipy 1.16.0
|
|
61
|
-
- pandas 2.2.0 (pandas 2.2+ and 3.x are both supported)
|
|
62
|
-
- xarray 2025.4.0
|
|
63
|
-
|
|
64
|
-
Copulas (Gaussian, Student's t, Clayton, Gumbel, and Frank) are supported
|
|
65
|
-
natively; no additional packages are required.
|
|
63
|
+
Requirements:
|
|
64
|
+
- python >= 3.11
|
|
65
|
+
- numpy >= 2.2.0
|
|
66
|
+
- scipy >= 1.16.0
|
|
67
|
+
- pandas >= 2.2.0 (pandas 2.2+ and 3.x are both supported)
|
|
68
|
+
- xarray >= 2025.4.0
|
|
66
69
|
|
|
67
|
-
For optional functionality,
|
|
68
|
-
- plotting: plotly
|
|
70
|
+
For optional functionality, additional packages are needed:
|
|
71
|
+
- plotting: plotly (`pip install "funcsim[plotting]"`); kaleido for static image export
|
|
69
72
|
|
|
70
|
-
Additionally, to run the
|
|
73
|
+
Additionally, to run the tests and build the docs:
|
|
71
74
|
- pytest
|
|
72
|
-
- sphinx, sphinx-autodoc-typehints
|
|
75
|
+
- sphinx, sphinx-autodoc-typehints (`pip install "funcsim[docs]"`)
|
|
76
|
+
|
|
77
|
+
### installation
|
|
78
|
+
```bash
|
|
79
|
+
pip install funcsim
|
|
80
|
+
```
|
|
73
81
|
|
|
74
82
|
### building html docs
|
|
75
83
|
From the top-level funcsim directory...
|
|
76
84
|
```bash
|
|
77
|
-
sphinx-build -b html docs/source/ docs/build/
|
|
85
|
+
sphinx-build -W -b html docs/source/ docs/build/
|
|
78
86
|
```
|
|
79
87
|
|
|
80
88
|
### running tests
|
funcsim-0.2.5/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# funcsim
|
|
2
|
+
Lightweight, functional stochastic simulation
|
|
3
|
+
|
|
4
|
+
Documentation: https://funcsim.readthedocs.io/
|
|
5
|
+
|
|
6
|
+
Features:
|
|
7
|
+
- static (cross-sectional) and recursive-dynamic simulations from a single user-written function
|
|
8
|
+
- pseudo-random numbers with an explicit seed (so that results are reproducible and comparable across runs or scenarios)
|
|
9
|
+
- stratified/Latin hypercube sampling
|
|
10
|
+
- painless multi-core simulations
|
|
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; covariance shrinkage
|
|
13
|
+
- expected utility and cumulative prospect theory calculations
|
|
14
|
+
- plotly-based fan charts and diagnostic plots
|
|
15
|
+
- highly flexible, and as simple as possible (but no more)
|
|
16
|
+
- functional paradigm
|
|
17
|
+
|
|
18
|
+
Requirements:
|
|
19
|
+
- python >= 3.11
|
|
20
|
+
- numpy >= 2.2.0
|
|
21
|
+
- scipy >= 1.16.0
|
|
22
|
+
- pandas >= 2.2.0 (pandas 2.2+ and 3.x are both supported)
|
|
23
|
+
- xarray >= 2025.4.0
|
|
24
|
+
|
|
25
|
+
For optional functionality, additional packages are needed:
|
|
26
|
+
- plotting: plotly (`pip install "funcsim[plotting]"`); kaleido for static image export
|
|
27
|
+
|
|
28
|
+
Additionally, to run the tests and build the docs:
|
|
29
|
+
- pytest
|
|
30
|
+
- sphinx, sphinx-autodoc-typehints (`pip install "funcsim[docs]"`)
|
|
31
|
+
|
|
32
|
+
### installation
|
|
33
|
+
```bash
|
|
34
|
+
pip install funcsim
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### building html docs
|
|
38
|
+
From the top-level funcsim directory...
|
|
39
|
+
```bash
|
|
40
|
+
sphinx-build -W -b html docs/source/ docs/build/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### running tests
|
|
44
|
+
From the top-level funcsim directory...
|
|
45
|
+
```bash
|
|
46
|
+
python3 -m pytest
|
|
47
|
+
```
|
|
@@ -183,17 +183,20 @@ def simulate(f: Callable[[Generator[int, float, None],
|
|
|
183
183
|
|
|
184
184
|
Parameters
|
|
185
185
|
----------
|
|
186
|
-
f :
|
|
187
|
-
Function that performs a single trial in a static simulation or a
|
|
188
|
-
single step through time in a recursive
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
a dict with
|
|
196
|
-
|
|
186
|
+
f : callable
|
|
187
|
+
Function that performs a single trial in a static simulation, or a
|
|
188
|
+
single step through time in a recursive-dynamic simulation. Its first
|
|
189
|
+
argument (conventionally ``ugen``) receives a generator that emits
|
|
190
|
+
independent standard uniform draws (or standard normal draws, if
|
|
191
|
+
`stdnorm` is True); obtain each draw with ``next(ugen)``. If `f`
|
|
192
|
+
takes a second argument (conventionally ``hist``), it receives a
|
|
193
|
+
per-trial history object whose ``recall(varname, lag)`` method returns
|
|
194
|
+
the value of a variable `lag` steps earlier; see
|
|
195
|
+
:class:`funcsim.rdarrays.RDdata`. `f` must return a dict with
|
|
196
|
+
variable names (strings) as keys and floats as values. The number of
|
|
197
|
+
times `f` calls ``next(ugen)`` must be the same in every trial and
|
|
198
|
+
step, because draws are pre-allocated across trials for stratified
|
|
199
|
+
sampling.
|
|
197
200
|
ntrials : int, optional
|
|
198
201
|
The number of trials to perform. Default is 500.
|
|
199
202
|
nsteps : int, optional
|
|
@@ -207,12 +210,14 @@ def simulate(f: Callable[[Generator[int, float, None],
|
|
|
207
210
|
Use multiple processes/cores for the simulation. Default is False.
|
|
208
211
|
When True, `f` must be picklable (e.g., defined at the top level of
|
|
209
212
|
a module, not inside another function), because worker processes
|
|
210
|
-
are spawned on most platforms.
|
|
213
|
+
are spawned on most platforms. For the same reason, a script that
|
|
214
|
+
calls ``simulate(..., multi=True)`` must guard the call with
|
|
215
|
+
``if __name__ == "__main__":``.
|
|
211
216
|
seed : int, optional
|
|
212
217
|
Seed for pseudo-random number generation. Default is 6.
|
|
213
|
-
stdnorm :
|
|
214
|
-
If False, ``next(
|
|
215
|
-
|
|
218
|
+
stdnorm : bool, optional
|
|
219
|
+
If False, ``next(ugen)`` within `f` returns standard uniform random
|
|
220
|
+
draws. If True, ``next(ugen)`` returns standard normal draws.
|
|
216
221
|
Default is False.
|
|
217
222
|
sampling : {'lh', 'mc'}, optional
|
|
218
223
|
If 'lh', Latin Hypercube sampling is employed. If 'mc', simple
|
|
@@ -221,7 +226,22 @@ def simulate(f: Callable[[Generator[int, float, None],
|
|
|
221
226
|
Returns
|
|
222
227
|
-------
|
|
223
228
|
xarray.DataArray
|
|
224
|
-
3-D xarray.DataArray with dimensions 'trials', 'variables', and
|
|
229
|
+
3-D xarray.DataArray with dimensions 'trials', 'variables', and
|
|
230
|
+
'steps'. The 'steps' coordinate continues the index of `hist0` (or
|
|
231
|
+
counts from 0 when `hist0` is not given), and includes any historical
|
|
232
|
+
steps from `hist0` ahead of the `nsteps` simulated steps.
|
|
233
|
+
|
|
234
|
+
Raises
|
|
235
|
+
------
|
|
236
|
+
ValueError
|
|
237
|
+
If `hist0` is malformed, `f` is not callable or takes more than two
|
|
238
|
+
arguments, `f` does not return a dict keyed by strings, or `sampling`
|
|
239
|
+
is not one of 'lh' or 'mc'.
|
|
240
|
+
RuntimeError
|
|
241
|
+
If `f` consumes a different number of draws in some trial or step
|
|
242
|
+
than it did when first probed.
|
|
243
|
+
funcsim.rdarrays.MissingValue
|
|
244
|
+
If `f` recalls a lagged value that is not available.
|
|
225
245
|
"""
|
|
226
246
|
if hist0 is not None:
|
|
227
247
|
_checkhist0(hist0)
|
|
@@ -315,7 +315,7 @@ def cpt(utilFunc: Callable,
|
|
|
315
315
|
Sequence of possible stochastic outcomes.
|
|
316
316
|
refOutcome : float
|
|
317
317
|
Reference point for gains and losses.
|
|
318
|
-
probabilities :
|
|
318
|
+
probabilities : Iterable of float, optional
|
|
319
319
|
Probabilities for each outcome. If None, outcomes are assumed
|
|
320
320
|
equally likely.
|
|
321
321
|
precision : float, optional
|
|
@@ -436,7 +436,7 @@ def cptBV(outcomes: Iterable,
|
|
|
436
436
|
Sequence of possible stochastic outcomes.
|
|
437
437
|
refOutcome : float
|
|
438
438
|
Reference point for gains and losses.
|
|
439
|
-
probabilities :
|
|
439
|
+
probabilities : Iterable of float, optional
|
|
440
440
|
Probabilities for each outcome. If None, outcomes are assumed equally
|
|
441
441
|
likely.
|
|
442
442
|
|
|
@@ -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
|
|
@@ -191,12 +191,17 @@ class MvKde():
|
|
|
191
191
|
Parameters
|
|
192
192
|
----------
|
|
193
193
|
data : ArrayLike
|
|
194
|
-
Input data array
|
|
194
|
+
Input data array with variables in columns and observations
|
|
195
195
|
in rows.
|
|
196
196
|
bw : str or ArrayLike, optional
|
|
197
197
|
Bandwidth selection method ('scott' or 'silverman'), or a K-by-K
|
|
198
198
|
bandwidth covariance matrix in the units of the data.
|
|
199
199
|
Default is 'scott'.
|
|
200
|
+
|
|
201
|
+
Notes
|
|
202
|
+
-----
|
|
203
|
+
Each call to :meth:`draw` consumes K + 1 values from ``ugen``, where K
|
|
204
|
+
is the number of variables.
|
|
200
205
|
"""
|
|
201
206
|
def __init__(self,
|
|
202
207
|
data: conversions.ArrayLike,
|
|
@@ -279,16 +284,24 @@ class MvKde():
|
|
|
279
284
|
|
|
280
285
|
class MvNorm():
|
|
281
286
|
"""
|
|
282
|
-
A multivariate normal distribution object.
|
|
283
|
-
and a covariance matrix are computed from the input
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
A multivariate normal distribution object. Constructed from data, a
|
|
288
|
+
vector of means and a covariance matrix are computed from the input.
|
|
289
|
+
Constructed with :meth:`from_params`, the mean vector and covariance
|
|
290
|
+
matrix are supplied directly. Either way, if the covariance matrix is
|
|
291
|
+
not positive definite, the Higham method is used to calculate the
|
|
292
|
+
nearest positive definite matrix.
|
|
286
293
|
|
|
287
294
|
Parameters
|
|
288
295
|
----------
|
|
289
296
|
data : ArrayLike
|
|
290
|
-
Input data array
|
|
297
|
+
Input data array with variables in columns and observations
|
|
291
298
|
in rows.
|
|
299
|
+
|
|
300
|
+
Notes
|
|
301
|
+
-----
|
|
302
|
+
Each call to :meth:`draw` consumes K values from ``ugen``, where K is
|
|
303
|
+
the number of variables. A warning is issued for any variable whose
|
|
304
|
+
Shapiro-Wilk test rejects normality at the 5% level.
|
|
292
305
|
"""
|
|
293
306
|
def __init__(self,
|
|
294
307
|
data: conversions.ArrayLike,
|
|
@@ -312,10 +325,80 @@ class MvNorm():
|
|
|
312
325
|
swp = shapiro.swtest(self._data[:, k])[1]
|
|
313
326
|
if not swp > 0.05:
|
|
314
327
|
msg = (f"variable '{self._names[k]}' may not be "
|
|
315
|
-
f"
|
|
328
|
+
f"normally distributed. (Shapiro-Wilk p-value"
|
|
316
329
|
f"={swp:.3f})")
|
|
317
330
|
warnings.warn(msg, UserWarning)
|
|
318
331
|
|
|
332
|
+
@classmethod
|
|
333
|
+
def from_params(cls,
|
|
334
|
+
mu: conversions.VectorLike,
|
|
335
|
+
sigma: conversions.ArrayLike,
|
|
336
|
+
names: Optional[Sequence[str]] = None,
|
|
337
|
+
) -> "MvNorm":
|
|
338
|
+
"""
|
|
339
|
+
Create a multivariate normal distribution object from a mean vector
|
|
340
|
+
and a covariance matrix, rather than from data.
|
|
341
|
+
|
|
342
|
+
Parameters
|
|
343
|
+
----------
|
|
344
|
+
mu : VectorLike
|
|
345
|
+
Mean vector of length K.
|
|
346
|
+
sigma : ArrayLike
|
|
347
|
+
K-by-K covariance matrix (a nested list is also accepted). It
|
|
348
|
+
must be symmetric. If it is not positive definite, the nearest
|
|
349
|
+
positive definite matrix (Higham, 1988) is substituted with a
|
|
350
|
+
warning.
|
|
351
|
+
names : sequence of str, optional
|
|
352
|
+
Variable names, length K. If omitted, the index of `mu` (if it
|
|
353
|
+
is a pandas Series) or the column labels of `sigma` (if it is a
|
|
354
|
+
pandas DataFrame) are used; otherwise the variables are named
|
|
355
|
+
'v0', 'v1', ....
|
|
356
|
+
|
|
357
|
+
Returns
|
|
358
|
+
-------
|
|
359
|
+
MvNorm
|
|
360
|
+
A distribution object whose :meth:`draw` method returns joint
|
|
361
|
+
draws with the given means and covariances.
|
|
362
|
+
|
|
363
|
+
Notes
|
|
364
|
+
-----
|
|
365
|
+
No normality check is performed, since there are no data to check.
|
|
366
|
+
|
|
367
|
+
Examples
|
|
368
|
+
--------
|
|
369
|
+
>>> dist = fs.MvNorm.from_params([3.0, 4.0], [[1.0, 0.5], [0.5, 1.0]])
|
|
370
|
+
"""
|
|
371
|
+
muA = np.asarray(conversions.vlToArray(mu), dtype=float)
|
|
372
|
+
if isinstance(sigma, (list, tuple)):
|
|
373
|
+
sigmaA = np.asarray(sigma, dtype=float)
|
|
374
|
+
else:
|
|
375
|
+
sigmaA = np.asarray(conversions.alToArray(sigma), dtype=float)
|
|
376
|
+
K = muA.shape[0]
|
|
377
|
+
if sigmaA.shape != (K, K):
|
|
378
|
+
raise ValueError(f"sigma must be {K}-by-{K} to match mu; "
|
|
379
|
+
f"got shape {sigmaA.shape}")
|
|
380
|
+
if not np.allclose(sigmaA, sigmaA.T):
|
|
381
|
+
raise ValueError("sigma must be symmetric")
|
|
382
|
+
if names is not None:
|
|
383
|
+
nms = pd.Index(list(names))
|
|
384
|
+
elif isinstance(mu, pd.Series):
|
|
385
|
+
nms = pd.Index(mu.index)
|
|
386
|
+
elif isinstance(sigma, pd.DataFrame):
|
|
387
|
+
nms = pd.Index(sigma.columns)
|
|
388
|
+
else:
|
|
389
|
+
nms = pd.Index([f"v{k}" for k in range(K)])
|
|
390
|
+
if len(nms) != K:
|
|
391
|
+
raise ValueError(f"names must have length {K}; got {len(nms)}")
|
|
392
|
+
|
|
393
|
+
obj = cls.__new__(cls)
|
|
394
|
+
obj._data = None
|
|
395
|
+
obj._names = nms
|
|
396
|
+
(obj._M, obj._K) = (0, K)
|
|
397
|
+
obj._mu = muA
|
|
398
|
+
obj._sigma = nearby.nearestpd(sigmaA)
|
|
399
|
+
obj._A = np.linalg.cholesky(obj._sigma)
|
|
400
|
+
return obj
|
|
401
|
+
|
|
319
402
|
def draw(self,
|
|
320
403
|
ugen: Generator[float, None, None]
|
|
321
404
|
) -> pd.Series:
|
|
@@ -330,11 +413,12 @@ class MvNorm():
|
|
|
330
413
|
Returns
|
|
331
414
|
-------
|
|
332
415
|
pd.Series
|
|
333
|
-
A pandas Series representing a joint draw from the
|
|
334
|
-
values are the variable names,
|
|
335
|
-
values.
|
|
336
|
-
|
|
337
|
-
|
|
416
|
+
A pandas Series representing a joint draw from the multivariate
|
|
417
|
+
normal distribution. The index values are the variable names,
|
|
418
|
+
and the values are the random values. If no variable names were
|
|
419
|
+
provided (as column labels of the input data, or through the
|
|
420
|
+
`names` argument of :meth:`from_params`), the variables are
|
|
421
|
+
named 'v0', 'v1', ..., in column order.
|
|
338
422
|
"""
|
|
339
423
|
uvec = [next(ugen) for i in range(self._K)]
|
|
340
424
|
retA = self._mu + np.dot(self._A, stats.norm.ppf(uvec))
|
|
@@ -353,10 +437,15 @@ class CopulaGauss():
|
|
|
353
437
|
columns and observations in rows. That is, each column
|
|
354
438
|
represents the result of applying the fitted CDF of some marginal
|
|
355
439
|
distribution to the raw data for that variable. The
|
|
356
|
-
values in each column should be in the range
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
calculate the nearest positive definite matrix.
|
|
440
|
+
values in each column should be in the range (0, 1). The correlation
|
|
441
|
+
matrix is fit using the method of moments on the normal scores of
|
|
442
|
+
the pseudo-observations. If it is not positive definite, the Higham
|
|
443
|
+
method is used to calculate the nearest positive definite matrix.
|
|
444
|
+
|
|
445
|
+
Notes
|
|
446
|
+
-----
|
|
447
|
+
Each call to :meth:`draw` consumes K values from ``ugen``, where K is
|
|
448
|
+
the number of variables.
|
|
360
449
|
"""
|
|
361
450
|
|
|
362
451
|
def __init__(self,
|
|
@@ -412,7 +501,7 @@ class CopulaGauss():
|
|
|
412
501
|
standard uniform draws are the values in the Series.
|
|
413
502
|
If no variable names were provided in the input data,
|
|
414
503
|
the variables will be named 'v0', 'v1', ..., reflecting the
|
|
415
|
-
|
|
504
|
+
order of the columns in the input data.
|
|
416
505
|
|
|
417
506
|
"""
|
|
418
507
|
uvec = [next(ugen) for i in range(self._K)]
|
|
@@ -432,9 +521,14 @@ class CopulaStudent():
|
|
|
432
521
|
columns and observations in rows. That is, each column
|
|
433
522
|
represents the result of applying the fitted CDF of some marginal
|
|
434
523
|
distribution to the raw data for that variable. The
|
|
435
|
-
values in each column should be in the range
|
|
524
|
+
values in each column should be in the range (0, 1). The correlation
|
|
436
525
|
matrix is fit by pairwise Kendall's-tau inversion, and the degrees
|
|
437
|
-
of freedom are then fit by profile maximum likelihood.
|
|
526
|
+
of freedom are then fit by profile maximum pseudo-likelihood.
|
|
527
|
+
|
|
528
|
+
Notes
|
|
529
|
+
-----
|
|
530
|
+
Each call to :meth:`draw` consumes K + 1 values from ``ugen``, where K
|
|
531
|
+
is the number of variables.
|
|
438
532
|
"""
|
|
439
533
|
|
|
440
534
|
def __init__(self,
|
|
@@ -477,7 +571,7 @@ class CopulaStudent():
|
|
|
477
571
|
standard uniform draws are the values in the Series.
|
|
478
572
|
If no variable names were provided in the input data,
|
|
479
573
|
the variables will be named 'v0', 'v1', ..., reflecting the
|
|
480
|
-
|
|
574
|
+
order of the columns in the input data.
|
|
481
575
|
|
|
482
576
|
"""
|
|
483
577
|
uvec = [next(ugen) for i in range(self._K)]
|
|
@@ -500,10 +594,18 @@ class CopulaClayton():
|
|
|
500
594
|
columns and observations in rows. That is, each column
|
|
501
595
|
represents the result of applying the fitted CDF of some marginal
|
|
502
596
|
distribution to the raw data for that variable. The
|
|
503
|
-
values in each column should be in the range
|
|
504
|
-
fit
|
|
597
|
+
values in each column should be in the range (0, 1). The dependence
|
|
598
|
+
parameter theta is fit by maximum pseudo-likelihood, starting from
|
|
599
|
+
the Kendall's-tau inversion estimate. This implementation accommodates
|
|
505
600
|
only positive dependence, so the fitted value for theta is
|
|
506
601
|
constrained to be > 0.
|
|
602
|
+
|
|
603
|
+
Notes
|
|
604
|
+
-----
|
|
605
|
+
Each call to :meth:`draw` consumes K + 1 values from ``ugen``, where K
|
|
606
|
+
is the number of variables. If the data exhibit negative dependence
|
|
607
|
+
(mean pairwise Kendall's tau <= 0), theta is set to its minimum
|
|
608
|
+
(near independence) and a warning is issued.
|
|
507
609
|
"""
|
|
508
610
|
|
|
509
611
|
def __init__(self,
|
|
@@ -525,7 +627,7 @@ class CopulaClayton():
|
|
|
525
627
|
(self._theta, taub, clamped) = copfit.fit_clayton(self._data)
|
|
526
628
|
if clamped:
|
|
527
629
|
warnings.warn(f"The Clayton copula implementation in funcsim "
|
|
528
|
-
f"
|
|
630
|
+
f"accommodates only positive dependence, but the "
|
|
529
631
|
f"data exhibit negative dependence (mean pairwise "
|
|
530
632
|
f"Kendall's tau = {taub:.3f}). A theta value of "
|
|
531
633
|
f"{copfit.THETA_MIN_CLAYTON} is being used rather "
|
|
@@ -557,7 +659,7 @@ class CopulaClayton():
|
|
|
557
659
|
standard uniform draws are the values in the Series.
|
|
558
660
|
If no variable names were provided in the input data,
|
|
559
661
|
the variables will be named 'v0', 'v1', ..., reflecting the
|
|
560
|
-
|
|
662
|
+
order of the columns in the input data.
|
|
561
663
|
|
|
562
664
|
"""
|
|
563
665
|
# floor the gamma frailty: for large theta the shape parameter is
|
|
@@ -582,10 +684,18 @@ class CopulaGumbel():
|
|
|
582
684
|
columns and observations in rows. That is, each column
|
|
583
685
|
represents the result of applying the fitted CDF of some marginal
|
|
584
686
|
distribution to the raw data for that variable. The
|
|
585
|
-
values in each column should be in the range
|
|
586
|
-
fit
|
|
687
|
+
values in each column should be in the range (0, 1). The dependence
|
|
688
|
+
parameter theta is fit by maximum pseudo-likelihood, starting from
|
|
689
|
+
the Kendall's-tau inversion estimate. This implementation accommodates
|
|
587
690
|
only positive dependence, so the fitted value for theta is
|
|
588
691
|
constrained to be > 1.0.
|
|
692
|
+
|
|
693
|
+
Notes
|
|
694
|
+
-----
|
|
695
|
+
Each call to :meth:`draw` consumes K + 2 values from ``ugen``, where K
|
|
696
|
+
is the number of variables. If the data exhibit negative dependence
|
|
697
|
+
(mean pairwise Kendall's tau <= 0), theta is set to its minimum
|
|
698
|
+
(near independence) and a warning is issued.
|
|
589
699
|
"""
|
|
590
700
|
|
|
591
701
|
def __init__(self,
|
|
@@ -607,7 +717,7 @@ class CopulaGumbel():
|
|
|
607
717
|
(self._theta, taub, clamped) = copfit.fit_gumbel(self._data)
|
|
608
718
|
if clamped:
|
|
609
719
|
warnings.warn(f"The Gumbel copula implementation in funcsim "
|
|
610
|
-
f"
|
|
720
|
+
f"accommodates only positive dependence, but the "
|
|
611
721
|
f"data exhibit negative dependence (mean pairwise "
|
|
612
722
|
f"Kendall's tau = {taub:.3f}). A theta value of "
|
|
613
723
|
f"(approximately) 1.0 is being used rather than a "
|
|
@@ -639,7 +749,7 @@ class CopulaGumbel():
|
|
|
639
749
|
standard uniform draws are the values in the Series.
|
|
640
750
|
If no variable names were provided in the input data,
|
|
641
751
|
the variables will be named 'v0', 'v1', ..., reflecting the
|
|
642
|
-
|
|
752
|
+
order of the columns in the input data.
|
|
643
753
|
|
|
644
754
|
"""
|
|
645
755
|
gamma = math.cos(0.5 * math.pi / self._theta)**self._theta
|
|
@@ -662,10 +772,18 @@ class CopulaFrank():
|
|
|
662
772
|
columns and observations in rows. That is, each column
|
|
663
773
|
represents the result of applying the fitted CDF of some marginal
|
|
664
774
|
distribution to the raw data for that variable. The
|
|
665
|
-
values in each column should be in the range
|
|
666
|
-
fit
|
|
775
|
+
values in each column should be in the range (0, 1). The dependence
|
|
776
|
+
parameter theta is fit by maximum pseudo-likelihood, starting from
|
|
777
|
+
the Kendall's-tau inversion estimate. This implementation accommodates
|
|
667
778
|
only positive dependence, so the fitted value for theta is
|
|
668
779
|
constrained to be > 0.
|
|
780
|
+
|
|
781
|
+
Notes
|
|
782
|
+
-----
|
|
783
|
+
Each call to :meth:`draw` consumes K + 2 values from ``ugen``, where K
|
|
784
|
+
is the number of variables. If the data exhibit negative dependence
|
|
785
|
+
(mean pairwise Kendall's tau <= 0), theta is set to its minimum
|
|
786
|
+
(near independence) and a warning is issued.
|
|
669
787
|
"""
|
|
670
788
|
|
|
671
789
|
def __init__(self,
|
|
@@ -687,7 +805,7 @@ class CopulaFrank():
|
|
|
687
805
|
(self._theta, taub, clamped) = copfit.fit_frank(self._data)
|
|
688
806
|
if clamped:
|
|
689
807
|
warnings.warn(f"The Frank copula implementation in funcsim "
|
|
690
|
-
f"
|
|
808
|
+
f"accommodates only positive dependence, but the "
|
|
691
809
|
f"data exhibit negative dependence (mean pairwise "
|
|
692
810
|
f"Kendall's tau = {taub:.3f}). A theta value of "
|
|
693
811
|
f"{copfit.THETA_MIN_FRANK} is being used rather "
|
|
@@ -716,7 +834,7 @@ class CopulaFrank():
|
|
|
716
834
|
standard uniform draws are the values in the Series.
|
|
717
835
|
If no variable names were provided in the input data,
|
|
718
836
|
the variables will be named 'v0', 'v1', ..., reflecting the
|
|
719
|
-
|
|
837
|
+
order of the columns in the input data.
|
|
720
838
|
|
|
721
839
|
"""
|
|
722
840
|
# Generate d uniform random variables
|
|
@@ -414,7 +414,8 @@ def fit(data: conversions.VectorLike,
|
|
|
414
414
|
scipydist : scipy.stats.rv_continuous
|
|
415
415
|
The scipy.stats distribution object to fit (e.g., stats.norm).
|
|
416
416
|
distName : str, optional
|
|
417
|
-
Name
|
|
417
|
+
Name recorded in the ``distName`` field of the result (for example,
|
|
418
|
+
the label used by ``compare``). Default None.
|
|
418
419
|
lowerBound : float, optional
|
|
419
420
|
If given, the lower bound of the support of the fitted distribution
|
|
420
421
|
is fixed at this value rather than estimated. The distribution must
|
|
@@ -446,6 +447,8 @@ def fit(data: conversions.VectorLike,
|
|
|
446
447
|
The frozen fitted distribution object.
|
|
447
448
|
distName : str
|
|
448
449
|
Name of the fitted distribution.
|
|
450
|
+
warnings : list
|
|
451
|
+
Warnings captured during fitting (empty for a clean fit).
|
|
449
452
|
|
|
450
453
|
Raises
|
|
451
454
|
------
|
|
@@ -118,10 +118,14 @@ def kstest(data: conversions.VectorLike,
|
|
|
118
118
|
----------
|
|
119
119
|
data : VectorLike
|
|
120
120
|
Sample data vector.
|
|
121
|
-
dist : str or frozen distribution
|
|
122
|
-
|
|
121
|
+
dist : str, scipy.stats distribution, or frozen distribution
|
|
122
|
+
The hypothesized distribution: the name of a ``scipy.stats``
|
|
123
|
+
distribution (e.g., ``"norm"``), an unfrozen distribution object
|
|
124
|
+
(e.g., ``stats.norm``), or a frozen distribution (e.g.,
|
|
125
|
+
``stats.norm(0.0, 1.0)``).
|
|
123
126
|
args : tuple, optional
|
|
124
|
-
|
|
127
|
+
Shape, location, and scale parameters, applied when `dist` is a name
|
|
128
|
+
or an unfrozen distribution. Ignored for a frozen distribution.
|
|
125
129
|
assume_sorted : bool, optional
|
|
126
130
|
If True, assumes that `data` is already sorted. Defaults to False.
|
|
127
131
|
|
|
@@ -146,10 +150,14 @@ def cvmtest(data: conversions.VectorLike,
|
|
|
146
150
|
----------
|
|
147
151
|
data : VectorLike
|
|
148
152
|
Sample data vector.
|
|
149
|
-
dist : str or frozen distribution
|
|
150
|
-
|
|
153
|
+
dist : str, scipy.stats distribution, or frozen distribution
|
|
154
|
+
The hypothesized distribution: the name of a ``scipy.stats``
|
|
155
|
+
distribution (e.g., ``"norm"``), an unfrozen distribution object
|
|
156
|
+
(e.g., ``stats.norm``), or a frozen distribution (e.g.,
|
|
157
|
+
``stats.norm(0.0, 1.0)``).
|
|
151
158
|
args : tuple, optional
|
|
152
|
-
|
|
159
|
+
Shape, location, and scale parameters, applied when `dist` is a name
|
|
160
|
+
or an unfrozen distribution. Ignored for a frozen distribution.
|
|
153
161
|
assume_sorted : bool, optional
|
|
154
162
|
If True, assumes that `data` is already sorted. Defaults to False.
|
|
155
163
|
|
|
@@ -173,10 +181,14 @@ def adtest(data: conversions.VectorLike,
|
|
|
173
181
|
----------
|
|
174
182
|
data : VectorLike
|
|
175
183
|
Sample data vector.
|
|
176
|
-
dist : str or frozen distribution
|
|
177
|
-
|
|
184
|
+
dist : str, scipy.stats distribution, or frozen distribution
|
|
185
|
+
The hypothesized distribution: the name of a ``scipy.stats``
|
|
186
|
+
distribution (e.g., ``"norm"``), an unfrozen distribution object
|
|
187
|
+
(e.g., ``stats.norm``), or a frozen distribution (e.g.,
|
|
188
|
+
``stats.norm(0.0, 1.0)``).
|
|
178
189
|
args : tuple, optional
|
|
179
|
-
|
|
190
|
+
Shape, location, and scale parameters, applied when `dist` is a name
|
|
191
|
+
or an unfrozen distribution. Ignored for a frozen distribution.
|
|
180
192
|
assume_sorted : bool, optional
|
|
181
193
|
If True, assumes that `data` is already sorted. Defaults to False.
|
|
182
194
|
|
|
@@ -53,7 +53,7 @@ def eut(util: Callable[[float], float],
|
|
|
53
53
|
Compute expected utility and certainty equivalent income.
|
|
54
54
|
|
|
55
55
|
This can operate on an arbitrary utility function, numerically solving
|
|
56
|
-
for the certainty equivalent. For isoelastic expected
|
|
56
|
+
for the certainty equivalent. For isoelastic expected utility and
|
|
57
57
|
certainty equivalents, the function "eutIsoelastic" will be less
|
|
58
58
|
likely to suffer from numerical problems.
|
|
59
59
|
|
|
@@ -74,7 +74,7 @@ def eut(util: Callable[[float], float],
|
|
|
74
74
|
Named tuple with fields:
|
|
75
75
|
|
|
76
76
|
ExpectedValue : float
|
|
77
|
-
The mean
|
|
77
|
+
The mean utility of the outcomes.
|
|
78
78
|
CertaintyEquiv : float
|
|
79
79
|
The certainty equivalent income.
|
|
80
80
|
"""
|
|
@@ -40,12 +40,12 @@ def imanconover(spear: conversions.ArrayLike,
|
|
|
40
40
|
)-> pd.DataFrame:
|
|
41
41
|
|
|
42
42
|
"""
|
|
43
|
-
Induce a Spearman correlation
|
|
43
|
+
Induce a Spearman correlation structure using the Iman & Conover method.
|
|
44
44
|
|
|
45
45
|
Parameters
|
|
46
46
|
----------
|
|
47
47
|
spear : ArrayLike
|
|
48
|
-
Desired Spearman correlation matrix (must be
|
|
48
|
+
Desired Spearman correlation matrix (must be symmetric and
|
|
49
49
|
positive definite).
|
|
50
50
|
vectors : list of VectorLike
|
|
51
51
|
List of vectors, each representing draws for one variable.
|
|
@@ -59,7 +59,7 @@ def imanconover(spear: conversions.ArrayLike,
|
|
|
59
59
|
-------
|
|
60
60
|
pandas.DataFrame
|
|
61
61
|
DataFrame with one column for each vector/variable, where the
|
|
62
|
-
data
|
|
62
|
+
data reflect the desired Spearman correlation structure.
|
|
63
63
|
|
|
64
64
|
References
|
|
65
65
|
----------
|
|
@@ -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)
|
|
@@ -51,15 +51,18 @@ def fan(da: xr.DataArray,
|
|
|
51
51
|
varname : str
|
|
52
52
|
Name of the variable to plot from the "variables" dimension.
|
|
53
53
|
filepath : str, optional
|
|
54
|
-
Path to save the chart.
|
|
54
|
+
Path to save the chart. A ``.html`` extension writes an interactive
|
|
55
|
+
HTML file; ``.png``, ``.jpg``, ``.jpeg``, ``.webp``, ``.svg``, and
|
|
56
|
+
``.pdf`` write a static image, which requires the optional
|
|
57
|
+
``kaleido`` package. Default None (do not save).
|
|
55
58
|
line_color : str, optional
|
|
56
59
|
Color of the mean line. Default is 'blue'.
|
|
57
60
|
title : str, optional
|
|
58
61
|
Title for the figure. Default is "" (no title).
|
|
59
62
|
width : int, optional
|
|
60
|
-
Width of the chart in pixels. Default is
|
|
63
|
+
Width of the chart in pixels. Default is 750.
|
|
61
64
|
height : int, optional
|
|
62
|
-
Height of the chart in pixels. Default is
|
|
65
|
+
Height of the chart in pixels. Default is 400.
|
|
63
66
|
|
|
64
67
|
Returns
|
|
65
68
|
-------
|
|
@@ -244,12 +247,12 @@ def twofuncs(f0: Callable[[float], float],
|
|
|
244
247
|
Label for the first function. Default is "f0".
|
|
245
248
|
name1 : str, optional
|
|
246
249
|
Label for the second function. Default is "f1".
|
|
247
|
-
title : str,
|
|
248
|
-
Title for the
|
|
250
|
+
title : str, optional
|
|
251
|
+
Title for the figure. Default is "" (no title).
|
|
249
252
|
width : int, optional
|
|
250
|
-
Width of the chart in pixels. Default is
|
|
253
|
+
Width of the chart in pixels. Default is 750.
|
|
251
254
|
height : int, optional
|
|
252
|
-
Height of the chart in pixels. Default is
|
|
255
|
+
Height of the chart in pixels. Default is 400.
|
|
253
256
|
|
|
254
257
|
Returns
|
|
255
258
|
-------
|
|
@@ -309,9 +312,9 @@ def histpdf(data: conversions.VectorLike,
|
|
|
309
312
|
title : str, optional
|
|
310
313
|
Title for the figure. Default is "" (no title).
|
|
311
314
|
width : int, optional
|
|
312
|
-
Width of the chart in pixels. Default is
|
|
315
|
+
Width of the chart in pixels. Default is 750.
|
|
313
316
|
height : int, optional
|
|
314
|
-
Height of the chart in pixels. Default is
|
|
317
|
+
Height of the chart in pixels. Default is 400.
|
|
315
318
|
|
|
316
319
|
Returns
|
|
317
320
|
-------
|
|
@@ -389,7 +392,7 @@ def dblscat(a0: conversions.ArrayLike,
|
|
|
389
392
|
title : str, optional
|
|
390
393
|
Title for the figure. Default is "" (no title).
|
|
391
394
|
width : int, optional
|
|
392
|
-
Width of the chart in pixels. Default is
|
|
395
|
+
Width of the chart in pixels. Default is 500.
|
|
393
396
|
height : int, optional
|
|
394
397
|
Height of the chart in pixels. Default is 500.
|
|
395
398
|
|
|
@@ -530,8 +533,10 @@ def show(fig):
|
|
|
530
533
|
"""
|
|
531
534
|
Flexibly display a plotly plot in a Jupyter notebook.
|
|
532
535
|
|
|
533
|
-
Invokes plotly's fig.show() with a `renderer` argument set to the
|
|
534
|
-
|
|
536
|
+
Invokes plotly's ``fig.show()`` with a `renderer` argument set to the
|
|
537
|
+
value of the environment variable ``FUNCSIM_PLOTLY_RENDERER`` (for
|
|
538
|
+
example ``"notebook"``, ``"vscode"``, ``"browser"``, or ``"png"``).
|
|
539
|
+
If the variable is not set, plotly's default renderer is used.
|
|
535
540
|
|
|
536
541
|
Parameters
|
|
537
542
|
----------
|
|
@@ -3,10 +3,21 @@ import xarray as xr
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class MissingValue(Exception):
|
|
6
|
+
"""Raised by :meth:`RDdata.recall` when a requested value is unavailable."""
|
|
6
7
|
pass
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class RDdata():
|
|
11
|
+
"""
|
|
12
|
+
Per-trial history for a recursive-dynamic simulation.
|
|
13
|
+
|
|
14
|
+
``simulate`` passes an instance of this class as the second argument
|
|
15
|
+
(conventionally ``hist``) to a step function that accepts two
|
|
16
|
+
arguments. It holds the historical values supplied via ``hist0``
|
|
17
|
+
followed by the values the step function has returned so far in the
|
|
18
|
+
current trial. Step functions should only call :meth:`recall`; the
|
|
19
|
+
class is not meant to be instantiated by users.
|
|
20
|
+
"""
|
|
10
21
|
# container for an np array with pre-allocated memory for future values
|
|
11
22
|
# for a single trial in an RD sim
|
|
12
23
|
def __init__(self, a, steps, namePositions):
|
|
@@ -48,7 +59,9 @@ class RDdata():
|
|
|
48
59
|
varname : str
|
|
49
60
|
Name of the variable to recall.
|
|
50
61
|
lag : int, optional
|
|
51
|
-
Number of steps to lag
|
|
62
|
+
Number of steps to look back. ``lag=1`` is the previous step
|
|
63
|
+
(the most recent value available while a step is being
|
|
64
|
+
computed). Default is 0.
|
|
52
65
|
|
|
53
66
|
Returns
|
|
54
67
|
-------
|
|
@@ -73,7 +86,7 @@ class RDdata():
|
|
|
73
86
|
f'simulation, no (non-NaN) value for the '
|
|
74
87
|
f'variable "{varname}" with {lag} lag(s) is '
|
|
75
88
|
f'available. Be sure that you passed a '
|
|
76
|
-
f'
|
|
89
|
+
f'"hist0" array to "simulate" and that it '
|
|
77
90
|
f'contains this value.')
|
|
78
91
|
else:
|
|
79
92
|
raise MissingValue(f'In time step {self._currStep} in the '
|
|
@@ -351,8 +351,17 @@ def screen(data: conversions.VectorLike,
|
|
|
351
351
|
Returns
|
|
352
352
|
-------
|
|
353
353
|
str
|
|
354
|
-
A formatted string summarizing the results of stationarity,
|
|
354
|
+
A formatted string summarizing the results of stationarity,
|
|
355
355
|
heteroskedasticity, autocorrelation, and randomness tests.
|
|
356
|
+
|
|
357
|
+
Notes
|
|
358
|
+
-----
|
|
359
|
+
Line A is an augmented Dickey-Fuller (ADF) test whose equation includes
|
|
360
|
+
a constant, so its alternative is stationarity around a constant
|
|
361
|
+
(possibly nonzero) mean. Line B adds a linear time trend, so its
|
|
362
|
+
alternative is trend stationarity. Lines C (White) and D (Ljung-Box)
|
|
363
|
+
are applied to the residuals from a regression of the series on the
|
|
364
|
+
observation number. Lines E and F test the overall i.i.d. null.
|
|
356
365
|
"""
|
|
357
366
|
|
|
358
367
|
if alpha <= 0 or alpha >= 1:
|
|
@@ -369,9 +378,13 @@ def screen(data: conversions.VectorLike,
|
|
|
369
378
|
y_hat = X @ beta
|
|
370
379
|
resid = y - y_hat
|
|
371
380
|
|
|
372
|
-
# ADF tests: line A
|
|
373
|
-
#
|
|
374
|
-
|
|
381
|
+
# ADF tests: line A includes a constant, so it tests for stationarity
|
|
382
|
+
# around a constant mean (a no-constant equation has zero-mean
|
|
383
|
+
# stationarity as its alternative, so it fails to reject the unit root,
|
|
384
|
+
# and the report warns, for an i.i.d. series whose mean is large
|
|
385
|
+
# relative to its standard deviation); line B includes a constant and
|
|
386
|
+
# a linear trend, so it is a genuine trend-stationarity test
|
|
387
|
+
p_adf = adf_test_with_const(seriesA, max_lag=2, n_sim=1000, seed=42)[1]
|
|
375
388
|
p_adf_t = adf_test_const_trend(seriesA, max_lag=2, n_sim=1000, seed=42)[1]
|
|
376
389
|
|
|
377
390
|
# White test for heteroskedasticity (constant is added inside
|
|
@@ -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
|
|
|
@@ -216,22 +220,43 @@ def shrink(data: conversions.ArrayLike,
|
|
|
216
220
|
data : ArrayLike
|
|
217
221
|
Data array with variables in columns and observations in rows.
|
|
218
222
|
target : str
|
|
219
|
-
Shrinkage target, one of
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
223
|
+
Shrinkage target, one of 'A' through 'F', following Table 2 of
|
|
224
|
+
Schafer and Strimmer (2005):
|
|
225
|
+
|
|
226
|
+
- 'A': diagonal, unit variance
|
|
227
|
+
- 'B': diagonal, common variance
|
|
228
|
+
- 'C': common variance and common covariance
|
|
229
|
+
- 'D': diagonal, unequal variance
|
|
230
|
+
- 'E': perfect positive correlation
|
|
231
|
+
- 'F': constant correlation
|
|
232
|
+
|
|
233
|
+
Targets 'B', 'E', and 'F' originate in Ledoit and Wolf (2003,
|
|
234
|
+
2004). The shrinkage intensity is estimated analytically in each
|
|
235
|
+
case.
|
|
236
|
+
return_intensity : bool, optional
|
|
237
|
+
If True, also return the estimated shrinkage intensity. Default is
|
|
238
|
+
False.
|
|
225
239
|
|
|
226
240
|
Returns
|
|
227
241
|
-------
|
|
228
|
-
ArrayLike
|
|
229
|
-
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.
|
|
230
248
|
|
|
231
249
|
Raises
|
|
232
250
|
------
|
|
233
251
|
ValueError
|
|
234
252
|
If target is not one of: 'A', 'B', 'C', 'D', 'E', 'F'.
|
|
253
|
+
|
|
254
|
+
References
|
|
255
|
+
----------
|
|
256
|
+
Schafer, J., & Strimmer, K. (2005). A shrinkage approach to large-scale
|
|
257
|
+
covariance matrix estimation and implications for functional genomics.
|
|
258
|
+
Statistical Applications in Genetics and Molecular Biology, 4(1),
|
|
259
|
+
Article 32.
|
|
235
260
|
"""
|
|
236
261
|
if target not in ['A', 'B', 'C', 'D', 'E', 'F']:
|
|
237
262
|
raise ValueError("target must be one of: A, B, C, D, E, F")
|
|
@@ -245,26 +270,30 @@ def shrink(data: conversions.ArrayLike,
|
|
|
245
270
|
'E': _target_e,
|
|
246
271
|
'F': _target_f}
|
|
247
272
|
|
|
248
|
-
sig = target_map[target](a_np)
|
|
273
|
+
sig, lam = target_map[target](a_np)
|
|
249
274
|
|
|
250
275
|
# return the same type of array that was passed. the result is a
|
|
251
276
|
# p-by-p covariance matrix, so both axes are labeled with the
|
|
252
277
|
# variable (column) labels of the input, not the observation index
|
|
253
278
|
if isinstance(data, pd.DataFrame):
|
|
254
|
-
|
|
255
|
-
|
|
279
|
+
result = pd.DataFrame(data=sig, index=data.columns,
|
|
280
|
+
columns=data.columns)
|
|
256
281
|
elif isinstance(data, xr.DataArray):
|
|
257
282
|
coldim = str(data.dims[-1])
|
|
258
283
|
if coldim in data.coords:
|
|
259
284
|
varnames = np.asarray(data.coords[coldim].values)
|
|
260
285
|
else:
|
|
261
286
|
varnames = np.arange(sig.shape[0])
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
287
|
+
result = xr.DataArray(sig,
|
|
288
|
+
dims=(coldim, coldim + "_"),
|
|
289
|
+
coords={coldim: varnames,
|
|
290
|
+
coldim + "_": varnames})
|
|
266
291
|
else:
|
|
267
|
-
|
|
292
|
+
result = sig
|
|
293
|
+
|
|
294
|
+
if return_intensity:
|
|
295
|
+
return result, float(lam)
|
|
296
|
+
return result
|
|
268
297
|
|
|
269
298
|
|
|
270
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.5
|
|
4
4
|
Summary: functional, simple stochastic simulation
|
|
5
5
|
Home-page: https://github.com/h-bryant/funcsim
|
|
6
6
|
Author: Henry Bryant
|
|
@@ -46,35 +46,43 @@ Dynamic: summary
|
|
|
46
46
|
# funcsim
|
|
47
47
|
Lightweight, functional stochastic simulation
|
|
48
48
|
|
|
49
|
+
Documentation: https://funcsim.readthedocs.io/
|
|
50
|
+
|
|
49
51
|
Features:
|
|
50
|
-
- cross-sectional and recursive
|
|
51
|
-
- pseudo-random numbers (so that results are comparable across
|
|
52
|
+
- static (cross-sectional) and recursive-dynamic simulations from a single user-written function
|
|
53
|
+
- pseudo-random numbers with an explicit seed (so that results are reproducible and comparable across runs or scenarios)
|
|
52
54
|
- stratified/Latin hypercube sampling
|
|
53
55
|
- painless multi-core simulations
|
|
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; covariance shrinkage
|
|
58
|
+
- expected utility and cumulative prospect theory calculations
|
|
59
|
+
- plotly-based fan charts and diagnostic plots
|
|
54
60
|
- highly flexible, and as simple as possible (but no more)
|
|
55
61
|
- functional paradigm
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
- python >= 3.
|
|
59
|
-
- numpy 2.2.0
|
|
60
|
-
- scipy 1.16.0
|
|
61
|
-
- pandas 2.2.0 (pandas 2.2+ and 3.x are both supported)
|
|
62
|
-
- xarray 2025.4.0
|
|
63
|
-
|
|
64
|
-
Copulas (Gaussian, Student's t, Clayton, Gumbel, and Frank) are supported
|
|
65
|
-
natively; no additional packages are required.
|
|
63
|
+
Requirements:
|
|
64
|
+
- python >= 3.11
|
|
65
|
+
- numpy >= 2.2.0
|
|
66
|
+
- scipy >= 1.16.0
|
|
67
|
+
- pandas >= 2.2.0 (pandas 2.2+ and 3.x are both supported)
|
|
68
|
+
- xarray >= 2025.4.0
|
|
66
69
|
|
|
67
|
-
For optional functionality,
|
|
68
|
-
- plotting: plotly
|
|
70
|
+
For optional functionality, additional packages are needed:
|
|
71
|
+
- plotting: plotly (`pip install "funcsim[plotting]"`); kaleido for static image export
|
|
69
72
|
|
|
70
|
-
Additionally, to run the
|
|
73
|
+
Additionally, to run the tests and build the docs:
|
|
71
74
|
- pytest
|
|
72
|
-
- sphinx, sphinx-autodoc-typehints
|
|
75
|
+
- sphinx, sphinx-autodoc-typehints (`pip install "funcsim[docs]"`)
|
|
76
|
+
|
|
77
|
+
### installation
|
|
78
|
+
```bash
|
|
79
|
+
pip install funcsim
|
|
80
|
+
```
|
|
73
81
|
|
|
74
82
|
### building html docs
|
|
75
83
|
From the top-level funcsim directory...
|
|
76
84
|
```bash
|
|
77
|
-
sphinx-build -b html docs/source/ docs/build/
|
|
85
|
+
sphinx-build -W -b html docs/source/ docs/build/
|
|
78
86
|
```
|
|
79
87
|
|
|
80
88
|
### running tests
|
funcsim-0.2.3/README.md
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# funcsim
|
|
2
|
-
Lightweight, functional stochastic simulation
|
|
3
|
-
|
|
4
|
-
Features:
|
|
5
|
-
- cross-sectional and recursive dynamic simulations
|
|
6
|
-
- pseudo-random numbers (so that results are comparable across multiple runs or scenarios)
|
|
7
|
-
- stratified/Latin hypercube sampling
|
|
8
|
-
- painless multi-core simulations
|
|
9
|
-
- highly flexible, and as simple as possible (but no more)
|
|
10
|
-
- functional paradigm
|
|
11
|
-
|
|
12
|
-
Developed using:
|
|
13
|
-
- python >= 3.10
|
|
14
|
-
- numpy 2.2.0
|
|
15
|
-
- scipy 1.16.0
|
|
16
|
-
- pandas 2.2.0 (pandas 2.2+ and 3.x are both supported)
|
|
17
|
-
- xarray 2025.4.0
|
|
18
|
-
|
|
19
|
-
Copulas (Gaussian, Student's t, Clayton, Gumbel, and Frank) are supported
|
|
20
|
-
natively; no additional packages are required.
|
|
21
|
-
|
|
22
|
-
For optional functionality, additinoal packages are needed:
|
|
23
|
-
- plotting: plotly
|
|
24
|
-
|
|
25
|
-
Additionally, to run the demos, run tests, and build docs:
|
|
26
|
-
- pytest
|
|
27
|
-
- sphinx, sphinx-autodoc-typehints
|
|
28
|
-
|
|
29
|
-
### building html docs
|
|
30
|
-
From the top-level funcsim directory...
|
|
31
|
-
```bash
|
|
32
|
-
sphinx-build -b html docs/source/ docs/build/
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### running tests
|
|
36
|
-
From the top-level funcsim directory...
|
|
37
|
-
```bash
|
|
38
|
-
python3 -m pytest
|
|
39
|
-
```
|
|
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
|