25 template <BoundIndices Idx>
31 template <BoundIndices Idx>
38 template <Surface::SurfaceType type_t>
40 using Desc = std::tuple<CyclicAngle<eBoundPhi>>;
56 template <
typename Callable>
58 switch (surface.
type()) {
64 return callable(desc);
68 return callable(desc);
72 return callable(desc);
78 typename angle_desc_t>
81 projector_t &&projector,
82 const angle_desc_t &angleDesc) {
85 for (
const auto &
cmp : components) {
86 const auto &[weight_l, pars_l, cov_l] = projector(
cmp);
88 cov += weight_l * cov_l;
93 auto handleCyclicCov = [&l = pars_l, &
m =
mean, &diff = diff](
auto desc) {
96 m[desc.idx] / desc.constant, 2 * M_PI) *
100 std::apply([&](
auto... dsc) { (handleCyclicCov(dsc), ...); }, angleDesc);
102 cov += weight_l * diff * diff.transpose();
129 projector_t &&projector = projector_t{},
130 const angle_desc_t &angleDesc = angle_desc_t{}) {
132 const auto &[beginWeight, beginPars, beginCov] =
133 projector(components.front());
136 using ParsType = std::decay_t<decltype(beginPars)>;
137 using CovType = std::decay_t<decltype(beginCov)>;
138 using WeightType = std::decay_t<decltype(beginWeight)>;
140 constexpr
int D = ParsType::RowsAtCompileTime;
141 EIGEN_STATIC_ASSERT_VECTOR_ONLY(ParsType);
142 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(CovType, D, D);
143 static_assert(std::is_floating_point_v<WeightType>);
147 #if defined(__GNUC__) && __GNUC__ < 9 && !defined(__clang__)
151 [&](
auto... d) { static_assert((std::less<int>{}(d.idx, D) && ...)); },
156 using RetType = std::tuple<ActsVector<D>, ActsSquareMatrix<D>>;
159 if (components.size() == 1) {
160 return RetType{beginPars / beginWeight, beginCov / beginWeight};
164 ActsVector<D>
mean = ActsVector<D>::Zero();
165 WeightType sumOfWeights{0.0};
167 for (
const auto &
cmp : components) {
168 const auto &[weight_l, pars_l, cov_l] = projector(
cmp);
170 sumOfWeights += weight_l;
171 mean += weight_l * pars_l;
174 auto handleCyclicMean = [&
ref = beginPars, &
pars = pars_l,
175 &weight = weight_l, &mean =
mean](
auto desc) {
176 const auto delta = (
ref[desc.idx] - pars[desc.idx]) / desc.constant;
179 mean[desc.idx] += (2 * M_PI) * weight * desc.constant;
180 }
else if (
delta < -M_PI) {
181 mean[desc.idx] -= (2 * M_PI) * weight * desc.constant;
185 std::apply([&](
auto... dsc) { (handleCyclicMean(dsc), ...); }, angleDesc);
188 mean /= sumOfWeights;
190 auto wrap = [&](
auto desc) {
192 wrap_periodic(mean[desc.idx] / desc.constant, -M_PI, 2 * M_PI) *
196 std::apply([&](
auto... dsc) { (wrap(dsc), ...); }, angleDesc);
203 return RetType{
mean, cov};
222 template <
typename mixture_t,
typename projector_t = Acts::Identity>
225 projector_t &&projector = projector_t{}) {
226 using R = std::tuple<Acts::BoundVector, Acts::BoundSquareMatrix>;
232 if (method == MixtureReductionMethod::eMean) {
235 const auto maxWeightIt = std::max_element(
236 mixture.begin(), mixture.end(), [&](
const auto &
a,
const auto &
b) {
237 return std::get<0>(projector(
a)) < std::get<0>(projector(
b));
239 const BoundVector meanMaxWeight = std::get<1>(projector(*maxWeightIt));
241 return R{meanMaxWeight,
cov};