ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
partial_pivot_lud.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
9#pragma once
10
11// Project include(s).
12#include "detray/algebra/common/math.hpp"
13#include "detray/algebra/concepts.hpp"
14#include "detray/definitions/detail/qualifiers.hpp"
15
16// System include(s).
17#include <array>
18
19namespace detray::algebra::generic::matrix::decomposition {
20
22template <concepts::matrix matrix_t>
25 using scalar_t = detray::traits::value_t<matrix_t>;
27 using index_t = detray::traits::index_t<matrix_t>;
29 using vector_t = detray::traits::vector_t<matrix_t>;
30
32 template <index_t N>
33 struct lud {
36 matrix_t lu;
37
40
42 int n_pivot = 0;
43 };
44
48 DETRAY_HOST_DEVICE constexpr lud<detray::traits::max_rank<matrix_t>>
49 operator()(const matrix_t& m) const {
50 // Function (object) used for accessing a matrix element
51 using element_getter_t = detray::traits::element_getter_t<matrix_t>;
52
53 constexpr element_getter_t elem{};
54 constexpr index_t N{detray::traits::max_rank<matrix_t>};
55
56 // LU decomposition matrix
57 matrix_t lu = m;
58
59 // Permutation
60 vector_t P;
61
62 // Max index and value
63 index_t max_idx;
64 scalar_t max_val;
65 scalar_t abs_val;
66
67 // Number of pivoting
68 int n_pivot = N;
69
70 // Rows for swapping
71 vector_t row_0;
72 vector_t row_1;
73
74 // Unit permutation matrix, P[N] initialized with N
75 for (index_t i = 0; i < N; i++) {
76 P[i] = static_cast<scalar_t>(i);
77 }
78
79 for (index_t i = 0; i < N; i++) {
80 max_val = 0;
81 max_idx = i;
82
83 for (index_t k = i; k < N; k++) {
84 abs_val = algebra::math::fabs(elem(lu, k, i));
85
86 if (abs_val > max_val) {
87 max_val = abs_val;
88 max_idx = k;
89 }
90 }
91
92 if (max_idx != i) {
93 // Pivoting P
94 auto j = P[i];
95
96 P[i] = P[max_idx];
97 P[max_idx] = j;
98
99 // Pivoting rows of A
100 for (index_t q = 0; q < N; q++) {
101 row_0[q] = elem(lu, i, q);
102 row_1[q] = elem(lu, max_idx, q);
103 }
104 for (index_t q = 0; q < N; q++) {
105 elem(lu, i, q) = row_1[q];
106 elem(lu, max_idx, q) = row_0[q];
107 }
108
109 // counting pivots starting from N (for determinant)
110 n_pivot++;
111 }
112
113 for (index_t j = i + 1; j < N; j++) {
114 // m[j][i] /= m[i][i];
115 elem(lu, j, i) /= elem(lu, i, i);
116
117 for (index_t k = i + 1; k < N; k++) {
118 // m[j][k] -= m[j][i] * m[i][k];
119 elem(lu, j, k) -= elem(lu, j, i) * elem(lu, i, k);
120 }
121 }
122 }
123
124 return {lu, P, n_pivot};
125 }
126};
127
128} // namespace detray::algebra::generic::matrix::decomposition
constexpr decltype(auto) fabs(T &&vec)
Definition vc_soa_math.hpp:71
Result of LU decomposition for a matrix of rank N.
Definition partial_pivot_lud.hpp:33
int n_pivot
Number of pivots.
Definition partial_pivot_lud.hpp:42
vector_t P
Permutation vector.
Definition partial_pivot_lud.hpp:39
matrix_t lu
LU decomposition matrix, equal to (L - I) + U, where the diagonal components of L is always 1.
Definition partial_pivot_lud.hpp:36
"Partial Pivot LU Decomposition", assuming a N X N matrix
Definition partial_pivot_lud.hpp:23
constexpr lud< detray::traits::max_rank< matrix_t > > operator()(const matrix_t &m) const
Decompose the input matrix using partial pivoting.
Definition partial_pivot_lud.hpp:49
detray::traits::index_t< matrix_t > index_t
Matrix index type.
Definition partial_pivot_lud.hpp:27
detray::traits::vector_t< matrix_t > vector_t
Vector type used to store row permutations.
Definition partial_pivot_lud.hpp:29
detray::traits::value_t< matrix_t > scalar_t
Matrix element type.
Definition partial_pivot_lud.hpp:25