C++ 为什么可以';我能得到犰狳对称正定矩阵的平方根吗?
我有矩阵A: 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 100 0 0 0 0 1100C++ 为什么可以';我能得到犰狳对称正定矩阵的平方根吗?,c++,armadillo,C++,Armadillo,我有矩阵A: 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 100 0 0 0 0 1100 这个矩阵显然是对称的,所以A*A显然是正定矩阵。我试图用犰狳来计算它的平方根,但失败了。我做错了什么 代码如下: #include <iostream> #include <armadillo> using namespace arma; using namespace std; int main(){ mat A(6,6); for(in
这个矩阵显然是对称的,所以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);
}
它适用于某些半正定矩阵而不适用于其他矩阵的原因似乎是,有时本应为零的特征值变成了具有小范数的负数。这导致了一个问题,因为该算法最有可能需要特征值的平方根 为了能够得到对称定半正对称矩阵的平方根,我们可以使用特征值分解特性,然后取对角部分的平方根。(注意将“负零”更改为实际零) 下面是一些实现此功能的代码:
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();
}
mat-raiz(const-mat&A){
vec-D;
材料B;
eig_sym(D、B、A);
无符号整数n=D.n_元素;
mat G(n,n,fill::零);
对于(unsigned int i=0;i它之所以适用于某些确定的半正矩阵而不适用于其他矩阵,似乎是因为有时假定为零的特征值变成了具有小范数的负数。这导致了一个问题,因为该算法最有可能将特征值的平方根带到某个地方
为了能够得到对称定半正对称矩阵的平方根,我们可以使用特征值分解特性,然后取对角部分的平方根。(注意将“负零”更改为实际零)
下面是一些实现此功能的代码:
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();
}
mat-raiz(const-mat&A){
vec-D;
材料B;
eig_sym(D、B、A);
无符号整数n=D.n_元素;
mat G(n,n,fill::零);
对于(unsigned int i=0;i)你的矩阵不是正定的。它是半正定的,特征值为0。好吧,你是对的,但它似乎适用于其他一些半正定矩阵。我的意思是,它显然有一个平方根。矩阵a
是奇异的(例如,两行相同,两列相同),因此,A*A
实际上是正不定或正半定(取决于您使用的行话)。理论上,并非所有此类矩阵都有平方根(特别是带有实数元素的矩阵),尝试用数字计算此类矩阵是有问题的(例如,除以零).我想,但这不是有点愚蠢吗?我的意思是很明显,这样的矩阵也有平方根。它适用于其他矩阵(如零矩阵)。零矩阵有一个实元素的平方根,即使它是奇异的。但是,尝试计算它的逆,你会有麻烦。你的矩阵不是正定的。它是半正定的,特征值为0。好吧,你是对的,但它似乎与其他一些半正定矩阵一起工作。我的意思是,它显然有平方根对吗?矩阵a
是单数的(例如,两行相同,两列相同),因此a*a
实际上是正不定或正半定的(取决于您使用的行话)。理论上,并非所有这样的矩阵都有平方根(特别是带有实元素的矩阵)试图用数字计算这样的东西是有问题的(例如,被零除)。我想,但这不是有点愚蠢吗?我的意思是很明显,这样的矩阵也有平方根。它适用于其他矩阵(如零矩阵)。零矩阵有一个实数元素的平方根,即使它是奇异的。但是,尝试计算它的逆,你会遇到麻烦。我上传这篇文章的唯一原因是它可能会帮助其他有相同问题的人。我已经自己解决了这个问题。代码中仍然有基本的错误。(1)矩阵G在使用前未设置为零,仅设置了矩阵G的对角线;G的非对角线元素是垃圾,导致返回错误的结果;请阅读上的文档,了解如何正确初始化矩阵。(2)矩阵A在输入raiz()时被不必要地复制,导致额外的内存使用和速度减慢;请改用常量引用。(3)不需要对矩阵B的转置求逆;使用B*G*B.t()更快、更简单@M非常感谢您的回复,我想我已经解决了其中两个bug,但我不知道如何使用const引用,您介意编辑该部分吗?我已经修改了代码。但是,最好使用更通用的,而不是专用的或raiz()
function。将尝试计算近似的矩阵平方根。示例:cx\u mat B=sqrtmat(A);
@m sqrtmat的所有问题是它并不总是给你主要的平方根。我上传它的唯一原因是它可能会帮助其他有同样问题的人。我已经自己解决了这个问题。代码中仍然有一些基本的错误。(1)矩阵G在使用前未设置为零,仅设置了矩阵G的对角线;G的非对角线元素是垃圾,导致返回错误的结果;请阅读上的文档,了解如何正确初始化矩阵。(2)矩阵A在输入raiz()时被不必要地复制,导致额外的内存使用和速度减慢;请改用常量引用。(3)不需要对矩阵B的转置求逆;使用B*G*B.t()更快、更简单@M非常感谢您的回复,我想我已经解决了其中两个bug,但我不知道如何使用const引用,您介意编辑该部分吗?我已经修改了代码。但是,最好使用更通用的,而不是专用的或raiz()
函数。将尝试计算近似的矩阵平方根。示例:cx_mat B=sqrtmat(A);
@mtall