xref: /freebsd/contrib/llvm-project/libcxx/include/__random/fisher_f_distribution.h (revision 18054d0220cfc8df9c9568c437bd6fbb59d53c3c)
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_FISHER_F_DISTRIBUTION_H
10 #define _LIBCPP___RANDOM_FISHER_F_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 fisher_f_distribution
28 {
29 public:
30     // types
31     typedef _RealType result_type;
32 
33     class _LIBCPP_TEMPLATE_VIS param_type
34     {
35         result_type __m_;
36         result_type __n_;
37     public:
38         typedef fisher_f_distribution distribution_type;
39 
40         _LIBCPP_INLINE_VISIBILITY
41         explicit param_type(result_type __m = 1, result_type __n = 1)
42             : __m_(__m), __n_(__n) {}
43 
44         _LIBCPP_INLINE_VISIBILITY
45         result_type m() const {return __m_;}
46         _LIBCPP_INLINE_VISIBILITY
47         result_type n() const {return __n_;}
48 
49         friend _LIBCPP_INLINE_VISIBILITY
50             bool operator==(const param_type& __x, const param_type& __y)
51             {return __x.__m_ == __y.__m_ && __x.__n_ == __y.__n_;}
52         friend _LIBCPP_INLINE_VISIBILITY
53             bool operator!=(const param_type& __x, const param_type& __y)
54             {return !(__x == __y);}
55     };
56 
57 private:
58     param_type __p_;
59 
60 public:
61     // constructor and reset functions
62 #ifndef _LIBCPP_CXX03_LANG
63     _LIBCPP_INLINE_VISIBILITY
64     fisher_f_distribution() : fisher_f_distribution(1) {}
65     _LIBCPP_INLINE_VISIBILITY
66     explicit fisher_f_distribution(result_type __m, result_type __n = 1)
67         : __p_(param_type(__m, __n)) {}
68 #else
69     _LIBCPP_INLINE_VISIBILITY
70     explicit fisher_f_distribution(result_type __m = 1, result_type __n = 1)
71         : __p_(param_type(__m, __n)) {}
72 #endif
73     _LIBCPP_INLINE_VISIBILITY
74     explicit fisher_f_distribution(const param_type& __p)
75         : __p_(__p) {}
76     _LIBCPP_INLINE_VISIBILITY
77     void reset() {}
78 
79     // generating functions
80     template<class _URNG>
81         _LIBCPP_INLINE_VISIBILITY
82         result_type operator()(_URNG& __g)
83         {return (*this)(__g, __p_);}
84     template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
85 
86     // property functions
87     _LIBCPP_INLINE_VISIBILITY
88     result_type m() const {return __p_.m();}
89     _LIBCPP_INLINE_VISIBILITY
90     result_type n() const {return __p_.n();}
91 
92     _LIBCPP_INLINE_VISIBILITY
93     param_type param() const {return __p_;}
94     _LIBCPP_INLINE_VISIBILITY
95     void param(const param_type& __p) {__p_ = __p;}
96 
97     _LIBCPP_INLINE_VISIBILITY
98     result_type min() const {return 0;}
99     _LIBCPP_INLINE_VISIBILITY
100     result_type max() const {return numeric_limits<result_type>::infinity();}
101 
102     friend _LIBCPP_INLINE_VISIBILITY
103         bool operator==(const fisher_f_distribution& __x,
104                         const fisher_f_distribution& __y)
105         {return __x.__p_ == __y.__p_;}
106     friend _LIBCPP_INLINE_VISIBILITY
107         bool operator!=(const fisher_f_distribution& __x,
108                         const fisher_f_distribution& __y)
109         {return !(__x == __y);}
110 };
111 
112 template <class _RealType>
113 template<class _URNG>
114 _RealType
115 fisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
116 {
117     gamma_distribution<result_type> __gdm(__p.m() * result_type(.5));
118     gamma_distribution<result_type> __gdn(__p.n() * result_type(.5));
119     return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g));
120 }
121 
122 template <class _CharT, class _Traits, class _RT>
123 basic_ostream<_CharT, _Traits>&
124 operator<<(basic_ostream<_CharT, _Traits>& __os,
125            const fisher_f_distribution<_RT>& __x)
126 {
127     __save_flags<_CharT, _Traits> __lx(__os);
128     typedef basic_ostream<_CharT, _Traits> _OStream;
129     __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
130                _OStream::scientific);
131     _CharT __sp = __os.widen(' ');
132     __os.fill(__sp);
133     __os << __x.m() << __sp << __x.n();
134     return __os;
135 }
136 
137 template <class _CharT, class _Traits, class _RT>
138 basic_istream<_CharT, _Traits>&
139 operator>>(basic_istream<_CharT, _Traits>& __is,
140            fisher_f_distribution<_RT>& __x)
141 {
142     typedef fisher_f_distribution<_RT> _Eng;
143     typedef typename _Eng::result_type result_type;
144     typedef typename _Eng::param_type param_type;
145     __save_flags<_CharT, _Traits> __lx(__is);
146     typedef basic_istream<_CharT, _Traits> _Istream;
147     __is.flags(_Istream::dec | _Istream::skipws);
148     result_type __m;
149     result_type __n;
150     __is >> __m >> __n;
151     if (!__is.fail())
152         __x.param(param_type(__m, __n));
153     return __is;
154 }
155 
156 _LIBCPP_END_NAMESPACE_STD
157 
158 _LIBCPP_POP_MACROS
159 
160 #endif // _LIBCPP___RANDOM_FISHER_F_DISTRIBUTION_H
161