flopscope 0.2.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.
- benchmarks/__init__.py +1 -0
- benchmarks/__main__.py +6 -0
- benchmarks/_baseline.py +171 -0
- benchmarks/_bitwise.py +231 -0
- benchmarks/_complex.py +176 -0
- benchmarks/_contractions.py +291 -0
- benchmarks/_fft.py +198 -0
- benchmarks/_impl_urls.py +139 -0
- benchmarks/_linalg.py +197 -0
- benchmarks/_linalg_delegates.py +407 -0
- benchmarks/_metadata.py +141 -0
- benchmarks/_misc.py +653 -0
- benchmarks/_perf.py +321 -0
- benchmarks/_perm_group_calibration.py +175 -0
- benchmarks/_pointwise.py +372 -0
- benchmarks/_polynomial.py +193 -0
- benchmarks/_random.py +209 -0
- benchmarks/_reductions.py +136 -0
- benchmarks/_sorting.py +289 -0
- benchmarks/_stats.py +137 -0
- benchmarks/_window.py +92 -0
- benchmarks/accumulation/__init__.py +0 -0
- benchmarks/accumulation/bench_cost_compute.py +138 -0
- benchmarks/dashboard.py +312 -0
- benchmarks/runner.py +636 -0
- flopscope/__init__.py +273 -0
- flopscope/_accumulation/__init__.py +13 -0
- flopscope/_accumulation/_bipartite.py +121 -0
- flopscope/_accumulation/_burnside.py +51 -0
- flopscope/_accumulation/_cache.py +146 -0
- flopscope/_accumulation/_components.py +153 -0
- flopscope/_accumulation/_cost.py +1414 -0
- flopscope/_accumulation/_cost_descriptions.py +63 -0
- flopscope/_accumulation/_detection.py +318 -0
- flopscope/_accumulation/_ladder.py +191 -0
- flopscope/_accumulation/_output_orbit.py +104 -0
- flopscope/_accumulation/_partition.py +290 -0
- flopscope/_accumulation/_path_info.py +211 -0
- flopscope/_accumulation/_public.py +169 -0
- flopscope/_accumulation/_reduction.py +310 -0
- flopscope/_accumulation/_regimes.py +303 -0
- flopscope/_accumulation/_shape.py +33 -0
- flopscope/_accumulation/_wreath.py +209 -0
- flopscope/_budget.py +1027 -0
- flopscope/_config.py +118 -0
- flopscope/_counting_ops.py +451 -0
- flopscope/_display.py +478 -0
- flopscope/_docstrings.py +59 -0
- flopscope/_dtypes.py +20 -0
- flopscope/_einsum.py +717 -0
- flopscope/_errstate.py +25 -0
- flopscope/_flops.py +282 -0
- flopscope/_free_ops.py +2654 -0
- flopscope/_ndarray.py +1126 -0
- flopscope/_opt_einsum/LICENSE +21 -0
- flopscope/_opt_einsum/NOTICE +59 -0
- flopscope/_opt_einsum/__init__.py +209 -0
- flopscope/_opt_einsum/_contract.py +1478 -0
- flopscope/_opt_einsum/_helpers.py +164 -0
- flopscope/_opt_einsum/_hsluv.py +273 -0
- flopscope/_opt_einsum/_path_random.py +462 -0
- flopscope/_opt_einsum/_paths.py +1653 -0
- flopscope/_opt_einsum/_subgraph_symmetry.py +544 -0
- flopscope/_opt_einsum/_symmetry.py +140 -0
- flopscope/_opt_einsum/_typing.py +37 -0
- flopscope/_perm_group.py +717 -0
- flopscope/_pointwise.py +2522 -0
- flopscope/_polynomial.py +278 -0
- flopscope/_registry.py +3216 -0
- flopscope/_sorting_ops.py +571 -0
- flopscope/_symmetric.py +812 -0
- flopscope/_symmetry_transport.py +510 -0
- flopscope/_symmetry_utils.py +669 -0
- flopscope/_type_info.py +12 -0
- flopscope/_unwrap.py +70 -0
- flopscope/_validation.py +83 -0
- flopscope/_version_check.py +46 -0
- flopscope/_weights.py +195 -0
- flopscope/_window.py +177 -0
- flopscope/accounting.py +565 -0
- flopscope/data/default_weights.json +462 -0
- flopscope/data/weights.csv +509 -0
- flopscope/errors.py +197 -0
- flopscope/numpy/__init__.py +878 -0
- flopscope/numpy/fft/__init__.py +55 -0
- flopscope/numpy/fft/_free.py +51 -0
- flopscope/numpy/fft/_transforms.py +695 -0
- flopscope/numpy/linalg/__init__.py +105 -0
- flopscope/numpy/linalg/_aliases.py +126 -0
- flopscope/numpy/linalg/_compound.py +161 -0
- flopscope/numpy/linalg/_decompositions.py +353 -0
- flopscope/numpy/linalg/_properties.py +533 -0
- flopscope/numpy/linalg/_solvers.py +444 -0
- flopscope/numpy/linalg/_svd.py +122 -0
- flopscope/numpy/random/__init__.py +684 -0
- flopscope/numpy/random/_cost_formulas.py +115 -0
- flopscope/numpy/random/_counted_classes.py +241 -0
- flopscope/numpy/testing/__init__.py +13 -0
- flopscope/numpy/typing/__init__.py +30 -0
- flopscope/py.typed +0 -0
- flopscope/stats/__init__.py +84 -0
- flopscope/stats/_base.py +77 -0
- flopscope/stats/_cauchy.py +146 -0
- flopscope/stats/_erf.py +190 -0
- flopscope/stats/_expon.py +146 -0
- flopscope/stats/_laplace.py +150 -0
- flopscope/stats/_logistic.py +148 -0
- flopscope/stats/_lognorm.py +160 -0
- flopscope/stats/_ndtri.py +133 -0
- flopscope/stats/_norm.py +149 -0
- flopscope/stats/_truncnorm.py +186 -0
- flopscope/stats/_uniform.py +141 -0
- flopscope-0.2.0.dist-info/METADATA +23 -0
- flopscope-0.2.0.dist-info/RECORD +115 -0
- flopscope-0.2.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""Cauchy distribution for :mod:`flopscope.stats`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as _np
|
|
6
|
+
|
|
7
|
+
from flopscope.stats._base import ContinuousDistribution
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CauchyDistribution(ContinuousDistribution):
|
|
11
|
+
"""Cauchy (Lorentz) continuous random variable.
|
|
12
|
+
|
|
13
|
+
This object mirrors ``scipy.stats.cauchy``.
|
|
14
|
+
|
|
15
|
+
Methods
|
|
16
|
+
-------
|
|
17
|
+
pdf(x, loc=0, scale=1)
|
|
18
|
+
Evaluate the probability density function.
|
|
19
|
+
cdf(x, loc=0, scale=1)
|
|
20
|
+
Evaluate the cumulative distribution function.
|
|
21
|
+
ppf(q, loc=0, scale=1)
|
|
22
|
+
Evaluate the percent-point function.
|
|
23
|
+
|
|
24
|
+
Notes
|
|
25
|
+
-----
|
|
26
|
+
``loc`` is the location parameter and ``scale`` is the half-width at
|
|
27
|
+
half-maximum. Each public method deducts ``1 * numel(input)`` FLOPs from
|
|
28
|
+
the active budget.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
super().__init__("cauchy")
|
|
33
|
+
|
|
34
|
+
def pdf(self, x, loc=0, scale=1):
|
|
35
|
+
"""Evaluate the probability density function.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
x : array_like
|
|
40
|
+
Points at which to evaluate the density.
|
|
41
|
+
loc : float, optional
|
|
42
|
+
Location parameter of the distribution. Defaults to ``0``.
|
|
43
|
+
scale : float, optional
|
|
44
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
FlopscopeArray
|
|
49
|
+
Probability density evaluated elementwise at ``x``.
|
|
50
|
+
|
|
51
|
+
Notes
|
|
52
|
+
-----
|
|
53
|
+
Equivalent to ``scipy.stats.cauchy.pdf(x, loc, scale)``.
|
|
54
|
+
FLOP cost: ``1 * numel(x)``.
|
|
55
|
+
|
|
56
|
+
Examples
|
|
57
|
+
--------
|
|
58
|
+
>>> import numpy as np
|
|
59
|
+
>>> import flopscope as flops
|
|
60
|
+
>>> x = np.array([-1.0, 0.0, 1.0])
|
|
61
|
+
>>> np.round(flops.stats.cauchy.pdf(x), 3)
|
|
62
|
+
array([0.159, 0.318, 0.159])
|
|
63
|
+
"""
|
|
64
|
+
return self._deduct_and_call("pdf", 1, x, loc=loc, scale=scale)
|
|
65
|
+
|
|
66
|
+
def cdf(self, x, loc=0, scale=1):
|
|
67
|
+
"""Evaluate the cumulative distribution function.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
x : array_like
|
|
72
|
+
Points at which to evaluate the cumulative probability.
|
|
73
|
+
loc : float, optional
|
|
74
|
+
Location parameter of the distribution. Defaults to ``0``.
|
|
75
|
+
scale : float, optional
|
|
76
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
FlopscopeArray
|
|
81
|
+
Cumulative probability evaluated elementwise at ``x``.
|
|
82
|
+
|
|
83
|
+
Notes
|
|
84
|
+
-----
|
|
85
|
+
Equivalent to ``scipy.stats.cauchy.cdf(x, loc, scale)``.
|
|
86
|
+
FLOP cost: ``1 * numel(x)``.
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
>>> import numpy as np
|
|
91
|
+
>>> import flopscope as flops
|
|
92
|
+
>>> x = np.array([-1.0, 0.0, 1.0])
|
|
93
|
+
>>> np.round(flops.stats.cauchy.cdf(x), 3)
|
|
94
|
+
array([0.25, 0.5 , 0.75])
|
|
95
|
+
"""
|
|
96
|
+
return self._deduct_and_call("cdf", 1, x, loc=loc, scale=scale)
|
|
97
|
+
|
|
98
|
+
def ppf(self, q, loc=0, scale=1):
|
|
99
|
+
"""Evaluate the percent-point function.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
q : array_like
|
|
104
|
+
Probabilities in ``[0, 1]``.
|
|
105
|
+
loc : float, optional
|
|
106
|
+
Location parameter of the distribution. Defaults to ``0``.
|
|
107
|
+
scale : float, optional
|
|
108
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
FlopscopeArray
|
|
113
|
+
Quantiles corresponding to ``q``.
|
|
114
|
+
|
|
115
|
+
Notes
|
|
116
|
+
-----
|
|
117
|
+
Equivalent to ``scipy.stats.cauchy.ppf(q, loc, scale)``.
|
|
118
|
+
FLOP cost: ``1 * numel(q)``.
|
|
119
|
+
|
|
120
|
+
Examples
|
|
121
|
+
--------
|
|
122
|
+
>>> import numpy as np
|
|
123
|
+
>>> import flopscope as flops
|
|
124
|
+
>>> q = np.array([0.25, 0.5, 0.75])
|
|
125
|
+
>>> np.round(flops.stats.cauchy.ppf(q), 3)
|
|
126
|
+
array([-1., 0., 1.])
|
|
127
|
+
"""
|
|
128
|
+
return self._deduct_and_call("ppf", 1, q, loc=loc, scale=scale)
|
|
129
|
+
|
|
130
|
+
def _compute_pdf(self, x, loc=0, scale=1):
|
|
131
|
+
z = (x - loc) / scale
|
|
132
|
+
return 1.0 / (_np.pi * scale * (1.0 + z * z))
|
|
133
|
+
|
|
134
|
+
def _compute_cdf(self, x, loc=0, scale=1):
|
|
135
|
+
z = (x - loc) / scale
|
|
136
|
+
return 0.5 + _np.arctan(z) / _np.pi
|
|
137
|
+
|
|
138
|
+
def _compute_ppf(self, q, loc=0, scale=1):
|
|
139
|
+
result = loc + scale * _np.tan(_np.pi * (q - 0.5))
|
|
140
|
+
result = _np.where((q > 0) & (q < 1), result, _np.nan)
|
|
141
|
+
result = _np.where(q == 0, -_np.inf, result)
|
|
142
|
+
result = _np.where(q == 1, _np.inf, result)
|
|
143
|
+
return result
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
cauchy = CauchyDistribution()
|
flopscope/stats/_erf.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""Vectorized error function using the fdlibm/Sun rational approximation.
|
|
2
|
+
|
|
3
|
+
Uses the same algorithm and coefficients as the C99 math.erf / glibc / fdlibm
|
|
4
|
+
``s_erf.c`` implementation, which is the gold-standard for double-precision erf.
|
|
5
|
+
|
|
6
|
+
Four regions:
|
|
7
|
+
|x| < 0.84375 : erf(x) = x + x*P(x^2)/Q(x^2)
|
|
8
|
+
0.84375<=|x|<1.25 : erf(x) = erx + P(|x|-1)/Q(|x|-1)
|
|
9
|
+
1.25 <= |x| < ~6 : erfc(x) = exp(-x^2-0.5625+R(1/x^2)/S(1/x^2)) / |x|
|
|
10
|
+
|x| >= 6 : erf(x) = sign(x) * 1.0
|
|
11
|
+
|
|
12
|
+
Accuracy: matches C99 math.erf / scipy.special.erf to ~1 ULP.
|
|
13
|
+
|
|
14
|
+
References
|
|
15
|
+
----------
|
|
16
|
+
.. [1] Sun Microsystems, "Freely Distributable LIBM (fdlibm) s_erf.c",
|
|
17
|
+
https://www.netlib.org/fdlibm/s_erf.c
|
|
18
|
+
Algorithm and coefficients by Sun Microsystems (see copyright below).
|
|
19
|
+
|
|
20
|
+
.. [2] glibc implementation (derived from fdlibm):
|
|
21
|
+
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/ieee754/dbl-64/s_erf.c
|
|
22
|
+
|
|
23
|
+
Copyright (original fdlibm source)
|
|
24
|
+
-----------------------------------
|
|
25
|
+
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
26
|
+
Developed at SunSoft, a Sun Microsystems, Inc. business.
|
|
27
|
+
Permission to use, copy, modify, and distribute this software is freely
|
|
28
|
+
granted, provided that this notice is preserved.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import numpy as np
|
|
34
|
+
|
|
35
|
+
# ---------------------------------------------------------------------------
|
|
36
|
+
# Coefficients from fdlibm s_erf.c (Sun / glibc / OpenBSD)
|
|
37
|
+
# ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
# erx = erf(1) to extended precision
|
|
40
|
+
_erx = 8.45062911510467529297e-01
|
|
41
|
+
|
|
42
|
+
# Region 1: |x| < 0.84375 -- erf(x) = x + x * pp(x^2)/qq(x^2)
|
|
43
|
+
_pp0 = 1.28379167095512558561e-01
|
|
44
|
+
_pp1 = -3.25042107247001499370e-01
|
|
45
|
+
_pp2 = -2.84817495755985104766e-02
|
|
46
|
+
_pp3 = -5.77027029648944159157e-03
|
|
47
|
+
_pp4 = -2.37630166566501626084e-05
|
|
48
|
+
|
|
49
|
+
_qq1 = 3.97917223959155352819e-01
|
|
50
|
+
_qq2 = 6.50222499887672944485e-02
|
|
51
|
+
_qq3 = 5.08130628187576562776e-03
|
|
52
|
+
_qq4 = 1.32494738004321644526e-04
|
|
53
|
+
_qq5 = -3.96022827877536812320e-06
|
|
54
|
+
|
|
55
|
+
# Region 2: 0.84375 <= |x| < 1.25 -- erf(x) = erx + P(s)/Q(s), s = |x| - 1
|
|
56
|
+
_pa0 = -2.36211856075265944077e-03
|
|
57
|
+
_pa1 = 4.14856118683748331666e-01
|
|
58
|
+
_pa2 = -3.72207876035701323847e-01
|
|
59
|
+
_pa3 = 3.18346619901161753674e-01
|
|
60
|
+
_pa4 = -1.10894694282396677476e-01
|
|
61
|
+
_pa5 = 3.54783043195201877747e-02
|
|
62
|
+
_pa6 = -2.16637559983254089680e-03
|
|
63
|
+
|
|
64
|
+
_qa1 = 1.06420880400844228286e-01
|
|
65
|
+
_qa2 = 5.40397917702171048937e-01
|
|
66
|
+
_qa3 = 7.18286544141962539399e-02
|
|
67
|
+
_qa4 = 1.26171219808761642112e-01
|
|
68
|
+
_qa5 = 1.36370839120290507362e-02
|
|
69
|
+
_qa6 = 1.19844998467991074170e-02
|
|
70
|
+
|
|
71
|
+
# Region 3a: 1.25 <= |x| < 1/0.35 (~2.857)
|
|
72
|
+
_ra0 = -9.86494403484714822705e-03
|
|
73
|
+
_ra1 = -6.93858572707181764372e-01
|
|
74
|
+
_ra2 = -1.05586262253232909814e01
|
|
75
|
+
_ra3 = -6.23753324503260060396e01
|
|
76
|
+
_ra4 = -1.62396669462573071767e02
|
|
77
|
+
_ra5 = -1.84605092906711035994e02
|
|
78
|
+
_ra6 = -8.12874355063065934246e01
|
|
79
|
+
_ra7 = -9.81432934416914548592e00
|
|
80
|
+
|
|
81
|
+
_sa1 = 1.96512716674392571292e01
|
|
82
|
+
_sa2 = 1.37657754143519702237e02
|
|
83
|
+
_sa3 = 4.34565877475229228608e02
|
|
84
|
+
_sa4 = 6.45387271733267880594e02
|
|
85
|
+
_sa5 = 4.29008140027567833386e02
|
|
86
|
+
_sa6 = 1.08635005541779435134e02
|
|
87
|
+
_sa7 = 6.57024977031928170135e00
|
|
88
|
+
_sa8 = -6.04244152148580987438e-02
|
|
89
|
+
|
|
90
|
+
# Region 3b: 1/0.35 (~2.857) <= |x| < 6
|
|
91
|
+
_rb0 = -9.86494292470009928597e-03
|
|
92
|
+
_rb1 = -7.99283237680523006574e-01
|
|
93
|
+
_rb2 = -1.77579549177547519889e01
|
|
94
|
+
_rb3 = -1.60636384855557935030e02
|
|
95
|
+
_rb4 = -6.37566443368389085394e02
|
|
96
|
+
_rb5 = -1.02509513161107724954e03
|
|
97
|
+
_rb6 = -4.83519191608651397019e02
|
|
98
|
+
|
|
99
|
+
_sb1 = 3.03380607875625778203e01
|
|
100
|
+
_sb2 = 3.25792512996573918826e02
|
|
101
|
+
_sb3 = 1.53672958608443695994e03
|
|
102
|
+
_sb4 = 3.19985821950859553908e03
|
|
103
|
+
_sb5 = 2.55305040643316442583e03
|
|
104
|
+
_sb6 = 4.74528541206955367215e02
|
|
105
|
+
_sb7 = -2.24409524465858183362e01
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _erf(x):
|
|
109
|
+
"""Vectorized error function matching scipy.special.erf to ~1 ULP.
|
|
110
|
+
|
|
111
|
+
Algorithm and coefficients from fdlibm ``s_erf.c`` [1]_.
|
|
112
|
+
"""
|
|
113
|
+
x = np.asarray(x, dtype=np.float64)
|
|
114
|
+
scalar = x.ndim == 0
|
|
115
|
+
x = np.atleast_1d(x)
|
|
116
|
+
|
|
117
|
+
out = np.empty_like(x)
|
|
118
|
+
ax = np.abs(x)
|
|
119
|
+
sign = np.sign(x)
|
|
120
|
+
|
|
121
|
+
# --- Region 1: |x| < 0.84375 ---
|
|
122
|
+
m1 = ax < 0.84375
|
|
123
|
+
if np.any(m1):
|
|
124
|
+
xm = x[m1]
|
|
125
|
+
s = xm * xm
|
|
126
|
+
r = _pp0 + s * (_pp1 + s * (_pp2 + s * (_pp3 + s * _pp4)))
|
|
127
|
+
S = 1.0 + s * (_qq1 + s * (_qq2 + s * (_qq3 + s * (_qq4 + s * _qq5))))
|
|
128
|
+
out[m1] = xm + xm * (r / S)
|
|
129
|
+
|
|
130
|
+
# --- Region 2: 0.84375 <= |x| < 1.25 ---
|
|
131
|
+
m2 = (ax >= 0.84375) & (ax < 1.25)
|
|
132
|
+
if np.any(m2):
|
|
133
|
+
s = ax[m2] - 1.0
|
|
134
|
+
P = _pa0 + s * (
|
|
135
|
+
_pa1 + s * (_pa2 + s * (_pa3 + s * (_pa4 + s * (_pa5 + s * _pa6))))
|
|
136
|
+
)
|
|
137
|
+
Q = 1.0 + s * (
|
|
138
|
+
_qa1 + s * (_qa2 + s * (_qa3 + s * (_qa4 + s * (_qa5 + s * _qa6))))
|
|
139
|
+
)
|
|
140
|
+
out[m2] = sign[m2] * (_erx + P / Q)
|
|
141
|
+
|
|
142
|
+
# --- Region 3a: 1.25 <= |x| < 1/0.35 (~2.857) ---
|
|
143
|
+
m3a = (ax >= 1.25) & (ax < (1.0 / 0.35))
|
|
144
|
+
if np.any(m3a):
|
|
145
|
+
axm = ax[m3a]
|
|
146
|
+
s = 1.0 / (axm * axm)
|
|
147
|
+
R = _ra0 + s * (
|
|
148
|
+
_ra1
|
|
149
|
+
+ s * (_ra2 + s * (_ra3 + s * (_ra4 + s * (_ra5 + s * (_ra6 + s * _ra7)))))
|
|
150
|
+
)
|
|
151
|
+
S = 1.0 + s * (
|
|
152
|
+
_sa1
|
|
153
|
+
+ s
|
|
154
|
+
* (
|
|
155
|
+
_sa2
|
|
156
|
+
+ s
|
|
157
|
+
* (_sa3 + s * (_sa4 + s * (_sa5 + s * (_sa6 + s * (_sa7 + s * _sa8)))))
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
erfc_val = np.exp(-axm * axm - 0.5625 + R / S) / axm
|
|
161
|
+
out[m3a] = sign[m3a] * (1.0 - erfc_val)
|
|
162
|
+
|
|
163
|
+
# --- Region 3b: 1/0.35 <= |x| < 6 ---
|
|
164
|
+
m3b = (ax >= (1.0 / 0.35)) & (ax < 6.0)
|
|
165
|
+
if np.any(m3b):
|
|
166
|
+
axm = ax[m3b]
|
|
167
|
+
s = 1.0 / (axm * axm)
|
|
168
|
+
R = _rb0 + s * (
|
|
169
|
+
_rb1 + s * (_rb2 + s * (_rb3 + s * (_rb4 + s * (_rb5 + s * _rb6))))
|
|
170
|
+
)
|
|
171
|
+
S = 1.0 + s * (
|
|
172
|
+
_sb1
|
|
173
|
+
+ s * (_sb2 + s * (_sb3 + s * (_sb4 + s * (_sb5 + s * (_sb6 + s * _sb7)))))
|
|
174
|
+
)
|
|
175
|
+
erfc_val = np.exp(-axm * axm - 0.5625 + R / S) / axm
|
|
176
|
+
out[m3b] = sign[m3b] * (1.0 - erfc_val)
|
|
177
|
+
|
|
178
|
+
# --- Region 4: |x| >= 6 ---
|
|
179
|
+
m4 = ax >= 6.0
|
|
180
|
+
if np.any(m4):
|
|
181
|
+
out[m4] = sign[m4] * 1.0
|
|
182
|
+
|
|
183
|
+
if scalar:
|
|
184
|
+
return float(out[0])
|
|
185
|
+
return out
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _erfc(x):
|
|
189
|
+
"""Vectorized complementary error function: erfc(x) = 1 - erf(x)."""
|
|
190
|
+
return 1.0 - _erf(x)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""Exponential distribution for :mod:`flopscope.stats`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as _np
|
|
6
|
+
|
|
7
|
+
from flopscope.stats._base import ContinuousDistribution
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ExponDistribution(ContinuousDistribution):
|
|
11
|
+
"""Exponential continuous random variable.
|
|
12
|
+
|
|
13
|
+
This object mirrors ``scipy.stats.expon``.
|
|
14
|
+
|
|
15
|
+
Methods
|
|
16
|
+
-------
|
|
17
|
+
pdf(x, loc=0, scale=1)
|
|
18
|
+
Evaluate the probability density function.
|
|
19
|
+
cdf(x, loc=0, scale=1)
|
|
20
|
+
Evaluate the cumulative distribution function.
|
|
21
|
+
ppf(q, loc=0, scale=1)
|
|
22
|
+
Evaluate the percent-point function.
|
|
23
|
+
|
|
24
|
+
Notes
|
|
25
|
+
-----
|
|
26
|
+
``loc`` shifts the origin and ``scale`` is the reciprocal of the rate.
|
|
27
|
+
Each public method deducts ``1 * numel(input)`` FLOPs from the active
|
|
28
|
+
budget.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
super().__init__("expon")
|
|
33
|
+
|
|
34
|
+
def pdf(self, x, loc=0, scale=1):
|
|
35
|
+
"""Evaluate the probability density function.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
x : array_like
|
|
40
|
+
Points at which to evaluate the density.
|
|
41
|
+
loc : float, optional
|
|
42
|
+
Location parameter that shifts the support. Defaults to ``0``.
|
|
43
|
+
scale : float, optional
|
|
44
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
FlopscopeArray
|
|
49
|
+
Probability density evaluated elementwise at ``x``.
|
|
50
|
+
|
|
51
|
+
Notes
|
|
52
|
+
-----
|
|
53
|
+
Equivalent to ``scipy.stats.expon.pdf(x, loc, scale)``.
|
|
54
|
+
FLOP cost: ``1 * numel(x)``.
|
|
55
|
+
|
|
56
|
+
Examples
|
|
57
|
+
--------
|
|
58
|
+
>>> import numpy as np
|
|
59
|
+
>>> import flopscope as flops
|
|
60
|
+
>>> x = np.array([0.0, 1.0, 2.0])
|
|
61
|
+
>>> np.round(flops.stats.expon.pdf(x), 3)
|
|
62
|
+
array([1. , 0.368, 0.135])
|
|
63
|
+
"""
|
|
64
|
+
return self._deduct_and_call("pdf", 1, x, loc=loc, scale=scale)
|
|
65
|
+
|
|
66
|
+
def cdf(self, x, loc=0, scale=1):
|
|
67
|
+
"""Evaluate the cumulative distribution function.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
x : array_like
|
|
72
|
+
Points at which to evaluate the cumulative probability.
|
|
73
|
+
loc : float, optional
|
|
74
|
+
Location parameter that shifts the support. Defaults to ``0``.
|
|
75
|
+
scale : float, optional
|
|
76
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
FlopscopeArray
|
|
81
|
+
Cumulative probability evaluated elementwise at ``x``.
|
|
82
|
+
|
|
83
|
+
Notes
|
|
84
|
+
-----
|
|
85
|
+
Equivalent to ``scipy.stats.expon.cdf(x, loc, scale)``.
|
|
86
|
+
FLOP cost: ``1 * numel(x)``.
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
>>> import numpy as np
|
|
91
|
+
>>> import flopscope as flops
|
|
92
|
+
>>> x = np.array([0.0, 1.0, 2.0])
|
|
93
|
+
>>> np.round(flops.stats.expon.cdf(x), 3)
|
|
94
|
+
array([0. , 0.632, 0.865])
|
|
95
|
+
"""
|
|
96
|
+
return self._deduct_and_call("cdf", 1, x, loc=loc, scale=scale)
|
|
97
|
+
|
|
98
|
+
def ppf(self, q, loc=0, scale=1):
|
|
99
|
+
"""Evaluate the percent-point function.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
q : array_like
|
|
104
|
+
Probabilities in ``[0, 1]``.
|
|
105
|
+
loc : float, optional
|
|
106
|
+
Location parameter that shifts the support. Defaults to ``0``.
|
|
107
|
+
scale : float, optional
|
|
108
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
FlopscopeArray
|
|
113
|
+
Quantiles corresponding to ``q``.
|
|
114
|
+
|
|
115
|
+
Notes
|
|
116
|
+
-----
|
|
117
|
+
Equivalent to ``scipy.stats.expon.ppf(q, loc, scale)``.
|
|
118
|
+
FLOP cost: ``1 * numel(q)``.
|
|
119
|
+
|
|
120
|
+
Examples
|
|
121
|
+
--------
|
|
122
|
+
>>> import numpy as np
|
|
123
|
+
>>> import flopscope as flops
|
|
124
|
+
>>> q = np.array([0.25, 0.5, 0.75])
|
|
125
|
+
>>> np.round(flops.stats.expon.ppf(q), 3)
|
|
126
|
+
array([0.288, 0.693, 1.386])
|
|
127
|
+
"""
|
|
128
|
+
return self._deduct_and_call("ppf", 1, q, loc=loc, scale=scale)
|
|
129
|
+
|
|
130
|
+
def _compute_pdf(self, x, loc=0, scale=1):
|
|
131
|
+
z = (x - loc) / scale
|
|
132
|
+
return _np.where(x >= loc, _np.exp(-z) / scale, 0.0)
|
|
133
|
+
|
|
134
|
+
def _compute_cdf(self, x, loc=0, scale=1):
|
|
135
|
+
z = (x - loc) / scale
|
|
136
|
+
return _np.where(x >= loc, 1.0 - _np.exp(-z), 0.0)
|
|
137
|
+
|
|
138
|
+
def _compute_ppf(self, q, loc=0, scale=1):
|
|
139
|
+
result = loc - scale * _np.log1p(-q)
|
|
140
|
+
result = _np.where((q >= 0) & (q <= 1), result, _np.nan)
|
|
141
|
+
result = _np.where(q == 0, loc, result)
|
|
142
|
+
result = _np.where(q == 1, _np.inf, result)
|
|
143
|
+
return result
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
expon = ExponDistribution()
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""Laplace distribution for :mod:`flopscope.stats`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as _np
|
|
6
|
+
|
|
7
|
+
from flopscope.stats._base import ContinuousDistribution
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class LaplaceDistribution(ContinuousDistribution):
|
|
11
|
+
"""Laplace (double-exponential) continuous random variable.
|
|
12
|
+
|
|
13
|
+
This object mirrors ``scipy.stats.laplace``.
|
|
14
|
+
|
|
15
|
+
Methods
|
|
16
|
+
-------
|
|
17
|
+
pdf(x, loc=0, scale=1)
|
|
18
|
+
Evaluate the probability density function.
|
|
19
|
+
cdf(x, loc=0, scale=1)
|
|
20
|
+
Evaluate the cumulative distribution function.
|
|
21
|
+
ppf(q, loc=0, scale=1)
|
|
22
|
+
Evaluate the percent-point function.
|
|
23
|
+
|
|
24
|
+
Notes
|
|
25
|
+
-----
|
|
26
|
+
``loc`` is the center and ``scale`` controls the exponential decay away
|
|
27
|
+
from that center. Each public method deducts ``1 * numel(input)`` FLOPs
|
|
28
|
+
from the active budget.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
super().__init__("laplace")
|
|
33
|
+
|
|
34
|
+
def pdf(self, x, loc=0, scale=1):
|
|
35
|
+
"""Evaluate the probability density function.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
x : array_like
|
|
40
|
+
Points at which to evaluate the density.
|
|
41
|
+
loc : float, optional
|
|
42
|
+
Location parameter of the distribution. Defaults to ``0``.
|
|
43
|
+
scale : float, optional
|
|
44
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
FlopscopeArray
|
|
49
|
+
Probability density evaluated elementwise at ``x``.
|
|
50
|
+
|
|
51
|
+
Notes
|
|
52
|
+
-----
|
|
53
|
+
Equivalent to ``scipy.stats.laplace.pdf(x, loc, scale)``.
|
|
54
|
+
FLOP cost: ``1 * numel(x)``.
|
|
55
|
+
|
|
56
|
+
Examples
|
|
57
|
+
--------
|
|
58
|
+
>>> import numpy as np
|
|
59
|
+
>>> import flopscope as flops
|
|
60
|
+
>>> x = np.array([-1.0, 0.0, 1.0])
|
|
61
|
+
>>> np.round(flops.stats.laplace.pdf(x), 3)
|
|
62
|
+
array([0.184, 0.5 , 0.184])
|
|
63
|
+
"""
|
|
64
|
+
return self._deduct_and_call("pdf", 1, x, loc=loc, scale=scale)
|
|
65
|
+
|
|
66
|
+
def cdf(self, x, loc=0, scale=1):
|
|
67
|
+
"""Evaluate the cumulative distribution function.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
x : array_like
|
|
72
|
+
Points at which to evaluate the cumulative probability.
|
|
73
|
+
loc : float, optional
|
|
74
|
+
Location parameter of the distribution. Defaults to ``0``.
|
|
75
|
+
scale : float, optional
|
|
76
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
FlopscopeArray
|
|
81
|
+
Cumulative probability evaluated elementwise at ``x``.
|
|
82
|
+
|
|
83
|
+
Notes
|
|
84
|
+
-----
|
|
85
|
+
Equivalent to ``scipy.stats.laplace.cdf(x, loc, scale)``.
|
|
86
|
+
FLOP cost: ``1 * numel(x)``.
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
>>> import numpy as np
|
|
91
|
+
>>> import flopscope as flops
|
|
92
|
+
>>> x = np.array([-1.0, 0.0, 1.0])
|
|
93
|
+
>>> np.round(flops.stats.laplace.cdf(x), 3)
|
|
94
|
+
array([0.184, 0.5 , 0.816])
|
|
95
|
+
"""
|
|
96
|
+
return self._deduct_and_call("cdf", 1, x, loc=loc, scale=scale)
|
|
97
|
+
|
|
98
|
+
def ppf(self, q, loc=0, scale=1):
|
|
99
|
+
"""Evaluate the percent-point function.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
q : array_like
|
|
104
|
+
Probabilities in ``[0, 1]``.
|
|
105
|
+
loc : float, optional
|
|
106
|
+
Location parameter of the distribution. Defaults to ``0``.
|
|
107
|
+
scale : float, optional
|
|
108
|
+
Scale parameter of the distribution. Defaults to ``1``.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
FlopscopeArray
|
|
113
|
+
Quantiles corresponding to ``q``.
|
|
114
|
+
|
|
115
|
+
Notes
|
|
116
|
+
-----
|
|
117
|
+
Equivalent to ``scipy.stats.laplace.ppf(q, loc, scale)``.
|
|
118
|
+
FLOP cost: ``1 * numel(q)``.
|
|
119
|
+
|
|
120
|
+
Examples
|
|
121
|
+
--------
|
|
122
|
+
>>> import numpy as np
|
|
123
|
+
>>> import flopscope as flops
|
|
124
|
+
>>> q = np.array([0.25, 0.5, 0.75])
|
|
125
|
+
>>> np.round(flops.stats.laplace.ppf(q), 3)
|
|
126
|
+
array([-0.693, 0. , 0.693])
|
|
127
|
+
"""
|
|
128
|
+
return self._deduct_and_call("ppf", 1, q, loc=loc, scale=scale)
|
|
129
|
+
|
|
130
|
+
def _compute_pdf(self, x, loc=0, scale=1):
|
|
131
|
+
z = _np.abs(x - loc) / scale
|
|
132
|
+
return _np.exp(-z) / (2.0 * scale)
|
|
133
|
+
|
|
134
|
+
def _compute_cdf(self, x, loc=0, scale=1):
|
|
135
|
+
z = (x - loc) / scale
|
|
136
|
+
return _np.where(z <= 0, 0.5 * _np.exp(z), 1.0 - 0.5 * _np.exp(-z))
|
|
137
|
+
|
|
138
|
+
def _compute_ppf(self, q, loc=0, scale=1):
|
|
139
|
+
result = _np.where(
|
|
140
|
+
q <= 0.5,
|
|
141
|
+
loc + scale * _np.log(2.0 * _np.maximum(q, 1e-300)),
|
|
142
|
+
loc - scale * _np.log(2.0 * _np.maximum(1.0 - q, 1e-300)),
|
|
143
|
+
)
|
|
144
|
+
result = _np.where((q >= 0) & (q <= 1), result, _np.nan)
|
|
145
|
+
result = _np.where(q == 0, -_np.inf, result)
|
|
146
|
+
result = _np.where(q == 1, _np.inf, result)
|
|
147
|
+
return result
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
laplace = LaplaceDistribution()
|