8#if UNI20_HAS_MPLAPACK_MPREAL
11#if UNI20_HAS_MPLAPACK_FLOAT80
17namespace least_squares_detail
21#if UNI20_HAS_MPLAPACK_MPREAL || UNI20_HAS_MPLAPACK_FLOAT80
22 requires(std::size_t n, std::span<S> a, std::span<make_real_t<S>> values, make_real_t<S>
const& cutoff,
31 "SVD least squares requires a finite nonnegative relative cutoff");
34template <LapackScalar S>
41 S* rhs = nrhs ? b.
storage().data() : &dummy;
42 blas_int provider_rank = 0;
43 std::vector<make_real_t<S>> rwork;
45 auto call = [&](S* work, blas_int length) {
48 provider_rank, work, length);
51 provider_rank, work, length, rwork.data());
53 auto code = call(&query, -1);
54 lapack::detail::check_invalid_argument(
"gelss", code);
55 if (code > 0)
return std::size_t(code);
57 std::vector<S> work(std::size_t(length), S{});
58 code = call(work.data(), length);
59 lapack::detail::check_invalid_argument(
"gelss", code);
60 if (!code) rank = std::size_t(provider_rank);
61 return std::size_t(code);
66template <
class X,
class A,
class B,
class... P>
67 requires least_squares_detail::Operands<X, A, B> &&
68 least_squares_detail::PrecisionArgs<
typename A::value_type, P...> &&
79template <
class X,
class A,
class B,
class... P>
80 requires least_squares_detail::Operands<X, A, B> &&
81 least_squares_detail::PrecisionArgs<
typename A::value_type, P...> &&
88 using S =
typename A::value_type;
90 auto p = least_squares_detail::working_precision<S>(precision...);
91 require_precision<S>(
p);
94 std::size_t m = a.extent(0), n = a.extent(1), nrhs = b.extent(1), k = std::min(m, n);
95 ERROR_IF(std::size_t(b.extent(0)) != m || std::size_t(x.extent(0)) != n || std::size_t(x.extent(1)) != nrhs ||
96 residuals.size() != nrhs,
97 "incompatible SVD least-squares shapes");
98 for (
auto extent : {m, n, nrhs})
104 auto as = aa.mdspan();
105 auto bs = ba.mdspan();
121 std::vector<R>
singular(k, scalar_at_precision<R>(0,
p));
122 std::size_t rank = 0;
127 for (std::size_t j = 0; j < nrhs; ++j)
128 for (std::size_t i = 0; i < m; ++i)
129 rhs[i, j] = bv[i, j];
130 std::size_t code = 0;
132#if UNI20_HAS_MPLAPACK_MPREAL || UNI20_HAS_MPLAPACK_FLOAT80
142 for (std::size_t j = 0; j < nrhs; ++j)
143 for (std::size_t i = 0; i < n; ++i)
144 solution[i, j] = rhs[i, j];
146 std::vector<R> norms;
148 !std::all_of(
singular.begin(),
singular.end(), [](R
const& s) { return uni20::isfinite(s); }) ||
155 auto xs = xa.mdspan();
157 std::copy_n(norms.begin(), nrhs, residuals.begin());
158 diagnostics = {.rank = rank,
159 .relative_cutoff = std::move(cutoff),
160 .singular_values = options.return_singular_values ? std::move(
singular) : std::vector<R>{}};
Synchronous packed-array boundary to the serial MPFR/MPC provider.
Safe conversion helpers for the configured signed BLAS integer ABI.
General-purpose owning tensor with immediate or deferred mdspan metadata.
Definition basic_tensor.hpp:109
auto extent(size_type axis) const noexcept
Return one tensor extent.
Definition basic_tensor.hpp:720
storage_type & storage() noexcept
Access the owned storage container.
Definition basic_tensor.hpp:542
auto mdspan() noexcept -> mdspan_type
Resolve a writable mdspan over the owned storage.
Definition basic_tensor.hpp:609
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
Concept for scalar types with a configured dense LAPACK backend.
Definition scalar_concepts.hpp:147
Concept for real scalar types (float, double, etc.).
Definition scalar_concepts.hpp:69
Definition backends/lapack/svd_least_squares.hpp:20
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
constexpr bool isfinite(I const &x) noexcept
Returns whether an integer scalar is finite.
Definition math.hpp:121
Checked LAPACK wrappers over provider-specific unchecked overloads.
Shared helpers for LAPACK operation-tag backend adapters.
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
blas_int gelss(blas_int m, blas_int n, blas_int nrhs, uni20::float128 *a, blas_int lda, uni20::float128 *b, blas_int ldb, uni20::float128 *s, uni20::float128 rcond, blas_int &rank, uni20::float128 *work, blas_int lwork)
Definition mplapack/general.hpp:206
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
constexpr std::optional< std::size_t > try_size_product(std::size_t left, std::size_t right) noexcept
Multiply allocation extents without wrapping std::size_t.
Definition linalg/backends/lapack/common.hpp:69
void require_svd_options(SvdLeastSquaresOptions< R > const &options)
Definition backends/lapack/svd_least_squares.hpp:28
bool residual_norms(DenseMatrix< S > const &av, DenseMatrix< S > const &bv, DenseMatrix< S > const &solution, std::vector< make_real_t< S > > &norms, Precision p)
Definition least_squares_common.hpp:58
bool finite(Matrix const &a)
Definition least_squares_common.hpp:31
std::size_t native_gelss(DenseMatrix< S > &a, DenseMatrix< S > &b, std::vector< make_real_t< S > > &singular, make_real_t< S > const &cutoff, std::size_t &rank)
Definition backends/lapack/svd_least_squares.hpp:35
void unpack(Tensor const &source, Span &target)
Definition packed_matrix.hpp:33
auto pack(Span const &span, Precision p, bool read=true)
Definition packed_matrix.hpp:19
auto values(Tensor &tensor)
Definition packed_matrix.hpp:29
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
@ singular
An exactly zero elimination pivot was found.
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::size_t gelss(std::size_t m, std::size_t n, std::size_t nrhs, std::span< float80 > a, std::span< float80 > b, std::span< float80 > values, float80 const &cutoff, std::size_t &rank, Precision p)
Packed GELSS; B has max(m,n) rows, values has min(m,n) entries.
Definition binary80.cpp:285
Definition data_table.cpp:8
auto acquire_host_read_access_sync(Mdspan const &mdspan)
Acquire a directly host-accessible read-only mdspan.
Definition access.hpp:616
auto acquire_host_write_access_sync(Mdspan &mdspan)
Acquire a directly host-accessible writable mdspan.
Definition access.hpp:626
Backend family for configured dense LAPACK kernels, including MPLAPACK scalar adapters.
Definition backend_selector.hpp:20
Completed numerical attempt; success does not certify rank or conditioning.
Definition least_squares_info.hpp:26
Rank diagnostics for a successful truncated-SVD solution.
Definition svd_least_squares_info.hpp:20
Singular-value truncation policy for minimum-norm least squares.
Definition svd_least_squares_info.hpp:10
std::optional< R > relative_cutoff
Relative cutoff; absent selects epsilon at working precision.
Definition svd_least_squares_info.hpp:14
Preserving minimum-norm SVD least squares with explicit rank diagnostics.
Definition operation_tags.hpp:27
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16
#define ERROR_IF(cond,...)
Definition trace.hpp:389