File indexing completed on 2025-01-18 09:11:08
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012
0013 #include <bitset>
0014 #include <optional>
0015
0016 #include "Eigen/Dense"
0017
0018 namespace Acts {
0019
0020
0021
0022
0023
0024
0025
0026
0027 template <typename MatrixType>
0028 MatrixType bitsetToMatrix(const std::bitset<MatrixType::RowsAtCompileTime *
0029 MatrixType::ColsAtCompileTime>
0030 bs) {
0031 constexpr int rows = MatrixType::RowsAtCompileTime;
0032 constexpr int cols = MatrixType::ColsAtCompileTime;
0033
0034 static_assert(rows != -1 && cols != -1,
0035 "bitsetToMatrix does not support dynamic matrices");
0036
0037 MatrixType m;
0038 auto* p = m.data();
0039 for (std::size_t i = 0; i < rows * cols; i++) {
0040 p[i] = bs[rows * cols - 1 - i];
0041 }
0042 return m;
0043 }
0044
0045
0046
0047
0048
0049
0050
0051 template <typename Derived>
0052 auto matrixToBitset(const Eigen::PlainObjectBase<Derived>& m) {
0053 using MatrixType = Eigen::PlainObjectBase<Derived>;
0054 constexpr std::size_t rows = MatrixType::RowsAtCompileTime;
0055 constexpr std::size_t cols = MatrixType::ColsAtCompileTime;
0056
0057 std::bitset<rows * cols> res;
0058
0059 auto* p = m.data();
0060 for (std::size_t i = 0; i < rows * cols; i++) {
0061 res[rows * cols - 1 - i] = static_cast<bool>(p[i]);
0062 }
0063
0064 return res;
0065 }
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 template <typename A, typename B>
0078 inline ActsMatrix<A::RowsAtCompileTime, B::ColsAtCompileTime> blockedMult(
0079 const A& a, const B& b) {
0080
0081
0082 constexpr int M = A::RowsAtCompileTime;
0083 constexpr int N = A::ColsAtCompileTime;
0084 constexpr int P = B::ColsAtCompileTime;
0085
0086
0087
0088 static_assert(N == B::RowsAtCompileTime);
0089
0090 if constexpr (M <= 4 && N <= 4 && P <= 4) {
0091
0092
0093 return a * b;
0094 } else {
0095
0096
0097
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 constexpr int M1 = M / 2;
0128 constexpr int M2 = (M + 1) / 2;
0129 constexpr int N1 = N / 2;
0130 constexpr int N2 = (N + 1) / 2;
0131 constexpr int P1 = P / 2;
0132 constexpr int P2 = (P + 1) / 2;
0133
0134
0135
0136 ActsMatrix<M, P> r;
0137
0138
0139 r.template topLeftCorner<M1, P1>().noalias() =
0140 a.template topLeftCorner<M1, N1>() *
0141 b.template topLeftCorner<N1, P1>() +
0142 a.template topRightCorner<M1, N2>() *
0143 b.template bottomLeftCorner<N2, P1>();
0144
0145
0146 r.template topRightCorner<M1, P2>().noalias() =
0147 a.template topLeftCorner<M1, N1>() *
0148 b.template topRightCorner<N1, P2>() +
0149 a.template topRightCorner<M1, N2>() *
0150 b.template bottomRightCorner<N2, P2>();
0151
0152
0153 r.template bottomLeftCorner<M2, P1>().noalias() =
0154 a.template bottomLeftCorner<M2, N1>() *
0155 b.template topLeftCorner<N1, P1>() +
0156 a.template bottomRightCorner<M2, N2>() *
0157 b.template bottomLeftCorner<N2, P1>();
0158
0159
0160 r.template bottomRightCorner<M2, P2>().noalias() =
0161 a.template bottomLeftCorner<M2, N1>() *
0162 b.template topRightCorner<N1, P2>() +
0163 a.template bottomRightCorner<M2, N2>() *
0164 b.template bottomRightCorner<N2, P2>();
0165
0166 return r;
0167 }
0168 }
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 template <typename MatrixType, typename ResultType = MatrixType>
0190 std::optional<ResultType> safeInverse(const MatrixType& m) noexcept {
0191 constexpr int rows = MatrixType::RowsAtCompileTime;
0192 constexpr int cols = MatrixType::ColsAtCompileTime;
0193
0194 static_assert(rows == cols);
0195
0196 ResultType result;
0197 bool invertible = false;
0198
0199 if constexpr (rows > 4 || rows == -1) {
0200 Eigen::FullPivLU<MatrixType> mFullPivLU(m);
0201 if (mFullPivLU.isInvertible()) {
0202 invertible = true;
0203 result = mFullPivLU.inverse();
0204 }
0205 } else {
0206 m.computeInverseWithCheck(result, invertible);
0207 }
0208
0209 if (invertible) {
0210 return result;
0211 }
0212
0213 return std::nullopt;
0214 }
0215
0216
0217
0218
0219 template <typename T>
0220 struct ExpSafeLimit {};
0221 template <>
0222 struct ExpSafeLimit<double> {
0223 constexpr static double value = 500.0;
0224 };
0225 template <>
0226 struct ExpSafeLimit<float> {
0227 constexpr static float value = 50.0;
0228 };
0229
0230
0231
0232
0233
0234
0235
0236 template <typename T>
0237 constexpr T safeExp(T val) noexcept {
0238 constexpr T maxExponent = ExpSafeLimit<T>::value;
0239 constexpr T minExponent = -maxExponent;
0240 if (val < minExponent) {
0241 return 0.0;
0242 }
0243
0244 if (val > maxExponent) {
0245 return std::numeric_limits<T>::infinity();
0246 }
0247
0248 return std::exp(val);
0249 }
0250
0251 }