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

How to find the common eigenvectors of two matrices with distincts eigenvalues

我正在寻找或更确切地说是在 2 个矩阵 AB 之间构建公共特征向量矩阵 X,例如:

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

BX=bX with "b" the diagonal matrix corresponding to the eigenvalues

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

我查看了 但未能得出结论,即当我构建最终想要的自同态 F 时得到有效结果,定义为:F = P D P^-1

我也读过 wikipedia topic and this interesting paper 但不必提取非常容易实现的方法。

我特别感兴趣的是 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)

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

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

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

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

编辑 1: 从数学交流中,有人建议在换向器 [A,B] 上使用奇异值分解 (SVD),即在 Matlab 中通过 :

“如果是一个公共特征向量,则‖(−)‖=0。SVD 方法为您提供了一个最小化‖(−)‖的单位向量(约束为‖‖=1)"= 47=]

所以我从 :

中提取近似特征向量 V
[U,S,V] = svd(A*B-B*A)

有没有办法提高准确率,尽量减少‖(−)‖?

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

关于特征向量的公共基础,我正在寻找 V1V2 的组合(向量或矩阵),或者直接在 2 输入上使用 null 运算符Fisher marices,为了建立这个新的基础“P”,其中,除了已知 D1D2(注意 D1aD2a)之外的其他特征值,我们可以:

F = P (D1a+D2a) P^-1

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

如果我知道特征向量 P 的公共基础,我可以从 D1D2 中推导出 D1aDa2,难道我不能?

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

Matrix A

Matrix B

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

步骤大纲:

  1. 分别为 A 和 B 得到 eigenvectors/values。

  2. 将生成的特征向量按特征space分组。

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

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

如何获得eigenvector/values

语法是

[V,D] = eig(A)

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

请注意数字错误。换句话说,如果你检查

tol=sum(abs(A*V(:,i)-D(i)*V(:,i)));

tol<n*eps 对于一些较小的 n 对于较小的矩阵 A 应该是正确的,但对于 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

如何根据特征值对特征向量进行分组spaces

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

  • 获取矩阵的对角线元素:diag(D)

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

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

ia(i) 告诉你第 i 个特征值的开始索引 space。因此,您可以预期 d(ia(i):ia(i+1)-1) 是相同的特征值,因此属于第 i 个特征的特征向量 space 是列 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

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

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

要完成寻找公共特征向量的任务,请对 AB 执行上述操作。接下来,对于每对 eigenspace,您检查线性相关性。如果存在线性相关性,则线性相交是一个答案。

检查线性相关性的方法有很多种。一种是使用别人的工具。示例:https://www.mathworks.com/matlabcentral/fileexchange/32060-intersection-of-linear-subspaces

一个是获取通过逐列连接列向量形成的矩阵的RREF

假设您在第 2 步中进行了计算,A 的计算结果为 V1, D1, d1, W1, ia1B 的计算结果为 V2, D2, d2, W2, ia2。你需要做

for i=1:numel(ia1)
    for j=1:numel(ia2)
         check_linear_dependency(col1,col2);
    end
end

其中 col1W1(:,ia1(i):ia1(i+1)-1),如步骤 2 中所述,但需要注意最后一个 space 以及 col2check_linear_dependency 我们意思如下。首先我们得到 RREF:

[R,p] = rref([col1,col2]);

您首先要找的是rank([col1,col2])<size([col1,col2],2)。如果您已经计算了 rref,那么您已经有了排名。您可以查看 Matlab documentation 了解详细信息。您将需要分析您的代码以选择更有效的方法。我将避免猜测估计 Matlab 在 rank() 中的作用。尽管做 rank() 是否意味着做 rref 中的工作可以成为一个很好的 separate 问题。

rank([col1,col2])<size([col1,col2],2)true 的情况下,某些行没有前导 1,我相信 p 将帮助您追溯哪些列依赖于其他哪些列.你可以从这里建立交叉点。像往常一样,请注意 == 语句中出现的数值错误。我们正在讨论另一个问题——即。如何在 Matlab 中从 rref() 获得线性相交,所以我将把它留在这里。

还有另一种使用 fundamental theorem of linear algebra 的方法(*叹息那个不幸的命名):

null( [null(col1.').' ; null(col2.').'] )

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


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


编辑 1:

让我们通过示例更加清楚地了解 ia 的工作原理。假设我们用 A 尾随 1B 尾随 2 来命名所有内容。我们需要

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

编辑 2:

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

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

当然,手头有多种方法,比较不同方法的结果是个好主意。

我怀疑这是一个相当微妙的问题。

首先,从数学上讲,A 和 B 同时可对角化当且仅当它们可交换,即当且仅当

A*B - B*A == 0 (often A*B-B*A is written [A,B])
(for if A*X = X*a and B*X = X*b with a, b diagonal then
A = X*a*inv(X), B = X*b*inv(X) 
[A,B] = X*[a,b]*inv(X) = 0 since a and b, being diagonal, commute)

所以我要说的第一件事是检查你的 A 和 B 确实通勤,这是第一个尴尬的问题:因为计算的 [A,B] 由于舍入误差不太可能全为零,您需要确定 [A,B] 非零是否只是由于舍入误差,或者实际上 A 和 B 不交换。

现在假设x是A的特征向量,特征值为e。那么

A*B*x = B*A*x = B*e*x = e*B*x

因此,从数学上讲,我们有两种可能性:要么 Bx 为 0,要么 Bx 也是 A 的特征向量,其特征值为 e。

一个很好的例子是 a 的所有元素都不同,即 A 的每个特征space 都是一维的。在这种情况下: 如果 AX = Xa 对于对角线 a,则 BX = Xb 对于对角线 b(您需要计算)。如果将 A 对角化,并且所有特征值都足够不同,那么您可以假设每个特征值 space 都是维度 1,但是 'sufficiently' 是什么意思?另一个微妙的问题,唉。如果两个计算出的特征值非常接近,那么特征值是否不同或者差异是否存在舍入误差? 无论如何,要为 A 的每个特征向量 x 计算 b 的特征值,请计算 Bx。如果 ||Bx||与 ||x|| 相比足够小那么B的特征值为0,否则为

x'*B*x/(x'*x) 

一般情况下,部分特征space的维数可能大于1,一维特征space可以按上述方式处理,但需要更多的计算更高维度的。

假设A的m个特征向量x[1].. x[m]对应特征值e。由于 A 和 B 通勤,很容易看出 B 将 xs 跨越的 space 映射到自身。令 C 为 mxm 矩阵

C[i,j] = x[j]'*B*x[i]

那么C是对称的,所以我们可以对角化它,即找到正交V和对角线c

C = V'*c*V

如果我们定义

y[l] = Sum{ k | V[l,k]*x[k] } l=1..m

然后一点代数表明 y[l] 是 B 的特征向量,特征值为 c[l]。此外,由于每个 x[i] 都是 A 的特征向量,具有相同的特征值 e,因此每个 y[l] 也是 A 的特征向量,具有相同的特征向量 e.

所以总而言之,我认为一个方法是:

  1. 计算[A,B],如果真的不为0,放弃
  2. 对角化 A,并对特征值进行递增排序(并对特征向量进行排序!)
  3. 确定A的特征space。对于一维space,A对应的特征向量是B的特征向量,你只需要计算B的特征值。对于更高维的,按照上一段进行。

测试换向器是否为零的相对昂贵(在计算量上)但相当可靠的方法是计算换向器的 svd 并取最大奇异值,例如 c,并取最大奇异值A的值(或特征值的最大绝对值)a和B的b。除非c小很多(例如1e-10倍)a和b中的较小者,你应该断定换向器不为零。