File indexing completed on 2026-07-26 08:22:02
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010
0011 #include "traccc/definitions/primitives.hpp"
0012 #include "traccc/definitions/qualifiers.hpp"
0013 #include "traccc/definitions/track_parametrization.hpp"
0014
0015
0016 #include <array>
0017
0018 namespace traccc {
0019
0020 template <typename algebra_t, detray::dindex_type<algebra_t> kFullSize,
0021 detray::dindex_type<algebra_t> kSize = 2u>
0022 struct subspace {
0023 static_assert(1u <= kSize, "Subspace size must be at least 1");
0024 static_assert(kSize <= kFullSize,
0025 "Subspace can only be as large as the full space");
0026
0027 public:
0028
0029 using size_type = detray::dindex_type<algebra_t>;
0030
0031
0032
0033
0034
0035
0036
0037 static constexpr size_type BITS_PER_INDEX = 4;
0038 static_assert(BITS_PER_INDEX >= 2);
0039
0040
0041 static constexpr size_type TOTAL_BITS = BITS_PER_INDEX * kSize;
0042 static_assert(TOTAL_BITS <= 64,
0043 "Subspaces with more than 64 necessary bits are not supported");
0044 using axes_type = std::conditional_t<TOTAL_BITS <= 32, std::uint_least32_t,
0045 std::uint_least64_t>;
0046
0047 static constexpr axes_type SIGN_BIT_MASK = 1 << (BITS_PER_INDEX - 1);
0048 static constexpr axes_type VALUE_BITS_MASK = (1 << (BITS_PER_INDEX - 1)) - 1;
0049 static constexpr axes_type ELEMENT_BITS_MASK = (1 << BITS_PER_INDEX) - 1;
0050 static_assert(((1 << (BITS_PER_INDEX - 1)) - 1) >= kFullSize);
0051 static_assert(ELEMENT_BITS_MASK == (SIGN_BIT_MASK | VALUE_BITS_MASK));
0052
0053 template <size_type ROWS, size_type COLS>
0054 using matrix_type = detray::dmatrix<algebra_t, ROWS, COLS>;
0055
0056 using subspace_vector = matrix_type<kSize, 1u>;
0057 using fullspace_vector = matrix_type<kFullSize, 1u>;
0058 using projection_matrix = matrix_type<kSize, kFullSize>;
0059 using expansion_matrix = matrix_type<kFullSize, kSize>;
0060
0061 static constexpr size_type size = kSize;
0062 static constexpr size_type fullSize = kFullSize;
0063
0064
0065
0066
0067 template <typename SIZE_TYPE>
0068 TRACCC_HOST_DEVICE constexpr subspace(
0069 const std::array<SIZE_TYPE, kSize>& indices)
0070 : m_axes(0) {
0071 for (size_type i = 0u; i < kSize; ++i) {
0072 assert((indices[i] < kFullSize) and
0073 "Axis indices must be within the full space");
0074 set_index(i, static_cast<axes_type>(indices[i]));
0075 }
0076 }
0077
0078
0079 TRACCC_HOST_DEVICE
0080 constexpr size_type get_index(const size_type& i) const {
0081 const size_type sr = i * BITS_PER_INDEX;
0082 return (m_axes >> sr) & VALUE_BITS_MASK;
0083 }
0084
0085
0086
0087
0088
0089 TRACCC_HOST_DEVICE
0090 constexpr bool get_valid(const size_type& i) const {
0091 const size_type sr = i * BITS_PER_INDEX;
0092 return ((m_axes >> sr) & VALUE_BITS_MASK) != VALUE_BITS_MASK;
0093 }
0094
0095
0096
0097 TRACCC_HOST_DEVICE
0098 constexpr bool get_sign(const size_type& i) const {
0099 const size_type sr = i * BITS_PER_INDEX;
0100 return (m_axes >> sr) & SIGN_BIT_MASK;
0101 }
0102
0103
0104 TRACCC_HOST_DEVICE
0105 constexpr void set_index(const size_type& i, const axes_type& j) {
0106 assert(j == (j & ELEMENT_BITS_MASK));
0107 const size_type sl = i * BITS_PER_INDEX;
0108 m_axes = (m_axes & static_cast<axes_type>(~(VALUE_BITS_MASK << sl))) |
0109 static_cast<axes_type>(j << sl);
0110 }
0111
0112
0113 TRACCC_HOST_DEVICE
0114 constexpr void set_invalid(const size_type& i) {
0115
0116
0117 set_index(i, ((1 << (BITS_PER_INDEX - 1)) - 1));
0118 }
0119
0120
0121
0122 TRACCC_HOST_DEVICE
0123 constexpr void set_sign(const size_type& i, const bool s) {
0124 const size_type sl = i * BITS_PER_INDEX;
0125 m_axes = (m_axes & static_cast<axes_type>(~(SIGN_BIT_MASK << sl))) |
0126 static_cast<axes_type>((s ? SIGN_BIT_MASK : 0) << sl);
0127 }
0128
0129
0130 template <size_type D>
0131 TRACCC_HOST_DEVICE auto projector() const -> matrix_type<D, kFullSize> {
0132 static_assert(D <= kSize,
0133 "The dimension of projection should be smaller than "
0134 "subspace dimension");
0135
0136 auto proj = matrix::zero<matrix_type<D, kFullSize>>();
0137
0138 for (size_type i = 0u; i < D; ++i) {
0139 if (get_index(i) < kFullSize) {
0140 getter::element(proj, i, get_index(i)) = (get_sign(i) ? -1.f : 1.f);
0141 }
0142 }
0143 return proj;
0144 }
0145
0146
0147 template <size_type D>
0148 TRACCC_HOST_DEVICE auto expander() const -> matrix_type<kFullSize, D> {
0149 static_assert(D <= kSize,
0150 "The dimension of projection should be smaller than "
0151 "subspace dimension");
0152
0153 auto expn = matrix::zero<matrix_type<kFullSize, D>>();
0154
0155 for (size_type i = 0u; i < kSize; ++i) {
0156 if (get_index(i) < kFullSize) {
0157 getter::element(expn, get_index(i), i) = (get_sign(i) ? -1.f : 1.f);
0158 }
0159 }
0160 return expn;
0161 }
0162
0163 private:
0164 axes_type m_axes;
0165 };
0166
0167 }