Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-14 08:50:58

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file corecel/random/distribution/UniformRealDistribution.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cmath>
0010 #include <type_traits>
0011 
0012 #include "corecel/Assert.hh"
0013 #include "corecel/Macros.hh"
0014 #include "corecel/Types.hh"
0015 
0016 #include "GenerateCanonical.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Sample from a uniform distribution.
0023  *
0024  * This distribution is defined between two arbitrary real numbers \em a and
0025  * \em b , and has a flat PDF between the two values. It \em is allowable for
0026  * the two numbers to have reversed order.
0027  * The normalized PDF is:
0028  * \f[
0029    f(x; a, b) = \frac{1}{b - a} \quad \mathrm{for} \ a \le x < b
0030    \f]
0031  * which integrated into a CDF and inverted gives a sample:
0032  * \f[
0033   x = (b - a) \xi + a
0034    \f]
0035  */
0036 template<class RealType = ::celeritas::real_type>
0037 class UniformRealDistribution
0038 {
0039     static_assert(std::is_floating_point_v<RealType>);
0040 
0041   public:
0042     //!@{
0043     //! \name Type aliases
0044     using real_type = RealType;
0045     using result_type = real_type;
0046     //!@}
0047 
0048   public:
0049     // Construct on [0, 1)
0050     CELER_CONSTEXPR_FUNCTION UniformRealDistribution();
0051 
0052     // Construct on an arbitrary interval
0053     CELER_CONSTEXPR_FUNCTION UniformRealDistribution(real_type a, real_type b);
0054 
0055     // Sample a random number according to the distribution
0056     template<class Generator>
0057     inline CELER_FUNCTION result_type operator()(Generator& rng) const;
0058 
0059     //// ACCESSORS ////
0060 
0061     //! Get the lower bound of the distribution
0062     CELER_CONSTEXPR_FUNCTION real_type a() const { return a_; }
0063 
0064     //! Get the upper bound of the distribution
0065     CELER_CONSTEXPR_FUNCTION real_type b() const { return delta_ + a_; }
0066 
0067   private:
0068     RealType a_;
0069     RealType delta_;
0070 };
0071 
0072 //---------------------------------------------------------------------------//
0073 // INLINE DEFINITIONS
0074 //---------------------------------------------------------------------------//
0075 /*!
0076  * Construct on the interval [0, 1).
0077  *
0078  * This constructor is generally unused because it's simpler and more efficient
0079  * to directly call ``generate_canonical``. We leave it for compatibility with
0080  * the standard.
0081  */
0082 template<class RealType>
0083 CELER_CONSTEXPR_FUNCTION
0084 UniformRealDistribution<RealType>::UniformRealDistribution()
0085     : UniformRealDistribution(0, 1)
0086 {
0087 }
0088 
0089 //---------------------------------------------------------------------------//
0090 /*!
0091  * Construct on the interval [a, b).
0092  *
0093  * Note that it's allowable for these two to be out of order to support other
0094  * generators (inverse square, power) where they may be inverted and out of
0095  * order.
0096  */
0097 template<class RealType>
0098 CELER_CONSTEXPR_FUNCTION
0099 UniformRealDistribution<RealType>::UniformRealDistribution(real_type a,
0100                                                            real_type b)
0101     : a_(a), delta_(b - a)
0102 {
0103 }
0104 
0105 //---------------------------------------------------------------------------//
0106 /*!
0107  * Sample a random number according to the distribution.
0108  */
0109 template<class RealType>
0110 template<class Generator>
0111 CELER_FUNCTION auto
0112 UniformRealDistribution<RealType>::operator()(Generator& rng) const -> result_type
0113 {
0114     return std::fma(delta_, generate_canonical<RealType>(rng), a_);
0115 }
0116 
0117 //---------------------------------------------------------------------------//
0118 }  // namespace celeritas