quant-pricer-cpp
Loading...
Searching...
No Matches
math.hpp
Go to the documentation of this file.
1
2#pragma once
3
4#include <cmath>
5#include <limits>
6#include <numbers>
7
8namespace quant::math {
9
11inline constexpr double kZ95 = 1.95996398454005423552;
12
15inline double inverse_normal_cdf(double p) {
16 if (p <= 0.0)
17 return -INFINITY;
18 if (p >= 1.0)
19 return INFINITY;
20
21 // Coefficients from Peter J. Acklam's approximation
22 static const double a1 = -3.969683028665376e+01;
23 static const double a2 = 2.209460984245205e+02;
24 static const double a3 = -2.759285104469687e+02;
25 static const double a4 = 1.383577518672690e+02;
26 static const double a5 = -3.066479806614716e+01;
27 static const double a6 = 2.506628277459239e+00;
28
29 static const double b1 = -5.447609879822406e+01;
30 static const double b2 = 1.615858368580409e+02;
31 static const double b3 = -1.556989798598866e+02;
32 static const double b4 = 6.680131188771972e+01;
33 static const double b5 = -1.328068155288572e+01;
34
35 static const double c1 = -7.784894002430293e-03;
36 static const double c2 = -3.223964580411365e-01;
37 static const double c3 = -2.400758277161838e+00;
38 static const double c4 = -2.549732539343734e+00;
39 static const double c5 = 4.374664141464968e+00;
40 static const double c6 = 2.938163982698783e+00;
41
42 static const double d1 = 7.784695709041462e-03;
43 static const double d2 = 3.224671290700398e-01;
44 static const double d3 = 2.445134137142996e+00;
45 static const double d4 = 3.754408661907416e+00;
46
47 const double plow = 0.02425;
48 const double phigh = 1.0 - plow;
49 double q, r, x;
50 if (p < plow) {
51 q = std::sqrt(-2.0 * std::log(p));
52 x = (((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) /
53 ((((d1 * q + d2) * q + d3) * q + d4) * q + 1.0);
54 } else if (p <= phigh) {
55 q = p - 0.5;
56 r = q * q;
57 x = (((((a1 * r + a2) * r + a3) * r + a4) * r + a5) * r + a6) * q /
58 (((((b1 * r + b2) * r + b3) * r + b4) * r + b5) * r + 1.0);
59 } else {
60 q = std::sqrt(-2.0 * std::log(1.0 - p));
61 x = -(((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) /
62 ((((d1 * q + d2) * q + d3) * q + d4) * q + 1.0);
63 }
64
65 // One Halley refinement
66 double e = 0.5 * std::erfc(-x / std::sqrt(2.0)) - p;
67 double u = e * std::sqrt(2.0 * std::numbers::pi) * std::exp(0.5 * x * x);
68 x = x - u / (1.0 + 0.5 * x * u);
69 return x;
70}
71
72} // namespace quant::math
double q
Definition bs_barrier_rr.cpp:18
double r
Definition bs_barrier_rr.cpp:17
Common mathematical utilities shared across engines.
Definition math.hpp:8
double inverse_normal_cdf(double p)
Definition math.hpp:15
constexpr double kZ95
95% two-sided normal quantile used for confidence intervals
Definition math.hpp:11