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/GenerateCanonical.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <limits>
0010 #include <random>
0011 #include <type_traits>
0012 
0013 #include "corecel/Macros.hh"
0014 #include "corecel/Types.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 //! Helper function to generate a random uniform number
0020 template<class RealType, class Generator>
0021 inline CELER_FUNCTION RealType generate_canonical(Generator& g);
0022 
0023 //---------------------------------------------------------------------------//
0024 //! Sample a real_type on [0, 1).
0025 template<class Generator>
0026 inline CELER_FUNCTION real_type generate_canonical(Generator& g);
0027 
0028 //---------------------------------------------------------------------------//
0029 //! Implementation of each GenerateCanonical, used for CachedRngEngine
0030 enum class GenerateCanonicalPolicy
0031 {
0032     std,  //!< Use standard library
0033     builtin32,  //!< Use detail::GenerateCanonical32
0034     builtin64,  //!< Use detail::GenerateCanonical64 (not yet implemented)
0035     custom,  //!< Custom method
0036     size_
0037 };
0038 
0039 //---------------------------------------------------------------------------//
0040 /*!
0041  * Generate random numbers in [0, 1).
0042  *
0043  * This is essentially an implementation detail; partial specialization can be
0044  * used to sample using special functions with a given generator.
0045  *
0046  * \todo For 1.0 refactor so that if RNGs have a builtin policy we call our
0047  * builtin functions; if they have a custom we call a function on the RNG
0048  * itself; and if they don't define a policy (e.g. a standard library
0049  * one) we fall back to calling std::generate_canonical.
0050  */
0051 template<class Generator, class RealType = ::celeritas::real_type>
0052 struct GenerateCanonical
0053 {
0054     static_assert(std::is_floating_point<RealType>::value,
0055                   "RealType must be float or double");
0056 
0057     //!@{
0058     //! \name Type aliases
0059     using real_type = RealType;
0060     using result_type = real_type;
0061     //!@}
0062 
0063     //! By default use standard library
0064     static constexpr auto policy = GenerateCanonicalPolicy::std;
0065 
0066     // Sample a random number
0067     inline result_type operator()(Generator& rng);
0068 };
0069 
0070 //---------------------------------------------------------------------------//
0071 // INLINE DEFINITIONS
0072 //---------------------------------------------------------------------------//
0073 /*!
0074  * Generate random numbers in [0, 1).
0075  *
0076  * This is the default implementation, for CPU-only code.
0077  */
0078 template<class Generator, class RealType>
0079 auto GenerateCanonical<Generator, RealType>::operator()(Generator& rng)
0080     -> result_type
0081 {
0082     using limits_t = std::numeric_limits<result_type>;
0083     return std::generate_canonical<result_type, limits_t::digits>(rng);
0084 }
0085 
0086 //---------------------------------------------------------------------------//
0087 /*!
0088  * Helper function to generate a random real number in [0, 1).
0089  */
0090 template<class RealType, class Generator>
0091 CELER_FUNCTION RealType generate_canonical(Generator& g)
0092 {
0093     return GenerateCanonical<Generator, RealType>()(g);
0094 }
0095 
0096 //---------------------------------------------------------------------------//
0097 /*!
0098  * Helper function to generate a random real number in [0, 1).
0099  */
0100 template<class Generator>
0101 CELER_FUNCTION real_type generate_canonical(Generator& g)
0102 {
0103     return GenerateCanonical<Generator, real_type>()(g);
0104 }
0105 
0106 //---------------------------------------------------------------------------//
0107 }  // namespace celeritas