Mantid
Loading...
Searching...
No Matches
normal_distribution.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
11#include <ios>
12#include <random>
13
14// Implementation of normal_distribution taken from llvm/libcxx at
15// https://github.com/llvm-mirror/libcxx/blob/661dff0e60093266e7833cbbf5d3809a4f950378/include/random#L497
16//
17// Each of our supported platforms has the header but gcc
18// (https://github.com/gcc-mirror/gcc/blob/da8dff89fa9398f04b107e388cb706517ced9505/libstdc%2B%2B-v3/include/bits/random.tcc#L1783)
19// differs to msvc/clang in which value it caches/returns. This makes writing
20// tests against the implementations much harder. This simply choose the libcxx
21// header as our "standard".
22//
23// Modifications to enable compilation:
24// * define required macros just for this header
25// * prefix some structures with std:: now they are not in std:: namespace
26// * include __save_flags helper class for io formatting
27// * disabled a maybe-uninitialized warning that would be disabled in the
28// system header anyway
29
30#ifdef _MSC_VER
31#define INLINE_VISIBILITY __forceinline
32#else
33#define INLINE_VISIBILITY __attribute__((__always_inline__))
34#endif
35
36namespace Mantid {
37namespace Kernel {
38
39template <class _CharT, class _Traits> class __save_flags {
40 using __stream_type = std::basic_ios<_CharT, _Traits>;
41 using fmtflags = typename __stream_type::fmtflags;
42
45 _CharT __fill_;
46
49
50public:
52 explicit __save_flags(__stream_type &__stream)
53 : __stream_(__stream), __fmtflags_(__stream.flags()), __fill_(__stream.fill()) {}
57 __stream_.fill(__fill_);
58 }
59};
60
61template <class _RealType = double> class DLLExport normal_distribution {
62public:
63 // types
64 using result_type = _RealType;
65
69
70 public:
72
74 explicit param_type(result_type __mean = 0, result_type __stddev = 1) : __mean_(__mean), __stddev_(__stddev) {}
75
77 result_type mean() const { return __mean_; }
79 result_type stddev() const { return __stddev_; }
80
81 friend INLINE_VISIBILITY bool operator==(const param_type &__x, const param_type &__y) {
82 return __x.__mean_ == __y.__mean_ && __x.__stddev_ == __y.__stddev_;
83 }
84 friend INLINE_VISIBILITY bool operator!=(const param_type &__x, const param_type &__y) { return !(__x == __y); }
85 };
86
87private:
90 bool _V_hot_;
91
92public:
93 // constructors and reset functions
95 explicit normal_distribution(result_type __mean = 0, result_type __stddev = 1)
96 : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}
98 explicit normal_distribution(const param_type &__p) : __p_(__p), _V_hot_(false) {}
100 void reset() { _V_hot_ = false; }
101
102 // generating functions
103 template <class _URNG> INLINE_VISIBILITY result_type operator()(_URNG &__g) { return (*this)(__g, __p_); }
104 template <class _URNG> result_type operator()(_URNG &__g, const param_type &__p);
105
106 // property functions
108 result_type mean() const { return __p_.mean(); }
110 result_type stddev() const { return __p_.stddev(); }
111
113 param_type param() const { return __p_; }
115 void param(const param_type &__p) { __p_ = __p; }
116
118 result_type min() const { return -std::numeric_limits<result_type>::infinity(); }
120 result_type max() const { return std::numeric_limits<result_type>::infinity(); }
121
123 return __x.__p_ == __y.__p_ && __x._V_hot_ == __y._V_hot_ && (!__x._V_hot_ || __x._V_ == __y._V_);
124 }
126 return !(__x == __y);
127 }
128
129 template <class _CharT, class _Traits, class _RT>
130 friend std::basic_ostream<_CharT, _Traits> &operator<<(std::basic_ostream<_CharT, _Traits> &__os,
131 const normal_distribution<_RT> &__x);
132
133 template <class _CharT, class _Traits, class _RT>
134 friend std::basic_istream<_CharT, _Traits> &operator>>(std::basic_istream<_CharT, _Traits> &__is,
136};
137
138GNU_DIAG_OFF("maybe-uninitialized")
139template <class _RealType>
140template <class _URNG>
141_RealType normal_distribution<_RealType>::operator()(_URNG &__g, const param_type &__p) {
142 result_type _Up;
143 if (_V_hot_) {
144 _V_hot_ = false;
145 _Up = _V_;
146 } else {
147 std::uniform_real_distribution<result_type> _Uni(-1, 1);
148 result_type __u;
149 result_type __v;
150 result_type __s;
151 do {
152 __u = _Uni(__g);
153 __v = _Uni(__g);
154 __s = __u * __u + __v * __v;
155 } while (__s > 1 || __s == 0);
156 result_type _Fp = std::sqrt(-2 * std::log(__s) / __s);
157 _V_ = __v * _Fp;
158 _V_hot_ = true;
159 _Up = __u * _Fp;
160 }
161 return _Up * __p.stddev() + __p.mean();
162}
163GNU_DIAG_ON("maybe-uninitialized")
164
165template <class _CharT, class _Traits, class _RT>
166std::basic_ostream<_CharT, _Traits> &operator<<(std::basic_ostream<_CharT, _Traits> &__os,
167 const normal_distribution<_RT> &__x) {
169 __os.flags(std::ios_base::dec | std::ios_base::left | std::ios_base::fixed | std::ios_base::scientific);
170 _CharT __sp = __os.widen(' ');
171 __os.fill(__sp);
172 __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_;
173 if (__x._V_hot_)
174 __os << __sp << __x._V_;
175 return __os;
176}
177
178template <class _CharT, class _Traits, class _RT>
179std::basic_istream<_CharT, _Traits> &operator>>(std::basic_istream<_CharT, _Traits> &__is,
181 using _Eng = normal_distribution<_RT>;
182 using result_type = typename _Eng::result_type;
183 using param_type = typename _Eng::param_type;
185 __is.flags(std::ios_base::dec | std::ios_base::skipws);
186 result_type __mean;
187 result_type __stddev;
188 result_type _Vp = 0;
189 bool _V_hot = false;
190 __is >> __mean >> __stddev >> _V_hot;
191 if (_V_hot)
192 __is >> _Vp;
193 if (!__is.fail()) {
194 __x.param(param_type(__mean, __stddev));
195 __x._V_hot_ = _V_hot;
196 __x._V_ = _Vp;
197 }
198 return __is;
199}
200
201// Clean up macros
202#undef INLINE_VISIBILITY
203
204} // namespace Kernel
205} // namespace Mantid
std::ostream & operator<<(std::ostream &out, const MantidQt::MantidWidgets::IndexType< i > &index)
Definition: IndexTypes.h:103
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
Definition: System.h:53
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
typename __stream_type::fmtflags fmtflags
std::basic_ios< _CharT, _Traits > __stream_type
__save_flags(const __save_flags &)
INLINE_VISIBILITY ~__save_flags()
__save_flags & operator=(const __save_flags &)
INLINE_VISIBILITY __save_flags(__stream_type &__stream)
INLINE_VISIBILITY result_type stddev() const
friend INLINE_VISIBILITY bool operator!=(const param_type &__x, const param_type &__y)
INLINE_VISIBILITY param_type(result_type __mean=0, result_type __stddev=1)
friend INLINE_VISIBILITY bool operator==(const param_type &__x, const param_type &__y)
INLINE_VISIBILITY result_type mean() const
INLINE_VISIBILITY result_type operator()(_URNG &__g)
friend INLINE_VISIBILITY bool operator==(const normal_distribution &__x, const normal_distribution &__y)
INLINE_VISIBILITY result_type max() const
friend INLINE_VISIBILITY bool operator!=(const normal_distribution &__x, const normal_distribution &__y)
INLINE_VISIBILITY result_type stddev() const
INLINE_VISIBILITY normal_distribution(const param_type &__p)
INLINE_VISIBILITY result_type mean() const
INLINE_VISIBILITY normal_distribution(result_type __mean=0, result_type __stddev=1)
INLINE_VISIBILITY void param(const param_type &__p)
INLINE_VISIBILITY result_type min() const
result_type operator()(_URNG &__g, const param_type &__p)
INLINE_VISIBILITY param_type param() const
MANTID_API_DLL std::istream & operator>>(std::istream &istr, API::Boolean &)
Redaing a Boolean from an input stream.
Definition: Column.cpp:61
MANTID_KERNEL_DLL std::istream & operator>>(std::istream &, Interpolation &)
Reads in parameter value.
Helper class which provides the Collimation Length for SANS instruments.
STL namespace.
#define INLINE_VISIBILITY