exponential_distribution.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #ifndef _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H
  9. #define _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H
  10. #include <__config>
  11. #include <__random/generate_canonical.h>
  12. #include <__random/is_valid.h>
  13. #include <__random/uniform_real_distribution.h>
  14. #include <cmath>
  15. #include <iosfwd>
  16. #include <limits>
  17. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  18. # pragma GCC system_header
  19. #endif
  20. _LIBCPP_PUSH_MACROS
  21. #include <__undef_macros>
  22. _LIBCPP_BEGIN_NAMESPACE_STD
  23. template<class _RealType = double>
  24. class _LIBCPP_TEMPLATE_VIS exponential_distribution
  25. {
  26. public:
  27. // types
  28. typedef _RealType result_type;
  29. class _LIBCPP_TEMPLATE_VIS param_type
  30. {
  31. result_type __lambda_;
  32. public:
  33. typedef exponential_distribution distribution_type;
  34. _LIBCPP_INLINE_VISIBILITY
  35. explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {}
  36. _LIBCPP_INLINE_VISIBILITY
  37. result_type lambda() const {return __lambda_;}
  38. friend _LIBCPP_INLINE_VISIBILITY
  39. bool operator==(const param_type& __x, const param_type& __y)
  40. {return __x.__lambda_ == __y.__lambda_;}
  41. friend _LIBCPP_INLINE_VISIBILITY
  42. bool operator!=(const param_type& __x, const param_type& __y)
  43. {return !(__x == __y);}
  44. };
  45. private:
  46. param_type __p_;
  47. public:
  48. // constructors and reset functions
  49. #ifndef _LIBCPP_CXX03_LANG
  50. _LIBCPP_INLINE_VISIBILITY
  51. exponential_distribution() : exponential_distribution(1) {}
  52. _LIBCPP_INLINE_VISIBILITY
  53. explicit exponential_distribution(result_type __lambda)
  54. : __p_(param_type(__lambda)) {}
  55. #else
  56. _LIBCPP_INLINE_VISIBILITY
  57. explicit exponential_distribution(result_type __lambda = 1)
  58. : __p_(param_type(__lambda)) {}
  59. #endif
  60. _LIBCPP_INLINE_VISIBILITY
  61. explicit exponential_distribution(const param_type& __p) : __p_(__p) {}
  62. _LIBCPP_INLINE_VISIBILITY
  63. void reset() {}
  64. // generating functions
  65. template<class _URNG>
  66. _LIBCPP_INLINE_VISIBILITY
  67. result_type operator()(_URNG& __g)
  68. {return (*this)(__g, __p_);}
  69. template<class _URNG>
  70. _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
  71. // property functions
  72. _LIBCPP_INLINE_VISIBILITY
  73. result_type lambda() const {return __p_.lambda();}
  74. _LIBCPP_INLINE_VISIBILITY
  75. param_type param() const {return __p_;}
  76. _LIBCPP_INLINE_VISIBILITY
  77. void param(const param_type& __p) {__p_ = __p;}
  78. _LIBCPP_INLINE_VISIBILITY
  79. result_type min() const {return 0;}
  80. _LIBCPP_INLINE_VISIBILITY
  81. result_type max() const {return numeric_limits<result_type>::infinity();}
  82. friend _LIBCPP_INLINE_VISIBILITY
  83. bool operator==(const exponential_distribution& __x,
  84. const exponential_distribution& __y)
  85. {return __x.__p_ == __y.__p_;}
  86. friend _LIBCPP_INLINE_VISIBILITY
  87. bool operator!=(const exponential_distribution& __x,
  88. const exponential_distribution& __y)
  89. {return !(__x == __y);}
  90. };
  91. template <class _RealType>
  92. template<class _URNG>
  93. _RealType
  94. exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
  95. {
  96. static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
  97. return -_VSTD::log
  98. (
  99. result_type(1) -
  100. _VSTD::generate_canonical<result_type,
  101. numeric_limits<result_type>::digits>(__g)
  102. )
  103. / __p.lambda();
  104. }
  105. template <class _CharT, class _Traits, class _RealType>
  106. _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  107. operator<<(basic_ostream<_CharT, _Traits>& __os,
  108. const exponential_distribution<_RealType>& __x)
  109. {
  110. __save_flags<_CharT, _Traits> __lx(__os);
  111. typedef basic_ostream<_CharT, _Traits> _OStream;
  112. __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
  113. _OStream::scientific);
  114. return __os << __x.lambda();
  115. }
  116. template <class _CharT, class _Traits, class _RealType>
  117. _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  118. operator>>(basic_istream<_CharT, _Traits>& __is,
  119. exponential_distribution<_RealType>& __x)
  120. {
  121. typedef exponential_distribution<_RealType> _Eng;
  122. typedef typename _Eng::result_type result_type;
  123. typedef typename _Eng::param_type param_type;
  124. __save_flags<_CharT, _Traits> __lx(__is);
  125. typedef basic_istream<_CharT, _Traits> _Istream;
  126. __is.flags(_Istream::dec | _Istream::skipws);
  127. result_type __lambda;
  128. __is >> __lambda;
  129. if (!__is.fail())
  130. __x.param(param_type(__lambda));
  131. return __is;
  132. }
  133. _LIBCPP_END_NAMESPACE_STD
  134. _LIBCPP_POP_MACROS
  135. #endif // _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H