Skip to content

Commit 8c20103

Browse files
ENH: impl random.pareto (#518)
1 parent 897cef6 commit 8c20103

File tree

7 files changed

+109
-4
lines changed

7 files changed

+109
-4
lines changed

dpnp/backend/include/dpnp_iface.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,20 @@ INP_DLLEXPORT void dpnp_rng_negative_binomial_c(void* result, double a, double p
855855
template <typename _DataType>
856856
INP_DLLEXPORT void dpnp_rng_normal_c(void* result, _DataType mean, _DataType stddev, size_t size);
857857

858+
/**
859+
* @ingroup BACKEND_API
860+
* @brief math library implementation of random number generator (Pareto distribution)
861+
*
862+
* @param [in] size Number of elements in `result` arrays.
863+
*
864+
* @param [in] alpha Shape of the distribution, alpha.
865+
*
866+
* @param [out] result Output array.
867+
*
868+
*/
869+
template <typename _DataType>
870+
INP_DLLEXPORT void dpnp_rng_pareto_c(void* result, double alpha, size_t size);
871+
858872
/**
859873
* @ingroup BACKEND_API
860874
* @brief math library implementation of random number generator (poisson distribution)

dpnp/backend/include/dpnp_iface_fptr.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ enum class DPNPFuncName : size_t
137137
DPNP_FN_RNG_MULTIVARIATE_NORMAL, /**< Used in numpy.random.multivariate_normal() implementation */
138138
DPNP_FN_RNG_NEGATIVE_BINOMIAL, /**< Used in numpy.random.negative_binomial() implementation */
139139
DPNP_FN_RNG_NORMAL, /**< Used in numpy.random.normal() implementation */
140+
DPNP_FN_RNG_PARETO, /**< Used in numpy.random.pareto() implementation */
140141
DPNP_FN_RNG_POISSON, /**< Used in numpy.random.poisson() implementation */
141142
DPNP_FN_RNG_RAYLEIGH, /**< Used in numpy.random.rayleigh() implementation */
142143
DPNP_FN_RNG_STANDARD_CAUCHY, /**< Used in numpy.random.standard_cauchy() implementation */

dpnp/backend/kernels/dpnp_krnl_random.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,29 @@ void dpnp_rng_normal_c(void* result, _DataType mean, _DataType stddev, size_t si
439439
event_out.wait();
440440
}
441441

442+
template <typename _DataType>
443+
void dpnp_rng_pareto_c(void* result, double alpha, size_t size)
444+
{
445+
if (!size)
446+
{
447+
return;
448+
}
449+
cl::sycl::vector_class<cl::sycl::event> no_deps;
450+
451+
const _DataType d_zero = _DataType(0.0);
452+
const _DataType d_one = _DataType(1.0);
453+
_DataType neg_rec_alp = -1.0/alpha;
454+
455+
_DataType* result1 = reinterpret_cast<_DataType*>(result);
456+
457+
mkl_rng::uniform<_DataType> distribution(d_zero, d_one);
458+
auto event_out = mkl_rng::generate(distribution, DPNP_RNG_ENGINE, size, result1);
459+
event_out.wait();
460+
461+
event_out = mkl_vm::powx(DPNP_QUEUE, size, result1, neg_rec_alp, result1, no_deps, mkl_vm::mode::ha);
462+
event_out.wait();
463+
}
464+
442465
template <typename _DataType>
443466
void dpnp_rng_poisson_c(void* result, double lambda, size_t size)
444467
{
@@ -618,6 +641,8 @@ void func_map_init_random(func_map_t& fmap)
618641

619642
fmap[DPNPFuncName::DPNP_FN_RNG_NORMAL][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_rng_normal_c<double>};
620643

644+
fmap[DPNPFuncName::DPNP_FN_RNG_PARETO][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_rng_pareto_c<double>};
645+
621646
fmap[DPNPFuncName::DPNP_FN_RNG_POISSON][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_rng_poisson_c<int>};
622647

623648
fmap[DPNPFuncName::DPNP_FN_RNG_RAYLEIGH][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_rng_rayleigh_c<double>};

dpnp/dpnp_algo/dpnp_algo.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
110110
DPNP_FN_RNG_MULTIVARIATE_NORMAL
111111
DPNP_FN_RNG_NEGATIVE_BINOMIAL
112112
DPNP_FN_RNG_NORMAL
113+
DPNP_FN_RNG_PARETO
113114
DPNP_FN_RNG_POISSON
114115
DPNP_FN_RNG_RAYLEIGH
115116
DPNP_FN_RNG_STANDARD_CAUCHY

dpnp/random/dpnp_algo_random.pyx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ __all__ = [
5757
"dpnp_multivariate_normal",
5858
"dpnp_negative_binomial",
5959
"dpnp_normal",
60+
"dpnp_pareto",
6061
"dpnp_poisson",
6162
"dpnp_randn",
6263
"dpnp_random",
@@ -92,6 +93,7 @@ ctypedef void(*fptr_dpnp_rng_multivariate_normal_c_1out_t)(void *,
9293
size_t) except +
9394
ctypedef void(*fptr_dpnp_rng_negative_binomial_c_1out_t)(void *, double, double, size_t) except +
9495
ctypedef void(*fptr_dpnp_rng_normal_c_1out_t)(void *, double, double, size_t) except +
96+
ctypedef void(*fptr_dpnp_rng_pareto_c_1out_t)(void *, double, size_t) except +
9597
ctypedef void(*fptr_dpnp_rng_poisson_c_1out_t)(void *, double, size_t) except +
9698
ctypedef void(*fptr_dpnp_rng_rayleigh_c_1out_t)(void *, double, size_t) except +
9799
ctypedef void(*fptr_dpnp_rng_standard_cauchy_c_1out_t)(void *, size_t) except +
@@ -595,6 +597,32 @@ cpdef dparray dpnp_normal(double loc, double scale, size):
595597
return result
596598

597599

600+
cpdef dparray dpnp_pareto(double alpha, size):
601+
"""
602+
Returns an array populated with samples from Pareto distribution.
603+
`dpnp_pareto` generates a matrix filled with random floats sampled from a
604+
univariate Pareto distribution of `alpha`.
605+
606+
"""
607+
608+
dtype = numpy.float64
609+
# convert string type names (dparray.dtype) to C enum DPNPFuncType
610+
cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(dtype)
611+
612+
# get the FPTR data structure
613+
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_RNG_PARETO, param1_type, param1_type)
614+
615+
result_type = dpnp_DPNPFuncType_to_dtype( < size_t > kernel_data.return_type)
616+
# ceate result array with type given by FPTR data
617+
cdef dparray result = dparray(size, dtype=dtype)
618+
619+
cdef fptr_dpnp_rng_pareto_c_1out_t func = <fptr_dpnp_rng_pareto_c_1out_t > kernel_data.ptr
620+
# call FPTR function
621+
func(result.get_data(), alpha, result.size)
622+
623+
return result
624+
625+
598626
cpdef dparray dpnp_poisson(double lam, size):
599627
"""
600628
Returns an array populated with samples from Poisson distribution.

dpnp/random/dpnp_iface_random.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -809,13 +809,30 @@ def pareto(a, size=None):
809809
810810
For full documentation refer to :obj:`numpy.random.pareto`.
811811
812-
Notes
813-
-----
814-
The function uses `numpy.random.pareto` on the backend and
815-
will be executed on fallback backend.
812+
Limitations
813+
-----------
814+
Parameter ``a`` is supported as a scalar.
815+
Otherwise, :obj:`numpy.random.pareto(a, size)` samples are drawn.
816+
Output array data type is :obj:`dpnp.float64`.
817+
818+
Examples
819+
--------
820+
Draw samples from the distribution:
821+
>>> a = .5 # alpha
822+
>>> s = dpnp.random.pareto(a, 1000)
816823
817824
"""
818825

826+
if not use_origin_backend(a):
827+
# TODO:
828+
# array_like of floats for `a`
829+
if not dpnp.isscalar(a):
830+
pass
831+
elif a <= 0:
832+
pass
833+
else:
834+
return dpnp_pareto(a, size)
835+
819836
return call_origin(numpy.random.pareto, a, size)
820837

821838

tests/test_random.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,25 @@ def test_seed(self):
557557
self.check_seed('normal', {'loc': loc, 'scale': scale})
558558

559559

560+
class TestDistributionsPareto(TestDistribution):
561+
562+
def test_moments(self):
563+
a = 30.0
564+
expected_mean = a / (a - 1)
565+
expected_var = a / (((a - 1)**2) * (a - 2))
566+
self.check_moments('pareto', expected_mean,
567+
expected_var, {'a': a})
568+
569+
def test_invalid_args(self):
570+
size = 10
571+
a = -1.0 # positive `a` is expected
572+
self.check_invalid_args('pareto', {'a': a})
573+
574+
def test_seed(self):
575+
a = 3.0 # a param for pareto distr
576+
self.check_seed('pareto', {'a': a})
577+
578+
560579
class TestDistributionsPoisson(TestDistribution):
561580

562581
def test_extreme_value(self):

0 commit comments

Comments
 (0)