特征库的矩阵逆函数返回NaN

Matrix inverse function of Eigen library returns NaN

本文关键字:函数 返回 NaN 特征      更新时间:2023-10-16

这是一个新创建的具有相同问题的示例。两个矩阵"firstMultiplyMat"answers"a"具有相同的值,但以不同的方式指定。然而,每一个的倒数都是不同的。无法获取"firstMultiplyMat"的逆矩阵,而"a"具有正确计算的逆矩阵。

#include<iostream>
#include<stdio.h>
#include <Eigen/Core> 
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
using Eigen::MatrixXd;
struct MemberLocation{
int id;
double x;
double y;
};
int main(){
//Attributes
int M = 2 ;//anchor
int N = 2 ;//nonanchor
int NA = 4;
int p = 0;
int numOfIterations =2;
MemberLocation *member1 = new MemberLocation[M];
MemberLocation *member2 = new MemberLocation[N];
MatrixXd neighbourdistanceEst(M,N);
MatrixXd neighbourdistanceDeriv(M,NA);
MatrixXd distanceDerivTranspose(NA,M);
MatrixXd firstMultiplyMat(NA,NA);
MatrixXd firstMultiplyMatInverse(NA,NA);
//Structs initilaization
member1[0].id = 5;
member1[0].x = 9.31301;
member1[0].y = 19.3955;
member1[1].id = 2;
member1[1].x = 46.6279;
member1[1].y = 0.00571905;
member2[0].id = 4;
member2[0].x = 11.7718;
member2[0].y = 7.99507;
member2[1].id = 6;
member2[1].x = 23.6158;
member2[1].y = 3.80408;
// Filling "neighbourdistanceDeriv" matrix
for (int i = 1 ; i <  numOfIterations ; i++ ){
for (int j = 0 ; j < M ; j++){
for (int k = 0 ; k < N ; k++){
    int id1 = member2[k].id; 
    int id2 = member1[j].id; 
    double xDiff = member2[k].x - member1[j].x; 
    double yDiff = member2[k].y - member1[j].y;
    double distance = pow(xDiff,2) + pow(yDiff,2);           
    neighbourdistanceEst(j,k) = sqrt(distance);
    neighbourdistanceDeriv(j,p) = xDiff / neighbourdistanceEst(j,k);
    neighbourdistanceDeriv(j,p+1) = yDiff / neighbourdistanceEst(j,k);
    p+=2;
}
p = 0;
}
}
// operations on "neighbourdistanceDeriv" matrix
distanceDerivTranspose = neighbourdistanceDeriv.transpose();
firstMultiplyMat = distanceDerivTranspose*neighbourdistanceDeriv;
firstMultiplyMatInverse = firstMultiplyMat.inverse();
// printing "firstMultiplyMat" matrix and its inverse
std::cout << "firstMultiplyMat:n" << firstMultiplyMat << std::endl;
std::cout << "inverse of firstMultiplyMat:n" << firstMultiplyMatInverse << std::endl<< std::endl;
// fixed array with same values obtained in "neighbourdistanceDeriv" matrix at runtime
MatrixXd a(4,4);
MatrixXd b(4,4);
a(0,0) =  0.994532;
a(0,1) =   -0.423853;
a(0,2)=  1.10423 ;
a(0,3) =    -0.314096;
a(1,0) = -0.423853 ;
a(1,1) = 1.00547 ;
a(1,2) =   -0.881237 ;
a(1,3) =  0.756726 ;
a(2,0) = 1.10423 ;
a(2,1) =   -0.881237;
a(2,2) =   1.43045;
a(2,3) =   -0.658827;
a(3,0) = -0.314096;
a(3,1) =  0.756726  ;
a(3,2) =  -0.658827;
a(3,3) = 0.569549 ;
b = a.inverse();
std::cout << "matrix a :n" << a <<std::endl;
std::cout << "inverse of matrix a :n" << b << std::endl;
//std::cout<<"hi n";
return 0;
}

输出:

firstMultiplyMat:
0.994534 -0.423857   1.10423 -0.314099
-0.423857   1.00547 -0.881237  0.756725
1.10423 -0.881237   1.43045 -0.658827
-0.314099  0.756725 -0.658827  0.569548
inverse of firstMultiplyMat:
-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -nan -nan -nan
-nan -inf -inf  inf
matrix a :
0.994532 -0.423853   1.10423 -0.314096
-0.423853   1.00547 -0.881237  0.756726
1.10423 -0.881237   1.43045 -0.658827
-0.314096  0.756726 -0.658827  0.569549
inverse of matrix a :
-119414     -1681.81       132361      89489.1
-1681.81       942762      10176.4 -1.24175e+06
132361      10176.4      -146638      -110149
89489.1 -1.24175e+06      -110149  1.57177e+06

矩阵firstMultiplyMat本身在内存方面很好;如果你把你放入的值推到里面,它就会正确地反转。您的问题在于firstMultiplyMat中的值,这些值与打印的值不完全相同,因为打印的内容被截断。

从本质上讲,你的矩阵可能不是可逆的。你可以通过不计算倒数,而是使用QR求解器来解决这个问题,例如:

HouseholderQR<MatrixXd> qr(A);
x = qr.solve(b); // computes A^-1 * b

有关HouseholderQR的更多信息,请点击此处