ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Calorimeter
CaloClusterCorrection
src
CaloClusterMLGaussianMixture.h
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#ifndef CALOCLUSTERCORRECTION_CALOCLUSTERMLCALIBGAUSSIANMIXTURE_H
6
#define CALOCLUSTERCORRECTION_CALOCLUSTERMLCALIBGAUSSIANMIXTURE_H
7
8
#include <cmath>
9
#include <vector>
10
#include <numeric>
11
#include <algorithm>
12
#include <limits>
13
14
namespace
CaloClusterMLCalib
15
{
16
constexpr
float
epsilon
= 1e-9;
// Introduced to avoid FPE DIVBYZERO warning in std::log()
17
18
// Helper function for logsumexp
19
float
log_sum_exp
(
const
std::vector<float> &
vec
)
20
{
21
if
(
vec
.empty())
22
{
23
return
-std::numeric_limits<float>::infinity();
24
}
25
float
max_val = *std::max_element(
vec
.begin(),
vec
.end());
26
float
sum = 0.0;
27
for
(
float
val :
vec
)
28
{
29
sum += std::exp(val - max_val);
30
}
31
return
max_val + std::log(sum);
32
}
33
34
float
log_likelihood
(
float
x
,
const
std::vector<float> &mus,
const
std::vector<float> &log_sigma2s,
const
std::vector<float> &alphas)
35
{
36
// Ensure vectors have the correct size
37
assert(mus.size() == 3 && log_sigma2s.size() == 3 && alphas.size() == 3);
38
39
std::vector<float> log_likelihood_components(3);
40
41
for
(
int
i = 0; i < 3; ++i)
42
{
43
// Calculate one-dimensional negative log-Gaussian
44
float
neg_log_gauss = std::pow(mus[i] -
x
, 2.0) / (2.0 * std::exp(log_sigma2s[i])) + 0.5 * log_sigma2s[i];
45
neg_log_gauss += 0.5 * std::log(2.0 *
M_PI
);
// M_PI is a common constant for pi
46
47
// log_prob_components = -neg_log_gauss_i + log(alpha_i)
48
log_likelihood_components[i] = -neg_log_gauss + std::log(alphas[i] +
epsilon
);
// Added epsilon to avoid FPE DIVBYZERO warning
49
}
50
51
// log_prob = log(sum_i exp(log_prob_components_i))
52
return
log_sum_exp
(log_likelihood_components);
53
}
54
55
float
modes
(
const
std::vector<float> &mus,
const
std::vector<float> &log_sigma2s,
const
std::vector<float> &alphas)
56
{
57
// Select range to check for maxima
58
float
x_min = 0.9 * (*std::min_element(mus.begin(), mus.end()));
59
float
x_max = 1.1 * (*std::max_element(mus.begin(), mus.end()));
60
61
// Create array of ranges to check for maxima
62
const
int
num_points = 1000;
63
std::vector<float> x_test(num_points);
64
float
step = (x_max - x_min) / (num_points - 1);
65
for
(
int
i = 0; i < num_points; ++i)
66
{
67
x_test[i] = x_min + i * step;
68
}
69
70
float
max_log_likelihood = -std::numeric_limits<float>::infinity();
71
float
mode = x_test[0];
// Initialize to first test point instead of 0
72
73
// Find the x-point with the largest likelihood value
74
for
(
float
x
: x_test)
75
{
76
float
ll =
log_likelihood
(
x
, mus, log_sigma2s, alphas);
77
if
(ll > max_log_likelihood)
78
{
79
max_log_likelihood = ll;
80
mode =
x
;
81
}
82
}
83
84
return
mode;
85
}
86
87
float
sigma_stoch
(
const
std::vector<float> &mus,
88
const
std::vector<float> &log_sigma2s,
89
const
std::vector<float> &alphas)
90
{
91
float
sigma_stoch2 = 0.0;
92
float
sum_alphas_mus = 0.0;
93
94
// This loop combines the first three lines of the Python function.
95
for
(
size_t
i = 0; i < mus.size(); ++i)
96
{
97
// Corresponds to: np.sum(alphas * sigma2s, axis=-1)
98
sigma_stoch2 += alphas[i] * std::exp(log_sigma2s[i]);
99
// Corresponds to: np.sum(alphas * np.power(mus, 2), axis=-1)
100
sigma_stoch2 += alphas[i] * std::pow(mus[i], 2);
101
// Accumulates sum for the final term: np.sum(alphas * mus, axis=-1)
102
sum_alphas_mus += alphas[i] * mus[i];
103
}
104
105
// Corresponds to: sigma_stoch2 -= np.power(np.sum(alphas * mus, axis=-1), 2)
106
sigma_stoch2 -= std::pow(sum_alphas_mus, 2);
107
108
// Corresponds to: return np.sqrt(sigma_stoch2)
109
return
std::sqrt(sigma_stoch2);
110
}
111
}
112
113
#endif
// CALOCLUSTERCORRECTION_CALOCLUSTERMLCALIBGAUSSIANMIXTURE_H
M_PI
#define M_PI
Definition
ActiveFraction.h:14
vec
std::vector< size_t > vec
Definition
CombinationsGeneratorTest.cxx:9
x
#define x
CaloClusterMLCalib
Definition
CaloClusterMLCalibFeatureTransform.h:16
CaloClusterMLCalib::modes
float modes(const std::vector< float > &mus, const std::vector< float > &log_sigma2s, const std::vector< float > &alphas)
Definition
CaloClusterMLGaussianMixture.h:55
CaloClusterMLCalib::log_likelihood
float log_likelihood(float x, const std::vector< float > &mus, const std::vector< float > &log_sigma2s, const std::vector< float > &alphas)
Definition
CaloClusterMLGaussianMixture.h:34
CaloClusterMLCalib::log_sum_exp
float log_sum_exp(const std::vector< float > &vec)
Definition
CaloClusterMLGaussianMixture.h:19
CaloClusterMLCalib::sigma_stoch
float sigma_stoch(const std::vector< float > &mus, const std::vector< float > &log_sigma2s, const std::vector< float > &alphas)
Definition
CaloClusterMLGaussianMixture.h:87
CaloClusterMLCalib::epsilon
constexpr float epsilon
Definition
CaloClusterMLGaussianMixture.h:16
Generated on
for ATLAS Offline Software by
1.17.0