RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
logistic.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <span>
4
9
10namespace randlib
11{
12
22template <typename RealType>
23class LogisticRand final : public ContinuousDistribution<RealType>
24{
25 RealType variate(detail::EngineRef g) const override { return (*this)(g); }
26
27 double mu = 0;
28 double s = 1;
29 double logS = 0;
30
31public:
32 LogisticRand(double location = 0, double scale = 1);
33
34 [[nodiscard]] std::string Name() const override;
35 [[nodiscard]] Support SupportType() const override { return Support::Infinite; }
36 [[nodiscard]] RealType MinValue() const override { return -INFINITY; }
37 [[nodiscard]] RealType MaxValue() const override { return INFINITY; }
38
39 void SetLocation(double location);
40 void SetScale(double scale);
41 [[nodiscard]] inline double GetLocation() const noexcept { return mu; }
42 [[nodiscard]] inline double GetScale() const noexcept { return s; }
43
44 [[nodiscard]] double f(const RealType &x) const override;
45 [[nodiscard]] double logf(const RealType &x) const override;
46 [[nodiscard]] double F(const RealType &x) const override;
47 [[nodiscard]] double S(const RealType &x) const override;
48 template <std::uniform_random_bit_generator G>
49 [[nodiscard]] RealType operator()(G &g) const;
50
51 [[nodiscard]] long double Mean() const override;
52 [[nodiscard]] long double Variance() const override;
53 [[nodiscard]] RealType Median() const override;
54 [[nodiscard]] RealType Mode() const override;
55 [[nodiscard]] long double Skewness() const override;
56 [[nodiscard]] long double ExcessKurtosis() const override;
57
58private:
59 RealType quantileImpl(double p) const override;
60 RealType quantileImpl1m(double p) const override;
61
62 std::complex<double> CFImpl(double t) const override;
63
64public:
65 [[nodiscard]] long double Entropy() const;
66
71 RANDLIB_DEPRECATED_FIT_MEMBER void FitLocation(std::span<const RealType> sample);
72};
73
74} // namespace randlib
75
77
78namespace randlib
79{
80
81template <typename RealType>
82LogisticRand<RealType>::LogisticRand(double location, double scale)
83{
84 SetLocation(location);
85 SetScale(scale);
86}
87
88template <typename RealType>
90{
91 return "Logistic(" + this->toStringWithPrecision(GetLocation()) + ", " + this->toStringWithPrecision(GetScale()) +
92 ")";
93}
94
95template <typename RealType>
97{
98 if (!std::isfinite(location))
99 throw std::invalid_argument("Logistic distribution: location should be finite");
100 mu = location;
101}
102
103template <typename RealType>
105{
106 if (!(scale > 0.0))
107 throw std::invalid_argument("Logistic distribution: scale of should be positive");
108 s = scale;
109 logS = std::log(s);
110}
111
112template <typename RealType>
113double LogisticRand<RealType>::f(const RealType &x) const
114{
116 double expMinusAbsZ = std::exp(-std::fabs(x - mu) / s);
117 double denominator = 1 + expMinusAbsZ;
118 return expMinusAbsZ / (denominator * denominator * s);
119}
120
121template <typename RealType>
122double LogisticRand<RealType>::logf(const RealType &x) const
123{
124 double x0 = (mu - x) / s;
125 double y = math::softplus(x0);
126 y *= 2;
127 y += logS;
128 return x0 - y;
129}
130
131template <typename RealType>
132double LogisticRand<RealType>::F(const RealType &x) const
133{
134 double expX = std::exp((mu - x) / s);
135 return 1.0 / (1 + expX);
136}
137
138template <typename RealType>
139double LogisticRand<RealType>::S(const RealType &x) const
140{
141 double expX = std::exp((mu - x) / s);
142 return expX / (1 + expX);
143}
144
145template <typename RealType>
146template <std::uniform_random_bit_generator G>
148{
150 return mu + s * std::log(1.0 / detail::uniform01<RealType>(g) - 1);
151}
152
153template <typename RealType>
155{
156 return mu;
157}
158
159template <typename RealType>
161{
162 double sPi = s * randlib::consts::pi;
163 return sPi * sPi / 3;
164}
165
166template <typename RealType>
167std::complex<double> LogisticRand<RealType>::CFImpl(double t) const
168{
169 double pist = randlib::consts::pi * s * t;
170 std::complex<double> y(0.0, t * mu);
171 y = std::exp(y);
172 y *= pist;
173 y /= std::sinh(pist);
174 return y;
175}
176
177template <typename RealType>
179{
180 return 2 + logS;
181}
182
183template <typename RealType>
184RealType LogisticRand<RealType>::quantileImpl(double p) const
185{
186 return mu - s * (std::log1pl(-p) - std::log(p));
187}
188
189template <typename RealType>
190RealType LogisticRand<RealType>::quantileImpl1m(double p) const
191{
192 return mu - s * (std::log(p) - std::log1pl(-p));
193}
194
195template <typename RealType>
197{
198 return mu;
199}
200
201template <typename RealType>
203{
204 return mu;
205}
206
207template <typename RealType>
209{
210 return 0;
211}
212
213template <typename RealType>
215{
216 return 1.2;
217}
218
219template <typename RealType>
220void LogisticRand<RealType>::FitLocation(std::span<const RealType> sample)
221{
222 double nHalf = 0.5 * sample.size();
223 RealType root = 0;
224 if (!math::findRootNewtonFirstOrder<RealType>(
225 [this, sample, nHalf](RealType m) {
226 double f1 = 0, f2 = 0;
227 for (const RealType &x : sample) {
228 double aux = std::exp((m - x) / s);
229 double denom = 1.0 + aux;
230 f1 += 1.0 / denom;
231 denom *= denom;
232 f2 -= aux / denom;
233 }
234 f1 -= nHalf;
235 return DoublePair(f1, f2);
236 },
237 root))
238 throw this->fitError(FitErrorCode::Undefined, "Error in root-finding procedure");
239 SetLocation(root);
240}
241
242} // namespace randlib
The ContinuousDistribution class Abstract class for all continuous distributions.
Definition continuous.hpp:22
The LogisticRand class Logistic distribution.
Definition logistic.hpp:24
double logf(const RealType &x) const override
Definition logistic.hpp:122
double F(const RealType &x) const override
Definition logistic.hpp:132
long double Skewness() const override
Definition logistic.hpp:208
long double ExcessKurtosis() const override
Definition logistic.hpp:214
void FitLocation(std::span< const RealType > sample)
fit location parameter via maximum-likelihood
Definition logistic.hpp:220
double GetScale() const noexcept
Definition logistic.hpp:42
double S(const RealType &x) const override
Definition logistic.hpp:139
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition logistic.hpp:202
long double Variance() const override
Definition logistic.hpp:160
long double Entropy() const
Definition logistic.hpp:178
void SetLocation(double location)
Definition logistic.hpp:96
long double Mean() const override
Definition logistic.hpp:154
RealType Median() const override
Definition logistic.hpp:196
double GetLocation() const noexcept
Definition logistic.hpp:41
RealType MinValue() const override
Definition logistic.hpp:36
double f(const RealType &x) const override
Definition logistic.hpp:113
RealType MaxValue() const override
Definition logistic.hpp:37
std::string Name() const override
Definition logistic.hpp:89
Support SupportType() const override
Definition logistic.hpp:35
RealType operator()(G &g) const
Definition logistic.hpp:147
void SetScale(double scale)
Definition logistic.hpp:104
LogisticRand(double location=0, double scale=1)
Definition logistic.hpp:82
virtual void sample(detail::EngineRef g, std::span< T > outputData) const
Fills the output with variate(g); distributions with a faster bulk algorithm override it.
Definition distribution.hpp:66
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
#define RANDLIB_DEPRECATED_FIT_MEMBER
Definition fwd.hpp:9
constexpr long double pi
Definition constants.hpp:22
Real standardNormal(G &g)
Ziggurat algorithm of Marsaglia and Tsang with 256 layers and an explicit sign bit.
Definition variates.hpp:45
Real softplus(Real x)
Definition functions.hpp:252
Definition bivariate_normal.hpp:10
@ Undefined
any other failure
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15
@ Infinite
(-∞, ∞)
Pair< double > DoublePair
Definition fwd.hpp:39