「C++」使用Eigen实现伪逆矩阵(pinV)

伪逆矩阵(Moore-Penrose pseudoinverse)A定义:

A+=VD+UT,其中,U,D和V是矩阵A奇异值分解后得到的矩阵。对角矩阵D的伪逆D+是非零元素取倒数之后再转置得到的。


C++实现伪逆矩阵,程序代码:

#include "funset.hpp"
#include <math.h>
#include <iostream>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <Eigen/Dense>
#include "common.hpp"
 
int test_pseudoinverse()
{
	//std::vector<std::vector<float>> vec{ { 0.68f, 0.597f },
	//				{ -0.211f, 0.823f },
	//				{ 0.566f, -0.605f } };
	//const int rows{ 3 }, cols{ 2 };
 
	std::vector<std::vector<float>> vec{ { 0.68f, 0.597f, -0.211f },
					{ 0.823f, 0.566f, -0.605f } };
	const int rows{ 2 }, cols{ 3 };
 
	std::vector<float> vec_;
	for (int i = 0; i < rows; ++i) {
		vec_.insert(vec_.begin() + i * cols, vec[i].begin(), vec[i].end());
	}
	Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> m(vec_.data(), rows, cols);
 
	fprintf(stderr, "source matrix:\n");
	std::cout << m << std::endl;
 
	fprintf(stderr, "\nEigen implement pseudoinverse:\n");
	auto svd = m.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
 
	const auto &singularValues = svd.singularValues();
	Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> singularValuesInv(m.cols(), m.rows());
	singularValuesInv.setZero();
	double  pinvtoler = 1.e-6; // choose your tolerance wisely
	for (unsigned int i = 0; i < singularValues.size(); ++i) {
		if (singularValues(i) > pinvtoler)
			singularValuesInv(i, i) = 1.0f / singularValues(i);
		else
			singularValuesInv(i, i) = 0.f;
	}
 
	Eigen::MatrixXf pinvmat = svd.matrixV() * singularValuesInv * svd.matrixU().transpose();
	std::cout << pinvmat << std::endl;
 
	return 0;
}

运行结果:

发布了191 篇原创文章 · 获赞 611 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/Robot_Starscream/article/details/100575556
今日推荐