File indexing completed on 2025-11-09 09:23:40
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Utilities/ArrayHelpers.hpp"
0013 #include "Acts/Utilities/MathHelpers.hpp"
0014
0015 #include <bitset>
0016 #include <cassert>
0017 #include <optional>
0018
0019 #include "Eigen/Dense"
0020
0021 namespace Acts {
0022
0023
0024
0025
0026
0027
0028
0029
0030 template <typename MatrixType>
0031 MatrixType bitsetToMatrix(const std::bitset<MatrixType::RowsAtCompileTime *
0032 MatrixType::ColsAtCompileTime>
0033 bs) {
0034 constexpr int rows = MatrixType::RowsAtCompileTime;
0035 constexpr int cols = MatrixType::ColsAtCompileTime;
0036
0037 static_assert(rows != -1 && cols != -1,
0038 "bitsetToMatrix does not support dynamic matrices");
0039
0040 MatrixType m;
0041 auto* p = m.data();
0042 for (std::size_t i = 0; i < rows * cols; i++) {
0043 p[i] = bs[rows * cols - 1 - i];
0044 }
0045 return m;
0046 }
0047
0048
0049
0050
0051
0052
0053
0054 template <typename Derived>
0055 auto matrixToBitset(const Eigen::PlainObjectBase<Derived>& m) {
0056 using MatrixType = Eigen::PlainObjectBase<Derived>;
0057 constexpr std::size_t rows = MatrixType::RowsAtCompileTime;
0058 constexpr std::size_t cols = MatrixType::ColsAtCompileTime;
0059
0060 std::bitset<rows * cols> res;
0061
0062 auto* p = m.data();
0063 for (std::size_t i = 0; i < rows * cols; i++) {
0064 res[rows * cols - 1 - i] = static_cast<bool>(p[i]);
0065 }
0066
0067 return res;
0068 }
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 template <typename A, typename B>
0081 inline ActsMatrix<A::RowsAtCompileTime, B::ColsAtCompileTime> blockedMult(
0082 const A& a, const B& b) {
0083
0084
0085 constexpr int M = A::RowsAtCompileTime;
0086 constexpr int N = A::ColsAtCompileTime;
0087 constexpr int P = B::ColsAtCompileTime;
0088
0089
0090
0091 static_assert(N == B::RowsAtCompileTime);
0092
0093 if constexpr (M <= 4 && N <= 4 && P <= 4) {
0094
0095
0096 return a * b;
0097 } else {
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 constexpr int M1 = M / 2;
0131 constexpr int M2 = (M + 1) / 2;
0132 constexpr int N1 = N / 2;
0133 constexpr int N2 = (N + 1) / 2;
0134 constexpr int P1 = P / 2;
0135 constexpr int P2 = (P + 1) / 2;
0136
0137
0138
0139 ActsMatrix<M, P> r;
0140
0141
0142 r.template topLeftCorner<M1, P1>().noalias() =
0143 a.template topLeftCorner<M1, N1>() *
0144 b.template topLeftCorner<N1, P1>() +
0145 a.template topRightCorner<M1, N2>() *
0146 b.template bottomLeftCorner<N2, P1>();
0147
0148
0149 r.template topRightCorner<M1, P2>().noalias() =
0150 a.template topLeftCorner<M1, N1>() *
0151 b.template topRightCorner<N1, P2>() +
0152 a.template topRightCorner<M1, N2>() *
0153 b.template bottomRightCorner<N2, P2>();
0154
0155
0156 r.template bottomLeftCorner<M2, P1>().noalias() =
0157 a.template bottomLeftCorner<M2, N1>() *
0158 b.template topLeftCorner<N1, P1>() +
0159 a.template bottomRightCorner<M2, N2>() *
0160 b.template bottomLeftCorner<N2, P1>();
0161
0162
0163 r.template bottomRightCorner<M2, P2>().noalias() =
0164 a.template bottomLeftCorner<M2, N1>() *
0165 b.template topRightCorner<N1, P2>() +
0166 a.template bottomRightCorner<M2, N2>() *
0167 b.template bottomRightCorner<N2, P2>();
0168
0169 return r;
0170 }
0171 }
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 template <typename MatrixType, typename ResultType = MatrixType>
0193 std::optional<ResultType> safeInverse(const MatrixType& m) noexcept {
0194 constexpr int rows = MatrixType::RowsAtCompileTime;
0195 constexpr int cols = MatrixType::ColsAtCompileTime;
0196
0197 static_assert(rows == cols);
0198
0199 ResultType result;
0200 bool invertible = false;
0201
0202 if constexpr (rows > 4 || rows == -1) {
0203 Eigen::FullPivLU<MatrixType> mFullPivLU(m);
0204 if (mFullPivLU.isInvertible()) {
0205 invertible = true;
0206 result = mFullPivLU.inverse();
0207 }
0208 } else {
0209 m.computeInverseWithCheck(result, invertible);
0210 }
0211
0212 if (invertible) {
0213 return result;
0214 }
0215
0216 return std::nullopt;
0217 }
0218
0219
0220
0221
0222 template <typename T>
0223 struct ExpSafeLimit {};
0224 template <>
0225 struct ExpSafeLimit<double> {
0226 constexpr static double value = 500.0;
0227 };
0228 template <>
0229 struct ExpSafeLimit<float> {
0230 constexpr static float value = 50.0;
0231 };
0232
0233
0234
0235
0236
0237
0238
0239 template <typename T>
0240 constexpr T safeExp(T val) noexcept {
0241 constexpr T maxExponent = ExpSafeLimit<T>::value;
0242 constexpr T minExponent = -maxExponent;
0243 if (val < minExponent) {
0244 return 0.0;
0245 }
0246
0247 if (val > maxExponent) {
0248 return std::numeric_limits<T>::infinity();
0249 }
0250
0251 return std::exp(val);
0252 }
0253
0254
0255
0256
0257
0258
0259 template <std::size_t N>
0260 constexpr std::size_t vecIdxFromSymMat(const std::size_t i, const std::size_t k)
0261 requires(N > 0)
0262 {
0263 assert(i < N);
0264 assert(k < N);
0265 if (k > i) {
0266 return vecIdxFromSymMat<N>(k, i);
0267 }
0268 return sumUpToN(i) + k;
0269 }
0270
0271
0272
0273
0274
0275
0276 template <std::size_t N>
0277 constexpr std::array<std::size_t, 2> symMatIndices(const std::size_t k)
0278 requires(N > 1)
0279 {
0280 assert(k < sumUpToN(N));
0281 constexpr std::size_t bound = sumUpToN(N - 1);
0282 if (k >= bound) {
0283 return std::array<std::size_t, 2>{N - 1, k - bound};
0284 }
0285 if constexpr (N > 2) {
0286 return symMatIndices<N - 1>(k);
0287 }
0288 return filledArray<std::size_t, 2>(0);
0289 }
0290
0291 }