Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
GaussianCopula.cpp
Go to the documentation of this file.
1#include "GaussianCopula.h"
2
4 this->R = nearest_psd(R);
5 this->L = cholesky_L(this->R);
6 this->logdet = this->R.slogdet().logdet;
7 this->R_inv = this->R.inv();
8}
9
10std::vector<std::vector<double>> GaussianCopula::sample_u(std::size_t n) {
11 std::vector<std::vector<double>> U;
12
13 for (std::size_t i = 0; i < n; i++) {
14 U.emplace_back(sample_u());
15 }
16
17 return U;
18}
19
20std::vector<double> GaussianCopula::sample_u() {
21 std::size_t d = L.cols();
22
23 RealMatrix z (d, 1);
24 for (std::size_t j = 0; j < d; j++) {
25 z.at(j, 0) = gsl_ran_ugaussian(eng_.get()); // z follows MN(0, 1)
26 }
27
28 z = L * z; // z follows MN(0, R)
29 std::vector<double> u (d, 0.0);
30 for (std::size_t j = 0; j < d; j++) {
31 u[j] = std::clamp(gsl_cdf_ugaussian_P(z.at(j, 0)), CLIP_U, 1 - CLIP_U); // u follows C(R)
32 }
33
34 return u;
35}
36
38 std::size_t d = u.size();
39 RealMatrix z (d, 1);
40
41 for (size_t i = 0; i < d; i++) {
42 z.at(i, 0) = gsl_cdf_ugaussian_Pinv(std::clamp(u[i], 1e-13, 1. - 1e-13));
43 }
44
45 // return -0.5 * logdet - 0.5 * (z.transpose() * (R_inv - eye(d)) * z).at(0, 0);
46 return -0.5 * (z.transpose() * (R_inv - eye(d)) * z).at(0, 0);
47}
48
50 std::size_t d = u.size();
51 RealMatrix z (d, 1);
52
53 for (size_t i = 0; i < d; i++) {
54 z.at(i, 0) = gsl_cdf_ugaussian_Pinv(std::clamp(u[i], 1e-13, 1. - 1e-13));
55 }
56
57 RealMatrix Az = (R_inv - eye(d)) * z;
58 RealMatrix dlogc (-Az);
59 for (size_t i = 0; i < d; i++) {
60 dlogc.at(i, 0) /= gsl_ran_ugaussian_pdf(z.at(i, 0));
61 }
62
63 return dlogc;
64}
65
67 std::size_t d = u.size();
68 RealMatrix z (d, 1);
69
70 for (size_t i = 0; i < d; i++) {
71 z.at(i, 0) = gsl_cdf_ugaussian_Pinv(std::clamp(u[i], 1e-13, 1. - 1e-13));
72 }
73
74 RealMatrix A = R_inv - eye(d);
75 RealMatrix Az = A * z;
76 RealMatrix ddlogc (d, d);
77 for (size_t i = 0; i < d; i++) {
78 for (size_t j = 0; j < d; j++) {
79 double num = -A.at(i, j);
80 if (i == j) num -= Az.at(i, 0) * z.at(i, 0);
81 double den = gsl_ran_ugaussian_pdf(z.at(i, 0)) * gsl_ran_ugaussian_pdf(z.at(j, 0));
82 ddlogc.at(i, j) = num / den;
83 }
84 }
85
86 return ddlogc;
87}
88
90 std::size_t d = u.size();
91 RealMatrix z (d, 1);
92 Vector phi_z (d, 0.0);
93
94 for (size_t i = 0; i < d; i++) {
95 z.at(i, 0) = gsl_cdf_ugaussian_Pinv(std::clamp(u[i], 1e-13, 1. - 1e-13));
96 phi_z[i] = gsl_ran_ugaussian_pdf(z.at(i, 0));
97 }
98
99 RealMatrix A = R_inv - eye(d);
100 RealMatrix Az = A * z;
101 RealMatrix dlogc (d, 1);
102 RealMatrix ddlogc (d, d);
103
104 double log_c = -0.5 * (z.transpose() * Az).at(0, 0);
105 for (size_t i = 0; i < d; i++) {
106 dlogc.at(i, 0) = -Az.at(i, 0) / phi_z[i];
107
108 for (size_t j = 0; j < d; j++) {
109 double num = -A.at(i, j);
110 if (i == j) num -= Az.at(i, 0) * z.at(i, 0);
111 double den = phi_z[i] * phi_z[j];
112 ddlogc.at(i, j) = num / den;
113 }
114 }
115
116 return {log_c, dlogc, ddlogc};
117}
Gaussian copula implementation.
constexpr double CLIP_U
Small clipping threshold used to avoid exact 0 or 1 uniforms.
RealMatrix nearest_psd(RealMatrix R, double thr)
Projects a matrix to the nearest positive semi-definite correlation-like matrix.
Definition Matrix.cpp:475
RealMatrix eye(std::size_t n)
Returns the identity matrix of size n.
Definition Matrix.cpp:453
RealMatrix cholesky_L(RealMatrix R)
Returns the lower-triangular Cholesky factor of a PSD matrix.
Definition Matrix.cpp:508
Vector sample_u() override
Draws a single sample from the copula.
LogDensityDiff log_c_dc_ddc(std::vector< double > u) override
Computes the log-density and its first and second derivatives.
double log_density(Vector u) override
Evaluates the log-density of the copula at a point in the unit cube.
GaussianCopula(unsigned int seed, RealMatrix R)
Constructs a Gaussian copula from a correlation matrix.
RealMatrix ddlog_density(std::vector< double > u) override
Computes the Hessian of the Gaussian copula log-density.
RealMatrix dlog_density(std::vector< double > u) override
Computes the gradient of the Gaussian copula log-density.
Partial base implementation of a copula with RNG support.
gsl_rng_sptr eng_
GSL RNG type used by the copula.
double & at(size_t i, size_t j)
Returns a mutable reference to element (i,j) with bounds checking.
Definition Matrix.cpp:587
SignedLogDet slogdet() const
Computes the signed logarithmic determinant via LU decomposition.
Definition Matrix.cpp:731
std::size_t cols() const
Returns the number of columns.
Definition Matrix.cpp:605
RealMatrix transpose() const
Returns the transpose of the matrix.
Definition Matrix.cpp:698
RealMatrix inv() const
Computes the inverse of the matrix via LU decomposition.
Definition Matrix.cpp:750
std::vector< double > Vector
double logdet
Definition Matrix.h:118