Schur(QZ) 分解差异

计算科学 线性代数 拉帕克 语言
2021-11-27 13:20:51

我无法理解为什么不同的语言会为 Schur(QZ) 分解产生不同的答案。我正在努力将 Matlab 中的一些旧东西写到 Julia 和 Python 中,并且遇到了一些与 Matlab qz、 Juliaschurfact和 Scipy 之间的差异的问题qz(Julia 和 Scipy 同意,Matlab 是不同的)。经过一番挖掘,问题的根源似乎是Matlabzgges默认使用LAPACK(甚至不确定你是否可以使用dgges,但看起来并不难)而Julia和Scipy都默认为LAPACKdgges并且可以zgges通过请求来访问事情要复杂。我可以得到我正在“寻找”的答案,但对简单地“到达”答案有点不满意。

Matlab坚持有理由zgges吗?对于实数,为什么会zgges产生dgges不同的答案(答案仅在几个不一定按行或列相关的数字上的符号不同)?

这是我正在谈论的一个例子(为了完整性和方便查看,使用所有三种语言)。

朱莉娅

A = reshape(1:9, 3, 3)

B = [ 0.47143516 -1.19097569 1.43270697
    -0.3126519 -0.72058873  0.88716294
     0.85958841 -0.6365235 0.01569637]

# This is the answer without using complex numbers
Freal = schurfact(A, B)
AAreal, BBreal = Freal[:S], Freal[:T]
Qreal, Zreal = Freal[:Q], Freal[:Z]

# This is the complex answer turned into reals
# and matches Matlab's answer
Fcomplex = schurfact(A+0im, B+0im)
AAcomplex, BBcomplex = real(Fcomplex[:S]), real(Fcomplex[:T])
Qcomplex, Zcomplex = real(Fcomplex[:Q]), real(Fcomplex[:Z])

Python

import numpy as np
import scipy.linalg as la

A = np.arange(1, 10).reshape(3, 3).T
B = np.array([[ 0.47143516, -1.19097569,  1.43270697],
              [-0.3126519 , -0.72058873,  0.88716294],
              [ 0.85958841, -0.6365235 ,  0.01569637]])

# Answer without using complex
AAreal, BBreal, Qreal, Zreal = la.qz(A, B)

# Answer using complex and
# matches Matlab's answer
Fcomplex = la.qz(A, B, output="complex")
AAcomplex, BBcomplex, Qcomplex, Zcomplex = map(np.real, Fcomplex)

MATLAB

A = reshape(1:9, 3, 3)
B = [ 0.47143516 -1.19097569 1.43270697
    -0.3126519 -0.72058873  0.88716294
     0.85958841 -0.6365235 0.01569637]

[AAm, BBm, Qm, Zm] = qz(A, B)

抱歉有点长,但我对为什么会发生这种情况感兴趣。

2个回答

MATLAB 的语法qz(A,B,'real')与 一致schur(A,'real'),所以我们不妨问一下为什么默认是 Schur 形式的复数。

我想到了两个原因。

  1. 向后兼容性。可能有一段时间,在 Matlab 中只实现了复杂的 Schur 形式(可能来自 LAPACK 之前的时代),默认情况下保留该行为,而不是破坏现有代码。显然,向后兼容性在 Matlab 中很重要,即使它会产生可憎的东西(参见logspacefor的语法b=pi)。

  2. 最少的惊喜。当人们打电话给 时schur,他们期望三角形因子是三角形的。那些想要真正的 Schur 形式的人知道至少有两种变体。

通常,这种“分歧”发生在语言、库、库版本等之间,因为正在执行不同的约定,并且请求的分解是等效的(但不完全相同)。我在实现增量奇异值分解时遇到了这类问题。我用我实现的算法获得的结果与奇异向量的符号中的标准奇异值分解不同,因为分解对于这些向量的符号是唯一的。

您最好询问 MATLAB 特定的论坛或邮件列表,为什么 MATLAB 选择zgges.