关于数学库Eigen两个常用函数实现(伪逆矩阵和协方差矩阵)

xingyun86 2020-8-6 2333

关于数学库Eigen两个常用函数实现(伪逆矩阵和协方差矩阵)

//求解协方差矩阵
Eigen::MatrixXd& cov(Eigen::MatrixXd& outMatrix, const Eigen::MatrixXd& inMatrix)
{
	Eigen::MatrixXd meanVec = inMatrix.colwise().mean();
	Eigen::RowVectorXd meanVecRow(Eigen::RowVectorXd::Map(meanVec.data(), inMatrix.cols()));
	Eigen::MatrixXd zeroMeanMat = inMatrix;
	zeroMeanMat.rowwise() -= meanVecRow;
	if (inMatrix.rows() == 1)
	{
		outMatrix = (zeroMeanMat.adjoint() * zeroMeanMat) / double(inMatrix.rows());
	}
	else
	{
		outMatrix = (zeroMeanMat.adjoint() * zeroMeanMat) / double(inMatrix.rows() - 1);
	}
	return outMatrix;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//伪逆矩阵(Moore-Penrose pseudoinverse)A定义:
//A+=VD+UT,其中,U,D和V是矩阵A奇异值分解后得到的矩阵。对角矩阵D的伪逆D+是非零元素取倒数之后再转置得到的。
//
Eigen::MatrixXd& pinv(Eigen::MatrixXd& outMatrix, const Eigen::MatrixXd& inMatrix)
{
	double pinvtoler = 1.e-6; // choose your tolerance wisely!
	Eigen::JacobiSVD<Eigen::MatrixXd> svd(inMatrix, Eigen::ComputeThinU | Eigen::ComputeThinV);
	Eigen::VectorXd singularValues_inv = svd.singularValues();
	Eigen::VectorXd sv = svd.singularValues();
	for (Eigen::Index i = 0; i < svd.cols(); ++i)
	{
		if (sv(i) > pinvtoler)
		{
			singularValues_inv(i) = 1.0 / sv(i);
		}
		else
		{
			singularValues_inv(i) = 0;
		}
	}
	outMatrix = (svd.matrixV() * singularValues_inv.asDiagonal() * svd.matrixU().transpose());
	return outMatrix;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回