QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
normaldistribution.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2002, 2003 Ferdinando Ametrano
5 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
6 Copyright (C) 2010 Kakhkhor Abdijalilov
7
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
26#ifndef quantlib_normal_distribution_hpp
27#define quantlib_normal_distribution_hpp
28
29#include <ql/math/errorfunction.hpp>
30#include <ql/errors.hpp>
31
32namespace QuantLib {
33
35
45 public:
49 QL_DEPRECATED
51
55 QL_DEPRECATED
57
58 NormalDistribution(Real average = 0.0,
59 Real sigma = 1.0);
60 // function
61 Real operator()(Real x) const;
62 Real derivative(Real x) const;
63 private:
66 };
67
69
70
72
81 public:
85 QL_DEPRECATED
87
91 QL_DEPRECATED
93
95 Real sigma = 1.0);
96 // function
97 Real operator()(Real x) const;
98 Real derivative(Real x) const;
99 private:
103 };
104
105
107
125 public:
129 QL_DEPRECATED
131
135 QL_DEPRECATED
137
138 InverseCumulativeNormal(Real average = 0.0,
139 Real sigma = 1.0);
140 // function
142 return average_ + sigma_*standard_value(x);
143 }
144 // value for average=0, sigma=1
145 /* Compared to operator(), this method avoids 2 floating point
146 operations (we use average=0 and sigma=1 most of the
147 time). The speed difference is noticeable.
148 */
150 Real z;
151 if (x < x_low_ || x_high_ < x) {
152 z = tail_value(x);
153 } else {
154 z = x - 0.5;
155 Real r = z*z;
156 z = (((((a1_*r+a2_)*r+a3_)*r+a4_)*r+a5_)*r+a6_)*z /
157 (((((b1_*r+b2_)*r+b3_)*r+b4_)*r+b5_)*r+1.0);
158 }
159
160 // The relative error of the approximation has absolute value less
161 // than 1.15e-9. One iteration of Halley's rational method (third
162 // order) gives full machine precision.
163 // #define REFINE_TO_FULL_MACHINE_PRECISION_USING_HALLEYS_METHOD
164 #ifdef REFINE_TO_FULL_MACHINE_PRECISION_USING_HALLEYS_METHOD
165 // error (f_(z) - x) divided by the cumulative's derivative
166 const Real r = (f_(z) - x) * M_SQRT2 * M_SQRTPI * exp(0.5 * z*z);
167 // Halley's method
168 z -= r/(1+0.5*z*r);
169 #endif
170
171 return z;
172 }
173 private:
174 /* Handling tails moved into a separate method, which should
175 make the inlining of operator() and standard_value method
176 easier. tail_value is called rarely and doesn't need to be
177 inlined.
178 */
179 static Real tail_value(Real x);
180 #if defined(QL_PATCH_SOLARIS)
182 #else
184 #endif
186 static const Real a1_;
187 static const Real a2_;
188 static const Real a3_;
189 static const Real a4_;
190 static const Real a5_;
191 static const Real a6_;
192 static const Real b1_;
193 static const Real b2_;
194 static const Real b3_;
195 static const Real b4_;
196 static const Real b5_;
197 static const Real c1_;
198 static const Real c2_;
199 static const Real c3_;
200 static const Real c4_;
201 static const Real c5_;
202 static const Real c6_;
203 static const Real d1_;
204 static const Real d2_;
205 static const Real d3_;
206 static const Real d4_;
207 static const Real x_low_;
208 static const Real x_high_;
209 };
210
211 // backward compatibility
213
215
235 public:
239 QL_DEPRECATED
241
245 QL_DEPRECATED
247
248 MoroInverseCumulativeNormal(Real average = 0.0,
249 Real sigma = 1.0);
250 // function
251 Real operator()(Real x) const;
252 private:
254 static const Real a0_;
255 static const Real a1_;
256 static const Real a2_;
257 static const Real a3_;
258 static const Real b0_;
259 static const Real b1_;
260 static const Real b2_;
261 static const Real b3_;
262 static const Real c0_;
263 static const Real c1_;
264 static const Real c2_;
265 static const Real c3_;
266 static const Real c4_;
267 static const Real c5_;
268 static const Real c6_;
269 static const Real c7_;
270 static const Real c8_;
271 };
272
274
287 public:
291 QL_DEPRECATED
293
297 QL_DEPRECATED
299
301 Real sigma = 1.0);
302 Real operator()(Real x) const;
303
304 private:
306 };
307
310 public:
314 QL_DEPRECATED
316
320 QL_DEPRECATED
322
323 MaddockCumulativeNormal(Real average = 0.0,
324 Real sigma = 1.0);
325 Real operator()(Real x) const;
326
327 private:
329 };
330
331
332 // inline definitions
333
335 Real sigma)
336 : average_(average), sigma_(sigma) {
337
338 QL_REQUIRE(sigma_>0.0,
339 "sigma must be greater than 0.0 ("
340 << sigma_ << " not allowed)");
341
342 normalizationFactor_ = M_SQRT_2*M_1_SQRTPI/sigma_;
345 }
346
348 Real deltax = x-average_;
349 Real exponent = -(deltax*deltax)/denominator_;
350 // debian alpha had some strange problem in the very-low range
351 return exponent <= -690.0 ? 0.0 : // exp(x) < 1.0e-300 anyway
352 Real(normalizationFactor_*std::exp(exponent));
353 }
354
356 return ((*this)(x) * (average_ - x)) / derNormalizationFactor_;
357 }
358
360 Real average, Real sigma)
361 : average_(average), sigma_(sigma) {
362
363 QL_REQUIRE(sigma_>0.0,
364 "sigma must be greater than 0.0 ("
365 << sigma_ << " not allowed)");
366 }
367
369 Real xn = (x - average_) / sigma_;
370 return gaussian_(xn) / sigma_;
371 }
372
374 Real average, Real sigma)
375 : average_(average), sigma_(sigma) {
376
377 QL_REQUIRE(sigma_>0.0,
378 "sigma must be greater than 0.0 ("
379 << sigma_ << " not allowed)");
380 }
381
383 Real average, Real sigma)
384 : average_(average), sigma_(sigma) {
385
386 QL_REQUIRE(sigma_>0.0,
387 "sigma must be greater than 0.0 ("
388 << sigma_ << " not allowed)");
389 }
390
391}
392
393
394#endif
Cumulative normal distribution function.
CumulativeNormalDistribution(Real average=0.0, Real sigma=1.0)
QL_DEPRECATED typedef Real argument_type
Inverse cumulative normal distribution function.
InverseCumulativeNormal(Real average=0.0, Real sigma=1.0)
static const CumulativeNormalDistribution f_
QL_DEPRECATED typedef Real argument_type
QL_DEPRECATED typedef Real result_type
Maddock's cumulative normal distribution class.
QL_DEPRECATED typedef Real argument_type
QL_DEPRECATED typedef Real result_type
Maddock's Inverse cumulative normal distribution class.
Moro Inverse cumulative normal distribution class.
QL_DEPRECATED typedef Real argument_type
MoroInverseCumulativeNormal(Real average=0.0, Real sigma=1.0)
Normal distribution function.
NormalDistribution(Real average=0.0, Real sigma=1.0)
QL_DEPRECATED typedef Real argument_type
QL_DEPRECATED typedef Real result_type
QL_REAL Real
real number
Definition: types.hpp:50
Definition: any.hpp:35
InverseCumulativeNormal InvCumulativeNormalDistribution
NormalDistribution GaussianDistribution