12#include "detray/algebra/common/math.hpp"
13#include "detray/algebra/concepts.hpp"
14#include "detray/algebra/generic/algorithms/utils/algorithm_selector.hpp"
15#include "detray/algebra/generic/impl/generic_vector.hpp"
16#include "detray/definitions/detail/qualifiers.hpp"
18namespace detray::algebra::generic::math {
21template <concepts::matrix M>
22DETRAY_HOST_DEVICE
constexpr M zero() {
23 using index_t = detray::traits::index_t<M>;
24 using element_getter_t = detray::traits::element_getter_t<M>;
28 for (index_t j = 0; j < detray::traits::columns<M>; ++j) {
29 for (index_t i = 0; i < detray::traits::rows<M>; ++i) {
30 element_getter_t{}(ret, i, j) = 0;
38template <concepts::matrix M>
39DETRAY_HOST_DEVICE
constexpr M identity() {
40 using index_t = detray::traits::index_t<M>;
41 using element_getter_t = detray::traits::element_getter_t<M>;
45 for (index_t i = 0; i < detray::traits::max_rank<M>; ++i) {
46 element_getter_t{}(ret, i, i) = 1;
53template <concepts::matrix M>
54DETRAY_HOST_DEVICE
constexpr void set_zero(M &m) {
59template <concepts::matrix M>
60DETRAY_HOST_DEVICE
constexpr void set_identity(M &m) {
65template <concepts::matrix M>
66DETRAY_HOST_DEVICE
constexpr auto transpose(
const M &m) {
67 using index_t = detray::traits::index_t<M>;
68 using value_t = detray::traits::value_t<M>;
69 using element_getter_t = detray::traits::element_getter_t<M>;
71 constexpr index_t rows{detray::traits::rows<M>};
72 constexpr index_t columns{detray::traits::columns<M>};
74 detray::traits::get_matrix_t<M, columns, rows, value_t> ret;
76 for (index_t i = 0; i < rows; ++i) {
77 for (index_t j = 0; j < columns; ++j) {
78 element_getter_t{}(ret, j, i) = element_getter_t{}(
m, i, j);
86template <concepts::square_matrix M, concepts::vector3D V>
87 requires(detray::traits::max_rank<M> == 3u)
88DETRAY_HOST_DEVICE
constexpr M column_wise_cross(
const M &m,
const V &v) {
89 using block_getter_t = detray::traits::block_getter_t<M>;
90 constexpr block_getter_t block{};
94 const V m_col0 = block.template vector<3>(m, 0u, 0u);
95 const V m_col1 = block.template vector<3>(m, 0u, 1u);
96 const V m_col2 = block.template vector<3>(m, 0u, 2u);
98 block.set(ret,
static_cast<V
>(cross(m_col0, v)), 0u, 0u);
99 block.set(ret,
static_cast<V
>(cross(m_col1, v)), 0u, 1u);
100 block.set(ret,
static_cast<V
>(cross(m_col2, v)), 0u, 2u);
106template <concepts::square_matrix M, concepts::vector V>
107 requires(detray::traits::max_rank<M> == detray::traits::size<V>)
108DETRAY_HOST_DEVICE
inline M column_wise_multiply(
const M &m,
const V &v) {
109 using element_getter_t = detray::traits::element_getter_t<M>;
110 constexpr element_getter_t elem{};
114 constexpr std::size_t N{detray::traits::max_rank<M>};
115 for (std::size_t i = 0u; i < N; i++) {
116 for (std::size_t j = 0u; j < N; j++) {
117 elem(ret, j, i) = elem(m, j, i) * elem(v, j);
125template <concepts::vector3D V3>
126DETRAY_HOST_DEVICE
inline auto cross_matrix(
const V3 &v) {
127 using scalar_t = detray::traits::scalar_t<V3>;
128 using matrix_33_t = detray::traits::get_matrix_t<V3, 3, 3, scalar_t>;
130 using element_getter_t = detray::traits::element_getter_t<V3>;
131 constexpr element_getter_t elem{};
134 elem(ret, 0u, 0u) = 0.f;
135 elem(ret, 0u, 1u) = -elem(v, 2u);
136 elem(ret, 0u, 2u) = elem(v, 1u);
137 elem(ret, 1u, 0u) = elem(v, 2u);
138 elem(ret, 1u, 1u) = 0.f;
139 elem(ret, 1u, 2u) = -elem(v, 0u);
140 elem(ret, 2u, 0u) = -elem(v, 1u);
141 elem(ret, 2u, 1u) = elem(v, 0u);
142 elem(ret, 2u, 2u) = 0.f;
148template <concepts::vector V>
149DETRAY_HOST_DEVICE
inline detray::traits::get_matrix_t<
150 V, detray::traits::size<V>, detray::traits::size<V>,
151 detray::traits::scalar_t<V>>
152outer_product(
const V &v1,
const V &v2) {
153 using scalar_t = detray::traits::scalar_t<V>;
154 using index_t = detray::traits::index_t<V>;
156 constexpr auto N{
static_cast<index_t
>(detray::traits::size<V>)};
157 using matrix_t = detray::traits::get_matrix_t<V, N, N, scalar_t>;
159 using element_getter_t = detray::traits::element_getter_t<V>;
160 constexpr element_getter_t elem{};
165 for (index_t row = 0; row < N; row++) {
166 for (index_t col = 0; col < N; col++) {
167 elem(ret, row, col) = elem(v1, row) * elem(v2, col);
175template <concepts::matrix MC, concepts::matrix MA, concepts::matrix MB>
176DETRAY_HOST_DEVICE
constexpr void set_product(MC &C,
const MA &A,
const MB &B)
177 requires(detray::concepts::matrix_multipliable_into<MA, MB, MC>)
179 using index_t = detray::traits::index_t<MC>;
180 using value_t = detray::traits::value_t<MC>;
182 for (index_t i = 0; i < detray::traits::rows<MC>; ++i) {
183 for (index_t j = 0; j < detray::traits::columns<MC>; ++j) {
186 for (index_t k = 0; k < detray::traits::rows<MB>; ++k) {
187 t += detray::traits::element_getter_t<MA>()(A, i, k) *
188 detray::traits::element_getter_t<MB>()(B, k, j);
191 detray::traits::element_getter_t<MC>()(C, i, j) = t;
197template <concepts::matrix MC, concepts::matrix MA, concepts::matrix MB>
198DETRAY_HOST_DEVICE
constexpr void set_product_left_transpose(MC &C,
const MA &A,
200 requires(detray::concepts::matrix_multipliable_into<
201 decltype(transpose(std::declval<MA>())), MB, MC>)
203 using index_t = detray::traits::index_t<MC>;
204 using value_t = detray::traits::value_t<MC>;
206 for (index_t i = 0; i < detray::traits::rows<MC>; ++i) {
207 for (index_t j = 0; j < detray::traits::columns<MC>; ++j) {
210 for (index_t k = 0; k < detray::traits::rows<MB>; ++k) {
211 t += detray::traits::element_getter_t<MA>()(A, k, i) *
212 detray::traits::element_getter_t<MB>()(B, k, j);
215 detray::traits::element_getter_t<MC>()(C, i, j) = t;
221template <concepts::matrix MC, concepts::matrix MA, concepts::matrix MB>
222DETRAY_HOST_DEVICE
constexpr void set_product_right_transpose(MC &C,
225 requires(detray::concepts::matrix_multipliable_into<
226 MA,
decltype(transpose(std::declval<MB>())), MC>)
228 using index_t = detray::traits::index_t<MC>;
229 using value_t = detray::traits::value_t<MC>;
231 for (index_t i = 0; i < detray::traits::rows<MC>; ++i) {
232 for (index_t j = 0; j < detray::traits::columns<MC>; ++j) {
235 for (index_t k = 0; k < detray::traits::columns<MA>; ++k) {
236 t += detray::traits::element_getter_t<MA>()(A, i, k) *
237 detray::traits::element_getter_t<MB>()(B, j, k);
240 detray::traits::element_getter_t<MC>()(C, i, j) = t;
246template <concepts::matrix MA, concepts::matrix MB>
247DETRAY_HOST_DEVICE
constexpr void set_inplace_product_right(MA &A,
const MB &B)
248 requires(detray::concepts::matrix_multipliable_into<MA, MB, MA>)
250 using index_t = detray::traits::index_t<MA>;
251 using value_t = detray::traits::value_t<MA>;
253 for (index_t i = 0; i < detray::traits::rows<MA>; ++i) {
254 detray::traits::get_matrix_t<MA, 1, detray::traits::columns<MA>, value_t> Q;
256 for (index_t j = 0; j < detray::traits::columns<MA>; ++j) {
257 detray::traits::element_getter_t<decltype(Q)>()(Q, 0, j) =
258 detray::traits::element_getter_t<MA>()(A, i, j);
261 for (index_t j = 0; j < detray::traits::columns<MA>; ++j) {
264 for (index_t k = 0; k < detray::traits::rows<MB>; ++k) {
265 t += detray::traits::element_getter_t<decltype(Q)>()(Q, 0, k) *
266 detray::traits::element_getter_t<MB>()(B, k, j);
269 detray::traits::element_getter_t<MA>()(A, i, j) = t;
275template <concepts::matrix MA, concepts::matrix MB>
276DETRAY_HOST_DEVICE
constexpr void set_inplace_product_left(MA &A,
const MB &B)
277 requires(detray::concepts::matrix_multipliable_into<MB, MA, MA>)
279 using index_t = detray::traits::index_t<MA>;
280 using value_t = detray::traits::value_t<MA>;
282 for (index_t j = 0; j < detray::traits::columns<MA>; ++j) {
283 detray::traits::get_matrix_t<MA, 1, detray::traits::columns<MA>, value_t> Q;
285 for (index_t i = 0; i < detray::traits::rows<MA>; ++i) {
286 detray::traits::element_getter_t<decltype(Q)>()(Q, 0, i) =
287 detray::traits::element_getter_t<MA>()(A, i, j);
290 for (index_t i = 0; i < detray::traits::rows<MA>; ++i) {
293 for (index_t k = 0; k < detray::traits::columns<MB>; ++k) {
294 t += detray::traits::element_getter_t<MB>()(B, i, k) *
295 detray::traits::element_getter_t<
decltype(Q)>()(Q, 0, k);
298 detray::traits::element_getter_t<MA>()(A, i, j) = t;
304template <concepts::matrix MA, concepts::matrix MB>
305DETRAY_HOST_DEVICE
constexpr void set_inplace_product_right_transpose(
307 requires(detray::concepts::matrix_multipliable_into<
308 MA,
decltype(transpose(std::declval<MB>())), MA>)
310 using index_t = detray::traits::index_t<MA>;
311 using value_t = detray::traits::value_t<MA>;
313 for (index_t i = 0; i < detray::traits::rows<MA>; ++i) {
314 detray::traits::get_matrix_t<MA, 1, detray::traits::columns<MA>, value_t> Q;
316 for (index_t j = 0; j < detray::traits::columns<MA>; ++j) {
317 detray::traits::element_getter_t<decltype(Q)>()(Q, 0, j) =
318 detray::traits::element_getter_t<MA>()(A, i, j);
321 for (index_t j = 0; j < detray::traits::columns<MA>; ++j) {
324 for (index_t k = 0; k < detray::traits::columns<MB>; ++k) {
325 T += detray::traits::element_getter_t<decltype(Q)>()(Q, 0, k) *
326 detray::traits::element_getter_t<MB>()(B, j, k);
329 detray::traits::element_getter_t<MA>()(A, i, j) = T;
335template <concepts::matrix MA, concepts::matrix MB>
336DETRAY_HOST_DEVICE
constexpr void set_inplace_product_left_transpose(
338 requires(detray::concepts::matrix_multipliable_into<
339 decltype(transpose(std::declval<MB>())), MA, MA>)
341 using index_t = detray::traits::index_t<MA>;
342 using value_t = detray::traits::value_t<MA>;
344 for (index_t j = 0; j < detray::traits::columns<MA>; ++j) {
345 detray::traits::get_matrix_t<MA, 1, detray::traits::columns<MA>, value_t> Q;
347 for (index_t i = 0; i < detray::traits::rows<MA>; ++i) {
348 detray::traits::element_getter_t<decltype(Q)>()(Q, 0, i) =
349 detray::traits::element_getter_t<MA>()(A, i, j);
352 for (index_t i = 0; i < detray::traits::rows<MA>; ++i) {
355 for (index_t k = 0; k < detray::traits::rows<MB>; ++k) {
356 T += detray::traits::element_getter_t<MB>()(B, k, i) *
357 detray::traits::element_getter_t<
decltype(Q)>()(Q, 0, k);
360 detray::traits::element_getter_t<MA>()(A, i, j) = T;
365template <
bool transpose, concepts::matrix M>
366DETRAY_HOST_DEVICE
constexpr detray::traits::value_t<M> transposable_get(
367 const M &A,
const detray::traits::index_t<M> i,
368 const detray::traits::index_t<M> j) {
369 if constexpr (transpose) {
370 return detray::traits::element_getter_t<M>()(A, j, i);
372 return detray::traits::element_getter_t<M>()(A, i, j);
376template <
bool transpose_left,
bool transpose_right, concepts::matrix MA,
378DETRAY_HOST_DEVICE
constexpr auto transposed_product(
const MA &A,
const MB &B)
379 requires(detray::concepts::matrix_multipliable<
380 std::conditional_t<transpose_left,
381 decltype(transpose(std::declval<MA>())), MA>,
382 std::conditional_t<transpose_right,
383 decltype(transpose(std::declval<MB>())), MB>>)
385 using index_t = detray::traits::index_t<MA>;
386 using value_t = detray::traits::value_t<MA>;
388 using effective_lhs_t =
389 std::conditional_t<transpose_left,
390 decltype(transpose(std::declval<MA>())), MA>;
391 using effective_rhs_t =
392 std::conditional_t<transpose_right,
393 decltype(transpose(std::declval<MB>())), MB>;
396 detray::traits::get_matrix_t<MA, detray::traits::rows<effective_lhs_t>,
397 detray::traits::columns<effective_rhs_t>,
400 result_t C = zero<result_t>();
402 for (index_t i = 0; i < detray::traits::columns<effective_lhs_t>; ++i) {
403 for (index_t j = 0; j < detray::traits::columns<result_t>; ++j) {
404 for (index_t k = 0; k < detray::traits::rows<result_t>; ++k) {
405 detray::traits::element_getter_t<result_t>()(C, k, j) +=
406 transposable_get<transpose_left>(A, k, i) *
407 transposable_get<transpose_right>(B, i, j);
416template <concepts::square_matrix M>
417DETRAY_HOST_DEVICE
constexpr detray::traits::scalar_t<M> determinant(
419 return determinant_t<M>{}(
m);
423template <concepts::square_matrix M>
424DETRAY_HOST_DEVICE
constexpr M inverse(
const M &m) {
425 return inversion_t<M>{}(
m);
429template <concepts::square_matrix M>
430DETRAY_HOST_DEVICE
constexpr M cholesky_decomposition(
const M &m) {
431 using index_t = detray::traits::index_t<M>;
432 using scalar_t = detray::traits::scalar_t<M>;
433 using element_getter_t = detray::traits::element_getter_t<M>;
435 constexpr element_getter_t elem{};
436 constexpr index_t N{detray::traits::max_rank<M>};
441 for (std::size_t i = 0u; i < N; i++) {
442 for (std::size_t j = 0u; j <= i; j++) {
444 for (std::size_t k = 0u; k < j; k++) {
445 sum += elem(L, i, k) * elem(L, j, k);
449 elem(L, i, j) =
static_cast<scalar_t
>(
452 elem(L, i, j) = (1.f / elem(L, j, j) * (elem(m, i, j) - sum));
constexpr double m
Meter.
Definition Units.hpp:97
constexpr double T
Magnetic field, native unit (eV*s)/(e*m²).
Definition Units.hpp:168
constexpr decltype(auto) sqrt(T &&vec)
Definition vc_soa_math.hpp:78