//================================================================================================== /* ROTGEN - Runtime Overlay for Eigen Copyright : CODE RECKONS SPDX-License-Identifier: BSL-1.0 */ //================================================================================================== #pragma once #include #include namespace rotgen { template struct svd { using base = Eigen::JacobiSVD; using u_type = typename base::MatrixUType; using v_type = typename base::MatrixVType; using d_type = typename base::SingularValuesType; svd(M const& m, int options = ComputeThinU | ComputeThinV) : svd_(m.base(),options) {} int rank() const { return svd_.rank(); } auto singular_values() const { if constexpr(!use_expression_templates) return as_concrete_t{svd_.singularValues()}; else return svd_.singularValues(); } auto U() const { if constexpr(!use_expression_templates) return as_concrete_t{svd_.matrixU()}; else return svd_.matrixU(); } auto V() const { if constexpr(!use_expression_templates) return as_concrete_t{svd_.matrixV()}; else return svd_.matrixV(); } auto D() const { auto d = svd_.singularValues().asDiagonal(); if constexpr(!use_expression_templates) return as_concrete_t{d.toDenseMatrix ()}; else return d; } auto singular_values(int r) const { auto that = svd_.singularValues().head(r); if constexpr(!use_expression_templates) return as_concrete_t{that}; else return svd_.singularValues(); } auto U(int r) const { auto that = svd_.matrixU().leftCols(r); if constexpr(!use_expression_templates) return as_concrete_t{that}; else return that; } auto V(int r) const { auto that = svd_.matrixV().leftCols(r); if constexpr(!use_expression_templates) return as_concrete_t{that}; else return that; } auto D(int r) const { auto d = svd_.singularValues().head(r).asDiagonal(); if constexpr(!use_expression_templates) return as_concrete_t{d.toDenseMatrix ()}; else return d; } private: base svd_; }; }