Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:35

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2020 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Utilities/detail/Subspace.hpp"
0013 
0014 #include <algorithm>
0015 #include <array>
0016 #include <cstddef>
0017 #include <numeric>
0018 #include <ostream>
0019 #include <tuple>
0020 #include <utility>
0021 #include <vector>
0022 
0023 namespace {
0024 
0025 using namespace Acts;
0026 
0027 // meta-programming type list of scalar type + subspace type combinations
0028 // clang-format off
0029 using ScalarsAndFixedSizeSubspaces = std::tuple<
0030   std::tuple<float, detail::FixedSizeSubspace<2u, 1u>>,
0031   std::tuple<float, detail::FixedSizeSubspace<2u, 2u>>,
0032   std::tuple<float, detail::FixedSizeSubspace<3u, 1u>>,
0033   std::tuple<float, detail::FixedSizeSubspace<3u, 2u>>,
0034   std::tuple<float, detail::FixedSizeSubspace<3u, 3u>>,
0035   std::tuple<float, detail::FixedSizeSubspace<6u, 1u>>,
0036   std::tuple<float, detail::FixedSizeSubspace<6u, 2u>>,
0037   std::tuple<float, detail::FixedSizeSubspace<6u, 4u>>,
0038   std::tuple<float, detail::FixedSizeSubspace<8u, 1u>>,
0039   std::tuple<float, detail::FixedSizeSubspace<8u, 2u>>,
0040   std::tuple<float, detail::FixedSizeSubspace<8u, 4u>>,
0041   std::tuple<double, detail::FixedSizeSubspace<2u, 1u>>,
0042   std::tuple<double, detail::FixedSizeSubspace<2u, 2u>>,
0043   std::tuple<double, detail::FixedSizeSubspace<3u, 1u>>,
0044   std::tuple<double, detail::FixedSizeSubspace<3u, 2u>>,
0045   std::tuple<double, detail::FixedSizeSubspace<3u, 3u>>,
0046   std::tuple<double, detail::FixedSizeSubspace<6u, 1u>>,
0047   std::tuple<double, detail::FixedSizeSubspace<6u, 2u>>,
0048   std::tuple<double, detail::FixedSizeSubspace<6u, 4u>>,
0049   std::tuple<double, detail::FixedSizeSubspace<8u, 1u>>,
0050   std::tuple<double, detail::FixedSizeSubspace<8u, 2u>>,
0051   std::tuple<double, detail::FixedSizeSubspace<8u, 4u>>
0052 >;
0053 // clang-format on
0054 
0055 /// Construct a random vector of the specified size.
0056 template <typename scalar_t, std::size_t kSize>
0057 Eigen::Matrix<scalar_t, kSize, 1> makeRandomVector() {
0058   Eigen::Matrix<scalar_t, kSize, 1> vec;
0059   vec.setRandom();
0060   return vec;
0061 }
0062 
0063 /// Construct a vector w/ monotonically inceasing values starting at 0.
0064 std::vector<std::size_t> makeMonotonicIndices(std::size_t n) {
0065   std::vector<std::size_t> indices(n);
0066   std::iota(indices.begin(), indices.end(), 0u);
0067   return indices;
0068 }
0069 
0070 /// Build a sorted array from the first kSize indices.
0071 template <std::size_t kSize>
0072 std::array<std::size_t, kSize> selectFixedIndices(
0073     const std::vector<std::size_t>& fullIndices) {
0074   std::array<std::size_t, kSize> indices{};
0075   for (auto i = 0u; i < kSize; ++i) {
0076     indices[i] = fullIndices[i];
0077   }
0078   std::sort(indices.begin(), indices.end());
0079   return indices;
0080 }
0081 
0082 }  // namespace
0083 
0084 BOOST_AUTO_TEST_SUITE(UtilitiesSubspace)
0085 
0086 // all these cases should lead to compile-time errors
0087 // BOOST_AUTO_TEST_CASE(ConstructFixedInvalid) {
0088 //   {
0089 //     using Subspace = detail::FixedSizeSubspace<6u, 7u>;
0090 //     Subspace subspace(0u, 1u, 2u, 3u, 4u, 5u, 6u);
0091 //   }
0092 //   {
0093 //     using Subspace = detail::FixedSizeSubspace<8u, 9u>;
0094 //     Subspace subspace(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u);
0095 //   }
0096 // }
0097 
0098 BOOST_AUTO_TEST_CASE_TEMPLATE(FixedSizeSubspaceFloat, ScalarAndSubspace,
0099                               ScalarsAndFixedSizeSubspaces) {
0100   // extract the test types
0101   using Scalar = std::tuple_element_t<0, ScalarAndSubspace>;
0102   using Subspace = std::tuple_element_t<1, ScalarAndSubspace>;
0103 
0104   auto x = makeRandomVector<Scalar, Subspace::fullSize()>();
0105   auto fullIndices = makeMonotonicIndices(Subspace::fullSize());
0106 
0107   // in principle, we would like to iterate over all possible ordered subsets
0108   // from the full space indices with a size identical to the subspace. since i
0109   // do not know how to do that in a simple manner, we are iterating over all
0110   // permutations of the full indices and pick the first n elements. this should
0111   // give a reasonable set of different subspace configurations.
0112   do {
0113     auto indices = selectFixedIndices<Subspace::size()>(fullIndices);
0114     Subspace subspace(indices);
0115 
0116     // verify projector/expander consistency
0117     BOOST_CHECK_EQUAL(subspace.template projector<Scalar>().transpose(),
0118                       subspace.template expander<Scalar>());
0119     BOOST_CHECK_EQUAL(subspace.template expander<Scalar>().transpose(),
0120                       subspace.template projector<Scalar>());
0121     // project into the subspace
0122     auto s0 = subspace.projectVector(x);
0123     auto s1 = (subspace.template projector<Scalar>() * x).eval();
0124     for (auto i = 0u; i < subspace.size(); ++i) {
0125       BOOST_TEST_INFO("Checking projected subspace component " << i);
0126       BOOST_CHECK_EQUAL(s0[i], x[indices[i]]);
0127       BOOST_CHECK_EQUAL(s1[i], x[indices[i]]);
0128     }
0129     // expand from the subspace back into the full space
0130     auto y0 = subspace.expandVector(s1);
0131     auto y1 = (subspace.template expander<Scalar>() * s0).eval();
0132     for (auto i = 0u; i < subspace.fullSize(); ++i) {
0133       BOOST_TEST_INFO("Checking expanded fullspace component " << i);
0134       BOOST_CHECK_EQUAL(y0[i], subspace.contains(i) ? x[i] : 0);
0135       BOOST_CHECK_EQUAL(y1[i], subspace.contains(i) ? x[i] : 0);
0136     }
0137   } while (std::next_permutation(fullIndices.begin(), fullIndices.end()));
0138 }
0139 
0140 BOOST_AUTO_TEST_SUITE_END()