14824e7fdSDimitry Andric //===----------------------------------------------------------------------===// 24824e7fdSDimitry Andric // 34824e7fdSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44824e7fdSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 54824e7fdSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64824e7fdSDimitry Andric // 74824e7fdSDimitry Andric //===----------------------------------------------------------------------===// 84824e7fdSDimitry Andric 94824e7fdSDimitry Andric #ifndef _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H 104824e7fdSDimitry Andric #define _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H 114824e7fdSDimitry Andric 124824e7fdSDimitry Andric #include <__algorithm/upper_bound.h> 134824e7fdSDimitry Andric #include <__config> 1481ad6265SDimitry Andric #include <__random/is_valid.h> 154824e7fdSDimitry Andric #include <__random/uniform_real_distribution.h> 165f757f3fSDimitry Andric #include <cmath> 174824e7fdSDimitry Andric #include <iosfwd> 184824e7fdSDimitry Andric #include <vector> 194824e7fdSDimitry Andric 204824e7fdSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 214824e7fdSDimitry Andric # pragma GCC system_header 224824e7fdSDimitry Andric #endif 234824e7fdSDimitry Andric 244824e7fdSDimitry Andric _LIBCPP_PUSH_MACROS 254824e7fdSDimitry Andric #include <__undef_macros> 264824e7fdSDimitry Andric 274824e7fdSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 284824e7fdSDimitry Andric 294824e7fdSDimitry Andric template <class _RealType = double> 30*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS piecewise_linear_distribution { 315f757f3fSDimitry Andric static_assert(__libcpp_random_is_valid_realtype<_RealType>::value, 325f757f3fSDimitry Andric "RealType must be a supported floating-point type"); 335f757f3fSDimitry Andric 344824e7fdSDimitry Andric public: 354824e7fdSDimitry Andric // types 364824e7fdSDimitry Andric typedef _RealType result_type; 374824e7fdSDimitry Andric 38*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS param_type { 394824e7fdSDimitry Andric vector<result_type> __b_; 404824e7fdSDimitry Andric vector<result_type> __densities_; 414824e7fdSDimitry Andric vector<result_type> __areas_; 42*cb14a3feSDimitry Andric 434824e7fdSDimitry Andric public: 444824e7fdSDimitry Andric typedef piecewise_linear_distribution distribution_type; 454824e7fdSDimitry Andric 4606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type(); 474824e7fdSDimitry Andric template <class _InputIteratorB, class _InputIteratorW> 48*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type(_InputIteratorB __f_b, _InputIteratorB __l_b, _InputIteratorW __f_w); 494824e7fdSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 504824e7fdSDimitry Andric template <class _UnaryOperation> 5106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type(initializer_list<result_type> __bl, _UnaryOperation __fw); 524824e7fdSDimitry Andric #endif // _LIBCPP_CXX03_LANG 534824e7fdSDimitry Andric template <class _UnaryOperation> 54*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw); 5506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type(param_type const&) = default; 5606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type& operator=(const param_type& __rhs); 574824e7fdSDimitry Andric 58*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI vector<result_type> intervals() const { return __b_; } 59*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI vector<result_type> densities() const { return __densities_; } 604824e7fdSDimitry Andric 61*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const param_type& __x, const param_type& __y) { 62*cb14a3feSDimitry Andric return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_; 63*cb14a3feSDimitry Andric } 64*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const param_type& __x, const param_type& __y) { return !(__x == __y); } 654824e7fdSDimitry Andric 664824e7fdSDimitry Andric private: 6706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __init(); 684824e7fdSDimitry Andric 694824e7fdSDimitry Andric friend class piecewise_linear_distribution; 704824e7fdSDimitry Andric 714824e7fdSDimitry Andric template <class _CharT, class _Traits, class _RT> 72*cb14a3feSDimitry Andric friend basic_ostream<_CharT, _Traits>& 73*cb14a3feSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const piecewise_linear_distribution<_RT>& __x); 744824e7fdSDimitry Andric 754824e7fdSDimitry Andric template <class _CharT, class _Traits, class _RT> 76*cb14a3feSDimitry Andric friend basic_istream<_CharT, _Traits>& 77*cb14a3feSDimitry Andric operator>>(basic_istream<_CharT, _Traits>& __is, piecewise_linear_distribution<_RT>& __x); 784824e7fdSDimitry Andric }; 794824e7fdSDimitry Andric 804824e7fdSDimitry Andric private: 814824e7fdSDimitry Andric param_type __p_; 824824e7fdSDimitry Andric 834824e7fdSDimitry Andric public: 844824e7fdSDimitry Andric // constructor and reset functions 85*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI piecewise_linear_distribution() {} 864824e7fdSDimitry Andric template <class _InputIteratorB, class _InputIteratorW> 875f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 88*cb14a3feSDimitry Andric piecewise_linear_distribution(_InputIteratorB __f_b, _InputIteratorB __l_b, _InputIteratorW __f_w) 89753f127fSDimitry Andric : __p_(__f_b, __l_b, __f_w) {} 904824e7fdSDimitry Andric 914824e7fdSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 924824e7fdSDimitry Andric template <class _UnaryOperation> 93*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI piecewise_linear_distribution(initializer_list<result_type> __bl, _UnaryOperation __fw) 944824e7fdSDimitry Andric : __p_(__bl, __fw) {} 954824e7fdSDimitry Andric #endif // _LIBCPP_CXX03_LANG 964824e7fdSDimitry Andric 974824e7fdSDimitry Andric template <class _UnaryOperation> 985f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 99*cb14a3feSDimitry Andric piecewise_linear_distribution(size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw) 1004824e7fdSDimitry Andric : __p_(__nw, __xmin, __xmax, __fw) {} 1014824e7fdSDimitry Andric 102*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit piecewise_linear_distribution(const param_type& __p) : __p_(__p) {} 1034824e7fdSDimitry Andric 104*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void reset() {} 1054824e7fdSDimitry Andric 1064824e7fdSDimitry Andric // generating functions 1074824e7fdSDimitry Andric template <class _URNG> 108*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g) { 109*cb14a3feSDimitry Andric return (*this)(__g, __p_); 110*cb14a3feSDimitry Andric } 11106c3fb27SDimitry Andric template <class _URNG> 11206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); 1134824e7fdSDimitry Andric 1144824e7fdSDimitry Andric // property functions 115*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI vector<result_type> intervals() const { return __p_.intervals(); } 116*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI vector<result_type> densities() const { return __p_.densities(); } 1174824e7fdSDimitry Andric 118*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type param() const { return __p_; } 119*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void param(const param_type& __p) { __p_ = __p; } 1204824e7fdSDimitry Andric 121*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type min() const { return __p_.__b_.front(); } 122*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type max() const { return __p_.__b_.back(); } 1234824e7fdSDimitry Andric 124*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool 125*cb14a3feSDimitry Andric operator==(const piecewise_linear_distribution& __x, const piecewise_linear_distribution& __y) { 126*cb14a3feSDimitry Andric return __x.__p_ == __y.__p_; 127*cb14a3feSDimitry Andric } 128*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool 129*cb14a3feSDimitry Andric operator!=(const piecewise_linear_distribution& __x, const piecewise_linear_distribution& __y) { 130*cb14a3feSDimitry Andric return !(__x == __y); 131*cb14a3feSDimitry Andric } 1324824e7fdSDimitry Andric 1334824e7fdSDimitry Andric template <class _CharT, class _Traits, class _RT> 134*cb14a3feSDimitry Andric friend basic_ostream<_CharT, _Traits>& 135*cb14a3feSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const piecewise_linear_distribution<_RT>& __x); 1364824e7fdSDimitry Andric 1374824e7fdSDimitry Andric template <class _CharT, class _Traits, class _RT> 138*cb14a3feSDimitry Andric friend basic_istream<_CharT, _Traits>& 139*cb14a3feSDimitry Andric operator>>(basic_istream<_CharT, _Traits>& __is, piecewise_linear_distribution<_RT>& __x); 1404824e7fdSDimitry Andric }; 1414824e7fdSDimitry Andric 1424824e7fdSDimitry Andric template <class _RealType> 1434824e7fdSDimitry Andric typename piecewise_linear_distribution<_RealType>::param_type& 144*cb14a3feSDimitry Andric piecewise_linear_distribution<_RealType>::param_type::operator=(const param_type& __rhs) { 1454824e7fdSDimitry Andric // These can throw 1464824e7fdSDimitry Andric __b_.reserve(__rhs.__b_.size()); 1474824e7fdSDimitry Andric __densities_.reserve(__rhs.__densities_.size()); 1484824e7fdSDimitry Andric __areas_.reserve(__rhs.__areas_.size()); 1494824e7fdSDimitry Andric 1504824e7fdSDimitry Andric // These can not throw 1514824e7fdSDimitry Andric __b_ = __rhs.__b_; 1524824e7fdSDimitry Andric __densities_ = __rhs.__densities_; 1534824e7fdSDimitry Andric __areas_ = __rhs.__areas_; 1544824e7fdSDimitry Andric return *this; 1554824e7fdSDimitry Andric } 1564824e7fdSDimitry Andric 1574824e7fdSDimitry Andric template <class _RealType> 158*cb14a3feSDimitry Andric void piecewise_linear_distribution<_RealType>::param_type::__init() { 1594824e7fdSDimitry Andric __areas_.assign(__densities_.size() - 1, result_type()); 16006c3fb27SDimitry Andric result_type __sp = 0; 161*cb14a3feSDimitry Andric for (size_t __i = 0; __i < __areas_.size(); ++__i) { 162*cb14a3feSDimitry Andric __areas_[__i] = (__densities_[__i + 1] + __densities_[__i]) * (__b_[__i + 1] - __b_[__i]) * .5; 16306c3fb27SDimitry Andric __sp += __areas_[__i]; 1644824e7fdSDimitry Andric } 165*cb14a3feSDimitry Andric for (size_t __i = __areas_.size(); __i > 1;) { 1664824e7fdSDimitry Andric --__i; 16706c3fb27SDimitry Andric __areas_[__i] = __areas_[__i - 1] / __sp; 1684824e7fdSDimitry Andric } 1694824e7fdSDimitry Andric __areas_[0] = 0; 1704824e7fdSDimitry Andric for (size_t __i = 1; __i < __areas_.size(); ++__i) 1714824e7fdSDimitry Andric __areas_[__i] += __areas_[__i - 1]; 1724824e7fdSDimitry Andric for (size_t __i = 0; __i < __densities_.size(); ++__i) 17306c3fb27SDimitry Andric __densities_[__i] /= __sp; 1744824e7fdSDimitry Andric } 1754824e7fdSDimitry Andric 1764824e7fdSDimitry Andric template <class _RealType> 177*cb14a3feSDimitry Andric piecewise_linear_distribution<_RealType>::param_type::param_type() : __b_(2), __densities_(2, 1.0), __areas_(1, 0.0) { 1784824e7fdSDimitry Andric __b_[1] = 1; 1794824e7fdSDimitry Andric } 1804824e7fdSDimitry Andric 1814824e7fdSDimitry Andric template <class _RealType> 1824824e7fdSDimitry Andric template <class _InputIteratorB, class _InputIteratorW> 1834824e7fdSDimitry Andric piecewise_linear_distribution<_RealType>::param_type::param_type( 184753f127fSDimitry Andric _InputIteratorB __f_b, _InputIteratorB __l_b, _InputIteratorW __f_w) 185*cb14a3feSDimitry Andric : __b_(__f_b, __l_b) { 186*cb14a3feSDimitry Andric if (__b_.size() < 2) { 1874824e7fdSDimitry Andric __b_.resize(2); 1884824e7fdSDimitry Andric __b_[0] = 0; 1894824e7fdSDimitry Andric __b_[1] = 1; 1904824e7fdSDimitry Andric __densities_.assign(2, 1.0); 1914824e7fdSDimitry Andric __areas_.assign(1, 0.0); 192*cb14a3feSDimitry Andric } else { 1934824e7fdSDimitry Andric __densities_.reserve(__b_.size()); 194753f127fSDimitry Andric for (size_t __i = 0; __i < __b_.size(); ++__i, ++__f_w) 195753f127fSDimitry Andric __densities_.push_back(*__f_w); 1964824e7fdSDimitry Andric __init(); 1974824e7fdSDimitry Andric } 1984824e7fdSDimitry Andric } 1994824e7fdSDimitry Andric 2004824e7fdSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 2014824e7fdSDimitry Andric 2024824e7fdSDimitry Andric template <class _RealType> 2034824e7fdSDimitry Andric template <class _UnaryOperation> 2044824e7fdSDimitry Andric piecewise_linear_distribution<_RealType>::param_type::param_type( 2054824e7fdSDimitry Andric initializer_list<result_type> __bl, _UnaryOperation __fw) 206*cb14a3feSDimitry Andric : __b_(__bl.begin(), __bl.end()) { 207*cb14a3feSDimitry Andric if (__b_.size() < 2) { 2084824e7fdSDimitry Andric __b_.resize(2); 2094824e7fdSDimitry Andric __b_[0] = 0; 2104824e7fdSDimitry Andric __b_[1] = 1; 2114824e7fdSDimitry Andric __densities_.assign(2, 1.0); 2124824e7fdSDimitry Andric __areas_.assign(1, 0.0); 213*cb14a3feSDimitry Andric } else { 2144824e7fdSDimitry Andric __densities_.reserve(__b_.size()); 2154824e7fdSDimitry Andric for (size_t __i = 0; __i < __b_.size(); ++__i) 2164824e7fdSDimitry Andric __densities_.push_back(__fw(__b_[__i])); 2174824e7fdSDimitry Andric __init(); 2184824e7fdSDimitry Andric } 2194824e7fdSDimitry Andric } 2204824e7fdSDimitry Andric 2214824e7fdSDimitry Andric #endif // _LIBCPP_CXX03_LANG 2224824e7fdSDimitry Andric 2234824e7fdSDimitry Andric template <class _RealType> 2244824e7fdSDimitry Andric template <class _UnaryOperation> 2254824e7fdSDimitry Andric piecewise_linear_distribution<_RealType>::param_type::param_type( 2264824e7fdSDimitry Andric size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw) 227*cb14a3feSDimitry Andric : __b_(__nw == 0 ? 2 : __nw + 1) { 2284824e7fdSDimitry Andric size_t __n = __b_.size() - 1; 2294824e7fdSDimitry Andric result_type __d = (__xmax - __xmin) / __n; 2304824e7fdSDimitry Andric __densities_.reserve(__b_.size()); 231*cb14a3feSDimitry Andric for (size_t __i = 0; __i < __n; ++__i) { 2324824e7fdSDimitry Andric __b_[__i] = __xmin + __i * __d; 2334824e7fdSDimitry Andric __densities_.push_back(__fw(__b_[__i])); 2344824e7fdSDimitry Andric } 2354824e7fdSDimitry Andric __b_[__n] = __xmax; 2364824e7fdSDimitry Andric __densities_.push_back(__fw(__b_[__n])); 2374824e7fdSDimitry Andric __init(); 2384824e7fdSDimitry Andric } 2394824e7fdSDimitry Andric 2404824e7fdSDimitry Andric template <class _RealType> 2414824e7fdSDimitry Andric template <class _URNG> 242*cb14a3feSDimitry Andric _RealType piecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) { 24381ad6265SDimitry Andric static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); 2444824e7fdSDimitry Andric typedef uniform_real_distribution<result_type> _Gen; 2454824e7fdSDimitry Andric result_type __u = _Gen()(__g); 246*cb14a3feSDimitry Andric ptrdiff_t __k = std::upper_bound(__p.__areas_.begin(), __p.__areas_.end(), __u) - __p.__areas_.begin() - 1; 2474824e7fdSDimitry Andric __u -= __p.__areas_[__k]; 2484824e7fdSDimitry Andric const result_type __dk = __p.__densities_[__k]; 2494824e7fdSDimitry Andric const result_type __dk1 = __p.__densities_[__k + 1]; 2504824e7fdSDimitry Andric const result_type __deltad = __dk1 - __dk; 2514824e7fdSDimitry Andric const result_type __bk = __p.__b_[__k]; 2524824e7fdSDimitry Andric if (__deltad == 0) 2534824e7fdSDimitry Andric return __u / __dk + __bk; 2544824e7fdSDimitry Andric const result_type __bk1 = __p.__b_[__k + 1]; 2554824e7fdSDimitry Andric const result_type __deltab = __bk1 - __bk; 256*cb14a3feSDimitry Andric return (__bk * __dk1 - __bk1 * __dk + std::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) / __deltad; 2574824e7fdSDimitry Andric } 2584824e7fdSDimitry Andric 2594824e7fdSDimitry Andric template <class _CharT, class _Traits, class _RT> 260bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 261*cb14a3feSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const piecewise_linear_distribution<_RT>& __x) { 2624824e7fdSDimitry Andric __save_flags<_CharT, _Traits> __lx(__os); 2634824e7fdSDimitry Andric typedef basic_ostream<_CharT, _Traits> _OStream; 264*cb14a3feSDimitry Andric __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | _OStream::scientific); 2654824e7fdSDimitry Andric _CharT __sp = __os.widen(' '); 2664824e7fdSDimitry Andric __os.fill(__sp); 2674824e7fdSDimitry Andric size_t __n = __x.__p_.__b_.size(); 2684824e7fdSDimitry Andric __os << __n; 2694824e7fdSDimitry Andric for (size_t __i = 0; __i < __n; ++__i) 2704824e7fdSDimitry Andric __os << __sp << __x.__p_.__b_[__i]; 2714824e7fdSDimitry Andric __n = __x.__p_.__densities_.size(); 2724824e7fdSDimitry Andric __os << __sp << __n; 2734824e7fdSDimitry Andric for (size_t __i = 0; __i < __n; ++__i) 2744824e7fdSDimitry Andric __os << __sp << __x.__p_.__densities_[__i]; 2754824e7fdSDimitry Andric __n = __x.__p_.__areas_.size(); 2764824e7fdSDimitry Andric __os << __sp << __n; 2774824e7fdSDimitry Andric for (size_t __i = 0; __i < __n; ++__i) 2784824e7fdSDimitry Andric __os << __sp << __x.__p_.__areas_[__i]; 2794824e7fdSDimitry Andric return __os; 2804824e7fdSDimitry Andric } 2814824e7fdSDimitry Andric 2824824e7fdSDimitry Andric template <class _CharT, class _Traits, class _RT> 283bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 284*cb14a3feSDimitry Andric operator>>(basic_istream<_CharT, _Traits>& __is, piecewise_linear_distribution<_RT>& __x) { 2854824e7fdSDimitry Andric typedef piecewise_linear_distribution<_RT> _Eng; 2864824e7fdSDimitry Andric typedef typename _Eng::result_type result_type; 2874824e7fdSDimitry Andric __save_flags<_CharT, _Traits> __lx(__is); 2884824e7fdSDimitry Andric typedef basic_istream<_CharT, _Traits> _Istream; 2894824e7fdSDimitry Andric __is.flags(_Istream::dec | _Istream::skipws); 2904824e7fdSDimitry Andric size_t __n; 2914824e7fdSDimitry Andric __is >> __n; 2924824e7fdSDimitry Andric vector<result_type> __b(__n); 2934824e7fdSDimitry Andric for (size_t __i = 0; __i < __n; ++__i) 2944824e7fdSDimitry Andric __is >> __b[__i]; 2954824e7fdSDimitry Andric __is >> __n; 2964824e7fdSDimitry Andric vector<result_type> __densities(__n); 2974824e7fdSDimitry Andric for (size_t __i = 0; __i < __n; ++__i) 2984824e7fdSDimitry Andric __is >> __densities[__i]; 2994824e7fdSDimitry Andric __is >> __n; 3004824e7fdSDimitry Andric vector<result_type> __areas(__n); 3014824e7fdSDimitry Andric for (size_t __i = 0; __i < __n; ++__i) 3024824e7fdSDimitry Andric __is >> __areas[__i]; 303*cb14a3feSDimitry Andric if (!__is.fail()) { 3044824e7fdSDimitry Andric swap(__x.__p_.__b_, __b); 3054824e7fdSDimitry Andric swap(__x.__p_.__densities_, __densities); 3064824e7fdSDimitry Andric swap(__x.__p_.__areas_, __areas); 3074824e7fdSDimitry Andric } 3084824e7fdSDimitry Andric return __is; 3094824e7fdSDimitry Andric } 3104824e7fdSDimitry Andric 3114824e7fdSDimitry Andric _LIBCPP_END_NAMESPACE_STD 3124824e7fdSDimitry Andric 3134824e7fdSDimitry Andric _LIBCPP_POP_MACROS 3144824e7fdSDimitry Andric 3154824e7fdSDimitry Andric #endif // _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H 316