File indexing completed on 2025-06-05 08:29:26
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/Types.hpp"
0014 #include "Acts/Utilities/AlgebraHelpers.hpp"
0015 #include "Acts/Utilities/Enumerate.hpp"
0016
0017 #include <bitset>
0018 #include <span>
0019
0020 #include <boost/container/static_vector.hpp>
0021
0022 namespace Acts {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 template <typename Container>
0036 inline static bool checkSubspaceIndices(const Container& container,
0037 std::size_t fullSize,
0038 std::size_t subspaceSize) {
0039 if (subspaceSize > fullSize) {
0040 return false;
0041 }
0042 if (container.size() != subspaceSize) {
0043 return false;
0044 }
0045 for (auto it = container.begin(); it != container.end();) {
0046 auto index = *it;
0047 if (index >= fullSize) {
0048 return false;
0049 }
0050 ++it;
0051 if (std::find(it, container.end(), index) != container.end()) {
0052 return false;
0053 }
0054 }
0055 return true;
0056 }
0057
0058
0059
0060
0061
0062
0063
0064
0065 template <std::size_t FullSize>
0066 inline static SerializedSubspaceIndices serializeSubspaceIndices(
0067 const SubspaceIndices<FullSize>& indices)
0068 requires(FullSize <= 8)
0069 {
0070 SerializedSubspaceIndices result = 0;
0071 for (std::size_t i = 0; i < FullSize; ++i) {
0072 result |= static_cast<SerializedSubspaceIndices>(indices[i]) << (i * 8);
0073 }
0074 return result;
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084 template <std::size_t FullSize>
0085 inline static SubspaceIndices<FullSize> deserializeSubspaceIndices(
0086 SerializedSubspaceIndices serialized)
0087 requires(FullSize <= 8)
0088 {
0089 SubspaceIndices<FullSize> result;
0090 for (std::size_t i = 0; i < FullSize; ++i) {
0091 result[i] = static_cast<std::uint8_t>(serialized >> (i * 8));
0092 }
0093 return result;
0094 }
0095
0096 namespace detail {
0097
0098
0099
0100
0101
0102
0103 template <typename Derived, std::size_t FullSize>
0104 class SubspaceHelperBase {
0105 public:
0106 static constexpr std::size_t kFullSize = FullSize;
0107
0108 using FullSquareMatrix = ActsSquareMatrix<kFullSize>;
0109
0110 bool empty() const { return self().empty(); }
0111 std::size_t size() const { return self().size(); }
0112
0113 auto operator[](std::size_t i) const { return self()[i]; }
0114
0115 auto begin() const { return self().begin(); }
0116 auto end() const { return self().end(); }
0117
0118 FullSquareMatrix fullProjector() const {
0119 FullSquareMatrix result = FullSquareMatrix::Zero();
0120 for (auto [i, index] : enumerate(*this)) {
0121 result(i, index) = 1;
0122 }
0123 return result;
0124 }
0125
0126 FullSquareMatrix fullExpander() const {
0127 FullSquareMatrix result = FullSquareMatrix::Zero();
0128 for (auto [i, index] : enumerate(*this)) {
0129 result(index, i) = 1;
0130 }
0131 return result;
0132 }
0133
0134 ProjectorBitset projectorBitset() const
0135 requires(kFullSize <= 8)
0136 {
0137 return matrixToBitset(fullProjector()).to_ullong();
0138 }
0139
0140 private:
0141 const Derived& self() const { return static_cast<const Derived&>(*this); }
0142 };
0143
0144 }
0145
0146
0147
0148
0149
0150 template <std::size_t FullSize, typename index_t = std::uint8_t>
0151 class VariableSubspaceHelper
0152 : public detail::SubspaceHelperBase<
0153 VariableSubspaceHelper<FullSize, index_t>, FullSize> {
0154 public:
0155 static constexpr std::size_t kFullSize = FullSize;
0156
0157 using IndexType = index_t;
0158 using Container = boost::container::static_vector<IndexType, FullSize>;
0159
0160 template <typename OtherContainer>
0161 explicit VariableSubspaceHelper(const OtherContainer& indices) {
0162 assert(checkSubspaceIndices(indices, kFullSize, indices.size()) &&
0163 "Invalid indices");
0164 m_indices.resize(indices.size());
0165 std::transform(indices.begin(), indices.end(), m_indices.begin(),
0166 [](auto index) { return static_cast<IndexType>(index); });
0167 }
0168
0169 bool empty() const { return m_indices.empty(); }
0170 std::size_t size() const { return m_indices.size(); }
0171
0172 IndexType operator[](std::size_t i) const { return m_indices[i]; }
0173
0174 auto begin() const { return m_indices.begin(); }
0175 auto end() const { return m_indices.end(); }
0176
0177 private:
0178 Container m_indices;
0179 };
0180
0181
0182
0183
0184
0185
0186 template <std::size_t FullSize, std::size_t SubspaceSize,
0187 typename index_t = std::uint8_t>
0188 class FixedSubspaceHelper
0189 : public detail::SubspaceHelperBase<
0190 FixedSubspaceHelper<FullSize, SubspaceSize, index_t>, FullSize> {
0191 public:
0192 static constexpr std::size_t kFullSize = FullSize;
0193 static constexpr std::size_t kSubspaceSize = SubspaceSize;
0194 static_assert(kSubspaceSize <= kFullSize, "Invalid subspace size");
0195
0196 using Projector = ActsMatrix<kSubspaceSize, kFullSize>;
0197 using Expander = ActsMatrix<kFullSize, kSubspaceSize>;
0198 using Vector = ActsVector<kSubspaceSize>;
0199 using SquareMatrix = ActsSquareMatrix<kSubspaceSize>;
0200 template <std::size_t K>
0201 using ApplyLeftResult = ActsMatrix<kSubspaceSize, kSubspaceSize>;
0202 template <std::size_t N>
0203 using ApplyRightResult = ActsMatrix<kSubspaceSize, kSubspaceSize>;
0204
0205 using IndexType = index_t;
0206 using Container = std::array<IndexType, kSubspaceSize>;
0207
0208 template <typename OtherContainer>
0209 explicit FixedSubspaceHelper(const OtherContainer& indices) {
0210 assert(checkSubspaceIndices(indices, kFullSize, kSubspaceSize) &&
0211 "Invalid indices");
0212 std::transform(indices.begin(), indices.end(), m_indices.begin(),
0213 [](auto index) { return static_cast<IndexType>(index); });
0214 }
0215
0216 bool empty() const { return m_indices.empty(); }
0217 std::size_t size() const { return m_indices.size(); }
0218
0219 IndexType operator[](std::uint32_t i) const { return m_indices[i]; }
0220
0221 auto begin() const { return m_indices.begin(); }
0222 auto end() const { return m_indices.end(); }
0223
0224 Projector projector() const {
0225 Projector result = Projector::Zero();
0226 for (auto [i, index] : enumerate(*this)) {
0227 result(i, index) = 1;
0228 }
0229 return result;
0230 }
0231
0232 Expander expander() const {
0233 Expander result = Expander::Zero();
0234 for (auto [i, index] : enumerate(*this)) {
0235 result(index, i) = 1;
0236 }
0237 return result;
0238 }
0239
0240 template <std::size_t K, typename Derived>
0241 ApplyLeftResult<K> applyLeftOf(
0242 const Eigen::DenseBase<Derived>& matrix) const {
0243 assert(matrix.rows() == kFullSize && "Invalid matrix size");
0244 ApplyLeftResult<K> result = ApplyLeftResult<K>::Zero();
0245 for (auto [i, indexI] : enumerate(*this)) {
0246 for (std::size_t j = 0; j < K; ++j) {
0247 result(i, j) = matrix(indexI, j);
0248 }
0249 }
0250 return result;
0251 }
0252
0253 template <std::size_t N, typename Derived>
0254 ApplyRightResult<N> applyRightOf(
0255 const Eigen::DenseBase<Derived>& matrix) const {
0256 assert(matrix.cols() == kSubspaceSize && "Invalid matrix size");
0257 ApplyRightResult<N> result = ApplyRightResult<N>::Zero();
0258 for (std::size_t i = 0; i < N; ++i) {
0259 for (auto [j, indexJ] : enumerate(*this)) {
0260 result(i, j) = matrix(i, indexJ);
0261 }
0262 }
0263 return result;
0264 }
0265
0266 template <typename Derived>
0267 Vector projectVector(const Eigen::DenseBase<Derived>& fullVector) const {
0268 assert(fullVector.size() == kFullSize && "Invalid full vector size");
0269 Vector result = Vector::Zero();
0270 for (auto [i, index] : enumerate(*this)) {
0271 result(i) = fullVector(index);
0272 }
0273 return result;
0274 }
0275
0276 template <typename Derived>
0277 SquareMatrix projectMatrix(
0278 const Eigen::DenseBase<Derived>& fullMatrix) const {
0279 assert(fullMatrix.rows() == kFullSize && fullMatrix.cols() == kFullSize &&
0280 "Invalid full matrix size");
0281 SquareMatrix result = SquareMatrix::Zero();
0282 for (auto [i, indexI] : enumerate(*this)) {
0283 for (auto [j, indexJ] : enumerate(*this)) {
0284 result(i, j) = fullMatrix(indexI, indexJ);
0285 }
0286 }
0287 return result;
0288 }
0289
0290 private:
0291 Container m_indices{};
0292 };
0293
0294 template <std::size_t SubspaceSize>
0295 using FixedBoundSubspaceHelper =
0296 FixedSubspaceHelper<Acts::eBoundSize, SubspaceSize, std::uint8_t>;
0297 using VariableBoundSubspaceHelper =
0298 VariableSubspaceHelper<Acts::eBoundSize, std::uint8_t>;
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 template <std::size_t kFullSize, typename Derived>
0309 SubspaceIndices<kFullSize> projectorToSubspaceIndices(
0310 const Eigen::DenseBase<Derived>& projector) {
0311 auto rows = static_cast<std::size_t>(projector.rows());
0312 auto cols = static_cast<std::size_t>(projector.cols());
0313 assert(cols == kFullSize && rows <= kFullSize && "Invalid projector size");
0314 SubspaceIndices<kFullSize> result;
0315 result.fill(kFullSize);
0316 for (std::size_t i = 0; i < rows; ++i) {
0317 for (std::size_t j = 0; j < cols; ++j) {
0318 assert((projector(i, j) == 0 || projector(i, j) == 1) &&
0319 "Invalid projector value");
0320 if (projector(i, j) == 1) {
0321 result[i] = j;
0322 }
0323 }
0324 }
0325 return result;
0326 }
0327
0328 }