C++SVD分解求伪逆 (Eigen库)(附C++代码)

SVD求解矩阵伪逆过程

  1. 首先对矩阵A进行SVD分解得到U, D, V三个矩阵,其中D为列矩阵,是从上到下,由大到小排列的A矩阵的奇异值

  2. D矩阵中元素个数为n则原矩阵有n奇异值,构建大小为V.cols() * U.cols()S矩阵,其中S矩阵的前n个对角线的各元素为各奇异值,即D矩阵各元素的倒数。需注意D矩阵元素非负, 且是由大到小的顺序进行取倒数。

  3. 最后利用公式构建A矩阵的伪逆矩阵。

    p i n v A = V ∗ S ∗ U T pinv_A = V * S * U^T pinvA=VSUT

C++代码

#include <iostream>
#include <Eigen/SVD>
#include <Eigen/Core>

using namespace std;


// 利用Eigen库,采用SVD分解的方法求解矩阵伪逆,默认误差er为0
Eigen::MatrixXd pinv_eigen_based(Eigen::MatrixXd & origin, const float er = 0) {
    // 进行svd分解
    Eigen::JacobiSVD<Eigen::MatrixXd> svd_holder(origin,
                                                 Eigen::ComputeThinU |
                                                 Eigen::ComputeThinV);
    // 构建SVD分解结果
    Eigen::MatrixXd U = svd_holder.matrixU();
    Eigen::MatrixXd V = svd_holder.matrixV();
    Eigen::MatrixXd D = svd_holder.singularValues();

    // 构建S矩阵
    Eigen::MatrixXd S(V.cols(), U.cols());
    S.setZero();

    for (unsigned int i = 0; i < D.size(); ++i) {

        if (D(i, 0) > er) {
            S(i, i) = 1 / D(i, 0);
        } else {
            S(i, i) = 0;
        }
    }

    // pinv_matrix = V * S * U^T
    return V * S * U.transpose();
}



int main() {
    // 设置矩阵行数、列数
    const int ROW = 3;
    const int COL = 4;

    // 生成大小 ROW * COL 的随机矩阵
    Eigen::MatrixXd A;
    A = Eigen::MatrixXd::Random(ROW, COL);
    
    // 打印矩阵A
    cout << "矩阵A为:" << endl;
    cout << A << endl;
    
    // 打印矩阵A的伪逆矩阵
    cout << "矩阵A的伪逆为:" << endl;
    cout << pinv_eigen_based(A) << endl;
}

C++伪逆计算结果

矩阵A为:

-0.999984 -0.0826997 -0.905911 0.869386

-0.736924 0.0655345 0.357729 -0.232996

0.511211 -0.562082 0.358593 0.0388327

矩阵A的伪逆为:

-0.312319 -0.919805 0.00626524

-0.406429 -0.350652 -1.37477

-0.245582 0.79061 0.573503

0.496441 -0.267508 0.474029

Matlab伪逆计算结果

矩阵A为

-0.999984000000000 -0.0826997000000000 -0.905911000000000 0.869386000000000
-0.736924000000000 0.0655345000000000 0.357729000000000 -0.232996000000000
0.511211000000000 -0.562082000000000 0.358593000000000 0.0388327000000000

矩阵A的伪逆为:

-0.312319329541589 -0.919806223588993 0.00626485031867355
-0.406429539737511 -0.350652955757283 -1.37477343275610
-0.245581499008346 0.790610522532372 0.573502890310835
0.496441264538540 -0.267507910015611 0.474028770291387

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值