Line data Source code
1 : // Class Distribution
2 : // This class can be used for creating a distribution object
3 : // with custom pdf, cdf, and estimate function that is used for
4 : // the sampling method.
5 : //
6 :
7 : #ifndef IPPL_DISTRIBUTION_H
8 : #define IPPL_DISTRIBUTION_H
9 :
10 : #include "Types/ViewTypes.h"
11 :
12 : #include "Random/Utility.h"
13 :
14 : namespace ippl {
15 : namespace random {
16 :
17 : /*!
18 : * @file Distribution.h
19 : * @class Distribution
20 : */
21 :
22 : /*!
23 : * @ingroup Distribution
24 : * @brief The class that represents a distribution.
25 : * @tparam T Datatype.
26 : * @tparam Dim Dimensionality of sample space.
27 : * @tparam DimP Dimensionality of the parameter array.
28 : * @tparam PDF Struct type for the PDF (Probability Density Function).
29 : * @tparam CDF Struct type for the CDF (Cumulative Distribution Function).
30 : * @tparam ESTIMATE Struct type for the ESTIMATE function.
31 : */
32 : template <typename T, unsigned Dim, unsigned DimP, typename DistributionFunctions>
33 : class Distribution {
34 : public:
35 : /*!
36 : * @param par_m An array of distribution parameters.
37 : * @param pdf_m PDF of the distribution class as a member functor.
38 : * @param cdf_m CDF of the distribution class as a member functor.
39 : * @param estimate_m Estimate of the initial guess for the sampling method as a member
40 : * functor.
41 : */
42 : T par_m[DimP];
43 : typename DistributionFunctions::PDF pdf_m;
44 : typename DistributionFunctions::CDF cdf_m;
45 : typename DistributionFunctions::Estimate estimate_m;
46 : /*!
47 : * @ingroup Distribution
48 : * @brief Constructor for the Distribution class.
49 : * @param par_ Pointer to the parameter array.
50 : */
51 0 : KOKKOS_INLINE_FUNCTION Distribution(const T* par_p) {
52 0 : for (unsigned int i = 0; i < DimP; i++) {
53 0 : par_m[i] = par_p[i];
54 : }
55 0 : }
56 :
57 : /*!
58 : * @ingroup Distribution
59 : * @brief Destructor for the Distribution class.
60 : */
61 0 : KOKKOS_INLINE_FUNCTION ~Distribution() {}
62 :
63 : /*!
64 : * @brief A wrapper to change the signature arguments of pdf in each dimension d
65 : * from (x, d, par) to (x, d).
66 : */
67 0 : KOKKOS_INLINE_FUNCTION T getPdf(T x, unsigned int d) const {
68 0 : return pdf_m(x, d, par_m);
69 : }
70 :
71 : /*!
72 : * @brief A wrapper to change the signature arguments of cdf in each dimension d
73 : * from (x, d, par) to (x, d).
74 : */
75 0 : KOKKOS_INLINE_FUNCTION T getCdf(T x, unsigned int d) const {
76 0 : return cdf_m(x, d, par_m);
77 : }
78 :
79 : /*!
80 : * @brief A wrapper to change the signature arguments of estimate in each dimension d
81 : * from (x, d, par) to (x, d).
82 : */
83 0 : KOKKOS_INLINE_FUNCTION T getEstimate(T x, unsigned int d) const {
84 0 : return estimate_m(x, d, par_m);
85 : }
86 :
87 : /*!
88 : * @returns Objective function that is used in inverse transform sampling, i.e. obj =
89 : * cdf(x)-u. Here u is uniformly distributed on [0, 1] and x is the sample of target
90 : * distribution.
91 : */
92 0 : KOKKOS_INLINE_FUNCTION T getObjFunc(T x, unsigned int d, T u) const {
93 0 : return getCdf(x, d) - u;
94 : }
95 :
96 : /*!
97 : * @returns Derivative of the objective function that is used in inverse transform
98 : * sampling, i.e. d(obj)/dx = pdf(x)
99 : */
100 0 : KOKKOS_INLINE_FUNCTION T getDerObjFunc(T x, unsigned int d) const {
101 0 : return getPdf(x, d);
102 : }
103 :
104 : /*!
105 : * @returns Total pdf given uncorrelated pdf in each dimension.
106 : * i.e. total_pdf = pdf(x_1) * pdf(x_2) * ... pdf(x_N).
107 : */
108 : KOKKOS_INLINE_FUNCTION T getFullPdf(ippl::Vector<T, Dim> x) const {
109 : T totalPdf = 1.0;
110 : for (unsigned int d = 0; d < Dim; d++) {
111 : totalPdf *= getPdf(x[d], d);
112 : }
113 : return totalPdf;
114 : }
115 : };
116 : } // namespace random
117 : } // namespace ippl
118 :
119 : #endif
|