Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions dpnp/backend/include/dpnp_iface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,22 @@ INP_DLLEXPORT void dpnp_rng_gumbel_c(void* result, double loc, double scale, siz
template <typename _DataType>
INP_DLLEXPORT void dpnp_rng_laplace_c(void* result, double loc, double scale, size_t size);

/**
* @ingroup BACKEND_API
* @brief math library implementation of random number generator (logistic distribution)
*
* @param [in] size Number of elements in `result` arrays.
*
* @param [in] loc The position of the distribution peak.
*
* @param [in] scale The exponential decay.
*
* @param [out] result Output array.
*
*/
template <typename _DataType>
INP_DLLEXPORT void dpnp_rng_logistic_c(void* result, double loc, double scale, size_t size);

/**
* @ingroup BACKEND_API
* @brief math library implementation of random number generator (lognormal distribution)
Expand Down
1 change: 1 addition & 0 deletions dpnp/backend/include/dpnp_iface_fptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ enum class DPNPFuncName : size_t
DPNP_FN_RNG_GUMBEL, /**< Used in numpy.random.gumbel() implementation */
DPNP_FN_RNG_HYPERGEOMETRIC, /**< Used in numpy.random.hypergeometric() implementation */
DPNP_FN_RNG_LAPLACE, /**< Used in numpy.random.laplace() implementation */
DPNP_FN_RNG_LOGISTIC, /**< Used in numpy.random.logistic() implementation */
DPNP_FN_RNG_LOGNORMAL, /**< Used in numpy.random.lognormal() implementation */
DPNP_FN_RNG_MULTINOMIAL, /**< Used in numpy.random.multinomial() implementation */
DPNP_FN_RNG_MULTIVARIATE_NORMAL, /**< Used in numpy.random.multivariate_normal() implementation */
Expand Down
26 changes: 26 additions & 0 deletions dpnp/backend/kernels/dpnp_krnl_random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,30 @@ void dpnp_rng_laplace_c(void* result, double loc, double scale, size_t size)
event_out.wait();
}

/* Logistic(loc, scale) ~ loc + scale * log(u/(1.0 - u)) */
template <typename _DataType>
void dpnp_rng_logistic_c(void* result, double loc, double scale, size_t size)
{
if (!size)
{
return;
}
cl::sycl::vector_class<cl::sycl::event> no_deps;

const _DataType d_zero = _DataType(0.0);
const _DataType d_one = _DataType(1.0);

_DataType* result1 = reinterpret_cast<_DataType*>(result);

mkl_rng::uniform<_DataType> distribution(d_zero, d_one);
auto event_out = mkl_rng::generate(distribution, DPNP_RNG_ENGINE, size, result1);
event_out.wait();

for(size_t i = 0; i < size; i++) result1[i] = log(result1[i]/(1.0 - result1[i]));

for(size_t i = 0; i < size; i++) result1[i] = loc + scale * result1[i];
}

template <typename _DataType>
void dpnp_rng_lognormal_c(void* result, _DataType mean, _DataType stddev, size_t size)
{
Expand Down Expand Up @@ -606,6 +630,8 @@ void func_map_init_random(func_map_t& fmap)

fmap[DPNPFuncName::DPNP_FN_RNG_LAPLACE][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_rng_laplace_c<double>};

fmap[DPNPFuncName::DPNP_FN_RNG_LOGISTIC][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_rng_logistic_c<double>};

fmap[DPNPFuncName::DPNP_FN_RNG_LOGNORMAL][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_rng_lognormal_c<double>};

fmap[DPNPFuncName::DPNP_FN_RNG_MULTINOMIAL][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_rng_multinomial_c<int>};
Expand Down
1 change: 1 addition & 0 deletions dpnp/dpnp_algo/dpnp_algo.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
DPNP_FN_RNG_GUMBEL
DPNP_FN_RNG_HYPERGEOMETRIC
DPNP_FN_RNG_LAPLACE
DPNP_FN_RNG_LOGISTIC
DPNP_FN_RNG_LOGNORMAL
DPNP_FN_RNG_MULTINOMIAL
DPNP_FN_RNG_MULTIVARIATE_NORMAL
Expand Down
28 changes: 28 additions & 0 deletions dpnp/random/dpnp_algo_random.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ __all__ = [
"dpnp_hypergeometric",
"dpnp_laplace",
"dpnp_lognormal",
"dpnp_rng_logistic",
"dpnp_multinomial",
"dpnp_multivariate_normal",
"dpnp_negative_binomial",
Expand Down Expand Up @@ -81,6 +82,7 @@ ctypedef void(*fptr_dpnp_rng_gaussian_c_1out_t)(void *, double, double, size_t)
ctypedef void(*fptr_dpnp_rng_gumbel_c_1out_t)(void *, double, double, size_t) except +
ctypedef void(*fptr_dpnp_rng_hypergeometric_c_1out_t)(void *, int, int, int, size_t) except +
ctypedef void(*fptr_dpnp_rng_laplace_c_1out_t)(void *, double, double, size_t) except +
ctypedef void(*fptr_dpnp_rng_logistic_c_1out_t)(void *, double, double, size_t) except +
ctypedef void(*fptr_dpnp_rng_lognormal_c_1out_t)(void *, double, double, size_t) except +
ctypedef void(*fptr_dpnp_rng_multinomial_c_1out_t)(void * result, int, const double *, const size_t, size_t) except +
ctypedef void(*fptr_dpnp_rng_multivariate_normal_c_1out_t)(void *,
Expand Down Expand Up @@ -396,6 +398,32 @@ cpdef dparray dpnp_laplace(double loc, double scale, size):
return result


cpdef dparray dpnp_rng_logistic(double loc, double scale, size):
"""
Returns an array populated with samples from logistic distribution.
`dpnp_rng_logistic` generates a matrix filled with random floats sampled from a
univariate logistic distribution.

"""

# convert string type names (dparray.dtype) to C enum DPNPFuncType
cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(numpy.float64)

# get the FPTR data structure
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_RNG_LOGISTIC, param1_type, param1_type)

result_type = dpnp_DPNPFuncType_to_dtype( < size_t > kernel_data.return_type)
# ceate result array with type given by FPTR data
cdef dparray result = dparray(size, dtype=result_type)

cdef fptr_dpnp_rng_logistic_c_1out_t func = < fptr_dpnp_rng_logistic_c_1out_t > kernel_data.ptr
# call FPTR function
func(result.get_data(), loc, scale, result.size)

return result



cpdef dparray dpnp_lognormal(double mean, double stddev, size):
"""
Returns an array populated with samples from lognormal distribution.
Expand Down
29 changes: 25 additions & 4 deletions dpnp/random/dpnp_iface_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,13 +527,34 @@ def logistic(loc=0.0, scale=1.0, size=None):

For full documentation refer to :obj:`numpy.random.logistic`.

Notes
-----
The function uses `numpy.random.logistic` on the backend and will be
executed on fallback backend.
Limitations
-----------
Parameters ``loc`` and ``scale`` are supported as scalar.
Otherwise, :obj:`numpy.random.logistic(loc, scale, size)` samples are drawn.
Output array data type is :obj:`dpnp.float64`.

Examples
--------
>>> loc, scale = 0., 1.
>>> s = dpnp.random.logistic(loc, scale, 1000)

"""

if not use_origin_backend(loc):
# TODO:
# array_like of floats for `loc` and `scale`
if not dpnp.isscalar(loc):
pass
elif not dpnp.isscalar(scale):
pass
elif scale < 0:
pass
else:
if size == None or size == 1:
return dpnp_rng_logistic(loc, scale, size)[0]
else:
return dpnp_rng_logistic(loc, scale, size)

return call_origin(numpy.random.logistic, loc, scale, size)


Expand Down
22 changes: 22 additions & 0 deletions tests/test_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,28 @@ def test_seed(self):
self.check_seed('laplace', {'loc': loc, 'scale': scale})


class TestDistributionsLogistic(TestDistribution):

def test_moments(self):
loc = 2.56
scale = 0.8
expected_mean = loc
expected_var = (scale ** 2) * (numpy.pi ** 2) / 3
self.check_moments('logistic', expected_mean,
expected_var, {'loc': loc, 'scale': scale})

def test_invalid_args(self):
loc = 3.0 # OK
scale = -1.0 # non-negative `scale` is expected
self.check_invalid_args('logistic',
{'loc': loc, 'scale': scale})

def test_seed(self):
loc = 2.56
scale = 0.8
self.check_seed('logistic', {'loc': loc, 'scale': scale})


class TestDistributionsLognormal(TestDistribution):

def test_extreme_value(self):
Expand Down
2 changes: 2 additions & 0 deletions tests_external/skipped_tests_numpy.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,7 @@ tests/test_random.py::TestRandomDist::test_gumbel_0
tests/test_random.py::TestRandomDist::test_hypergeometric
tests/test_random.py::TestRandomDist::test_laplace
tests/test_random.py::TestRandomDist::test_laplace_0
tests/test_random.py::TestRandomDist::test_logistic
tests/test_random.py::TestRandomDist::test_lognormal
tests/test_random.py::TestRandomDist::test_lognormal_0
tests/test_random.py::TestRandomDist::test_multinomial
Expand Down Expand Up @@ -1565,6 +1566,7 @@ tests/test_randomstate.py::TestRandomDist::test_gumbel_0
tests/test_randomstate.py::TestRandomDist::test_hypergeometric
tests/test_randomstate.py::TestRandomDist::test_laplace
tests/test_randomstate.py::TestRandomDist::test_laplace_0
tests/test_randomstate.py::TestRandomDist::test_logistic
tests/test_randomstate.py::TestRandomDist::test_lognormal
tests/test_randomstate.py::TestRandomDist::test_lognormal_0
tests/test_randomstate.py::TestRandomDist::test_multinomial
Expand Down