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_CHI_SQUARED_DISTRIBUTION_H
10 #define _LIBCPP___RANDOM_CHI_SQUARED_DISTRIBUTION_H
11 
12 #include <__config>
13 #include <__random/gamma_distribution.h>
14 #include <iosfwd>
15 #include <limits>
16 
17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18 #pragma GCC system_header
19 #endif
20 
21 _LIBCPP_PUSH_MACROS
22 #include <__undef_macros>
23 
24 _LIBCPP_BEGIN_NAMESPACE_STD
25 
26 template<class _RealType = double>
27 class _LIBCPP_TEMPLATE_VIS chi_squared_distribution
28 {
29 public:
30     // types
31     typedef _RealType result_type;
32 
33     class _LIBCPP_TEMPLATE_VIS param_type
34     {
35         result_type __n_;
36     public:
37         typedef chi_squared_distribution distribution_type;
38 
39         _LIBCPP_INLINE_VISIBILITY
40         explicit param_type(result_type __n = 1) : __n_(__n) {}
41 
42         _LIBCPP_INLINE_VISIBILITY
43         result_type n() const {return __n_;}
44 
45         friend _LIBCPP_INLINE_VISIBILITY
46             bool operator==(const param_type& __x, const param_type& __y)
47             {return __x.__n_ == __y.__n_;}
48         friend _LIBCPP_INLINE_VISIBILITY
49             bool operator!=(const param_type& __x, const param_type& __y)
50             {return !(__x == __y);}
51     };
52 
53 private:
54     param_type __p_;
55 
56 public:
57     // constructor and reset functions
58 #ifndef _LIBCPP_CXX03_LANG
59     _LIBCPP_INLINE_VISIBILITY
60     chi_squared_distribution() : chi_squared_distribution(1) {}
61     _LIBCPP_INLINE_VISIBILITY
62     explicit chi_squared_distribution(result_type __n)
63         : __p_(param_type(__n)) {}
64 #else
65     _LIBCPP_INLINE_VISIBILITY
66     explicit chi_squared_distribution(result_type __n = 1)
67         : __p_(param_type(__n)) {}
68 #endif
69     _LIBCPP_INLINE_VISIBILITY
70     explicit chi_squared_distribution(const param_type& __p)
71         : __p_(__p) {}
72     _LIBCPP_INLINE_VISIBILITY
73     void reset() {}
74 
75     // generating functions
76     template<class _URNG>
77         _LIBCPP_INLINE_VISIBILITY
78         result_type operator()(_URNG& __g)
79         {return (*this)(__g, __p_);}
80     template<class _URNG>
81         _LIBCPP_INLINE_VISIBILITY
82         result_type operator()(_URNG& __g, const param_type& __p)
83         {return gamma_distribution<result_type>(__p.n() / 2, 2)(__g);}
84 
85     // property functions
86     _LIBCPP_INLINE_VISIBILITY
87     result_type n() const {return __p_.n();}
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 chi_squared_distribution& __x,
101                         const chi_squared_distribution& __y)
102         {return __x.__p_ == __y.__p_;}
103     friend _LIBCPP_INLINE_VISIBILITY
104         bool operator!=(const chi_squared_distribution& __x,
105                         const chi_squared_distribution& __y)
106         {return !(__x == __y);}
107 };
108 
109 template <class _CharT, class _Traits, class _RT>
110 basic_ostream<_CharT, _Traits>&
111 operator<<(basic_ostream<_CharT, _Traits>& __os,
112            const chi_squared_distribution<_RT>& __x)
113 {
114     __save_flags<_CharT, _Traits> __lx(__os);
115     typedef basic_ostream<_CharT, _Traits> _OStream;
116     __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
117                _OStream::scientific);
118     __os << __x.n();
119     return __os;
120 }
121 
122 template <class _CharT, class _Traits, class _RT>
123 basic_istream<_CharT, _Traits>&
124 operator>>(basic_istream<_CharT, _Traits>& __is,
125            chi_squared_distribution<_RT>& __x)
126 {
127     typedef chi_squared_distribution<_RT> _Eng;
128     typedef typename _Eng::result_type result_type;
129     typedef typename _Eng::param_type param_type;
130     __save_flags<_CharT, _Traits> __lx(__is);
131     typedef basic_istream<_CharT, _Traits> _Istream;
132     __is.flags(_Istream::dec | _Istream::skipws);
133     result_type __n;
134     __is >> __n;
135     if (!__is.fail())
136         __x.param(param_type(__n));
137     return __is;
138 }
139 
140 _LIBCPP_END_NAMESPACE_STD
141 
142 _LIBCPP_POP_MACROS
143 
144 #endif // _LIBCPP___RANDOM_CHI_SQUARED_DISTRIBUTION_H
145