29namespace lapack_detail
33template <uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan,
class EigenScalar,
34 uni20::MutableRankedStr
idedMdspanLike<2> SchurVectorMdspan>
37 using matrix_scalar = std::remove_cv_t<typename MatrixMdspan::element_type>;
38 using vector_scalar = std::remove_cv_t<typename SchurVectorMdspan::element_type>;
54template <uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan,
class EigenScalar,
55 uni20::MutableRankedStr
idedMdspanLike<2> SchurVectorMdspan>
57 SchurVectorMdspan& schur_vectors)
59 using matrix_type = std::remove_cvref_t<MatrixMdspan>;
60 using scalar_type = std::remove_cv_t<typename matrix_type::element_type>;
64 CHECK_EQUAL(matrix_work.extent(0), matrix_work.extent(1));
65 std::size_t
const n =
static_cast<std::size_t
>(matrix_work.extent(0));
68 static_cast<std::size_t
>(schur_vectors.extent(1)) == n));
101 blas_int
const ldvs = op.
compute_vectors ? vectors->leading_dimension : 1;
103 blas_int selected_dimension = 0;
104 std::vector<blas_int> bwork(std::max<std::size_t>(1, n), 0);
111 uni20::lapack::gees(jobvs,
'N', order, matrix->data, matrix->leading_dimension, selected_dimension, wr.data(),
112 wi.data(), vector_data, ldvs, &work_query, -1, bwork.data());
114 std::vector<scalar_type> work(
static_cast<std::size_t
>(lwork),
scalar_type{});
115 uni20::lapack::gees(jobvs,
'N', order, matrix->data, matrix->leading_dimension, selected_dimension, wr.data(),
116 wi.data(), vector_data, ldvs, work.data(), lwork, bwork.data());
117 for (std::size_t index = 0; index < n; ++index)
119 eigenvalues[index] = complex_type{wr[index], wi[index]};
124 std::vector<complex_type> values(n, complex_type{});
125 std::vector<real_type> rwork(std::max<std::size_t>(1, n), real_type{});
126 complex_type work_query{};
127 uni20::lapack::gees(jobvs,
'N', order, matrix->data, matrix->leading_dimension, selected_dimension, values.data(),
128 vector_data, ldvs, &work_query, -1, rwork.data(), bwork.data());
130 std::vector<complex_type> work(
static_cast<std::size_t
>(lwork), complex_type{});
131 uni20::lapack::gees(jobvs,
'N', order, matrix->data, matrix->leading_dimension, selected_dimension, values.data(),
132 vector_data, ldvs, work.data(), lwork, rwork.data(), bwork.data());
133 std::ranges::copy(values, eigenvalues.begin());
140template <uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan,
class EigenScalar,
141 uni20::MutableRankedStr
idedMdspanLike<2> SchurVectorMdspan>
144 using matrix_scalar = std::remove_cv_t<typename MatrixMdspan::element_type>;
145 using vector_scalar = std::remove_cv_t<typename SchurVectorMdspan::element_type>;
147 std::same_as<EigenScalar, uni20::complex<matrix_scalar>> &&
159template <uni20::MutableRankedStr
idedMdspanLike<2> MatrixMdspan,
class EigenScalar,
160 uni20::MutableRankedStr
idedMdspanLike<2> SchurVectorMdspan>
162 std::span<EigenScalar> eigenvalues, SchurVectorMdspan& schur_vectors)
164 using scalar_type = std::remove_cv_t<typename std::remove_cvref_t<MatrixMdspan>::element_type>;
166 CHECK_EQUAL(hessenberg.extent(0), hessenberg.extent(1));
167 std::size_t
const n =
static_cast<std::size_t
>(hessenberg.extent(0));
170 static_cast<std::size_t
>(schur_vectors.extent(1)) == n));
200 blas_int
const ldz = op.
compute_vectors ? vectors->leading_dimension : 1;
205 wr.data(), wi.data(), vector_data, ldz, &work_query, -1);
207 std::vector<scalar_type> work(
static_cast<std::size_t
>(lwork),
scalar_type{});
209 wr.data(), wi.data(), vector_data, ldz, work.data(), lwork);
210 for (std::size_t index = 0; index < n; ++index)
218template <uni20::MutableRankedStr
idedMdspanLike<2> SchurFormMdspan,
219 uni20::MutableRankedStr
idedMdspanLike<2> SchurVectorMdspan>
222 using form_scalar = std::remove_cv_t<typename SchurFormMdspan::element_type>;
223 using vector_scalar = std::remove_cv_t<typename SchurVectorMdspan::element_type>;
237template <uni20::MutableRankedStr
idedMdspanLike<2> SchurFormMdspan,
238 uni20::MutableRankedStr
idedMdspanLike<2> SchurVectorMdspan>
240 SchurVectorMdspan& schur_vectors)
242 using form_type = std::remove_cvref_t<SchurFormMdspan>;
243 using scalar_type = std::remove_cv_t<typename form_type::element_type>;
245 CHECK_EQUAL(schur_form.extent(0), schur_form.extent(1));
246 std::size_t
const n =
static_cast<std::size_t
>(schur_form.extent(0));
250 static_cast<std::size_t
>(schur_vectors.extent(1)) == n));
281 blas_int
const ldq = op.
update_vectors ? vectors->leading_dimension : 1;
283 blas_int first =
static_cast<blas_int
>(op.
from + 1);
284 blas_int last =
static_cast<blas_int
>(op.
to + 1);
289 uni20::lapack::trexc(compq, order, form->data, form->leading_dimension, vector_data, ldq, first, last, work.data());
293 uni20::lapack::trexc(compq, order, form->data, form->leading_dimension, vector_data, ldq, first, last);
300template <
class Operation, uni20::MutableRankedStr
idedMdspecLike<2> MatrixMdspan,
class EigenScalar,
301 uni20::MutableRankedStr
idedMdspecLike<2> SchurVectorMdspan>
302 requires(std::same_as<Operation, schur_op> || std::same_as<Operation, hessenberg_schur_op>) &&
309 constexpr auto acceptance = [] {
310 if constexpr (std::same_as<Operation, schur_op>)
311 return lapack_detail::schur_acceptance<matrix_span, EigenScalar, vector_span>();
313 return lapack_detail::hessenberg_schur_acceptance<matrix_span, EigenScalar, vector_span>();
322template <
class Operation, uni20::MutableRankedStr
idedMdspecLike<2> MatrixMdspan,
class EigenScalar,
323 uni20::MutableRankedStr
idedMdspecLike<2> SchurVectorMdspan>
324 requires(std::same_as<Operation, schur_op> || std::same_as<Operation, hessenberg_schur_op>) &&
327 std::span<EigenScalar> eigenvalues, SchurVectorMdspan& schur_vectors)
330 [&](
auto& matrix_span,
auto& vector_span) {
331 if constexpr (std::same_as<Operation, schur_op>)
336 matrix_work, schur_vectors);
340template <uni20::MutableRankedStr
idedMdspecLike<2> SchurFormMdspan,
341 uni20::MutableRankedStr
idedMdspecLike<2> SchurVectorMdspan>
347 constexpr auto acceptance = lapack_detail::schur_reorder_acceptance<form_span, vector_span>();
355template <uni20::MutableRankedStr
idedMdspecLike<2> SchurFormMdspan,
356 uni20::MutableRankedStr
idedMdspecLike<2> SchurVectorMdspan>
359 SchurVectorMdspan& schur_vectors)
362 [&](
auto& form_span,
auto& vector_span) {
365 schur_form, schur_vectors);
RAII leases that resolve device descriptors and tensor views to mdspans.
Safe conversion helpers for the configured signed BLAS integer ABI.
An mdspan-like type whose accessor is stdex::default_accessor.
Definition mdspan/concepts.hpp:501
Mutable mdspec metadata supporting host write acquisition.
Definition access.hpp:694
Real scalar types supported by the configured raw-pointer LAPACK wrappers.
Definition scalar_concepts.hpp:115
Concept for scalar types with a configured dense LAPACK backend.
Definition scalar_concepts.hpp:147
Operation-tag backend dispatch over tensor-view operands.
typename detail::complex_type< Real >::type complex
Project-level complex scalar spelling.
Definition types.hpp:66
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
Checked LAPACK wrappers over provider-specific unchecked overloads.
Shared helpers for LAPACK operation-tag backend adapters.
Lower mdspan matrix views to provider-ready BLAS operands.
constexpr blas_int try_blas_int(Value value) noexcept
Convert a non-negative integer to blas_int, or return the negative invalid sentinel.
Definition blas_int.hpp:28
constexpr bool is_valid_blas_int(blas_int value) noexcept
Return whether a non-throwing BLAS integer conversion succeeded.
Definition blas_int.hpp:25
void gees(char jobvs, char sort, blas_int n, Scalar *a, blas_int lda, blas_int &selected_dimension, Scalar *wr, Scalar *wi, Scalar *vs, blas_int ldvs, Scalar *work, blas_int lwork, blas_int *bwork)
Compute the real Schur form of a real nonsymmetric matrix.
Definition lapack.hpp:846
void trexc(char compq, blas_int n, Scalar *t, blas_int ldt, Scalar *q, blas_int ldq, blas_int &first, blas_int &last, Scalar *work)
Reorder adjacent blocks in a real Schur form.
Definition lapack.hpp:889
void hseqr(char job, char compz, blas_int n, blas_int first, blas_int last, Scalar *h, blas_int ldh, Scalar *wr, Scalar *wi, Scalar *z, blas_int ldz, Scalar *work, blas_int lwork)
Compute a Schur form of a real upper Hessenberg matrix.
Definition lapack.hpp:876
auto try_lapack_writable_matrix(Mdspan const &span) -> std::optional< BlasWritableMatrix< std::remove_cv_t< typename Mdspan::element_type >, typename Mdspan::data_handle_type > >
Try to lower an mdspan to the strict column-major shape expected by LAPACK.
Definition mdspan_matrix.hpp:285
KernelAttempt try_hessenberg_schur(hessenberg_schur_op const &op, MatrixMdspan &hessenberg, std::span< EigenScalar > eigenvalues, SchurVectorMdspan &schur_vectors)
Compute a real upper-Hessenberg Schur form through LAPACK hseqr.
Definition backends/lapack/schur.hpp:161
blas_int workspace_size(Scalar const &query)
Convert a provider workspace query result to the configured LAPACK integer type.
Definition linalg/backends/lapack/common.hpp:43
consteval auto schur_acceptance()
Report compile-time eligibility for resolved LAPACK Schur decomposition.
Definition backends/lapack/schur.hpp:35
KernelAttempt with_host_write_mdspans(Function &&function, Mdspecs &... mdspecs)
Invoke a LAPACK attempt with host-writable mdspans under simultaneous leases.
Definition linalg/backends/lapack/common.hpp:29
KernelAttempt try_schur(schur_op const &op, MatrixMdspan &matrix_work, std::span< EigenScalar > eigenvalues, SchurVectorMdspan &schur_vectors)
Compute a dense Schur form through LAPACK gees.
Definition backends/lapack/schur.hpp:56
consteval auto hessenberg_schur_acceptance()
Report compile-time eligibility for resolved real upper-Hessenberg Schur decomposition.
Definition backends/lapack/schur.hpp:142
consteval auto schur_reorder_acceptance()
Report compile-time eligibility for resolved LAPACK Schur reordering.
Definition backends/lapack/schur.hpp:220
KernelAttempt try_schur_reorder(schur_reorder_op const &op, SchurFormMdspan &schur_form, SchurVectorMdspan &schur_vectors)
Move one real Schur block or complex Schur entry through LAPACK trexc.
Definition backends/lapack/schur.hpp:239
Definition linalg/async.hpp:28
KernelAttempt try_kernel(BlasBackend, gemm_op const &, C &c, S const &alpha, A &a, B &b, S const &beta)
Pack logical host values and execute GEMM through value-preserving provider conversion.
Definition linalg/backends/blas/binary80.hpp:30
KernelAttempt
Result of one runtime kernel backend attempt.
Definition kernel_attempt.hpp:27
constexpr KernelAcceptance< KernelTypeAcceptance::no > kernel_types_no
Report that a backend rejects the argument types.
Definition dispatch_error.hpp:34
consteval auto kernel_accepts_types(BlasBackend, gemm_op const &, C &, S const &, A &, B &, S const &)
Accept host-readable native binary80 operands, including transforming accessors.
Definition linalg/backends/blas/binary80.hpp:19
constexpr KernelAcceptance< KernelTypeAcceptance::maybe > kernel_types_maybe
Report that runtime operand values determine backend acceptance.
Definition dispatch_error.hpp:37
std::remove_cvref_t< decltype(std::declval< detail::host_write_mdspan_lease_t< Mdspec > & >().mdspan())> host_write_mdspan_t
Writable mdspan type resolved by host descriptor acquisition.
Definition access.hpp:684
Backend family for configured dense LAPACK kernels, including MPLAPACK scalar adapters.
Definition backend_selector.hpp:20
Schur decomposition of an already upper-Hessenberg real matrix.
Definition operation_tags.hpp:322
bool compute_vectors
Definition operation_tags.hpp:324
Dense Schur decomposition operation tag.
Definition operation_tags.hpp:315
bool compute_vectors
Definition operation_tags.hpp:317
Move one Schur block or entry to a requested position.
Definition operation_tags.hpp:329
std::size_t to
Definition operation_tags.hpp:332
bool update_vectors
Definition operation_tags.hpp:333
std::size_t from
Definition operation_tags.hpp:331
Trait to extract the scalar type from a type T.
Definition scalar_traits.hpp:93
Concepts for tensor-level objects that resolve mdspan kernel operands.
#define CHECK(cond,...)
Definition trace.hpp:299
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309