File indexing completed on 2025-01-18 09:13:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Utilities/AlgebraHelpers.hpp"
0014 #include "Acts/Utilities/detail/Subspace.hpp"
0015
0016 #include <algorithm>
0017 #include <array>
0018 #include <cstddef>
0019 #include <cstdint>
0020 #include <numeric>
0021 #include <ostream>
0022 #include <tuple>
0023 #include <utility>
0024 #include <vector>
0025
0026 namespace {
0027
0028 using namespace Acts;
0029
0030
0031
0032 using ScalarsAndFixedSizeSubspaces = std::tuple<
0033 std::tuple<float, detail::FixedSizeSubspace<2u, 1u>>,
0034 std::tuple<float, detail::FixedSizeSubspace<2u, 2u>>,
0035 std::tuple<float, detail::FixedSizeSubspace<3u, 1u>>,
0036 std::tuple<float, detail::FixedSizeSubspace<3u, 2u>>,
0037 std::tuple<float, detail::FixedSizeSubspace<3u, 3u>>,
0038 std::tuple<float, detail::FixedSizeSubspace<6u, 1u>>,
0039 std::tuple<float, detail::FixedSizeSubspace<6u, 2u>>,
0040 std::tuple<float, detail::FixedSizeSubspace<6u, 4u>>,
0041 std::tuple<float, detail::FixedSizeSubspace<8u, 1u>>,
0042 std::tuple<float, detail::FixedSizeSubspace<8u, 2u>>,
0043 std::tuple<float, detail::FixedSizeSubspace<8u, 4u>>,
0044 std::tuple<double, detail::FixedSizeSubspace<2u, 1u>>,
0045 std::tuple<double, detail::FixedSizeSubspace<2u, 2u>>,
0046 std::tuple<double, detail::FixedSizeSubspace<3u, 1u>>,
0047 std::tuple<double, detail::FixedSizeSubspace<3u, 2u>>,
0048 std::tuple<double, detail::FixedSizeSubspace<3u, 3u>>,
0049 std::tuple<double, detail::FixedSizeSubspace<6u, 1u>>,
0050 std::tuple<double, detail::FixedSizeSubspace<6u, 2u>>,
0051 std::tuple<double, detail::FixedSizeSubspace<6u, 4u>>,
0052 std::tuple<double, detail::FixedSizeSubspace<8u, 1u>>,
0053 std::tuple<double, detail::FixedSizeSubspace<8u, 2u>>,
0054 std::tuple<double, detail::FixedSizeSubspace<8u, 4u>>
0055 >;
0056
0057
0058
0059 template <typename scalar_t, std::size_t kSize>
0060 Eigen::Matrix<scalar_t, kSize, 1> makeRandomVector() {
0061 Eigen::Matrix<scalar_t, kSize, 1> vec;
0062 vec.setRandom();
0063 return vec;
0064 }
0065
0066
0067 std::vector<std::size_t> makeMonotonicIndices(std::size_t n) {
0068 std::vector<std::size_t> indices(n);
0069 std::iota(indices.begin(), indices.end(), 0u);
0070 return indices;
0071 }
0072
0073
0074 template <std::size_t kSize>
0075 std::array<std::size_t, kSize> selectFixedIndices(
0076 const std::vector<std::size_t>& fullIndices) {
0077 std::array<std::size_t, kSize> indices{};
0078 for (auto i = 0u; i < kSize; ++i) {
0079 indices[i] = fullIndices[i];
0080 }
0081 std::ranges::sort(indices);
0082 return indices;
0083 }
0084
0085 }
0086
0087 BOOST_AUTO_TEST_SUITE(UtilitiesSubspace)
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 BOOST_AUTO_TEST_CASE_TEMPLATE(FixedSizeSubspace, ScalarAndSubspace,
0102 ScalarsAndFixedSizeSubspaces) {
0103
0104 using Scalar = std::tuple_element_t<0, ScalarAndSubspace>;
0105 using Subspace = std::tuple_element_t<1, ScalarAndSubspace>;
0106
0107 auto x = makeRandomVector<Scalar, Subspace::fullSize()>();
0108 auto fullIndices = makeMonotonicIndices(Subspace::fullSize());
0109
0110
0111
0112
0113
0114
0115 do {
0116 auto indices = selectFixedIndices<Subspace::size()>(fullIndices);
0117 Subspace subspace(indices);
0118
0119
0120 BOOST_CHECK_EQUAL(subspace.template projector<Scalar>().transpose(),
0121 subspace.template expander<Scalar>());
0122 BOOST_CHECK_EQUAL(subspace.template expander<Scalar>().transpose(),
0123 subspace.template projector<Scalar>());
0124
0125 auto s0 = subspace.projectVector(x);
0126 auto s1 = (subspace.template projector<Scalar>() * x).eval();
0127 for (auto i = 0u; i < subspace.size(); ++i) {
0128 BOOST_TEST_INFO("Checking projected subspace component " << i);
0129 BOOST_CHECK_EQUAL(s0[i], x[indices[i]]);
0130 BOOST_CHECK_EQUAL(s1[i], x[indices[i]]);
0131 }
0132
0133 auto y0 = subspace.expandVector(s1);
0134 auto y1 = (subspace.template expander<Scalar>() * s0).eval();
0135 for (auto i = 0u; i < subspace.fullSize(); ++i) {
0136 BOOST_TEST_INFO("Checking expanded fullspace component " << i);
0137 BOOST_CHECK_EQUAL(y0[i], subspace.contains(i) ? x[i] : 0);
0138 BOOST_CHECK_EQUAL(y1[i], subspace.contains(i) ? x[i] : 0);
0139 }
0140 } while (std::next_permutation(fullIndices.begin(), fullIndices.end()));
0141 }
0142
0143 BOOST_AUTO_TEST_CASE_TEMPLATE(VariableSizeSubspace, ScalarAndSubspace,
0144 ScalarsAndFixedSizeSubspaces) {
0145
0146 using Scalar = std::tuple_element_t<0, ScalarAndSubspace>;
0147 using FixedSubspace = std::tuple_element_t<1, ScalarAndSubspace>;
0148 using VariableSubspace =
0149 detail::VariableSizeSubspace<FixedSubspace::fullSize()>;
0150
0151 auto fullIndices = makeMonotonicIndices(FixedSubspace::fullSize());
0152
0153
0154
0155
0156
0157
0158 do {
0159 auto indices = selectFixedIndices<FixedSubspace::size()>(fullIndices);
0160 FixedSubspace fixedSubspace(indices);
0161 VariableSubspace variableSubspace(indices);
0162
0163 BOOST_CHECK_EQUAL(variableSubspace.size(), fixedSubspace.size());
0164 BOOST_CHECK_EQUAL(variableSubspace.fullSize(), fixedSubspace.fullSize());
0165
0166 auto fixedProjector = fixedSubspace.template projector<Scalar>();
0167
0168 Eigen::Matrix<Scalar, FixedSubspace::fullSize(), FixedSubspace::fullSize()>
0169 fixedFullProjector;
0170 fixedFullProjector.setZero();
0171 fixedFullProjector.template topLeftCorner<FixedSubspace::size(),
0172 FixedSubspace::fullSize()>() =
0173 fixedProjector;
0174
0175 auto variableFullProjector =
0176 variableSubspace.template fullProjector<Scalar>();
0177
0178 BOOST_CHECK_EQUAL(variableFullProjector, fixedFullProjector);
0179 } while (std::next_permutation(fullIndices.begin(), fullIndices.end()));
0180 }
0181
0182 BOOST_AUTO_TEST_SUITE_END()