我一直在从头开始编写一个控制系统工具箱,纯粹是在 Python3 中(无耻的插件:)harold
。care.m
根据我过去的研究,我总是出于技术/无关的原因抱怨 Riccati 求解器。
因此,我一直在编写自己的一套例程。我找不到解决办法的一件事是获得一个高性能的平衡算法,至少和balance.m
. 在你提到它之前,xGEBAL
家庭在 Scipy 中公开,你基本上可以从 Scipy 调用如下,假设你有一个浮点类型的 2D 数组A
:
import scipy as sp
gebal = sp.linalg.get_lapack_funcs(('gebal'),(A,)) # this picks up DGEBAL
Ab, lo, hi, scaling , info = gebal(A, scale=1 , permute=1 , overwrite_a=0 )
现在,如果我使用以下测试矩阵
array([[ 6. , 0. , 0. , 0. , 0.000002],
[ 0. , 8. , 0. , 0. , 0. ],
[ 2. , 2. , 6. , 0. , 0. ],
[ 2. , 2. , 0. , 8. , 0. ],
[ 0. , 0. , 0.000002, 0. , 2. ]])
我明白了
array([[ 8. , 0. , 0. , 2. , 2. ],
[ 0. , 2. , 0.000002, 0. , 0. ],
[ 0. , 0. , 6. , 2. , 2. ],
[ 0. , 0.000002, 0. , 6. , 0. ],
[ 0. , 0. , 0. , 0. , 8. ]])
但是,如果我将其传递给balance.m
,我会得到
>> balance(A)
ans =
8.0000 0 0 0.0625 2.0000
0 2.0000 0.0001 0 0
0 0 6.0000 0.0002 0.0078
0 0.0003 0 6.0000 0
0 0 0 0 8.0000
如果您检查排列模式,它们是相同的,但缩放是关闭的。gebal
给出统一比例,而 matlab 给出以下 2 的幂[-5,0,8,0,2]
:
显然,这些都没有使用相同的机器。我尝试了各种选项,例如 Lemonnier、Van Dooren 双面缩放、原始 Parlett-Reinsch 以及文献中其他一些鲜为人知的方法,例如SPBALANCE
.
我可能要强调的一点是我了解本纳的工作。特别是专门为此目的的哈密顿矩阵的辛平衡。但是,请注意,这种类型的处理是在gcare.m
(广义 Riccati 求解器)内完成的,平衡是通过 直接完成的balance.m
。因此,如果有人能指出我的实际实施,我将不胜感激。
披露:我真的不是想对mathworks代码进行逆向工程:由于各种原因,包括这个问题的动机,我实际上想摆脱它,也就是说,我不知道它在做什么,这让我付出了很多代价时光倒流。我的目的是获得一个令人满意的平衡算法,它允许我传递 CAREX 示例,以便我可以在常规求解器之上实现牛顿迭代方法。