私は制御システムのツールボックスをゼロから作成し、純粋にPython3(恥知らずなプラグイン:)で作成していharold
ます。私の過去の調査から、Riccatiソルバーについて、care.m
技術的/無関係な理由で常に不満を持っています。
したがって、私は自分の一連のルーチンを作成しています。私が回避策を見つけることができない1つのことは、少なくともと同等の高性能バランシングアルゴリズムを取得することbalance.m
です。言及する前に、xGEBAL
ファミリはScipyで公開されており、基本的には次のようにScipyから呼び出すことができます。float型の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
は1のスケーリングを与えますが、MATLABは次の2のべき乗を与えます[-5,0,8,0,2]
。
明らかに、これらは同じ機械を使用していません。Lemonnier、Van Doorenの両面スケーリング、オリジナルのParlett-Reinschなどのさまざまなオプションを試しましたSPBALANCE
。また、の密集バージョンなど、あまり知られていない方法もあります。
私が強調するかもしれない一つのポイントは、私はベナーの仕事を知っているということです。特にこの目的のためのハミルトニアン行列のシンプレクティックバランシング。ただし、このタイプの処理はgcare.m
(一般化されたRiccatiソルバー)内で行われ、バランシングはを介して直接行われることに注意してくださいbalance.m
。したがって、実際の実装を誰かに教えていただければ幸いです。
開示:私はmathworksコードをリバースエンジニアリングしようとはしていません:この質問の動機を含むさまざまな理由のため、実際にそれから離れたいと思っています。昔の時間の。私の意図は、通常のソルバーの上にニュートン反復法を実装できるように、CAREXの例を渡すことができる満足のいくバランスアルゴリズムを取得することです。