Як розібратися зі складністю в числовому коді, наприклад, при роботі з великими матрицями Якобії?


10

Я розв'язую нелінійну систему з’єднаних рівнянь і підрахував якобіанську дискретизовану систему. Результат дійсно складний, нижче (лише!) Перші 3 стовпці матриці 3×9 ,

Часткова матриця Якобії

(Складність виникає частково тому, що числова схема вимагає експоненціального пристосування для стабільності.)

У мене досить загальне питання щодо впровадження числових кодів з використанням якобійців.

Я можу йти вперед і реалізувати цю матрицю в коді. Але моя інтуїція підказує мені очікувати кілька днів (можливо, тижнів!) Набридливої ​​налагодження через складну складність та неминучість введення помилок. Як можна впоратися зі складнощами, такими як ця в числовому коді, здається неминучим ?! Чи використовуєте ви автоматичне генерування коду з символічних пакетів (потім налаштовуйте код вручну)?

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

Оновлення

Я кодую це в Python і використовую симбію для створення якобіан. Можливо, я можу використовувати функцію генерації коду ?


Яку систему комп'ютерної алгебри ви використовуєте для генерування якобіанських виразів? Якщо ви використовуєте Maple, ви, можливо, захочете переглянути codegenпакет в ньому, оскільки він може генерувати компактний та ефективний код C або Fortran для кожного або всіх виразів автоматично.
Педро

Тут дуже багато корисних відповідей, не має сенсу вибирати. Чи варто зробити це повідомленням спільноти Wiki?
boyfarrell

Відповіді:


6

Одне слово: модульність .

У вашій якобіанській є багато повторних виразів, які можна записати як власну функцію. Немає підстав писати одну і ту ж операцію не один раз, і це полегшить налагодження; якщо ви пишете це лише раз, є лише одне місце для помилки (теоретично).

Модульний код також полегшить тестування; Ви можете писати тести для кожного компонента вашої якобіанської мови на відміну від спроб протестувати всю матрицю. Наприклад, якщо ви пишете свою функцію am () модульним способом, ви зможете легко написати для неї тести на обґрунтованість, перевірити, чи правильно ви її розмежуєте тощо.

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

  • Сакадо (Санді Лабораторії)
  • ADIC (Аргонна)

Вибачте, щойно побачив, що ви використовуєте python. ScientificPython має підтримку AD.


Хороша порада. Проміжні вирази часто не потребують власних функцій - просто зберігайте їх у проміжних змінних.
Девід Кетчесон

5

Дозвольте мені зважити тут декілька слів обережності, напередодні історії. Давно я працював з товаришем, коли тільки починав. Він мав вирішити проблему оптимізації з досить безладним завданням. Його рішення полягало в створенні аналітичних похідних для оптимізації.

Проблема, яку я бачив, - ці похідні були неприємними. Згенеровані за допомогою Macsyma, перетвореного на код fortran, вони тривали десятки заяв про продовження. Насправді компілятор Fortran засмутився тим, що перевищив максимальну кількість операторів продовження. Хоча ми знайшли прапор, який дозволив нам подолати цю проблему, були й інші проблеми.

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

  • Часто аналітичні похідні похідні фактично дорожче оцінювати, ніж чисельно генеровані похідні з використанням кінцевих різниць. Градієнт для n змінних може зайняти більш ніж n разів більше витрат на оцінку вашої цільової функції. (Можливо, ви зможете зекономити деякий час, оскільки багато термінів можна повторно використовувати в різних похідних, але це також змусить вас робити ретельне кодування вручну, а не використовувати вирази, створені комп'ютером. І будь-який час ви кодуєте неприємні математичні вирази, ймовірність помилки не є тривіальною. Переконайтесь, що ви перевіряєте ці похідні на точність.)

Сенс моєї історії полягає в тому, що ці вирази, створені ЦА, мають власні проблеми. Найсмішніше, що мій колега справді пишався складністю проблеми, що він чітко вирішував справді складну проблему, оскільки алгебра була такою неприємною. Я не думаю, що він вважав, що якщо ця алгебра насправді обчислює правильну річ, чи робила це так точно і чи робила це так ефективно.

Якби я на той час був старшим за цим проектом, я б прочитав йому акт про бунт. Його гордість змусила його використовувати рішення, яке, ймовірно, було зайвим, навіть не перевіряючи, чи гранієнт на основі обмежених різниць є адекватним. Б'юсь об заклад, що ми витратили, можливо, тиждень людини, щоб запустити цю оптимізацію. Як мінімум, я б порадив йому ретельно перевірити отриманий градієнт. Це було точно? Наскільки точним це було порівняно з похідними з кінцевою різницею? Насправді сьогодні існують інструменти, які також повернуть оцінку помилки в їх похідному прогнозуванні. Це, безумовно, справедливо для коду адаптивного диференціювання (витікаючого), який я написав у MATLAB.

Перевірте код. Перевірте похідні.

Але перш ніж робити це з будь-якого, подумайте, чи є інші, кращі схеми оптимізації варіант. Наприклад, якщо ви робите експоненціальну підгонку, то є дуже хороший шанс, що ви можете використовувати нелінійні розділені найменші квадрати (іноді їх називають відокремленими найменшими квадратами. Я думаю, що це був термін, який в своїй книзі використовували Seber і Wild.) полягає в тому, щоб розбити набір параметрів на внутрішньолінійні та суто нелінійні множини. Використовуйте оптимізацію, яка працює лише на нелінійних параметрах. З огляду на те, що ці параметри є "відомими", то внутрішньолінійні параметри можна оцінити, використовуючи прості лінійні найменші квадрати. Ця схема зменшить простір параметрів при оптимізації. Це робить проблему більш надійною, оскільки не потрібно знаходити початкові значення для лінійних параметрів. Це зменшує розмірність вашого пошукового простору, тому змушує проблему працювати швидше. Знову я поставивінструмент для цієї мети , але тільки в MATLAB.

Якщо ви використовуєте аналітичні похідні, кодуйте їх для повторного використання термінів. Це може бути серйозною економією часу, а може фактично зменшити помилки, заощаджуючи власний час. Але тоді перевірте ці цифри!


5

Існує кілька стратегій, які слід врахувати:

  1. Знайдіть похідні у символічній формі за допомогою CAS, а потім експортний код для обчислення похідних.

  2. Використовуйте інструмент автоматичної диференціації (AD) для створення коду, який обчислює похідні від коду для обчислення функцій.

  3. Використовуйте кінцеві різницькі наближення для наближення якобійців.

Автоматична диференціація могла б створити більш ефективний код для обчислення всього якобійського, а потім використовувати символічні обчислення для створення формули для кожного запису в матриці. Кінцеві відмінності - хороший спосіб перевірити свої похідні.



1

Окрім чудових пропозицій BrianBorcher, ще одним можливим підходом до функцій з реальною цінністю є використання комплексного крокового наближення похідних (див. Цю статтю (оплата) та цю статтю ). У деяких випадках такий підхід дає більш точні числові похідні ціною зміни значень змінних у вашій функції від реальних до складних. У другій статті перераховані деякі випадки, коли наближення комплексної функції може порушитися.

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