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> 83 _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); 84 85 // property functions 86 _LIBCPP_INLINE_VISIBILITY 87 result_type lambda() const {return __p_.lambda();} 88 89 _LIBCPP_INLINE_VISIBILITY 90 param_type param() const {return __p_;} 91 _LIBCPP_INLINE_VISIBILITY 92 void param(const param_type& __p) {__p_ = __p;} 93 94 _LIBCPP_INLINE_VISIBILITY 95 result_type min() const {return 0;} 96 _LIBCPP_INLINE_VISIBILITY 97 result_type max() const {return numeric_limits<result_type>::infinity();} 98 99 friend _LIBCPP_INLINE_VISIBILITY 100 bool operator==(const exponential_distribution& __x, 101 const exponential_distribution& __y) 102 {return __x.__p_ == __y.__p_;} 103 friend _LIBCPP_INLINE_VISIBILITY 104 bool operator!=(const exponential_distribution& __x, 105 const exponential_distribution& __y) 106 {return !(__x == __y);} 107 }; 108 109 template <class _RealType> 110 template<class _URNG> 111 _RealType 112 exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) 113 { 114 static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); 115 return -_VSTD::log 116 ( 117 result_type(1) - 118 _VSTD::generate_canonical<result_type, 119 numeric_limits<result_type>::digits>(__g) 120 ) 121 / __p.lambda(); 122 } 123 124 template <class _CharT, class _Traits, class _RealType> 125 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 126 operator<<(basic_ostream<_CharT, _Traits>& __os, 127 const exponential_distribution<_RealType>& __x) 128 { 129 __save_flags<_CharT, _Traits> __lx(__os); 130 typedef basic_ostream<_CharT, _Traits> _OStream; 131 __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | 132 _OStream::scientific); 133 return __os << __x.lambda(); 134 } 135 136 template <class _CharT, class _Traits, class _RealType> 137 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 138 operator>>(basic_istream<_CharT, _Traits>& __is, 139 exponential_distribution<_RealType>& __x) 140 { 141 typedef exponential_distribution<_RealType> _Eng; 142 typedef typename _Eng::result_type result_type; 143 typedef typename _Eng::param_type param_type; 144 __save_flags<_CharT, _Traits> __lx(__is); 145 typedef basic_istream<_CharT, _Traits> _Istream; 146 __is.flags(_Istream::dec | _Istream::skipws); 147 result_type __lambda; 148 __is >> __lambda; 149 if (!__is.fail()) 150 __x.param(param_type(__lambda)); 151 return __is; 152 } 153 154 _LIBCPP_END_NAMESPACE_STD 155 156 _LIBCPP_POP_MACROS 157 158 #endif // _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H 159