5namespace uni20::mplapack::detail
7template <
class Adapter,
class S>
8std::size_t gelss_impl(std::size_t m, std::size_t n, std::size_t nrhs, std::span<S> a, std::span<S> b,
9 std::span<make_real_t<S>> values, make_real_t<S>
const& cutoff, std::size_t& rank, Precision
p)
11 auto k = std::min(m, n), rows_b = std::max(m, n);
12 Adapter::check_size(a.size(), m, n);
13 Adapter::check_size(b.size(), rows_b, nrhs);
14 Adapter::check_size(
values.size(), k, 1);
15 if (!k)
throw std::invalid_argument(
"packed GELSS requires nonzero dimensions");
16 auto pm = Adapter::integer(m), pn = Adapter::integer(n), prhs = Adapter::integer(nrhs);
17 auto ldb = Adapter::integer(rows_b);
18 typename Adapter::precision_scope scope(
p);
19 using P =
typename Adapter::template scalar<S>;
20 auto av = Adapter::pack_values(std::span<S const>(a));
21 auto bv = Adapter::pack_values(std::span<S const>(b));
23 if (bv.empty()) bv.resize(1);
24 auto threshold = Adapter::pack_values(std::span(&cutoff, 1));
25 std::vector<typename Adapter::real>
singular(k), rwork;
26 if constexpr (Complex<S>) rwork.resize(auxiliary_size(k, 5));
27 mplapackint provider_rank = 0;
28 auto info = Adapter::template workspace_info<P>([&](P* work, mplapackint length, mplapackint& code) {
29 if constexpr (Real<S>)
30 Rgelss(pm, pn, prhs, av.data(), pm, bv.data(), ldb,
singular.data(), threshold[0], provider_rank, work, length,
33 Cgelss(pm, pn, prhs, av.data(), pm, bv.data(), ldb,
singular.data(), threshold[0], provider_rank, work, length,
36 if (info)
return static_cast<std::size_t
>(
info);
37 rank =
static_cast<std::size_t
>(provider_rank);
38 Adapter::unpack_values(av, a,
p);
40 Adapter::unpack_values(bv, b,
p);
41 Adapter::unpack_values(singular, values,
p);
45template <
class Adapter,
class S>
46make_real_t<S> gecon_impl(std::size_t n, std::span<S const> a, make_real_t<S>
const& anorm,
char norm, Precision
p)
48 Adapter::check_size(a.size(), n, n);
49 if (
norm !=
'1' &&
norm !=
'I')
throw std::invalid_argument(
"condition norm must be one or infinity");
50 auto pn = Adapter::integer(n);
51 typename Adapter::precision_scope scope(
p);
52 if (!n)
return scalar_at_precision<make_real_t<S>>(1,
p);
53 auto av = Adapter::pack_values(a);
54 auto norm_value = Adapter::pack_values(std::span(&anorm, 1));
55 using P =
typename Adapter::template scalar<S>;
56 typename Adapter::real rcond;
58 if constexpr (Real<S>)
60 std::vector<P> work(auxiliary_size(n, 4));
61 std::vector<mplapackint> iwork(n);
62 Rgecon(&
norm, pn, av.data(), pn, norm_value[0], rcond, work.data(), iwork.data(), info);
66 std::vector<P> work(auxiliary_size(n, 2));
67 std::vector<typename Adapter::real> rwork(auxiliary_size(n, 2));
68 Cgecon(&
norm, pn, av.data(), pn, norm_value[0], rcond, work.data(), rwork.data(), info);
70 if (info < 0)
throw std::logic_error(
"MPLAPACK rejected validated GECON arguments");
71 return Adapter::get_value(rcond,
p);
Shared packed MPLAPACK decomposition algorithms for compiled scalar adapters.
void info(checked_format_string< Args... > format, Args &&... args)
Emit an informational display message.
Definition display.hpp:393
auto values(Tensor &tensor)
Definition packed_matrix.hpp:29
@ singular
An exactly zero elimination pivot was found.
Definition data_table.cpp:8
mpreal norm(mpcomplex const &z)
Definition mpcomplex.hpp:494