1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H 10 #define _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H 11 12 #include <__config> 13 #include <__random/generate_canonical.h> 14 #include <__random/is_valid.h> 15 #include <__random/uniform_real_distribution.h> 16 #include <cmath> 17 #include <iosfwd> 18 #include <limits> 19 20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21 # pragma GCC system_header 22 #endif 23 24 _LIBCPP_PUSH_MACROS 25 #include <__undef_macros> 26 27 _LIBCPP_BEGIN_NAMESPACE_STD 28 29 template<class _RealType = double> 30 class _LIBCPP_TEMPLATE_VIS exponential_distribution 31 { 32 static_assert(__libcpp_random_is_valid_realtype<_RealType>::value, 33 "RealType must be a supported floating-point type"); 34 35 public: 36 // types 37 typedef _RealType result_type; 38 39 class _LIBCPP_TEMPLATE_VIS param_type 40 { 41 result_type __lambda_; 42 public: 43 typedef exponential_distribution distribution_type; 44 45 _LIBCPP_HIDE_FROM_ABI 46 explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {} 47 48 _LIBCPP_HIDE_FROM_ABI 49 result_type lambda() const {return __lambda_;} 50 51 friend _LIBCPP_HIDE_FROM_ABI 52 bool operator==(const param_type& __x, const param_type& __y) 53 {return __x.__lambda_ == __y.__lambda_;} 54 friend _LIBCPP_HIDE_FROM_ABI 55 bool operator!=(const param_type& __x, const param_type& __y) 56 {return !(__x == __y);} 57 }; 58 59 private: 60 param_type __p_; 61 62 public: 63 // constructors and reset functions 64 #ifndef _LIBCPP_CXX03_LANG 65 _LIBCPP_HIDE_FROM_ABI 66 exponential_distribution() : exponential_distribution(1) {} 67 _LIBCPP_HIDE_FROM_ABI 68 explicit exponential_distribution(result_type __lambda) 69 : __p_(param_type(__lambda)) {} 70 #else 71 _LIBCPP_HIDE_FROM_ABI 72 explicit exponential_distribution(result_type __lambda = 1) 73 : __p_(param_type(__lambda)) {} 74 #endif 75 _LIBCPP_HIDE_FROM_ABI 76 explicit exponential_distribution(const param_type& __p) : __p_(__p) {} 77 _LIBCPP_HIDE_FROM_ABI 78 void reset() {} 79 80 // generating functions 81 template<class _URNG> 82 _LIBCPP_HIDE_FROM_ABI 83 result_type operator()(_URNG& __g) 84 {return (*this)(__g, __p_);} 85 template<class _URNG> 86 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); 87 88 // property functions 89 _LIBCPP_HIDE_FROM_ABI 90 result_type lambda() const {return __p_.lambda();} 91 92 _LIBCPP_HIDE_FROM_ABI 93 param_type param() const {return __p_;} 94 _LIBCPP_HIDE_FROM_ABI 95 void param(const param_type& __p) {__p_ = __p;} 96 97 _LIBCPP_HIDE_FROM_ABI 98 result_type min() const {return 0;} 99 _LIBCPP_HIDE_FROM_ABI 100 result_type max() const {return numeric_limits<result_type>::infinity();} 101 102 friend _LIBCPP_HIDE_FROM_ABI 103 bool operator==(const exponential_distribution& __x, 104 const exponential_distribution& __y) 105 {return __x.__p_ == __y.__p_;} 106 friend _LIBCPP_HIDE_FROM_ABI 107 bool operator!=(const exponential_distribution& __x, 108 const exponential_distribution& __y) 109 {return !(__x == __y);} 110 }; 111 112 template <class _RealType> 113 template<class _URNG> 114 _RealType 115 exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) 116 { 117 static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); 118 return -std::log 119 ( 120 result_type(1) - 121 std::generate_canonical<result_type, 122 numeric_limits<result_type>::digits>(__g) 123 ) 124 / __p.lambda(); 125 } 126 127 template <class _CharT, class _Traits, class _RealType> 128 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 129 operator<<(basic_ostream<_CharT, _Traits>& __os, 130 const exponential_distribution<_RealType>& __x) 131 { 132 __save_flags<_CharT, _Traits> __lx(__os); 133 typedef basic_ostream<_CharT, _Traits> _OStream; 134 __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | 135 _OStream::scientific); 136 return __os << __x.lambda(); 137 } 138 139 template <class _CharT, class _Traits, class _RealType> 140 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 141 operator>>(basic_istream<_CharT, _Traits>& __is, 142 exponential_distribution<_RealType>& __x) 143 { 144 typedef exponential_distribution<_RealType> _Eng; 145 typedef typename _Eng::result_type result_type; 146 typedef typename _Eng::param_type param_type; 147 __save_flags<_CharT, _Traits> __lx(__is); 148 typedef basic_istream<_CharT, _Traits> _Istream; 149 __is.flags(_Istream::dec | _Istream::skipws); 150 result_type __lambda; 151 __is >> __lambda; 152 if (!__is.fail()) 153 __x.param(param_type(__lambda)); 154 return __is; 155 } 156 157 _LIBCPP_END_NAMESPACE_STD 158 159 _LIBCPP_POP_MACROS 160 161 #endif // _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H 162