Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
test_profiling.cpp
Go to the documentation of this file.
1#include "ILikelihood.h"
2#include "BaseLikelihood.h"
5#include "Profiler.h"
7#include "GaussianMarginal.h"
8#include "GaussianCopula.h"
9#include "Math.h"
10#include "ContourEngine.h"
11
12int main() {
13 unsigned long seed = 1234567890;
14
15 auto model_fn = [] (const std::vector<double>& p, const std::vector<double> eta) {
16 double a = p[0];
17 double b = p[1];
18 double c = p[2];
19 double d = eta[0];
20 double e = eta[1];
21
22 auto f = [a, b, c, d, e] (double x, double y) {
23 return a * x * x + b * y * y + c * x * y + d * x + e * y;
24 };
25
26 return std::vector<double> ({f(1, 0), f(0, 1), f(1, 1), f(-1, 0), f(0, -1), f(-1, -1), f(1, -1), f(-1, 1)});
27 };
28
29 std::vector<std::unique_ptr<IMarginalDistribution>> nuis_marginals;
30 nuis_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>(3, 1, seed)));
31 nuis_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>(-1, 0.5, seed)));
32
33 RealMatrix R_nuis ({
34 {1, 0.1},
35 {0.1, 1}
36 });
37
38 std::unique_ptr<ICopula> nuis_copula = std::make_unique<GaussianCopula>(seed, R_nuis);
39 std::unique_ptr<JointDistribution> nuis_dist = std::make_unique<JointDistribution>(std::move(nuis_marginals), std::move(nuis_copula));
40
41 std::vector<std::unique_ptr<IMarginalDistribution>> obs_marginals;
42 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.1, seed)));
43 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.3, seed)));
44 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.2, seed)));
45 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.1, seed)));
46 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.3, seed)));
47 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.2, seed)));
48 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.5, seed)));
49 obs_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>( 0, 0.3, seed)));
50
51 RealMatrix R_obs ({
52 {1, 0, 0.1, 0, 0, 0, 0, 0},
53 {0, 1, 0, 0, 0, 0, 0.5, 0},
54 {0.1, 0, 1, 0, 0, 0, 0, 0},
55 {0, 0, 0, 1, 0, 0, 0, 0},
56 {0, 0, 0, 0, 1, 0, 0, 0},
57 {0, 0, 0, 0, 0, 1, 0, 0},
58 {0, 0.5, 0, 0, 0, 0, 1, 0.1},
59 {0, 0, 0, 0, 0, 0, 0.1, 1}
60 });
61
62 std::unique_ptr<ICopula> obs_copula = std::make_unique<GaussianCopula>(seed, R_obs);
63 std::unique_ptr<JointDistribution> obs_dist = std::make_unique<JointDistribution>(std::move(obs_marginals), std::move(obs_copula));
64
65 std::shared_ptr<LikelihoodContext> ctx = std::make_shared<LikelihoodContext>();
66 ctx->exp_obs_dist = std::move(obs_dist);
67 ctx->nuisance_dist = std::move(nuis_dist);
68 ctx->exp_obs_values = {5, 0, 3, -1, 2, -1, 9, 1};
69 ctx->nuis_defs = {
70 fit_app::ParameterDefinition {"d", 3.0, 1.0},
71 fit_app::ParameterDefinition {"e", -1.0, 0.5}
72 };
73 ctx->fp_defs = {
77 };
78
79 std::shared_ptr<ILikelihood> base = std::make_shared<BaseLikelihood>(model_fn, ctx, 3);
80
81 std::cout << "Base likelihood:" << std::endl;
82 std::cout << "dim = " << base->dim() << std::endl;
83 std::cout << "nll(2, 1, -2, 3, -1) = " << base->nll({2, 1, -2, 3, -1}) << std::endl;
84
85 auto of = [base] (std::vector<double> theta) {
86 return base->nll(theta);
87 };
88
89 MinimizationContext min_ctx;
90 MinimizationResult res = minimize_combined(of, {0, 0, 0, 3.0, -1.0}, {1, 1, 1, 1, 1}, min_ctx);
91
92 auto of_profiled = [base, min_ctx] (std::vector<double> p) {
93 auto wrapped = [base, p] (std::vector<double> eta) {
94 std::vector<double> theta = p;
95 theta.insert(theta.end(), eta.begin(), eta.end());
96 return base->nll(theta);
97 };
98
99 return minimize_combined(wrapped, {3, -1}, {1, 1}, min_ctx).min;
100 };
101
102 RealMatrix cov = inverse_hessian(of_profiled, {res.argmin[0], res.argmin[1], res.argmin[2]}, {1, 1, 1});
103
104 RealMatrix corr = cov;
105 for (size_t i = 0; i < 3; i++) {
106 for (size_t j = 0; j < 3; j++)
107 corr.at(i, j) /= std::sqrt(cov.at(i, i) * cov.at(j, j));
108 }
109
110 FitResult fr;
111 fr.ell_hat = res.min;
112 fr.eta_hat = {res.argmin[3], res.argmin[4]};
113 fr.p_hat = {res.argmin[0], res.argmin[1], res.argmin[2]};
114 fr.p_hat_std = {std::sqrt(cov.at(0, 0)), std::sqrt(cov.at(1, 1)), std::sqrt(cov.at(2, 2))};
115 fr.p_hat_correlations = corr;
116
117 std::cout << "Toy master fit:" << std::endl;
118 std::cout << "min nll =" << fr.ell_hat << std::endl;
119 std::cout << "p_hat = (" << fr.p_hat[0] << ", " << fr.p_hat[1] << ", " << fr.p_hat[2] << ")" << std::endl;
120 std::cout << "eta_hat = (" << fr.eta_hat[0] << ", " << fr.eta_hat[1] << ")" << std::endl;
121 std::cout << "p_hat_std = (" << fr.p_hat_std[0] << ", " << fr.p_hat_std[1] << ", " << fr.p_hat_std[2] << ")" << std::endl;
122 std::cout << "p_hat_corr:" << std::endl;
123 std::cout << fr.p_hat_correlations << std::endl;
124
125
126 // std::shared_ptr<Profiler> profiler = std::make_shared<Profiler>(fit_app::make_minuit_backend());
127 // std::shared_ptr<IProfilingStrategy> slice = std::make_shared<SliceProfilingStrategy>(0, 1, fr);
128 // std::shared_ptr<IProfilingStrategy> project = std::make_shared<ProjectionProfilingStrategy>(0, 1, fr);
129
130 // ProfiledLikelihood2D pl_1 (base, profiler, slice);
131 // ProfiledLikelihood2D pl_2 (base, profiler, project);
132
133 // std::vector<std::unique_ptr<IMarginalDistribution>> fitted_marginals;
134 // fitted_marginals.emplace_back(std::move(std::make_unique<GaussianMarginal>(fr.p_hat[2], fr.p_hat_std[2], seed)));
135
136 // RealMatrix R_fitted = eye(1);
137
138 // std::unique_ptr<ICopula> fitted_copula = std::make_unique<GaussianCopula>(seed, R_fitted);
139 // std::unique_ptr<JointDistribution> fitted_dist = std::make_unique<JointDistribution>(std::move(fitted_marginals), std::move(fitted_copula));
140 // std::shared_ptr<ILikelihood> constrained_base = std::make_shared<WithGaussianConstraints>(base, std::move(fitted_dist), std::vector<std::size_t> ({2}));
141
142 // ProfiledLikelihood2D pl_3 (constrained_base, profiler, project);
143
144 // double ell_hat_1 = pl_1.profiled_nll(2.1, 0.9);
145 // double ell_hat_2 = pl_2.profiled_nll(2.1, 0.9);
146 // double ell_hat_3 = pl_3.profiled_nll(2.1, 0.9);
147
148 // std::cout << "Profiled likelihoods:" << std::endl;
149 // std::cout << "Method 1 (Slice):" << ell_hat_1 << std::endl;
150 // std::cout << "Method 2 (Free projection):" << ell_hat_2 << std::endl;
151 // std::cout << "Method 3 (Prior-constrained projection):" << ell_hat_3 << std::endl;
152
153 ContourConfig cc;
154 cc.fr = fr;
155 cc.x_id = 0;
156 cc.y_id = 1;
158 // cc.fallback_contour_method = ContourAlgorithm::AMS;
160
161 ContourEngine ce(base, cc);
162 Contour cl = ce.compute_contour(1.0, {1.8, 2.2, 0.8, 1.2}, 200);
163
164 std::ofstream os;
165 os.open("contour_proj_constrained.csv");
166 os << "x,y\n";
167 for(const Path& path: cl.paths) {
168 for (const Point& point: path) {
169 os << point.first << "," << point.second << "\n";
170 }
171 }
172
173 os.close();
174
175 return 0;
176}
Concrete profileable likelihood built from a model and joint distributions.
High-level engine for profiled two-dimensional likelihood contours.
@ MINUIT
Minuit contour extractor.
@ SLICE
Fix all fit parameters except nuisances; scan only the selected axes.
Gaussian copula implementation.
Abstract interface for likelihood functions used by the fitting layer.
Profiling strategies used to build two-dimensional likelihood scan requests.
Two-dimensional profiled likelihood wrapper.
Generic likelihood profiling engine.
Likelihood decorator adding an external Gaussian constraint term.
Orchestrates profiled likelihood contour computation.
Contour compute_contour(double z, std::array< double, 4 > bounds, std::size_t resolution)
Computes a profiled 2D contour for a requested significance.
double & at(size_t i, size_t j)
Returns a mutable reference to element (i,j) with bounds checking.
Definition Matrix.cpp:587
std::vector< Point > Path
Definition contour.h:16
std::pair< double, double > Point
Definition contour.h:13
RealMatrix inverse_hessian(const RealValuedForm &f, const std::vector< double > &x, const std::vector< double > &scales)
Definition diffcalc.cpp:90
MinimizationResult minimize_combined(RealValuedForm f, const std::vector< double > &x0, const std::vector< double > &scales, const MinimizationContext &context)
double f(double x)
Wilson special function f depending on x.
Configuration object for ContourEngine.
ProfilingMethod profiling_method
Profiling strategy used for non-displayed parameters.
std::size_t x_id
std::size_t y_id
Indices of the two fit parameters displayed on the contour axes.
ContourAlgorithm primary_contour_method
Primary contour extraction algorithm.
FitResult fr
Global fit result used for central values, uncertainties, and correlations.
Output of a contour extraction algorithm.
std::set< Path > paths
Extracted contour paths.
Summary of a global likelihood fit.
std::vector< double > p_hat_std
Standard deviations of the parameters of interest.
std::vector< double > eta_hat
Nuisance estimates at the global maximum-likelihood point.
std::vector< double > p_hat
Maximum-likelihood estimates for parameters of interest.
RealMatrix p_hat_correlations
Correlation matrix for the parameters of interest.
double ell_hat
Minimum NLL value at the global best-fit point.
std::vector< double > argmin
int main()