매트릭스 밸런싱 알고리즘


9

제어 시스템 도구 상자를 처음부터 순수하게 Python3 (shameless plug :)으로 작성했습니다 harold. 과거의 연구에서 나는 care.m기술적 / 관련이없는 이유로 Riccati 솔버 에 대해 항상 불만을 제기했습니다 .

따라서 나는 내 자신의 루틴 세트를 작성해 왔습니다. 내가 찾을 수없는 한 가지 방법은 적어도만큼 좋은 고성능 밸런싱 알고리즘을 얻는 것 balance.m입니다. 언급하기 전에 xGEBAL가족은 Scipy에 노출되며 기본적으로 다음과 같이 Scipy에서 호출 할 수 있습니다 .float type 2D array가 있다고 가정하십시오 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

순열 패턴을 확인하면 패턴이 동일하지만 스케일링이 해제됩니다. gebalmatlab은 다음과 같은 2의 제곱을 제공합니다 [-5,0,8,0,2].

따라서 분명히 동일한 기계를 사용하지 않습니다. 나는 Lemonnier, Van Dooren 양면 스케일링, 오리지널 Parlett-Reinsch와 같은 다양한 옵션을 시도했으며 밀도가 높은 버전과 같은 문헌에서 잘 알려지지 않은 다른 방법을 시도했습니다 SPBALANCE.

내가 강조 할 수있는 한 가지 점은 내가 Benner의 작업을 알고 있다는 것입니다. 특히이 목적을 위해 특히 해밀턴 행렬Symplectic Balancing . 그러나이 유형의 처리는 gcare.m(일반화 된 Riccati 솔버) 내에서 수행 되며을 통해 직접 밸런싱이 수행됩니다 balance.m. 따라서 누군가가 실제 구현을 지적 할 수 있다면 감사하겠습니다.


공개 : 나는 실제로 mathworks 코드를 리버스 엔지니어링하려고하지 않습니다. 실제로이 질문의 동기 부여를 포함하여 다양한 이유로 인해 코드에서 벗어나고 싶습니다. 하루의 시간. 내 의도는 정규 솔버 위에 Newton 반복 메소드를 구현할 수 있도록 CAREX 예제를 전달할 수있는 만족스러운 밸런싱 알고리즘을 얻는 것입니다.

답변:


7

이것을 알아내는 데 꽤 오랜 시간이 걸렸으며 평소와 같이 범인을 찾은 후에 분명해집니다 .

David S. Watkins 에보고 된 문제 사례를 확인한 후 균형이 해로운 경우. 전자. 트랜스 숫자. Anal, 23 : 1–4, 2006여기 에서의 논의 ( arXiv : 1401.5766v1 에서 인용 )는 matlab이 대각선 요소를 먼저 분리하여 밸런싱을 사용하는 것으로 나타났습니다.

필자의 초기 생각은 LAPACK 기능에 대한 고전적인 제한된 문서에 따라 GEBAL이 자동으로 수행 한 것입니다. 그러나 대각선 요소무시 하여 저자가 의미하는 것은 행 / 열 합계에서 요소 를 제거하지 않는 것 같습니다.

실제로 배열에서 대각선을 수동으로 제거하면 두 결과가 일치합니다.

import scipy as sp
gebal = sp.linalg.get_lapack_funcs(('gebal'),(A,)) # this picks up DGEBAL
Ab, lo, hi, scaling , info = gebal(A - np.diag(np.diag(A)), scale=1 , permute=1 , overwrite_a=0 )  

balance.m(물론 대각선 항목없이) 와 동일한 결과를 제공합니다 .

Fortran 사용자가 dgebal.f를 확인하여이를 확인할 수 있다면 감사하겠습니다.

편집 : 위의 결과가 이것이 유일한 차이점임을 암시하지는 않습니다. GEBAL과 balance.m이 대각선을 분리 한 후에도 다른 결과를 생성하는 다른 행렬도 구성했습니다.

차이점이 무엇인지 궁금하지만 MATLAB이 내장되어 있으므로 닫힌 코드이므로 알 수있는 방법이없는 것 같습니다.

EDIT2 : matlab은 이전 버전의 LAPACK (아마 3.5.0 이전)을 사용하고 있으며 2016b에는 최신 버전으로 업그레이드 된 것으로 보입니다. 이제 테스트 할 수있는 한 결과가 일치합니다. 그래서 그것이 문제를 해결한다고 생각합니다. 이전 LAPACK 버전으로 테스트 했어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.