7namespace uni20::linalg::detail::cpu_reference
9template <
class MatrixMdspan>
10void swap_rows(MatrixMdspan& matrix, std::size_t lhs, std::size_t rhs, std::size_t columns)
12 if (lhs == rhs)
return;
13 using index_type =
typename std::remove_cvref_t<MatrixMdspan>::index_type;
14 for (std::size_t col = 0; col <
columns; ++col)
16 auto const left_index =
static_cast<index_type>(lhs);
17 auto const right_index =
static_cast<index_type>(rhs);
18 auto const column =
static_cast<index_type>(col);
19 auto temporary =
static_cast<typename std::remove_cvref_t<MatrixMdspan>::value_type
>(matrix[left_index, column]);
20 auto right_value =
static_cast<typename std::remove_cvref_t<MatrixMdspan>::value_type
>(matrix[right_index, column]);
21 matrix[left_index, column] = right_value;
22 matrix[right_index, column] = temporary;
28template <
class Matrix>
29KernelAttempt lu_factor(Matrix& s, std::span<std::size_t> pivots,
30 LuNorms<make_real_t<typename Matrix::value_type>>* norms, SolveInfo& info,
31 SolveOptions<make_real_t<typename Matrix::value_type>>
const& options,
32 make_real_t<typename Matrix::value_type>
const& zero)
34 using S =
typename Matrix::value_type;
36 if (!detail::solve_matrix_is_finite(s))
41 detail::capture_lu_norms(s, norms, zero);
42 auto scale = detail::lu_input_scale(s, zero);
43 auto n = pivots.size();
45 bool rows_inner =
true;
46 if constexpr (StridedMdspanLike<
decltype(s)>) rows_inner = s.stride(0) <= s.stride(1);
47 auto update_entry = [&](std::size_t i, std::size_t j, S
const& multiplier, S
const& upper) {
48 S
value = S(s[i, j]) - multiplier * upper;
57 for (std::size_t k = 0; k < n; ++k)
59 auto magnitude = detail::lu_magnitude(S(s[k, k]));
60 std::size_t pivot = k;
61 for (std::size_t i = k + 1; i < n; ++i)
63 auto candidate = detail::lu_magnitude(S(s[i, k]));
64 if (detail::lu_magnitude_less(magnitude, candidate))
72 else if (detail::lu_small_pivot(magnitude, scale, options.relative_pivot_tolerance))
77 detail::cpu_reference::swap_rows(s, k, pivot, n);
78 for (std::size_t i = k + 1; i < n; ++i)
80 S multiplier = S(s[i, k]) / S(s[k, k]);
90 for (std::size_t j = k + 1; j < n; ++j)
93 for (std::size_t i = k + 1; i < n; ++i)
99 for (std::size_t i = k + 1; i < n; ++i)
101 S multiplier = s[i, k];
102 for (std::size_t j = k + 1; j < n; ++j)
110template <
class Matrix,
class Rhs>
111KernelAttempt lu_solve(Matrix
const& as, std::span<std::size_t const> pivots, Rhs& bs, SolveInfo& info)
114 using S =
typename Matrix::value_type;
115 if (!detail::solve_matrix_is_finite(bs))
120 auto n = pivots.size();
121 auto count = std::size_t(bs.extent(1));
122 for (std::size_t k = 0; k < n; ++k)
123 detail::cpu_reference::swap_rows(bs, k, pivots[k], count);
124 for (std::size_t col = 0; col <
count; ++col)
126 for (std::size_t i = 0; i < n; ++i)
128 S
value = bs[i, col];
129 for (std::size_t k = 0; k < i; ++k)
130 value -= S(as[i, k]) * S(bs[k, col]);
138 for (std::size_t i = n; i-- > 0;)
140 S
value = bs[i, col];
141 for (std::size_t k = i + 1; k < n; ++k)
142 value -= S(as[i, k]) * S(bs[k, col]);
143 value /= S(as[i, i]);
locale_t value
Definition data_table.cpp:49
Operation-tag backend dispatch over tensor-view operands.
constexpr bool isfinite(I const &x) noexcept
Returns whether an integer scalar is finite.
Definition math.hpp:121
Mdspan concept and accessor extensions for Uni20.
int columns(std::FILE *stream)
Return the terminal column count associated with a C stream.
Definition terminal.cpp:493
void info(checked_format_string< Args... > format, Args &&... args)
Emit an informational display message.
Definition display.hpp:393
DiagnosticMagnitude< R > magnitude(R const &value)
Definition gmres_diagnostics.hpp:98
KernelAttempt
Result of one runtime kernel backend attempt.
Definition kernel_attempt.hpp:27
@ nonfinite_input
An input coefficient or RHS component was nonfinite; both workspaces are preserved.
@ singular
An exactly zero elimination pivot was found.
@ nonfinite_result
A factor, solution, reduction, or required magnitude became nonfinite.
@ small_pivot
A nonzero pivot failed the requested relative threshold.
std::ptrdiff_t index_type
Definition types.hpp:19