如何找到具有不同特征值的两个矩阵的公共特征向量

you*_*t13 10 python matlab matrix linear-algebra eigenvector

我正在寻找或构建两个矩阵之间的公共特征向量矩阵 X AB例如:

AX=aX with "a" the diagonal matrix corresponding to the eigenvalues

BX=bX with "b" the diagonal matrix corresponding to the eigenvalues
Run Code Online (Sandbox Code Playgroud)

其中AB是方阵和可对角化矩阵。

我查看了类似的帖子,但没有得出结论,即当我构建F由以下定义的最终想要的内同态时得到有效结果:F = P D P^-1

我还阅读了维基百科主题和这篇有趣的论文,但不必提取非常容易实现的方法。

特别是,我对eig(A,B)Matlab 函数很感兴趣。

我试着像这样使用它:

% Search for common build eigen vectors between FISH_sp and FISH_xc
[V,D] = eig(FISH_sp,FISH_xc);
% Diagonalize the matrix (A B^-1) to compute Lambda since we have AX=Lambda B X
[eigenv, eigen_final] = eig(inv(FISH_xc)*FISH_sp);
% Compute the final endomorphism : F = P D P^-1
FISH_final = V*eye(7).*eigen_final*inv(V)
Run Code Online (Sandbox Code Playgroud)

但是矩阵FISH_final没有给出好的结果,因为我可以从这个矩阵FISH_final(这实际上是一个 Fisher 矩阵)进行其他计算,并且这些计算的结果是无效的。

所以可以肯定,我一定在上面的代码片段中犯了一个错误。第一次,我更喜欢在 Matlab 中得出结论,就好像它是一个原型一样,如果它有效,则寻找使用 MKL 或 Python 函数进行这种综合。因此也标记python。

如何构建这些常见的特征向量并找到相关的特征值?我对现有的所有执行它的潜在方法有点迷茫。

下面的屏幕截图显示了换向器的内核必须与空向量不同:

特征向量公用和换向器核

编辑 1:从数学交流中,有人建议在换向器 [A,B] 上使用奇异值分解 (SVD),这是在 Matlab 中执行的操作:

“如果是一个共同的特征向量,那么 ?(?)?=0。SVD 方法给你一个单位向量,最小化?(?)?(约束条件为 ??=1)”

所以我从 中提取近似特征向量 V:

[U,S,V] = svd(A*B-B*A)
Run Code Online (Sandbox Code Playgroud)

有没有办法提高准确性以最小化?(?)?越多越好 ?

重要提示:也许你们中的一些人没有完全理解我的目标。

关于特征向量的公共基础,我正在寻找V1and的组合(向量或矩阵)V2,或直接null在 2 个输入 Fisher marices 上使用运算符,以构建这个新的基础“P”,其中,与其他特征值相比,已知D1D2(注意到D1aD2a),我们可以有:

F = P (D1a+D2a) P^-1
Run Code Online (Sandbox Code Playgroud)

要计算新的 Fisher 矩阵 F,我需要知道P,假设D1aD2a分别等于D1D2对角矩阵(来自AB矩阵的对角化)

如果我知道特征向量的共同基础P,我可以推断D1a,并Da2D1D2我能不能?

2个Fisher矩阵可在这些链接上找到:

矩阵A

矩阵B

Arg*_*yll 5

我认为 Matlab 中没有内置工具来计算两个矩阵的共同特征值。我将概述暴力方法并在 Matlab 中进行,以突出显示一些与特征向量相关的方法。我们假设矩阵 A 和 B 是方阵且可对角化。

步骤概要:

  1. 分别获取 A 和 B 的特征向量/值。

  2. 按特征空间对所得特征向量进行分组。

  3. 通过一次检查一对特征空间 A 和 B 的特征向量之间的线性相关性来检查特征空间的交集。

Matlab 确实提供了(有效)完成每个步骤的方法!当然,第 3 步涉及多次检查线性相关性,这反过来意味着我们可能会进行不必要的计算。更不用说,找到共同特征向量可能不需要找到所有特征向量。所以这并不是一个通用的数值配方。

如何获取特征向量/值

语法是

[V,D] = eig(A)
Run Code Online (Sandbox Code Playgroud)

其中D(i), V(:,i)是相应的特征对。

只是要小心数字错误。换句话说,如果你检查

tol=sum(abs(A*V(:,i)-D(i)*V(:,i)));
Run Code Online (Sandbox Code Playgroud)

tol<n*eps对于较小的矩阵 A 来说应该是正确的n,但对于 0 或 1 可能不正确。

例子:

>> A = gallery('lehmer',4);
>> [V,D] = eig(A);
>> sum(abs(A*V(:,1)-D(1)*V(:,1)))<eps
ans =
  logical
   0
>> sum(abs(A*V(:,1)-D(1)*V(:,1)))<10*eps
ans =
  logical
   1
Run Code Online (Sandbox Code Playgroud)

如何按特征空间对特征向量进行分组

在 Matlab 中,特征值不会在 的输出中自动排序[V,D] = eig(A)。所以你需要这样做。

  • 获取矩阵的对角线条目:diag(D)

  • 排序并跟踪排序所需的排列:[d,I]=sort(diag(D))

  • 识别 中的重复元素d[~,ia,~]=unique(d,'stable')

ia(i)告诉您第特征空间的起始索引i。因此,您可以期望d(ia(i):ia(i+1)-1)具有相同的特征值,因此属于第 特征空间的特征向量是其中的i列。当然,对于最后一项,索引是W(:,ia(i):ia(i+1)-1)W=V(:,I)ia(end):end

最后一步恰好在这里得到了真正普遍的回答。在这里,unique至少对于小型 来说就足够了A

(请随意提出一个单独的问题,了解如何有效地完成“基于另一个对角矩阵对一个矩阵的列进行洗牌”的整个步骤。可能还有其他使用内置 Matlab 函数的有效方法。)

例如,

>> A=[1,2,0;1,2,2;3,6,1];
>> [V,D] = eig(A),
V =
         0         0    0.7071
    1.0000   -0.7071         0
         0    0.7071   -0.7071
D =
     3     0     0
     0     5     0
     0     0     3
>> [d,I]=sort(diag(D));
>> W=V(:,I),
W =
         0    0.7071         0
    1.0000         0   -0.7071
         0   -0.7071    0.7071
>> [~,ia,~]=unique(d,'stable'),
ia =
     1
     3
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为第一个特征空间的特征值为 3,由 的第 1 列和第 2 列的跨度组成W,第二个空间也类似。

如何获得两个集合(的跨度)的线性交集

要完成查找共同特征向量的任务,您需要对A和执行上述操作B。接下来,对于每对特征空间,检查线性相关性。如果存在线性相关性,则线性相交就是答案

有多种方法可以检查线性相关性。一是利用别人的工具。示例:https: //www.mathworks.com/matlabcentral/fileexchange/32060-intersection-of-线性-子空间

一种是获取通过按列连接列向量形成的矩阵的RREF 。

假设您在步骤 2 中进行了计算并得出了V1, D1, d1, W1, ia1forAV2, D2, d2, W2, ia2for B。你需要做

for i=1:numel(ia1)
    for j=1:numel(ia2)
         check_linear_dependency(col1,col2);
    end
end
Run Code Online (Sandbox Code Playgroud)

其中col1W1(:,ia1(i):ia1(i+1)-1)如步骤 2 中提到的,但对最后一个空格有警告,并且类似地col2check_linear_dependency我们的意思是以下内容。首先我们得到RREF:

[R,p] = rref([col1,col2]);
Run Code Online (Sandbox Code Playgroud)

您首先要寻找的是rank([col1,col2])<size([col1,col2],2)。如果你已经计算过了rref,那么你已经有了排名。详细内容可以查看Matlab文档。您将需要分析您的代码以选择更有效的方法。我将避免猜测 Matlab 在rank(). 尽管做是否rank()意味着做该工作rref可以使一个很好的分离问题。

rank([col1,col2])<size([col1,col2],2)在is的情况下true,某些行没有前导 1,我相信这p将帮助您追溯到哪些列依赖于哪些其他列。您可以从这里构建相交。像往常一样,要警惕妨碍==陈述的数字错误。我们正在讨论一个不同的问题——即。如何rref()在 Matlab 中获得线性相交,所以我将把它留在这里。

还有另一种使用线性代数基本定理的方法(*叹息这个不幸的命名):

null( [null(col1.').' ; null(col2.').'] )
Run Code Online (Sandbox Code Playgroud)

我从这里得到的公式。我认为 ftla 是它应该发挥作用的原因。如果这不是原因,或者您想确保该公式有效(您可能应该这样做),请提出一个单独的问题。请注意,纯数学问题应该放在不同的 stackexchange 网站上。


现在我想我们已经完成了!


编辑1:

让我们ia通过一个例子来更加清楚地了解如何工作。假设我们用1forA2for来命名所有内容B。我们需要

for i=1:numel(ia1)
    for j=1:numel(ia2)
        if i==numel(ia1)
            col1 = W1(:,ia1(end):end);
        else
            col1 = W1(:,ia1(i):ia1(i+1)-1);
        end
        if j==numel(ia2)
            col2 = W2(:,ia2(j):ia2(j+1)-1);
        else
            col2 = W2(:,ia2(end):end);
        end
        check_linear_dependency(col1,col2);
    end
end
Run Code Online (Sandbox Code Playgroud)

编辑2:

我应该提到共同特征向量应该是换向器零空间中的特征向量的观察结果。因此,也许null(A*B-B*A)会产生相同的结果。

但仍要警惕数字错误。使用强力方法,我们从低特征对开始tol(请参阅前面部分中的定义),因此我们已经验证了特征向量中的“特征”部分。对于null(A*B-B*A),也应该做同样的事情。

当然,由于手头有多种方法,最好比较不同方法的结果。