ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
matrix.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8#pragma once
9
10// Project include(s).
11#include "detray/algebra/common/vector.hpp"
12#include "detray/algebra/concepts.hpp"
13#include "detray/algebra/type_traits.hpp"
14
15// System include(s).
16#include <array>
17#include <cassert>
18
19namespace detray::algebra::storage {
20
22template <template <typename, std::size_t> class array_t,
23 concepts::scalar scalar_t, std::size_t ROW, std::size_t COL>
24struct DETRAY_ALIGN(alignof(algebra::storage::vector<ROW, scalar_t, array_t>))
25 matrix {
29 using scalar_type = scalar_t;
30
32 constexpr matrix() = default;
33
36 template <concepts::vector... vector_t>
37 DETRAY_HOST_DEVICE
38 requires(sizeof...(vector_t) == COL)
39 explicit matrix(vector_t &&...v) : m_storage{std::forward<vector_t>(v)...} {}
40
45 DETRAY_HOST_DEVICE
46 constexpr const vector_type &operator[](const std::size_t i) const {
47 assert(i < COL);
48 return m_storage[i];
49 }
50
52 DETRAY_HOST_DEVICE
53 constexpr vector_type &operator[](const std::size_t i) {
54 assert(i < COL);
55 return m_storage[i];
56 }
57
58
60 DETRAY_HOST_DEVICE
61 static consteval std::size_t rows() { return ROW; }
62
65 DETRAY_HOST_DEVICE
66 static consteval std::size_t storage_rows() {
68 }
69
71 DETRAY_HOST_DEVICE
72 static consteval std::size_t columns() { return COL; }
73
74 private:
76 template <std::size_t R, std::size_t C, typename S,
77 template <typename, std::size_t> class A>
78 DETRAY_HOST_DEVICE friend constexpr bool operator==(
79 const matrix<A, S, R, C> &lhs, const matrix<A, S, R, C> &rhs);
80
83 // AoS
84 template <std::size_t... I>
85 DETRAY_HOST_DEVICE
86 requires(!std::is_scalar_v<scalar_t>)
87 constexpr bool equal(const matrix &rhs,
88 std::index_sequence<I...> /*unused*/) const {
89 return (... && (m_storage[I] == rhs[I]));
90 }
91
92 // SoA
93 template <std::size_t... I>
94 DETRAY_HOST
95 requires(std::is_scalar_v<scalar_t>)
96 constexpr bool equal(const matrix &rhs,
97 std::index_sequence<I...> /*unused*/) const {
98 return (... && ((m_storage[I].get() == rhs[I].get()).isFull()));
99 }
101
104 template <std::size_t R, std::size_t C, typename S,
105 template <typename, std::size_t> class A>
106 DETRAY_HOST_DEVICE friend constexpr decltype(auto) operator+(
107 const matrix<A, S, R, C> &lhs, const matrix<A, S, R, C> &rhs) noexcept;
108
109 template <std::size_t R, std::size_t C, typename S,
110 template <typename, std::size_t> class A>
111 DETRAY_HOST_DEVICE friend constexpr decltype(auto) operator-(
112 const matrix<A, S, R, C> &lhs, const matrix<A, S, R, C> &rhs) noexcept;
113
114 template <std::size_t R, std::size_t C, typename S1, typename S2,
115 template <typename, std::size_t> class A>
116 DETRAY_HOST_DEVICE friend constexpr decltype(auto) operator*(
117 const S2 a, const matrix<A, S1, R, C> &rhs) noexcept;
118
119 template <std::size_t R, std::size_t C, concepts::scalar S1,
120 concepts::scalar S2, template <typename, std::size_t> class A>
121 DETRAY_HOST_DEVICE friend constexpr decltype(auto) operator*(
122 const matrix<A, S1, R, C> &lhs, const S2 a) noexcept;
123
125 template <std::size_t R, std::size_t C, typename S,
126 template <typename, std::size_t> class A>
127 DETRAY_HOST_DEVICE friend constexpr decltype(auto) operator*(
128 const matrix<A, S, R, C> &lhs, const vector<C, S, A> &v) noexcept;
129
131 template <std::size_t LR, std::size_t C, std::size_t RC, typename S,
132 template <typename, std::size_t> class A>
133 DETRAY_HOST_DEVICE friend constexpr decltype(auto) operator*(
134 const matrix<A, S, LR, C> &lhs, const matrix<A, S, C, RC> &rhs) noexcept;
136
138 std::array<vector_type, COL> m_storage;
139
140}; // struct matrix
141
143template <concepts::matrix matrix_t, std::size_t COLS = matrix_t::columns()>
144DETRAY_HOST_DEVICE constexpr matrix_t zero() noexcept {
145 matrix_t m;
146
147 DETRAY_UNROLL_N(COLS)
148 for (std::size_t j = 0u; j < COLS; ++j) {
149 // Fill zero initialized vector
150 m[j] = typename matrix_t::vector_type{};
151 }
152
153 return m;
154}
155
157template <concepts::matrix matrix_t>
158DETRAY_HOST_DEVICE constexpr void set_zero(matrix_t &m) noexcept {
159 m = zero<matrix_t>();
160}
161
163template <concepts::matrix matrix_t,
164 std::size_t R = detray::traits::max_rank<matrix_t>>
165DETRAY_HOST_DEVICE constexpr matrix_t identity() noexcept {
166 // Zero initialized
167 matrix_t m{zero<matrix_t>()};
168
169 DETRAY_UNROLL_N(R)
170 for (std::size_t i = 0u; i < R; ++i) {
171 m[i][i] = typename matrix_t::scalar_type(1);
172 }
173
174 return m;
175}
176
178template <concepts::matrix matrix_t>
179DETRAY_HOST_DEVICE constexpr void set_identity(matrix_t &m) noexcept {
180 m = identity<matrix_t>();
181}
182
184template <std::size_t ROW, std::size_t COL, concepts::scalar scalar_t,
185 template <typename, std::size_t> class array_t, std::size_t... I>
186DETRAY_HOST_DEVICE constexpr auto transpose(
188 std::index_sequence<I...> /*unused*/) noexcept {
189 using matrix_T_t = matrix<array_t, scalar_t, COL, ROW>;
190 using column_t = typename matrix_T_t::vector_type;
191
192 matrix_T_t res_m;
193
194 DETRAY_UNROLL_N(ROW)
195 for (std::size_t j = 0u; j < ROW; ++j) {
196 res_m[j] = column_t{m[I][j]...};
197 }
198
199 return res_m;
200}
201
203template <concepts::matrix matrix_t>
204DETRAY_HOST_DEVICE constexpr auto transpose(const matrix_t &m) noexcept {
205 return transpose(m, std::make_index_sequence<matrix_t::columns()>());
206}
207
209template <std::size_t ROW, std::size_t COL, typename scalar_t,
210 template <typename, std::size_t> class array_t>
211DETRAY_HOST_DEVICE constexpr bool operator==(
214 return lhs.equal(rhs, std::make_index_sequence<COL>());
215}
216
218template <concepts::matrix matrix_t, concepts::scalar scalar_t,
219 std::size_t... J>
220DETRAY_HOST_DEVICE constexpr matrix_t matrix_scalar_mul(
221 scalar_t a, const matrix_t &rhs,
222 std::index_sequence<J...> /*unused*/) noexcept {
223 using mat_scalar_t = detray::traits::scalar_t<matrix_t>;
224
225 return matrix_t{(static_cast<mat_scalar_t>(a) * rhs[J])...};
226}
227
229template <concepts::matrix matrix_t, std::size_t... J>
230DETRAY_HOST_DEVICE constexpr matrix_t matrix_add(
231 const matrix_t &lhs, const matrix_t &rhs,
232 std::index_sequence<J...> /*unused*/) noexcept {
233 return matrix_t{(lhs[J] + rhs[J])...};
234}
235
236template <concepts::matrix matrix_t, std::size_t... J>
237DETRAY_HOST_DEVICE constexpr decltype(auto) matrix_sub(
238 const matrix_t &lhs, const matrix_t &rhs,
239 std::index_sequence<J...> /*unused*/) noexcept {
240 return matrix_t{(lhs[J] - rhs[J])...};
241}
242
245template <std::size_t ROW, std::size_t COL, concepts::scalar scalar_t,
246 template <typename, std::size_t> class array_t>
247DETRAY_HOST_DEVICE constexpr decltype(auto) operator+(
249 const matrix<array_t, scalar_t, ROW, COL> &rhs) noexcept {
251
252 return matrix_add(lhs, rhs, std::make_index_sequence<matrix_t::columns()>());
253}
254
255template <std::size_t ROW, std::size_t COL, concepts::scalar scalar_t,
256 template <typename, std::size_t> class array_t>
257DETRAY_HOST_DEVICE constexpr decltype(auto) operator-(
259 const matrix<array_t, scalar_t, ROW, COL> &rhs) noexcept {
261
262 return matrix_sub(lhs, rhs, std::make_index_sequence<matrix_t::columns()>());
263}
264
265template <std::size_t R, std::size_t C, typename S1, typename S2,
266 template <typename, std::size_t> class A>
267DETRAY_HOST_DEVICE constexpr decltype(auto) operator*(
268 const S2 a, const matrix<A, S1, R, C> &rhs) noexcept {
269 using matrix_t = matrix<A, S2, R, C>;
270
271 return matrix_scalar_mul(static_cast<S1>(a), rhs,
272 std::make_index_sequence<matrix_t::columns()>());
273}
274
275template <std::size_t R, std::size_t C, concepts::scalar S1,
276 concepts::scalar S2, template <typename, std::size_t> class A>
277DETRAY_HOST_DEVICE constexpr decltype(auto) operator*(
278 const matrix<A, S1, R, C> &lhs, const S2 a) noexcept {
279 return static_cast<S1>(a) * lhs;
280}
281
283template <std::size_t ROW, std::size_t COL, concepts::scalar scalar_t,
284 template <typename, std::size_t> class array_t>
285DETRAY_HOST_DEVICE constexpr decltype(auto) operator*(
287 const vector<COL, scalar_t, array_t> &v) noexcept {
288 // Init vector
289 vector<ROW, scalar_t, array_t> res_v{v[0] * lhs[0]};
290
291 // Add the rest per column
292 DETRAY_UNROLL_N(COL)
293 for (std::size_t j = 1u; j < COL; ++j) {
294 // fma
295 res_v = res_v + v[j] * lhs[j];
296 }
297
298 return res_v;
299}
300
302template <std::size_t LROW, std::size_t COL, std::size_t RCOL,
303 concepts::scalar scalar_t,
304 template <typename, std::size_t> class array_t>
305DETRAY_HOST_DEVICE constexpr decltype(auto) operator*(
307 const matrix<array_t, scalar_t, COL, RCOL> &rhs) noexcept {
309
310 DETRAY_UNROLL_N(RCOL)
311 for (std::size_t j = 0u; j < RCOL; ++j) {
312 // Init column j
313 res_m[j] = rhs[j][0] * lhs[0];
314
315 // Add the rest per column
316 DETRAY_UNROLL_N(COL)
317 for (std::size_t i = 1u; i < COL; ++i) {
318 // fma
319 res_m[j] = res_m[j] + rhs[j][i] * lhs[i];
320 }
321 }
322
323 return res_m;
324}
326
327} // namespace detray::algebra::storage
Vector wrapper for AoS vs interleaved SoA data.
Definition vector.hpp:52
static consteval std::size_t simd_size()
Definition vector.hpp:56
Scalar concept: Elements of vectors/matrices (can be simd vectors).
Definition concepts.hpp:40
Vector concepts.
Definition concepts.hpp:59
constexpr double m
Meter.
Definition Units.hpp:97
constexpr double J
Joule in GeV.
Definition Units.hpp:153
@ R
Radial coordinate.
Definition SpacePointColumns.hpp:26
const auto & get(const detray::tuple< Ts... > &t) noexcept
Get a tuple element by index from a const tuple.
Definition tuple.hpp:152
Generic matrix type that can take vectors as columns.
Definition matrix.hpp:25
constexpr vector_type & operator[](const std::size_t i)
Definition matrix.hpp:53
static consteval std::size_t storage_rows()
Definition matrix.hpp:66
algebra::storage::vector< ROW, scalar_t, array_t > vector_type
The matrix consists of column vectors.
Definition matrix.hpp:27
matrix(vector_t &&...v)
Construct from given column vectors v.
Definition matrix.hpp:39
static consteval std::size_t columns()
Definition matrix.hpp:72
static consteval std::size_t rows()
Definition matrix.hpp:61
constexpr matrix()=default
Default constructor.
friend constexpr bool operator==(const matrix< A, S, R, C > &lhs, const matrix< A, S, R, C > &rhs)
Equality operator between two matrices.
scalar_t scalar_type
Value type: Can be simd types.
Definition matrix.hpp:29
constexpr const vector_type & operator[](const std::size_t i) const
Subscript operator.
Definition matrix.hpp:46