<p>我认为Matlab中没有内置的工具来计算两个矩阵的公共特征值。我将概述蛮力方法,并在Matlab中使用它,以突出其特征向量相关的一些方法。我们假设矩阵A和B是平方的且可对角化的</p>
<h3>步骤概述:</h3>
<ol>
<li><p>分别获取A和B的特征向量/值</p>
</li>
<li><p>将合成的特征向量按其特征空间分组</p>
</li>
<li><p>通过检查A和B的特征向量之间的线性相关性,一次检查一对特征空间,检查特征空间的相交</p>
</li>
</ol>
<p>Matlab确实提供了(有效地)完成每个步骤的方法!当然,第3步需要多次检查线性依赖关系,这意味着我们可能会进行不必要的计算。更不用说,查找公共特征向量可能不需要查找所有特征向量。所以这并不是一个通用的数值公式</p>
<h3>如何获得特征向量/值</h3>
<p>语法是</p>
<pre><code>[V,D] = eig(A)
</code></pre>
<p>其中<code>D(i), V(:,i)</code>是对应的本征对</p>
<p>只是要小心数字错误。换句话说,如果你检查</p>
<pre><code>tol=sum(abs(A*V(:,i)-D(i)*V(:,i)));
</code></pre>
<p><code>tol<n*</code><a href="https://www.mathworks.com/help/matlab/ref/eps.html" rel="nofollow noreferrer">^{<cd3>}</a>对于一些小的<code>n</code>对于小矩阵a应该是真的,但是对于0或1可能不是真的</p>
<p>例如:</p>
<pre><code>>> 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
</code></pre>
<h3>如何根据特征空间对特征向量进行分组</h3>
<p>在Matlab中,特征值不会在<code>[V,D] = eig(A)</code>的输出中自动排序。所以你需要这样做</p>
<ul>
<li><p>获取矩阵的对角项:<code>diag(D)</code></p>
</li>
<li><p>排序并跟踪排序所需的排列:<code>[d,I]=sort(diag(D))</code></p>
</li>
<li><p>识别<code>d</code>:<code>[~,ia,~]=unique(d,'stable')</code>中的重复元素</p>
</li>
</ul>
<p><code>ia(i)</code>告诉您第<code>i</code>个特征空间的开始索引。因此,您可以期望<code>d(ia(i):ia(i+1)-1)</code>是相同的特征值,因此属于<code>i</code>第特征空间的特征向量是<code>W(:,ia(i):ia(i+1)-1)</code>列,其中<code>W=V(:,I)</code>。当然,对于最后一个,索引是<code>ia(end):end</code></p>
<p>最后一步恰好得到了真正一般性的回答<a href="https://stackoverflow.com/q/65384350/3181104">here</a>。在这里,<code>unique</code>至少对于小的<code>A</code>是足够的</p>
<p>(请随意问一个单独的问题,关于如何有效地执行“基于另一对角矩阵洗牌一个矩阵的列”的整个步骤。可能还有其他使用内置Matlab函数的有效方法。)</p>
<p>比如说,</p>
<pre><code>>> 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
</code></pre>
<p>这是有意义的,因为第一个特征空间的特征值3由<code>W</code>的第1列和第2列的跨度组成,第二个空间也是如此</p>
<h3>如何获得两个集合的(跨度)线性相交</h3>
<p>要完成查找公共特征向量的任务,请对<code>A</code>和<code>B</code>执行上述操作。接下来,对于每对特征空间,检查线性相关性。如果存在线性相关性,则线性相交为<em>答案</p>
<p>检查线性依赖关系有多种方法。一是使用他人的工具。示例:<a href="https://www.mathworks.com/matlabcentral/fileexchange/32060-intersection-of-linear-subspaces" rel="nofollow noreferrer">https://www.mathworks.com/matlabcentral/fileexchange/32060-intersection-of-linear-subspaces</a></p>
<p>一种是通过逐列连接列向量得到矩阵的<a href="https://www.google.com/search?q=row+reduced+echelon+form" rel="nofollow noreferrer">RREF</a></p>
<p>假设您在步骤2中进行了计算,得到了<code>V1, D1, d1, W1, ia1</code>的<code>A</code>和<code>V2, D2, d2, W2, ia2</code>的<code>B</code>。你需要做什么</p>
<pre><code>for i=1:numel(ia1)
for j=1:numel(ia2)
check_linear_dependency(col1,col2);
end
end
</code></pre>
<p>其中<code>col1</code>是<code>W1(:,ia1(i):ia1(i+1)-1)</code>,如第2步所述,但最后一个空格和类似的<code>col2</code>有警告,我们所说的<code>check_linear_dependency</code>是指以下内容。首先我们得到RREF:</p>
<pre><code>[R,p] = rref([col1,col2]);
</code></pre>
<p>首先,您正在寻找<code>rank([col1,col2])<size([col1,col2],2)</code>。如果您已经计算了<code>rref</code>,那么您已经有了排名。您可以查看Matlab <a href="https://www.mathworks.com/help/matlab/ref/rref.html" rel="nofollow noreferrer">documentation</a>以了解详细信息。您需要分析代码以选择更有效的方法。我将避免猜测Matlab在<code>rank()</code>中的作用。尽管做<code>rank()</code>是否意味着做<code>rref</code>中的工作可以成为一个好的<em>独立的</em>问题</p>
<p>在<code>rank([col1,col2])<size([col1,col2],2)</code>为<code>true</code>的情况下,某些行没有前导1我相信<code>p</code>将帮助您追溯哪些列依赖于哪些其他列。你可以从这里建立交叉点。像往常一样,要警惕数字错误妨碍了<code>==</code>语句。我们将要讨论一个不同的问题,即如何从Matlab中的<code>rref()</code>得到线性相交,所以我将把它留在这里</p>
<p>还有另一种方法使用<a href="https://www.google.com/search?q=fundamental+theorem+of+linear+algebra" rel="nofollow noreferrer">fundamental theorem of linear algebra</a>(*对这个不幸的命名感到叹息):</p>
<pre><code>null( [null(col1.').' ; null(col2.').'] )
</code></pre>
<p>我从<a href="https://www.mathworks.com/matlabcentral/answers/656413-help-me-how-to-find-the-base-of-the-intersection-of-two-subspaces" rel="nofollow noreferrer">here</a>得到的公式。我认为ftla是它应该起作用的原因。如果这不是原因,或者如果您想确保公式有效(您可能应该这样做),请问一个<em>单独的</em>问题。请注意,纯数学问题应该放在不同的stackexchange网站上</p>
<hr/>
<p>现在我想我们完了</p>
<hr/>
<p>编辑1:</p>
<p>让我们用一个例子来说明<code>ia</code>是如何工作的。假设我们用一个尾随的<code>1</code>来命名所有事物,用<code>A</code>和<code>2</code>来命名所有事物。我们需要</p>
<pre><code>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
</code></pre>
<hr/>
<p>编辑2:</p>
<p>我应该提到一个观察结果,即公共特征向量应该是换向器零空间中的特征向量。因此,也许<code>null(A*B-B*A)</code>会产生相同的结果</p>
<p>但仍然要警惕数字错误。使用蛮力法,我们从低<code>tol</code>的特征对开始(见前面章节中的定义),因此我们已经验证了特征向量中的“特征”部分。对于<code>null(A*B-B*A)</code>,也应该这样做</p>
<p>当然,有多种方法在手,比较不同方法的结果是个好主意</p>