2023-02-22 16:07:15 +08:00

398 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# coding=utf-8
# -----------------------------------------------------
# Author: Yaqiang Wang
# Date: 2016-7-10
# Purpose: MeteoInfoLab random module
# Note: Jython
# -----------------------------------------------------
from org.meteoinfo.math.random import RandomUtil
from org.meteoinfo.math.distribution import DistributionUtil
from org.apache.commons.statistics.distribution import NormalDistribution, BetaDistribution, \
BinomialDistribution, ChiSquaredDistribution, ExponentialDistribution, FDistribution, \
GammaDistribution, GumbelDistribution, LaplaceDistribution, LogisticDistribution, \
LogNormalDistribution, ParetoDistribution, TDistribution, TriangularDistribution, \
UniformContinuousDistribution, WeibullDistribution
from .. import core as np
__all__ = [
'chisquare', 'exponential', 'f', 'gamma', 'gumbel', 'laplace', 'logistic',
'lognormal', 'multivariate_normal', 'normal', 'rand', 'randn', 'randint', 'random', 'pareto',
'poisson', 'seed', 'standard_t', 'triangular', 'uniform', 'weibull'
]
def seed(seed=None):
"""
Seed the generator.
:param seed: (*int*) Seed for random data generator.
"""
if seed is None:
RandomUtil.useSeed = False
else:
RandomUtil.useSeed = True
RandomUtil.seed = seed
def random(size=None):
"""
Random values in a given shape.
Create an array of the given shape and propagate it with random samples from a uniform
distribution over [0, 1).
:param size: (*int or tuple*) Output shape. If the given shape is, e.g., (m, n, k), then m * n * k samples
are drawn. Default is None, in which case a single value is returned.
:returns: Random values array.
"""
if size is None:
return RandomUtil.rand()
else:
return np.NDArray(RandomUtil.rand(size))
def rand(*args):
"""
Random values in a given shape.
Create an array of the given shape and propagate it with random samples from a uniform
distribution over [0, 1).
:param d0, d1, ..., dn: (*int*) optional. The dimensions of the returned array, should all
be positive. If no argument is given a single Python float is returned.
:returns: Random values array.
"""
if len(args) == 0:
return RandomUtil.rand()
elif len(args) == 1:
return np.NDArray(RandomUtil.rand(args[0]))
else:
return np.NDArray(RandomUtil.rand(args))
def randn(*args):
"""
Return a sample (or samples) from the “standard normal” distribution.
Create an array of the given shape and propagate it with random samples from a "normal"
(Gaussian) distribution of mean 0 and variance 1.
:param d0, d1, ..., dn: (*int*) optional. The dimensions of the returned array, should all
be positive. If no argument is given a single Python float is returned.
:returns: Random values array.
"""
if len(args) == 0:
return RandomUtil.randn()
elif len(args) == 1:
return np.NDArray(RandomUtil.randn(args[0]))
else:
return np.NDArray(RandomUtil.randn(args))
def randint(low, high=None, size=None):
"""
Return random integers from low (inclusive) to high (exclusive).
Return random integers from the “discrete uniform” distribution of the specified dtype in the “half-open”
interval [low, high). If high is None (the default), then results are from [0, low).
:param low: (*int*) Lowest (signed) integer to be drawn from the distribution (unless high=None, in which
case this parameter is one above the highest such integer).
:param high: (*int*) If provided, one above the largest (signed) integer to be drawn from the distribution
(see above for behavior if high=None).
:param size: (*int or tuple*) Output shape. If the given shape is, e.g., (m, n, k), then m * n * k samples
are drawn. Default is None, in which case a single value is returned.
:returns: (*int or array*) Random integer array.
"""
if high is None:
high = low
low = 0
else:
high = high - low
if size is None:
r = RandomUtil.randint(high)
r += low
else:
r = np.NDArray(RandomUtil.randint(high, size))
if low != 0:
r += low
return r
def poisson(lam=1.0, size=None):
"""
Draw samples from a Poisson distribution.
:param lam: (*float*) Expectation of interval, should be >= 0.
:param size: (*int or tuple*) Output shape. If the given shape is, e.g., (m, n, k), then m * n * k samples
are drawn. Default is None, in which case a single value is returned.
:returns: (*float or array*) Drawn samples from the parameterized Poisson distribution.
"""
if size is None:
r = RandomUtil.poisson(lam)
else:
r = np.NDArray(RandomUtil.poisson(lam, size))
return r
def normal(loc=0.0, scale=1.0, size=None):
"""
Draw random samples from a normal (Gaussian) distribution.
:param loc: (*float*) Mean (“centre”) of the distribution.
:param scale: (*float*) Standard deviation (spread or “width”) of the distribution.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
"""
dist = NormalDistribution.of(loc, scale)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def chisquare(df, size=None):
"""
Draw samples from a chi-square distribution.
:param df: (*float*) Number of degrees of freedom, should be > 0.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized chisquare distribution.
"""
dist = ChiSquaredDistribution.of(df)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def exponential(scale=1.0, size=None):
"""
Draw samples from a exponential distribution.
:param scale: (*float*) The scale parameter.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized exponential distribution.
"""
dist = ExponentialDistribution.of(scale)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def f(dfnum, dfden, size=None):
"""
Draw random samples from a F distribution.
:param dfnum: (*float*) Degrees of freedom in numerator, should be > 0.
:param dfden: (*float*) Degrees of freedom in denominator, should be > 0.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Fisher distribution.
"""
dist = FDistribution.of(dfnum, dfden)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def gamma(shape, scale=1.0, size=None):
"""
Draw random samples from a Gamma distribution.
:param shape: (*float*) The shape of the gamma distribution. Should be greater than zero.
:param scale: (*float*) Standard deviation (spread or “width”) of the distribution.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Gamma distribution.
"""
dist = GammaDistribution.of(shape, scale)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def gumbel(loc=0.0, scale=1.0, size=None):
"""
Draw random samples from a Gumbel distribution.
:param loc: (*float*) Mean (“centre”) of the distribution.
:param scale: (*float*) Standard deviation (spread or “width”) of the distribution.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Gumbel distribution.
"""
dist = GumbelDistribution.of(loc, scale)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def laplace(loc=0.0, scale=1.0, size=None):
"""
Draw samples from the Laplace or double exponential distribution with specified location (or mean) and scale (decay).
:param loc: (*float*) Mean (“centre”) of the distribution.
:param scale: (*float*) Standard deviation (spread or “width”) of the distribution.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Laplace distribution.
"""
dist = LaplaceDistribution.of(loc, scale)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def logistic(loc=0.0, scale=1.0, size=None):
"""
Draw samples from the Logistic distribution.
:param loc: (*float*) Mean (“centre”) of the distribution.
:param scale: (*float*) Standard deviation (spread or “width”) of the distribution.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Logistic distribution.
"""
dist = LogisticDistribution.of(loc, scale)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def lognormal(mean=0.0, sigma=1.0, size=None):
"""
Draw samples from the log-normal distribution.
:param mean: (*float*) Mean value of the underlying normal distribution. Default is 0.
:param sigma: (*float*) Standard deviation of the underlying normal distribution. Should be greater than zero. Default is 1.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized log-normal distribution.
"""
dist = LogNormalDistribution.of(loc, scale)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def pareto(a, size=None):
"""
Draw samples from a Pareto II or Lomax distribution with specified shape.
:param a: (*float*) Shape of the distribution. Should be greater than zero.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Pareto distribution.
"""
dist = ParetoDistribution.of(1, a)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def standard_t(df, size=None):
"""
Draw samples from a standard Students t distribution with df degrees of freedom.
:param df: (*float*) Degrees of freedom, should be > 0.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Students t distribution.
"""
dist = TDistribution.of(df)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def triangular(left, mode, right, size=None):
"""
Draw samples from the triangular distribution over the interval [left, right].
:param left: (*float*) Lower limit.
:param mode: (*float*) The value where the peak of the distribution occurs. The value
should fulfill the condition left <= mode <= right.
:param right: (*float*) Upper limit, should be larger than left.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized triangular distribution.
"""
dist = TriangularDistribution.of(left, mode, right)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def uniform(low=0.0, high=1.0, size=None):
"""
Draw samples from the uniform distribution.
:param low: (*float*) Lower boundary of the output interval. All values generated will
be greater than or equal to low. The default value is 0.
:param high: (*float*) Upper boundary of the output interval. All values generated will
be less than high. The default value is 1.0.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized uniform distribution.
"""
dist = UniformContinuousDistribution.of(low, high)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def weibull(a, size=None):
"""
Draw samples from a Weibull distribution.
:param a: (*float*) Shape parameter of the distribution. Must be nonnegative.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:returns: (*ndarray or scalar*) Drawn samples from the parameterized Weibull distribution.
"""
dist = WeibullDistribution.of(a, 1)
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)
def multivariate_normal(mean, cov, size=None):
"""
Draw samples from a multiple variate normal distribution.
:param mean: (*array*) Mean values.
:param cov: (*array*) Covariant matrix.
:param size: (*int*) Output shape. If size is None (default), a single value is returned.
:return: (*ndarray or scalar*) Drawn samples from the multiple variate normal distribution.
"""
mean = np.asarray(mean)
cov = np.asarray(cov)
dist = DistributionUtil.mvNormDist(mean.asarray(), cov.asarray())
if size is None:
size = 1
r = DistributionUtil.rvs(dist, size)
return np.NDArray(r)