Алгоритм врівноваження матриці


9

Я писав набір інструментів системи управління з нуля і суто в Python3 (безсоромний штекер:) harold. У моєму минулому дослідженні я завжди скаржився на вирішувач Ріккаті care.mз причин, які є технічними / неактуальними.

Отже, я писав власний набір процедур. Одна річ, яку я не можу знайти, - це отримати високоефективний алгоритм балансування, принаймні так добре 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(узагальнений рішувач Ріккаті), а врівноваження здійснюється безпосередньо через balance.m. Отже, я вдячний, якщо хтось може вказати мені на реальну реалізацію.


Розкриття: Я дійсно не намагаюся змінити інженерний код математики: я фактично хочу відійти від нього через різні причини, включаючи мотивацію цього питання, тобто, я не знаю, що це робить, що коштувало мені багато часу назад у день. Моя мета - отримати задовільний алгоритм балансування, який дозволяє мені передавати приклади CAREX таким чином, щоб я міг реалізувати методи ітерації Ньютона поверх звичайного рішення.

Відповіді:


7

Займав мене досить довго, щоб зрозуміти це, і, як завжди, це стає очевидним після того, як ти знайдеш винуватця.

Після перевірки проблемних випадків, про які повідомляв Девід С. Уоткінс. Випадок, коли балансування шкідливо. Електрон. Транс. Число. 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-savy може підтвердити це, перевіривши dgebal.f , я буду вдячний.

EDIT: Наведений результат не означає, що це єдина різниця. Я побудував також різні матриці, де GEBAL і баланс.m дають різні результати навіть після розділення діагоналей.

Мені дуже цікаво, яка може бути різниця, але, здається, немає ніякого способу дізнатися, оскільки це вбудований матлаб і, отже, закритий код.

EDIT2 : Виявляється, matlab використовував старішу версію LAPACK (можливо, до 3.5.0), і до 2016b вони, здається, були оновлені до нової версії. Тепер результати узгоджуються, наскільки я можу перевірити. Тому я думаю, що це вирішує питання. Я мав би тестувати це на старих версіях LAPACK.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.