rotgen/include/rotgen/fixed/svd.hpp
2025-09-28 16:15:15 +02:00

88 lines
No EOL
2.5 KiB
C++

//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <Eigen/Dense>
#include <Eigen/SVD>
namespace rotgen
{
template<typename M>
struct svd
{
using base = Eigen::JacobiSVD<typename M::parent>;
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<d_type, matrix>{svd_.singularValues()};
else return svd_.singularValues();
}
auto U() const
{
if constexpr(!use_expression_templates) return as_concrete_t<u_type, matrix>{svd_.matrixU()};
else return svd_.matrixU();
}
auto V() const
{
if constexpr(!use_expression_templates) return as_concrete_t<v_type, matrix>{svd_.matrixV()};
else return svd_.matrixV();
}
auto D() const
{
auto d = svd_.singularValues().asDiagonal();
if constexpr(!use_expression_templates)
return as_concrete_t<decltype(d.toDenseMatrix()), matrix>{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<decltype(that), matrix>{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<decltype(that), matrix>{that};
else return that;
}
auto V(int r) const
{
auto that = svd_.matrixV().leftCols(r);
if constexpr(!use_expression_templates) return as_concrete_t<decltype(that), matrix>{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<decltype(d.toDenseMatrix()), matrix>{d.toDenseMatrix ()};
else
return d;
}
private:
base svd_;
};
}