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 public: 33 // types 34 typedef _RealType result_type; 35 36 class _LIBCPP_TEMPLATE_VIS param_type 37 { 38 result_type __lambda_; 39 public: 40 typedef exponential_distribution distribution_type; 41 42 _LIBCPP_INLINE_VISIBILITY 43 explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {} 44 45 _LIBCPP_INLINE_VISIBILITY 46 result_type lambda() const {return __lambda_;} 47 48 friend _LIBCPP_INLINE_VISIBILITY 49 bool operator==(const param_type& __x, const param_type& __y) 50 {return __x.__lambda_ == __y.__lambda_;} 51 friend _LIBCPP_INLINE_VISIBILITY 52 bool operator!=(const param_type& __x, const param_type& __y) 53 {return !(__x == __y);} 54 }; 55 56 private: 57 param_type __p_; 58 59 public: 60 // constructors and reset functions 61 #ifndef _LIBCPP_CXX03_LANG 62 _LIBCPP_INLINE_VISIBILITY 63 exponential_distribution() : exponential_distribution(1) {} 64 _LIBCPP_INLINE_VISIBILITY 65 explicit exponential_distribution(result_type __lambda) 66 : __p_(param_type(__lambda)) {} 67 #else 68 _LIBCPP_INLINE_VISIBILITY 69 explicit exponential_distribution(result_type __lambda = 1) 70 : __p_(param_type(__lambda)) {} 71 #endif 72 _LIBCPP_INLINE_VISIBILITY 73 explicit exponential_distribution(const param_type& __p) : __p_(__p) {} 74 _LIBCPP_INLINE_VISIBILITY 75 void reset() {} 76 77 // generating functions 78 template<class _URNG> 79 _LIBCPP_INLINE_VISIBILITY 80 result_type operator()(_URNG& __g) 81 {return (*this)(__g, __p_);} 82 template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); 83 84 // property functions 85 _LIBCPP_INLINE_VISIBILITY 86 result_type lambda() const {return __p_.lambda();} 87 88 _LIBCPP_INLINE_VISIBILITY 89 param_type param() const {return __p_;} 90 _LIBCPP_INLINE_VISIBILITY 91 void param(const param_type& __p) {__p_ = __p;} 92 93 _LIBCPP_INLINE_VISIBILITY 94 result_type min() const {return 0;} 95 _LIBCPP_INLINE_VISIBILITY 96 result_type max() const {return numeric_limits<result_type>::infinity();} 97 98 friend _LIBCPP_INLINE_VISIBILITY 99 bool operator==(const exponential_distribution& __x, 100 const exponential_distribution& __y) 101 {return __x.__p_ == __y.__p_;} 102 friend _LIBCPP_INLINE_VISIBILITY 103 bool operator!=(const exponential_distribution& __x, 104 const exponential_distribution& __y) 105 {return !(__x == __y);} 106 }; 107 108 template <class _RealType> 109 template<class _URNG> 110 _RealType 111 exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) 112 { 113 static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); 114 return -_VSTD::log 115 ( 116 result_type(1) - 117 _VSTD::generate_canonical<result_type, 118 numeric_limits<result_type>::digits>(__g) 119 ) 120 / __p.lambda(); 121 } 122 123 template <class _CharT, class _Traits, class _RealType> 124 basic_ostream<_CharT, _Traits>& 125 operator<<(basic_ostream<_CharT, _Traits>& __os, 126 const exponential_distribution<_RealType>& __x) 127 { 128 __save_flags<_CharT, _Traits> __lx(__os); 129 typedef basic_ostream<_CharT, _Traits> _OStream; 130 __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | 131 _OStream::scientific); 132 return __os << __x.lambda(); 133 } 134 135 template <class _CharT, class _Traits, class _RealType> 136 basic_istream<_CharT, _Traits>& 137 operator>>(basic_istream<_CharT, _Traits>& __is, 138 exponential_distribution<_RealType>& __x) 139 { 140 typedef exponential_distribution<_RealType> _Eng; 141 typedef typename _Eng::result_type result_type; 142 typedef typename _Eng::param_type param_type; 143 __save_flags<_CharT, _Traits> __lx(__is); 144 typedef basic_istream<_CharT, _Traits> _Istream; 145 __is.flags(_Istream::dec | _Istream::skipws); 146 result_type __lambda; 147 __is >> __lambda; 148 if (!__is.fail()) 149 __x.param(param_type(__lambda)); 150 return __is; 151 } 152 153 _LIBCPP_END_NAMESPACE_STD 154 155 _LIBCPP_POP_MACROS 156 157 #endif // _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H 158