Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:00

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 // meta-programming type list of scalar type + subspace type combinations
0031 // clang-format off
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 // clang-format on
0057 
0058 /// Construct a random vector of the specified size.
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 /// Construct a vector w/ monotonically inceasing values starting at 0.
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 /// Build a sorted array from the first kSize indices.
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 }  // namespace
0086 
0087 BOOST_AUTO_TEST_SUITE(UtilitiesSubspace)
0088 
0089 // all these cases should lead to compile-time errors
0090 // BOOST_AUTO_TEST_CASE(ConstructFixedInvalid) {
0091 //   {
0092 //     using Subspace = detail::FixedSizeSubspace<6u, 7u>;
0093 //     Subspace subspace(0u, 1u, 2u, 3u, 4u, 5u, 6u);
0094 //   }
0095 //   {
0096 //     using Subspace = detail::FixedSizeSubspace<8u, 9u>;
0097 //     Subspace subspace(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u);
0098 //   }
0099 // }
0100 
0101 BOOST_AUTO_TEST_CASE_TEMPLATE(FixedSizeSubspace, ScalarAndSubspace,
0102                               ScalarsAndFixedSizeSubspaces) {
0103   // extract the test types
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   // in principle, we would like to iterate over all possible ordered subsets
0111   // from the full space indices with a size identical to the subspace. since i
0112   // do not know how to do that in a simple manner, we are iterating over all
0113   // permutations of the full indices and pick the first n elements. this should
0114   // give a reasonable set of different subspace configurations.
0115   do {
0116     auto indices = selectFixedIndices<Subspace::size()>(fullIndices);
0117     Subspace subspace(indices);
0118 
0119     // verify projector/expander consistency
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     // project into the subspace
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     // expand from the subspace back into the full space
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   // extract the test types
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   // in principle, we would like to iterate over all possible ordered subsets
0154   // from the full space indices with a size identical to the subspace. since i
0155   // do not know how to do that in a simple manner, we are iterating over all
0156   // permutations of the full indices and pick the first n elements. this should
0157   // give a reasonable set of different subspace configurations.
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()