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/BernoulliDistribution.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "corecel/Types.hh"
0012 
0013 #include "GenerateCanonical.hh"
0014 
0015 namespace celeritas
0016 {
0017 //---------------------------------------------------------------------------//
0018 /*!
0019  * Select one of two options with a given probability.
0020  *
0021  * The constructor argument is the chance of returning `true`, with an optional
0022  * second argument for normalizing with a fraction of `false` values.
0023  * \code
0024     BernoulliDistribution snake_eyes(1, 35);
0025     if (snake_eyes(rng))
0026     {
0027         // ...
0028     }
0029     BernoulliDistribution also_snake_eyes(1.0 / 36.0);
0030    \endcode
0031  */
0032 class BernoulliDistribution
0033 {
0034   public:
0035     //!@{
0036     //! \name Type aliases
0037     using result_type = bool;
0038     //!@}
0039 
0040   public:
0041     // Construct with the probability of returning true
0042     explicit inline CELER_FUNCTION BernoulliDistribution(real_type p_true);
0043 
0044     // Construct with the UNnormalized probability of returning true or false
0045     inline CELER_FUNCTION
0046     BernoulliDistribution(real_type scaled_true, real_type scaled_false);
0047 
0048     // Sample true or false based on the probability
0049     template<class Generator>
0050     inline CELER_FUNCTION result_type operator()(Generator& rng) const;
0051 
0052     //! Probability of returning `true` from operator()
0053     real_type p() const { return p_true_; }
0054 
0055   private:
0056     real_type p_true_;
0057 };
0058 
0059 //---------------------------------------------------------------------------//
0060 // INLINE DEFINITIONS
0061 //---------------------------------------------------------------------------//
0062 /*!
0063  * Construct with the probability of returning true.
0064  */
0065 CELER_FUNCTION BernoulliDistribution::BernoulliDistribution(real_type p_true)
0066     : p_true_(p_true)
0067 {
0068     CELER_EXPECT(p_true >= 0 && p_true <= 1);
0069 }
0070 
0071 //---------------------------------------------------------------------------//
0072 /*!
0073  * Construct with the UNnormalized probability of returning true or false
0074  */
0075 CELER_FUNCTION
0076 BernoulliDistribution::BernoulliDistribution(real_type scaled_true,
0077                                              real_type scaled_false)
0078     : p_true_(scaled_true / (scaled_true + scaled_false))
0079 {
0080     CELER_EXPECT(scaled_true > 0 || scaled_false > 0);
0081     CELER_EXPECT(scaled_true >= 0 && scaled_false >= 0);
0082 }
0083 
0084 //---------------------------------------------------------------------------//
0085 /*!
0086  * Construct with the probability of returning true.
0087  */
0088 template<class Generator>
0089 CELER_FUNCTION auto
0090 BernoulliDistribution::operator()(Generator& rng) const -> result_type
0091 {
0092     return generate_canonical<real_type>(rng) < p_true_;
0093 }
0094 
0095 //---------------------------------------------------------------------------//
0096 }  // namespace celeritas