Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:30

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