Spaces:
Running
Running
File size: 6,329 Bytes
6a86ad5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
from functools import singledispatch
from sympy.core.symbol import Dummy
from sympy.functions.elementary.exponential import exp
from sympy.utilities.lambdify import lambdify
from sympy.external import import_module
from sympy.stats import DiscreteDistributionHandmade
from sympy.stats.crv import SingleContinuousDistribution
from sympy.stats.crv_types import ChiSquaredDistribution, ExponentialDistribution, GammaDistribution, \
LogNormalDistribution, NormalDistribution, ParetoDistribution, UniformDistribution, BetaDistribution, \
StudentTDistribution, CauchyDistribution
from sympy.stats.drv_types import GeometricDistribution, LogarithmicDistribution, NegativeBinomialDistribution, \
PoissonDistribution, SkellamDistribution, YuleSimonDistribution, ZetaDistribution
from sympy.stats.frv import SingleFiniteDistribution
scipy = import_module("scipy", import_kwargs={'fromlist':['stats']})
@singledispatch
def do_sample_scipy(dist, size, seed):
return None
# CRV
@do_sample_scipy.register(SingleContinuousDistribution)
def _(dist: SingleContinuousDistribution, size, seed):
# if we don't need to make a handmade pdf, we won't
import scipy.stats
z = Dummy('z')
handmade_pdf = lambdify(z, dist.pdf(z), ['numpy', 'scipy'])
class scipy_pdf(scipy.stats.rv_continuous):
def _pdf(dist, x):
return handmade_pdf(x)
scipy_rv = scipy_pdf(a=float(dist.set._inf),
b=float(dist.set._sup), name='scipy_pdf')
return scipy_rv.rvs(size=size, random_state=seed)
@do_sample_scipy.register(ChiSquaredDistribution)
def _(dist: ChiSquaredDistribution, size, seed):
# same parametrisation
return scipy.stats.chi2.rvs(df=float(dist.k), size=size, random_state=seed)
@do_sample_scipy.register(ExponentialDistribution)
def _(dist: ExponentialDistribution, size, seed):
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.expon.html#scipy.stats.expon
return scipy.stats.expon.rvs(scale=1 / float(dist.rate), size=size, random_state=seed)
@do_sample_scipy.register(GammaDistribution)
def _(dist: GammaDistribution, size, seed):
# https://stackoverflow.com/questions/42150965/how-to-plot-gamma-distribution-with-alpha-and-beta-parameters-in-python
return scipy.stats.gamma.rvs(a=float(dist.k), scale=float(dist.theta), size=size, random_state=seed)
@do_sample_scipy.register(LogNormalDistribution)
def _(dist: LogNormalDistribution, size, seed):
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.lognorm.html
return scipy.stats.lognorm.rvs(scale=float(exp(dist.mean)), s=float(dist.std), size=size, random_state=seed)
@do_sample_scipy.register(NormalDistribution)
def _(dist: NormalDistribution, size, seed):
return scipy.stats.norm.rvs(loc=float(dist.mean), scale=float(dist.std), size=size, random_state=seed)
@do_sample_scipy.register(ParetoDistribution)
def _(dist: ParetoDistribution, size, seed):
# https://stackoverflow.com/questions/42260519/defining-pareto-distribution-in-python-scipy
return scipy.stats.pareto.rvs(b=float(dist.alpha), scale=float(dist.xm), size=size, random_state=seed)
@do_sample_scipy.register(StudentTDistribution)
def _(dist: StudentTDistribution, size, seed):
return scipy.stats.t.rvs(df=float(dist.nu), size=size, random_state=seed)
@do_sample_scipy.register(UniformDistribution)
def _(dist: UniformDistribution, size, seed):
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.uniform.html
return scipy.stats.uniform.rvs(loc=float(dist.left), scale=float(dist.right - dist.left), size=size, random_state=seed)
@do_sample_scipy.register(BetaDistribution)
def _(dist: BetaDistribution, size, seed):
# same parametrisation
return scipy.stats.beta.rvs(a=float(dist.alpha), b=float(dist.beta), size=size, random_state=seed)
@do_sample_scipy.register(CauchyDistribution)
def _(dist: CauchyDistribution, size, seed):
return scipy.stats.cauchy.rvs(loc=float(dist.x0), scale=float(dist.gamma), size=size, random_state=seed)
# DRV:
@do_sample_scipy.register(DiscreteDistributionHandmade)
def _(dist: DiscreteDistributionHandmade, size, seed):
from scipy.stats import rv_discrete
z = Dummy('z')
handmade_pmf = lambdify(z, dist.pdf(z), ['numpy', 'scipy'])
class scipy_pmf(rv_discrete):
def _pmf(dist, x):
return handmade_pmf(x)
scipy_rv = scipy_pmf(a=float(dist.set._inf), b=float(dist.set._sup),
name='scipy_pmf')
return scipy_rv.rvs(size=size, random_state=seed)
@do_sample_scipy.register(GeometricDistribution)
def _(dist: GeometricDistribution, size, seed):
return scipy.stats.geom.rvs(p=float(dist.p), size=size, random_state=seed)
@do_sample_scipy.register(LogarithmicDistribution)
def _(dist: LogarithmicDistribution, size, seed):
return scipy.stats.logser.rvs(p=float(dist.p), size=size, random_state=seed)
@do_sample_scipy.register(NegativeBinomialDistribution)
def _(dist: NegativeBinomialDistribution, size, seed):
return scipy.stats.nbinom.rvs(n=float(dist.r), p=float(dist.p), size=size, random_state=seed)
@do_sample_scipy.register(PoissonDistribution)
def _(dist: PoissonDistribution, size, seed):
return scipy.stats.poisson.rvs(mu=float(dist.lamda), size=size, random_state=seed)
@do_sample_scipy.register(SkellamDistribution)
def _(dist: SkellamDistribution, size, seed):
return scipy.stats.skellam.rvs(mu1=float(dist.mu1), mu2=float(dist.mu2), size=size, random_state=seed)
@do_sample_scipy.register(YuleSimonDistribution)
def _(dist: YuleSimonDistribution, size, seed):
return scipy.stats.yulesimon.rvs(alpha=float(dist.rho), size=size, random_state=seed)
@do_sample_scipy.register(ZetaDistribution)
def _(dist: ZetaDistribution, size, seed):
return scipy.stats.zipf.rvs(a=float(dist.s), size=size, random_state=seed)
# FRV:
@do_sample_scipy.register(SingleFiniteDistribution)
def _(dist: SingleFiniteDistribution, size, seed):
# scipy can handle with custom distributions
from scipy.stats import rv_discrete
density_ = dist.dict
x, y = [], []
for k, v in density_.items():
x.append(int(k))
y.append(float(v))
scipy_rv = rv_discrete(name='scipy_rv', values=(x, y))
return scipy_rv.rvs(size=size, random_state=seed)
|