Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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++_Math_Matrix_Eigenvector_Eigenvalue - Fatal编程技术网

C++ 求协方差矩阵的特征向量生成三维边界球

C++ 求协方差矩阵的特征向量生成三维边界球,c++,math,matrix,eigenvector,eigenvalue,C++,Math,Matrix,Eigenvector,Eigenvalue,我目前正在编写一个函数,为三维空间中的一组点找到一个“精确”的边界球体。到目前为止,我想我对这个过程有一个很好的理解,但我被卡住了 以下是我的工作内容: A) 三维空间中的点 B) 存储在4x4矩阵类中的3x3协方差矩阵(由单元格m0、m1、m2、m3、m4等引用,而不是行和列) 我已经找到了点的协方差矩阵的3个特征值,并且我已经建立了一个函数,通过高斯消去法将矩阵转换为缩减行梯队形式(rref) 我已经根据我在网上找到的示例中的数字测试了这两个函数,它们似乎工作正常 下一步是使用以下等式找到特

我目前正在编写一个函数,为三维空间中的一组点找到一个“精确”的边界球体。到目前为止,我想我对这个过程有一个很好的理解,但我被卡住了

以下是我的工作内容: A) 三维空间中的点 B) 存储在4x4矩阵类中的3x3协方差矩阵(由单元格m0、m1、m2、m3、m4等引用,而不是行和列)

我已经找到了点的协方差矩阵的3个特征值,并且我已经建立了一个函数,通过高斯消去法将矩阵转换为缩减行梯队形式(rref)

我已经根据我在网上找到的示例中的数字测试了这两个函数,它们似乎工作正常

下一步是使用以下等式找到特征向量: (M-λ*I)*V

。。。其中M是协方差矩阵,λ是特征值之一,I是单位矩阵,V是特征向量

然而,我似乎没有在重新计算4x3矩阵之前正确地构造它,因为在运行rref之前和之后,应该计算特征向量分量的最右列为0。我理解为什么它们在后面是零(没有任何常数,线性方程组的最简单解就是所有系数都是零),但我不知道该放在那里什么

以下是迄今为止的功能:

Vect eigenVector(const Matrix &M, const float eval) { Matrix A = Matrix(M); A -= Matrix(IDENTITY)*eval; A.rref(); return Vect(A[m3],A[m7],A[m11]); } 向量特征向量(常数矩阵和M,常数浮点值){ 矩阵A=矩阵(M); A-=矩阵(恒等式)*eval; A.rref(); 返回向量(A[m3],A[m7],A[m11]); } 3x3协方差矩阵作为M传递,特征值作为eval传递。矩阵(标识)返回标识矩阵。m3、m7和m11对应于4x3矩阵的最右列

下面是我用来测试函数的示例3x3矩阵(存储在4x4矩阵类中):

Matrix(1.5f, 0.5f, 0.75f, 0, 0.5f, 0.5f, 0.25f, 0, 0.75f, 0.25f, 0.5f, 0, 0, 0, 0, 0); 矩阵(1.5f,0.5f,0.75f,0, 0.5f,0.5f,0.25f,0, 0.75f,0.25f,0.5f,0, 0, 0, 0, 0); 我从另一个函数中得到了2.097,0.3055,0.09756的特征值

上面的特征向量()正确地从对角线(0,0 1,1 2,2)减去传递的特征值

rref()后的矩阵A:

[(1, 0, 0, -0), (-0, 1, 0, -0), (-0, -0, 1, -0), (0, 0, 0, -2.09694)] 对于rref()函数,我使用的是一个经过翻译的python函数,可以在这里找到:

我传递给rref()的矩阵应该是什么样子才能得到特征向量

(M-λI)V不是一个方程,它只是一个表达式。然而,(M-λI)V=0是。这个方程把特征向量和特征值联系起来


因此,假设您的
rref
函数起作用,我会设想您创建一个扩充矩阵作为
[(M-λI)| 0]
,其中
0
表示零向量。这听起来像你已经在做的事情,所以我不得不假设你的
rref
函数坏了。或者,它不知道如何处理4x4矩阵(与4x3矩阵相反,这是它对增强矩阵的期望)。

啊,经过几个小时的艰苦研究,我终于解决了我的问题

问题在于,没有“一”组特征向量,而是一个具有不同量级的无穷多个特征向量

我选择的方法是使用REF(行梯队形式)而不是RREF,在矩阵中留下足够的信息,让我可以用任意值替换z,然后反向求解y和x。然后,我对向量进行归一化,得到一个单位特征向量,这应该适用于我的目的

我的最终代码:

Vect eigenVector(const Matrix &M, const float eVal) { Matrix A = Matrix(M); A -= Matrix(IDENTITY)*eVal; A.ref(); float K = 16; // Arbitrary value float J = -K*A[m6]; // Substitute in K to find J float I = -K*A[m2]-J*A[m1]; // Substitute in K and J to find I Vect eVec = Vect(I,J,K); eVec.norm(); // Normalize eigenvector return eVec; } 向量特征向量(常数矩阵和M,常数浮点值){ 矩阵A=矩阵(M); A-=矩阵(恒等式)*eVal; A.ref(); 浮点K=16;//任意值 float J=-K*A[m6];//在K中替换以找到J float I=-K*A[m2]-J*A[m1];//用K和J代入I Vect-eVec=Vect(I,J,K); eVec.norm();//规范化特征向量 返回eVec; }
唯一奇怪的是,特征向量出现的方向与我预期的相反(它们被否定了!),但这是一个没有实际意义的问题。

这也是我的想法,我花了相当长的时间尝试不同的变化。实际上,我认为,这是一个解线性方程组的无限解。在我得到有意义的结果之前,我必须先向系统抛出一个任意的值。看看下面我的答案,我最终做了什么。不过,感谢您抽出时间帮忙:) Vect eigenVector(const Matrix &M, const float eVal) { Matrix A = Matrix(M); A -= Matrix(IDENTITY)*eVal; A.ref(); float K = 16; // Arbitrary value float J = -K*A[m6]; // Substitute in K to find J float I = -K*A[m2]-J*A[m1]; // Substitute in K and J to find I Vect eVec = Vect(I,J,K); eVec.norm(); // Normalize eigenvector return eVec; }