9 #include <boost/test/unit_test.hpp>
35 #include <initializer_list>
43 #include <Eigen/Eigenvalues>
45 #define CHECK_CLOSE_MATRIX(a, b, t) \
46 BOOST_CHECK(((a - b).array().abs() < t).all())
49 using namespace Acts::UnitLiterals;
61 template <
typename T,
int D>
64 using Vector = Eigen::Matrix<T, D, 1>;
65 using Matrix = Eigen::Matrix<T, D, D>;
74 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eigenSolver(boundCov);
76 eigenSolver.eigenvalues().cwiseSqrt().asDiagonal();
79 template <
typename generator_t>
81 std::normal_distribution<T> normal;
90 std::size_t n_samples, std::mt19937 &
gen) {
93 std::vector<MultiNormal> dists;
94 std::vector<double> weights;
95 for (
const auto &
cmp : cmps) {
96 dists.push_back(MultiNormal(
cmp.boundPars,
cmp.boundCov));
97 weights.push_back(
cmp.weight);
100 std::discrete_distribution choice(weights.begin(), weights.end());
102 auto sample = [&]() {
103 const auto n = choice(gen);
104 return dists[
n](
gen);
107 std::vector<ActsVector<D>> samples(n_samples);
108 std::generate(samples.begin(), samples.end(), sample);
118 for (
const auto &
x : samples) {
122 return mean / samples.size();
132 for (
const auto &
s : samples) {
133 for (
int i = 0;
i <
D; ++
i) {
134 x[
i] += std::cos(
s[
i]);
135 y[
i] += std::sin(
s[i]);
141 for (
int i = 0;
i <
D; ++
i) {
142 mean[
i] = std::atan2(y[
i], x[i]);
150 template <
int D,
typename subtract_t = std::minus<ActsVector<D>>>
156 for (
const auto &smpl : samples) {
157 boundCov += sub(smpl, mu) * sub(smpl, mu).transpose();
160 return boundCov / samples.size();
171 auto x = 0.0,
y = 0.0;
174 for (
const auto &
cmp : cmps) {
179 for (
auto &
cmp : cmps) {
185 throw std::runtime_error(
"Cone surface not supported");
190 for (
const auto &
cmp : cmps) {
205 mean.head<3>() = intersection.position();
216 template <
typename angle_description_t>
218 const LocPosArray &loc_pos,
double expectedError) {
221 for (
auto phi : {-175_degree, 0_degree, 175_degree}) {
222 for (
auto theta : {5_degree, 90_degree, 175_degree}) {
224 std::vector<DummyComponent<eBoundSize>> cmps;
226 auto p_it = loc_pos.begin();
228 for (
auto dphi : {-10_degree, 10_degree}) {
229 for (
auto dtheta : {-5_degree, 5_degree}) {
240 a.
boundCov = BoundSquareMatrix::Zero();
247 const auto [mean_approx, cov_approx] =
258 std::mt19937
gen(42);
259 std::vector<DummyComponent<2>> cmps(2);
261 cmps[0].boundPars << 1.0, 1.0;
262 cmps[0].boundCov << 1.0, 0.0, 0.0, 1.0;
263 cmps[0].weight = 0.5;
265 cmps[1].boundPars << -2.0, -2.0;
266 cmps[1].boundCov << 1.0, 1.0, 1.0, 2.0;
267 cmps[1].weight = 0.5;
270 const auto mean_data =
mean(samples);
271 const auto boundCov_data =
boundCov(samples, mean_data);
273 const auto [mean_test, boundCov_test] =
281 std::mt19937
gen(42);
282 std::vector<DummyComponent<2>> cmps(2);
284 cmps[0].boundPars << 175_degree, 5_degree;
285 cmps[0].boundCov << 20_degree, 0.0, 0.0, 20_degree;
286 cmps[0].weight = 0.5;
288 cmps[1].boundPars << -175_degree, -5_degree;
289 cmps[1].boundCov << 20_degree, 20_degree, 20_degree, 40_degree;
290 cmps[1].weight = 0.5;
294 const auto boundCov_data =
boundCov(samples, mean_data, [](
auto a,
auto b) {
296 for (
int i = 0;
i < 2; ++
i) {
302 using detail::CyclicAngle;
304 const auto [mean_test, boundCov_test] =
318 Surface::makeShared<PlaneSurface>(
Vector3{0, 0, 0},
Vector3{1, 0, 0});
320 const LocPosArray p{{{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}};
326 const Transform3 trafo = Transform3::Identity();
328 const double halfz = 100;
330 const auto surface = Surface::makeShared<CylinderSurface>(trafo,
r, halfz);
332 const double z1 = -1, z2 = 1;
333 const double phi1 = 178_degree, phi2 = -176_degree;
336 {{r * phi1, z1}, {r * phi1, -z2}, {r * phi2, z1}, {r * phi2, z2}}};
339 std::get<0>(desc).constant = r;
345 const Transform3 trafo = Transform3::Identity();
346 const auto radius = 1;
348 const auto surface = Surface::makeShared<DiscSurface>(trafo, 0.0, radius);
350 const double r1 = 0.4,
r2 = 0.8;
351 const double phi1 = -178_degree, phi2 = 176_degree;
363 const auto surface = Surface::makeShared<PerigeeSurface>(
Vector3{0, 0, 0});
368 const LocPosArray p{{{d, z}, {d, -z}, {2 * d, z}, {2 * d, -z}}};