File indexing completed on 2025-01-18 09:10:49
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 <ranges>
0018
0019 #include <boost/container/static_vector.hpp>
0020
0021 namespace Acts {
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 template <std::ranges::sized_range index_range_t>
0035 inline static bool checkSubspaceIndices(const index_range_t& indexRange,
0036 std::size_t fullSize,
0037 std::size_t subspaceSize) {
0038 if (subspaceSize > fullSize) {
0039 return false;
0040 }
0041 if (static_cast<std::size_t>(indexRange.size()) != subspaceSize) {
0042 return false;
0043 }
0044 for (auto it = indexRange.begin(); it != indexRange.end();) {
0045 auto index = *it;
0046 if (index >= fullSize) {
0047 return false;
0048 }
0049 ++it;
0050 if (std::find(it, indexRange.end(), index) != indexRange.end()) {
0051 return false;
0052 }
0053 }
0054 return true;
0055 }
0056
0057
0058
0059
0060
0061
0062
0063
0064 template <std::size_t FullSize>
0065 inline static SerializedSubspaceIndices serializeSubspaceIndices(
0066 const SubspaceIndices<FullSize>& indices)
0067 requires(FullSize <= 8)
0068 {
0069 SerializedSubspaceIndices result = 0;
0070 for (std::size_t i = 0; i < FullSize; ++i) {
0071 result |= static_cast<SerializedSubspaceIndices>(indices[i] & 0xFF)
0072 << (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)) & 0xFF);
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 bool contains(std::uint8_t index) const {
0119 return std::find(begin(), end(), index) != end();
0120 }
0121 std::size_t indexOf(std::uint8_t index) const {
0122 auto it = std::find(begin(), end(), index);
0123 return it != end() ? std::distance(begin(), it) : kFullSize;
0124 }
0125
0126 template <typename EigenDerived>
0127 ActsVector<kFullSize> expandVector(
0128 const Eigen::DenseBase<EigenDerived>& vector) const {
0129 ActsVector<kFullSize> result = ActsVector<kFullSize>::Zero();
0130 for (auto [i, index] : enumerate(*this)) {
0131 result(index) = vector(i);
0132 }
0133 return result;
0134 }
0135
0136 template <typename EigenDerived>
0137 FullSquareMatrix expandMatrix(
0138 const Eigen::DenseBase<EigenDerived>& matrix) const {
0139 FullSquareMatrix result = FullSquareMatrix::Zero();
0140 for (auto [i, indexI] : enumerate(*this)) {
0141 for (auto [j, indexJ] : enumerate(*this)) {
0142 result(indexI, indexJ) = matrix(i, j);
0143 }
0144 }
0145 return result;
0146 }
0147
0148 FullSquareMatrix fullProjector() const {
0149 FullSquareMatrix result = FullSquareMatrix::Zero();
0150 for (auto [i, index] : enumerate(*this)) {
0151 result(i, index) = 1;
0152 }
0153 return result;
0154 }
0155
0156 FullSquareMatrix fullExpander() const {
0157 FullSquareMatrix result = FullSquareMatrix::Zero();
0158 for (auto [i, index] : enumerate(*this)) {
0159 result(index, i) = 1;
0160 }
0161 return result;
0162 }
0163
0164 ProjectorBitset projectorBitset() const
0165 requires(kFullSize <= 8)
0166 {
0167 return matrixToBitset(fullProjector()).to_ullong();
0168 }
0169
0170 private:
0171 const Derived& self() const { return static_cast<const Derived&>(*this); }
0172 };
0173
0174 }
0175
0176
0177
0178
0179
0180 template <std::size_t FullSize, typename index_t = std::uint8_t>
0181 class VariableSubspaceHelper
0182 : public detail::SubspaceHelperBase<
0183 VariableSubspaceHelper<FullSize, index_t>, FullSize> {
0184 public:
0185 static constexpr std::size_t kFullSize = FullSize;
0186
0187 using IndexType = index_t;
0188 using Container = boost::container::static_vector<IndexType, FullSize>;
0189
0190 template <std::ranges::sized_range other_index_range_t>
0191 explicit VariableSubspaceHelper(const other_index_range_t& indices) {
0192 assert(checkSubspaceIndices(indices, kFullSize, indices.size()) &&
0193 "Invalid indices");
0194 m_indices.resize(indices.size());
0195 std::transform(indices.begin(), indices.end(), m_indices.begin(),
0196 [](auto index) { return static_cast<IndexType>(index); });
0197 }
0198
0199 bool empty() const { return m_indices.empty(); }
0200 std::size_t size() const { return m_indices.size(); }
0201 const Container& indices() const { return m_indices; }
0202
0203 IndexType operator[](std::size_t i) const { return m_indices[i]; }
0204
0205 auto begin() const { return m_indices.begin(); }
0206 auto end() const { return m_indices.end(); }
0207
0208 private:
0209 Container m_indices;
0210 };
0211
0212
0213
0214
0215
0216
0217 template <std::size_t FullSize, std::size_t SubspaceSize,
0218 typename index_t = std::uint8_t>
0219 class FixedSubspaceHelper
0220 : public detail::SubspaceHelperBase<
0221 FixedSubspaceHelper<FullSize, SubspaceSize, index_t>, FullSize> {
0222 public:
0223 static constexpr std::size_t kFullSize = FullSize;
0224 static constexpr std::size_t kSubspaceSize = SubspaceSize;
0225 static_assert(kSubspaceSize <= kFullSize, "Invalid subspace size");
0226
0227 using Projector = ActsMatrix<kSubspaceSize, kFullSize>;
0228 using Expander = ActsMatrix<kFullSize, kSubspaceSize>;
0229 using Vector = ActsVector<kSubspaceSize>;
0230 using SquareMatrix = ActsSquareMatrix<kSubspaceSize>;
0231 template <std::size_t K>
0232 using ApplyLeftResult = ActsMatrix<kSubspaceSize, kSubspaceSize>;
0233 template <std::size_t N>
0234 using ApplyRightResult = ActsMatrix<kSubspaceSize, kSubspaceSize>;
0235
0236 using IndexType = index_t;
0237 using Container = std::array<IndexType, kSubspaceSize>;
0238
0239 template <std::ranges::sized_range other_index_range_t>
0240 explicit FixedSubspaceHelper(const other_index_range_t& indices) {
0241 assert(checkSubspaceIndices(indices, kFullSize, kSubspaceSize) &&
0242 "Invalid indices");
0243 std::transform(indices.begin(), indices.end(), m_indices.begin(),
0244 [](auto index) { return static_cast<IndexType>(index); });
0245 }
0246
0247 bool empty() const { return m_indices.empty(); }
0248 std::size_t size() const { return m_indices.size(); }
0249 const Container& indices() const { return m_indices; }
0250
0251 IndexType operator[](std::uint32_t i) const { return m_indices[i]; }
0252
0253 auto begin() const { return m_indices.begin(); }
0254 auto end() const { return m_indices.end(); }
0255
0256 Projector projector() const {
0257 Projector result = Projector::Zero();
0258 for (auto [i, index] : enumerate(*this)) {
0259 result(i, index) = 1;
0260 }
0261 return result;
0262 }
0263
0264 Expander expander() const {
0265 Expander result = Expander::Zero();
0266 for (auto [i, index] : enumerate(*this)) {
0267 result(index, i) = 1;
0268 }
0269 return result;
0270 }
0271
0272 template <std::size_t K, typename Derived>
0273 ApplyLeftResult<K> applyLeftOf(
0274 const Eigen::DenseBase<Derived>& matrix) const {
0275 assert(matrix.rows() == kFullSize && "Invalid matrix size");
0276 ApplyLeftResult<K> result = ApplyLeftResult<K>::Zero();
0277 for (auto [i, indexI] : enumerate(*this)) {
0278 for (std::size_t j = 0; j < K; ++j) {
0279 result(i, j) = matrix(indexI, j);
0280 }
0281 }
0282 return result;
0283 }
0284
0285 template <std::size_t N, typename Derived>
0286 ApplyRightResult<N> applyRightOf(
0287 const Eigen::DenseBase<Derived>& matrix) const {
0288 assert(matrix.cols() == kSubspaceSize && "Invalid matrix size");
0289 ApplyRightResult<N> result = ApplyRightResult<N>::Zero();
0290 for (std::size_t i = 0; i < N; ++i) {
0291 for (auto [j, indexJ] : enumerate(*this)) {
0292 result(i, j) = matrix(i, indexJ);
0293 }
0294 }
0295 return result;
0296 }
0297
0298 template <typename Derived>
0299 Vector projectVector(const Eigen::DenseBase<Derived>& fullVector) const {
0300 assert(fullVector.size() == kFullSize && "Invalid full vector size");
0301 Vector result = Vector::Zero();
0302 for (auto [i, index] : enumerate(*this)) {
0303 result(i) = fullVector(index);
0304 }
0305 return result;
0306 }
0307
0308 template <typename Derived>
0309 SquareMatrix projectMatrix(
0310 const Eigen::DenseBase<Derived>& fullMatrix) const {
0311 assert(fullMatrix.rows() == kFullSize && fullMatrix.cols() == kFullSize &&
0312 "Invalid full matrix size");
0313 SquareMatrix result = SquareMatrix::Zero();
0314 for (auto [i, indexI] : enumerate(*this)) {
0315 for (auto [j, indexJ] : enumerate(*this)) {
0316 result(i, j) = fullMatrix(indexI, indexJ);
0317 }
0318 }
0319 return result;
0320 }
0321
0322 private:
0323 Container m_indices{};
0324 };
0325
0326 template <std::size_t SubspaceSize>
0327 using FixedBoundSubspaceHelper =
0328 FixedSubspaceHelper<Acts::eBoundSize, SubspaceSize, std::uint8_t>;
0329 using VariableBoundSubspaceHelper =
0330 VariableSubspaceHelper<Acts::eBoundSize, std::uint8_t>;
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340 template <std::size_t kFullSize, typename Derived>
0341 SubspaceIndices<kFullSize> projectorToSubspaceIndices(
0342 const Eigen::DenseBase<Derived>& projector) {
0343 auto rows = static_cast<std::size_t>(projector.rows());
0344 auto cols = static_cast<std::size_t>(projector.cols());
0345 assert(cols == kFullSize && rows <= kFullSize && "Invalid projector size");
0346 SubspaceIndices<kFullSize> result;
0347 result.fill(kFullSize);
0348 for (std::size_t i = 0; i < rows; ++i) {
0349 for (std::size_t j = 0; j < cols; ++j) {
0350 assert((projector(i, j) == 0 || projector(i, j) == 1) &&
0351 "Invalid projector value");
0352 if (projector(i, j) == 1) {
0353 result[i] = j;
0354 }
0355 }
0356 }
0357 return result;
0358 }
0359
0360 }