вирішити для за допомогою LAPACK та BLAS


12

Я переношу існуючий код з MATLAB на C ++ і маю лінійну систему для вирішення (а не більш типову форму )xA=bAx=b

Матриця щільна і загальної форми, але не більше 1000х1000. Отже, у MATLAB рішення знайдено за функцією або позначенням вперед-косою рисоюAmrdivide(b,A)x = b/A;

Як я можу це вирішити у своєму коді C ++ за допомогою підпрограм BLAS та LAPACK?

Я знайомий з програмою LAPACK, DGESVяка вирішує для .Ax=bx

Отже, одна думка, яку я маю, - це зробити кілька маніпуляцій, використовуючи матричні транспозитні ідентичності:

(xA)T=bT

ATxT=bT

xT=(AT)1bT

Потім вирішити остаточну форму з допомогою DGESVпрацюючих на транспонованою . (так коштує перенести та вартість рішення системи)ATA

Чи є підхід більш ефективним чи інакше кращим ?

Я працюю з матричними та векторними класами, а також реалізацією BLAS з бібліотеки BOOST uBLAS, а також прив'язкою до підпрограм бібліотеки LAPACK. Я успішно використовую цю установку для інших операцій і сподіваюся знайти рішення, обмежене цими бібліотеками.

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

Можливо, ця документація на MATLAB mrdivideкорисна для інших.

Відповіді:


10

Тривіальний відповідь на квадратний : використання , яке вирішує також і для , коли .AdgesvxATx=bTRANS = 'T'

Зверніть увагу, що за допомогою BLAS або LAPACK вам навряд чи доведеться транспонувати (замінювати елементи в пам'яті) матрицю: більшість підпрограм мають TRANSаргумент для роботи на транспозиційній матриці або на матриці, що зберігається з іншим компонуванням пам'яті. (Транспозиція еквівалентна зміні компонування пам'яті Фортран-суцільної пам'яті на C-contiguos one і viceversa.)


Дякуємо за відповідь та пояснення! Я дуже мало працював з LAPACK, і тепер я знаю, як шукати варіант TRANS. У мене виникають проблеми з тим, щоб аргумент TRANS пропрацював boost::numeric::bindings::lapack::gesvx(), але це не є частиною мого питання. Якщо я маю успіх, я повернусь із запискою про те, як це зробити.
НойР

У мене є робоче рішення, що використовує gesvx(), хоча і не без спотикання на цьому шляху. Коли аргумент TRANS дорівнює 'T', документація LAPACK говорить, що gesvxвирішує , але насправді вона вирішує оскільки очікується, що форма вхідних аргументів і не буде -перекладена форма. Отже, аргумент переміщується, тоді як і - ні. Чудово, що зручніше. Якщо хтось інший натрапляє на це, намагаючись використати прискорені числові прив'язки, я скажу, що мені не вдалося отримати інтерфейс транспонування, який використовується в цьому soln. працювати через прив’язки. ATX=BATXT=BTXBAXB
НойР

Гаразд, я знайшов хитрість використовувати gesvxформу транспонування наскрізь boost::numeric::bindings. Загорніть транспонована матриця в функції. Це визначає параметр як тип транспонування : ATtrans()boost::numeric::bindings::lapack::gesvx( FACT, boost::numeric::bindings::trans(Atransposed), af, ipiv, equed, r, c, b, x, rcond, ferr, berr );
NoahR

0

Ви можете обчислити псевдоінверсію , використовуючи, скажімо, QR-декомпозицію SVD, які включені в LAPACK.A

xA=bxQR=bx=bR1QT

Це буде працювати для будь-якого прямокутного .A


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