Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么可以';我能得到犰狳对称正定矩阵的平方根吗?_C++_Armadillo - Fatal编程技术网

C++ 为什么可以';我能得到犰狳对称正定矩阵的平方根吗?

C++ 为什么可以';我能得到犰狳对称正定矩阵的平方根吗?,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:

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(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