我有矩阵A:
0 0 0 0 1 1
0 0 0 0 0 1
0 0 0 0 0 1
0 0 0 0 0 1
1 0 0 0 0 0
1 1 1 1 0 0。
该矩阵明显对称,因此A * A显然是正定矩阵。我试图计算它在犰狳中的平方根但是失败了。我做错了什么?
以下是代码:
#include <iostream>
#include <armadillo>
using namespace arma;
using namespace std;
int main(){
mat A(6,6);
for(int i=0;i<6;i++){ // this part just reads the matrix,
for(int j=0;j<6;j++){
int x;
scanf("%d",&x);
A(i,j)=x;
}
}
cout << sqrtmat_sympd(A*A);
}
我编译了它,它适用于像单位矩阵这样的矩阵,但当我尝试使用它时,它会说:
error: sqrtmat_sympd(): transformation failed
terminate called after throwing an instance of 'std::runtime_error'
what(): sqrtmat_sympd(): transformation failed
Aborted (core dumped)
答案 0 :(得分:0)
它适用于某些确定的半正矩阵而不适用于其他矩阵的原因似乎是有时候应该为零的特征值变成具有小范数的负数。这导致了一个问题,因为算法最有可能在特定值的某个地方采用特征值的平方根。
为了能够得到对称确定半正对称矩阵的平方根,我们可以使用特征值分解特征,然后取对角线部分的平方根。(小心改变&#34;负值零和#34;到实际的零。
以下是一些执行此操作的代码:
mat raiz(const mat& A){
vec D;
mat B;
eig_sym(D,B,A);
unsigned int n = D.n_elem;
mat G(n,n,fill::zeros);
for(unsigned int i=0;i<n;i++){
if(D(i)<0 ) D(i)=0;
G(i,i)=sqrt(D(i));
}
return B*G*B.t();
}
注意:sqrtmat()函数可能更合适,因为它已尝试近似矩阵平方根。