矩阵SVD分解计算

对于有数学库的时候,进行矩阵相关计算还是不复杂,但是没有数学库就很麻烦,利用算法实现了矩阵奇异值分解。

void decompose(const std::vector<std::vector<double>>& A,
        std::vector<std::vector<double>>& U, std::vector<double>& S,
        std::vector<std::vector<double>>& V) 
{
        if (A.empty() || A[0].empty()) 
        {
            throw std::invalid_argument("Matrix A cannot be empty");
        }

        size_t m = A.size();
        size_t n = A[0].size();

        if (m < n) 
        {
            throw std::invalid_argument("Number of rows must be >= number of columns in SVD");
        }

        U = A;
        S.resize(n);
        V.assign(n, std::vector<double>(n, 0.0));
        
        std::vector<double> rv1(n);
        double g = 0.0, scale = 0.0, anorm = 0.0;

        for (size_t i = 0; i < n; ++i) {
            size_t l = i + 1;
            rv1[i] = scale * g;
            g = scale = 0.0;

            if (i < m) {
                for (size_t k = i; k < m; ++k) scale += std::abs(U[k][i]);
                if (scale != 0.0) {
                    for (size_t k = i; k < m; ++k) {
                        U[k][i] /= scale;
                        g += U[k][i] * U[k][i];
                    }
                    double f = U[i][i];
                    g = -sign(std::sqrt(g), f);
                    double h = f * g - g * g;
                    U[i][i] = f - g;
                    for (size_t j = l; j < n; ++j) {
                        double s = 0.0;
                        for (size_t k = i; k < m; ++k) s += U[k][i] * U[k][j];
                        f = s / h;
                        for (size_t k = i; k < m; ++k) U[k][j] += f * U[k][i];
                    }
                    for (size_t k = i; k < m; ++k) U[k][i] *= scale;
                }
            }
            S[i] = scale * g;

            g = scale = 0.0;
            if (i < m && i != n - 1) {
                for (size_t k = l; k < n; ++k) scale += std::abs(U[i][k]);
                if (scale != 0.0) {
                    for (size_t k = l; k < n; ++k) {
                        U[i][k] /= scale;
                        g += U[i][k

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值