Які найпоширеніші бібліотеки математики векторної / матричної / математичної / лінійної алгебри C ++ та їхні вигідні витрати та вигоди? [зачинено]


243

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

Я хотів би уникнути цього, не будуючи залежності від якоїсь дотично пов'язаної бібліотеки (наприклад, OpenCV, OpenSceneGraph).

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

Я шукаю відмінності стосовно будь-якого з: API, швидкості, використання пам'яті, широти / повноти, вузькості / специфічності, розширюваності та / або зрілості / стабільності.

Оновлення

Я в кінцевому рахунку використовував Eigen3, яким я надзвичайно задоволений.


2
Оскільки ви згадали про OSG та OpenCV, я гадаю, що вам просто потрібні векторні / матриці 3D-графіки, тобто: 3x3 та 4x4 матриці. Я базував свою відповідь на цьому, але ви, можливо, захочете вказати, як саме ви це використовуєте - чи потрібно матричне рішення? Математика вищої розмірної матриці? пр.
Рід Копсі

Зараз я займаюся лише двовимірною геометрією, але гіпотетично вам іноді потрібні 3х3 операції над двовимірними даними, і незрозуміло, чи потрібні 3D-дані, таким чином, 4х4 операції. Ми хотіли б використовувати загальну бібліотеку по всій компанії. Я не маю хорошого розуміння, яким би був компроміс. Більш загальне було б краще, але за якою ціною питання.
Catskul

1
Якщо ви просто робите геометричні перетворення, я б дуже рекомендував поглянути на GGT, як я вже згадував у своїй відповіді. Це дуже повно для цього, але насправді нічого не робить, Але це дуже чистий, простий варіант. BLAS і LAPACK більше призначені для комплексних матричних рішень (наприклад: матриць 50x50, малих матриць тощо) для наукових та математичних, а не геометричних перетворень.
Рід Копсей

Відповіді:


114

Для цього існує досить багато проектів, які розраховані на інструментарії загальної графіки . GMTL там є приємний - він досить маленький, дуже функціональний і використовувався досить широко, щоб бути дуже надійним. OpenSG, VRJuggler та інші проекти перейшли на використання цього замість власної ручної прокатки математики вертору / матриці.

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


Редагувати:

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

GMTL -

Переваги: ​​простий API, спеціально розроблений для графічних двигунів. Включає багато примітивних типів, спрямованих на візуалізацію (наприклад, літаки, AABB, кватерніони з багаторазовою інтерполяцією тощо), яких немає в жодному іншому пакеті. Дуже низький об'єм пам'яті, досить швидкий, простий у користуванні.

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

Айген -

Переваги: чистий API , досить простий у використанні. Включає модуль Geometry з кватерніонами та геометричними перетвореннями. Низькі накладні витрати. Повне, високоефективне рішення великих матриць NxN та інших математичних процедур загального призначення.

Недоліки: може бути трохи більше, ніж ви хочете (?). Менше геометричних / рендеринга конкретних процедур порівняно з GMTL (тобто: визначення кута Ейлера тощо).

IMSL -

Переваги: ​​Дуже повна чисельна бібліотека. Дуже, дуже швидко (нібито найшвидший вирішувач). На сьогодні найбільший, найповніший математичний API. Комерційно підтримується, зрілий та стабільний.

Мінуси: вартість - недешева. Дуже мало геометричних / рендеринга конкретних методів, тому вам потрібно буде прокрутити свій власний верх на їх лінійні класи алгебри.

NT2 -

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

Недоліки: математичні, не орієнтовані на надання. Напевно, не такий виконавський, як Ейген.

ЛАПАК -

Переваги: ​​Дуже стійкі, перевірені алгоритми. Був довгий час. Повне рішення матриці тощо. Багато варіантів незрозумілої математики.

Недоліки: Не настільки високоефективні в деяких випадках. Перенесено з Fortran, з дивним API для використання.

Особисто для мене зводиться до одного питання - як ти це плануєш використовувати. Якщо ви зосереджуєтесь саме на візуалізації та графіці, мені подобається Generic Graphics Toolkit , оскільки вона добре працює і підтримує багато корисних операцій з виведення з коробки без необхідності впроваджувати власні. Якщо вам потрібно вирішення матриць загального призначення (тобто: розкладання SVD або LU великих матриць), я б пішов з Eigen , оскільки він обробляє це, забезпечує деякі геометричні операції, і дуже добре працює з рішеннями великих матриць. Можливо, вам потрібно буде написати більше власних графічних / геометричних операцій (поверх їх матриць / векторів), але це не жахливо.


Ви оцінювали інші бібліотеки, перш ніж прийняти рішення про GMTL? Поверхове порівняння спонукає мене до думки, що Eigen підтримується краще, але це на основі перегляду відповідних веб-сайтів. Чи знаєте ви якісь конкретні переваги одного над іншим?
Catskul

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

Я думаю, що я можу поставити питання до самого суті: чи зробили ви свій вибір суб'єктивно на кшталт "Це виглядає краще" або там, де є особливості (api, швидкість, використання пам'яті, широта, вузькість, розширюваність), які вплинули на зміни. Я припускаю, що термін погашення підпадає під ці критерії, але якби зрілість була єдиною метрикою, я думаю, ви вибрали б варіант на основі BLAS або LAPACK.
Catskul

Я вибрав це, спробувавши декілька варіантів, і ґрунтувався на цьому: продуктивність, зручність використання та низький накладний час виконання / компіляції. Зараз Ейген виглядає набагато краще, ніж тоді, тому я не можу судити між ними. Однак я дуже задоволений GMTL за наші використання.
Рід Копсей

Це частина, чому мені подобається GMTL, і я ним користувався. Це було просто природно у використанні, і було дуже, дуже легко працювати. Він також підтримував все, що мені потрібно, в цьому випадку, оскільки я просто переживав за те, щоб безпосередньо обробляти геометричну трансформацію та обертання кватерніона.
Рід Копсей

38

Отже, я досить критична людина, і, якщо я буду інвестувати в бібліотеку, я краще буду знати, в що я потрапляю. Я вважаю, що краще уважно ставитись до критики, а також до лестощів при вивченні; те, що не в цьому, має набагато більше наслідків для майбутнього, ніж те, що правильно. Тому я збираюся трохи зайти за борт тут, щоб надати відповідь, яка допомогла б мені, і я сподіваюся, що допоможе іншим, хто може пройти цей шлях. Майте на увазі, що це ґрунтується на тому, що я мало перевіряю / тестую, що я робив із цими лайками О, і я вкрав деякі позитивні описи у Рід.

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

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

Eigen2 / Eigen3

Переваги: LGPL MPL2, чистий, добре розроблений API, досить простий у використанні. Здається, добре підтримує живучу спільноту. Низькі накладні витрати. Висока продуктивність. Створений для загальної лінійної алгебри, але також доступна хороша геометрична функціональність. Вся вкладка заголовка, не потрібно зв'язувати.

Idiocyncracies / downsides: (Дещо / всього цього можна уникнути за допомогою деяких визначень, які доступні в поточній галузі розвитку Eigen3)

  • Небезпечні оптимізації роботи призводять до необхідності ретельного дотримання правил. Недотримання правил спричиняє збої.
    • ви просто не можете безпечно передати цінність
    • використання типів Eigen як членів вимагає спеціального налаштування алокатора (або ви завершите роботу)
    • використовувати з типами контейнерів stl та, можливо, іншими шаблонами, потрібні спеціальні налаштування розподілу (інакше ви завершите роботу)
    • певні компілятори потребують особливої ​​обережності для запобігання збоїв у функціональних викликах (вікна GCC)

GMTL

Переваги: ​​LGPL, досить простий API, спеціально розроблений для графічних двигунів. Включає багато примітивних типів, спрямованих на візуалізацію (наприклад, літаки, AABB, кватерніони з багаторазовою інтерполяцією тощо), яких немає в жодному іншому пакеті. Дуже низький об'єм пам'яті, досить швидкий, простий у користуванні. Все на основі заголовка, ніяких посилань не потрібно.

Ідентифікація / мінуси:

  • API химерний
    • що може бути myVec.x () в іншій lib, доступне лише через myVec [0] (проблема читабельності)
      • масив або stl :: вектор точок може змусити вас зробити щось на зразок pointsList [0] [0] для доступу до компонента x першої точки
    • в наївній спробі оптимізації видаляється хрест (vec, vec) і замінюється makeCross (vec, vec, vec), коли компілятор так чи інакше усуває непотрібні темпи
    • звичайні математичні операції не повертають нормальні типи, якщо ви не відключили деякі функції оптимізації, наприклад: vec1 - vec2не повертає нормальний вектор, тому length( vecA - vecB )не vecC = vecA - vecBпрацює, хоча працює. Ви повинні загортатись так:length( Vec( vecA - vecB ) )
    • Операції над векторами забезпечуються зовнішніми функціями, а не членами. Це може вимагати використання роздільної здатності скрізь, оскільки загальні імена символів можуть стикатися
    • ви повинні зробити
        length( makeCross( vecA, vecB ) )
      або
        gmtl::length( gmtl::makeCross( vecA, vecB ) )
      де інакше ви можете спробувати
        vecA.cross( vecB ).length()
  • недостатньо підтримується
    • як і раніше заявляється як "бета"
    • в документації відсутня основна інформація, наприклад, які заголовки потрібні для нормальної функціональності
      • Vec.h не містить операцій для Vectors, VecOps.h містить деякі, інші є в Generate.h, наприклад. хрест (vec &, vec &, vec &) у VecOps.h, [make] хрест (vec &, vec &) у Generate.h
  • незрілий / нестабільний API; все ще змінюється.
    • Наприклад, "cross" перемістився з "VecOps.h" на "Generate.h", а потім назву було змінено на "makeCross". Приклади документації не вдається, оскільки все ще відносяться до старих версій функцій, які вже не існують.

NT2

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

Останній реліз понад 2 роки тому.

Мабуть, жодної документації англійською мовою, хоча нібито десь є щось французькою.

Не можете знайти сліди спільноти навколо проекту.

LAPACK & BLAS

Переваги: ​​Старі та зрілі.

Недоліки:

  • старі як динозаври з дійсно хитрими API

1
Щодо тверджень Eigen, що вирівнюються: для отримання високої продуктивності операцій SSE (1,2,3 або 4) для невеликих наборів даних вам абсолютно потрібні вирівняні дані. Неузгоджені операції завантаження / зберігання значно повільніші. Рішення між вирівняним або нерівним завантаженням / зберіганням також вимагає часу. Будь-яка реалізація "загальної мети" матиме справді важкий час, щоб зробити правильну справу для всіх, якщо тільки вони не розділили інтерфейс на "узгоджені" та "нерівні" операції - і тоді це знову просто не дуже загальна мета.
Joris Timmermans

@Catskul Я хотів би використовувати Eigen3. Чи можете ви, будь ласка, розширити "оптимізацію, яка робить його небезпечним, можна вимкнути за допомогою визначення"? Інші проблеми, які ви перераховуєте під Eigen2, ретельно деталізуються в документі в розділі Теми, пов'язані з проблемами вирівнювання . Я можу жити з цими питаннями.
Алі

Проблеми з безпекою я маю на увазі, що стосуються всіх вирівнювань і однакові у Eigen2. Якщо з Eigen2 у вас все в порядку, з Eigen3 вам все буде добре.
Catskul

2
BLAS і LAPACK - це насправді не бібліотеки, а специфікації / API. Ви могли б згадати їх початкові реалізації через netlib або інші реалізації, такі як ATLAS та OpenBLAS.
Foad

12

Що варто, я спробував і Ейген, і Армаділло. Нижче наведена коротка оцінка.

Переваги власних властивостей: 1. Повністю автономна - відсутність залежності від зовнішнього BLAS або LAPACK. 2. Документація гідна. 3. Нібито швидко, хоча я не поставив це на тест.

Недолік: алгоритм QR повертає лише одну матрицю з матрицею R, вбудованою у верхній трикутник. Немає уявлення, звідки береться решта матриці, і жодна матриця Q не може бути доступна.

Переваги Armadillo: 1. Широкий спектр декомпозицій та інших функцій (включаючи QR). 2. Розумно швидко (використовує шаблони виразів), але знову ж таки, я не дуже підштовхував це до високих розмірів.

Недоліки: 1. Залежить від зовнішнього BLAS та / або LAPACK для матричного розкладу. 2. Документація не має IMHO (включаючи специфіку wrt LAPACK, крім зміни оператора #define).

Було б добре, якби була доступна бібліотека з відкритим кодом, яка є автономною та простою у використанні. Я стикався з цим самим питанням 10 років, і це стає неприємним. Якось я використовував GSL для C і писав навколо нього обгортки C ++, але з сучасними C ++ - особливо з використанням переваг шаблонів виразів - нам не слід було возитися з C у 21 столітті. Просто мій туппенчахапенний.


2
Armadillo має навмисний синтаксис, схожий на Matlab, так що його легко використовувати. Я не впевнений, що ви маєте на увазі про "документації бракує ... специфіки wrt LAPACK". Документація чітко документує всі доступні користувачеві функції, а також приклади їх використання. Вся суть про бібліотеку обгортки C ++ полягає в тому, щоб абстрагувати складність та багатослівність LAPACK. Ви завжди можете переглянути джерело, якщо хочете побачити, як Armadillo називає LAPACK.
mtall

Щодо розкладу QR у Ейґені, ви маєте на увазі Eigen2 чи Eigen3?
qed

11

Якщо ви шукаєте матричну / лінійну алгебру / оптимізацію високоефективної роботи на процесорах Intel, я би поглянув на MKL-бібліотеку Intel.

MKL ретельно оптимізовано для швидкого виконання робочого часу - значна частина заснована на дуже зрілих стандартах fortran BLAS / LAPACK. А його продуктивність масштабується з кількістю наявних ядер. Гнучка масштабованість з наявними ядрами - це майбутнє обчислень, і я б не використовував жодну математичну бібліотеку для нового проекту, не підтримує багатоядерні процесори.

Дуже коротко, вона включає:

  1. Основні операції вектор-вектор, вектор-матриця та матриця-матриця
  2. Матрична факторизація (розпад LU, герміт, розріджений)
  3. Найменші квадрати та проблеми з власним значенням
  4. Рідкі лінійні системні рішення
  5. Нелінійний розв'язувач найменших квадратів (довірчі регіони)
  6. Плюс підпрограми обробки сигналів, такі як FFT та convolution
  7. Генератори дуже швидких випадкових чисел (mersenne twist)
  8. Набагато більше .... див .: текст посилання

Мінусом є те, що API MKL може бути досить складним залежно від підпрограм, які вам потрібні. Ви також можете поглянути на їхню бібліотеку IPP (Integrated Performance Primitive), яка орієнтована на високопродуктивні операції обробки зображень, але, тим не менш, досить широка.

Пол

Програмне забезпечення CenterSpace, бібліотеки .NET Math, centerpace.net


8

Я чула хороші речі про Eigen та NT2 , але особисто також не використовувала. Є також Boost.UBLAS , який, на мою думку, трохи затягується в зуб. Розробники NT2 будують наступну версію з наміром перетворити її в Boost, так що це може розраховувати на щось.

Мій лін. alg потреби не виходять за межі корпусу матриці 4x4, тому я не можу коментувати розширені функціональні можливості; Я просто вказую на деякі варіанти.


На мій досвід (більші матриці), Boost.UBLAS використовується більше. Однак, коли я заглянув у це, мені це не сподобалось (головним чином через документацію), тому я сконцентрувався на Ейґені. У Eigen є модуль геометрії , але я сам його не використовував.
Jitse Niesen

Eigen, очевидно, використовується ROS (вербовий гараж), Celestia, Koffice і libmv. Я бачу деяку балаканину про UBLAS, але мені було важко зустріти проект, який рекламує його використання. Дітто для NT2. Чи можете ви детальніше розповісти, які хороші речі ви почули?
Catskul

Саме в дискусії в списку розсилки Boost про додавання сучасної бібліотеки LinAlg до Boost - Eigen та NT2 були згадані як можливі кандидати, але лише розробники NT2 виявили зацікавленість у її здійсненні. Обидві бібліотеки видалися гідними; як ви вже говорили, Eigen трохи популярніший, а також більше C ++ - ish; NT2 покликаний максимально імітувати MATLAB.
Джефф Харді

8

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

Якщо ви також хочете мати можливість робити звичайні лінійні алгебри (розв’язування систем, регресія найменших квадратів, декомпозиція тощо), погляньте на LAPACK .


7

Що з GLM ?

Він заснований на специфікації OpenGL Shading Language (GLSL) та випущений під ліцензією MIT. Чітко націлена на графічних програмістів


добре, він забезпечує графічне програмування вектора та матриць. він представляє приємну кількість накладних витрат, щоб зберігати сумісність з GLSL (якщо ви можете це зробити в GLSL, більшість разів це робити в GLSL краще, особливо це стосується GL 4.x), і не вистачає багатьох примітивів для графічного програмування (фрустум, AABB, BB, еліпсоїд ). Його інтерфейс, що перебуває у плазмі, є ожирінням. Набагато кращою альтернативою було б, якби вона мала функції ".xyzz ()", що генеруються при створенні коду. Це ідеально, коли вам доведеться прототипувати програми opengl і починати показувати його негативні сторони на великих проектах. ніколи не кодуйте математичну бібліотеку.
CoffeDeveloper

5

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

Одна з переваг, про яку не згадувалося: дуже просто використовувати SSE з Eigen, що значно покращує продуктивність операцій 2D-3D (де все може бути додано до 128 біт).


1
Вся "якщо ви це зробите, то переконайтесь, що ..." річ вражає мене як трохи червоним прапором. Поки що я двічі стикався з цими проблемами, і я тільки почав його використовувати. Я справді сподівався не обтяжувати майбутніх розробників тим, що знає всі види ідіосинкразій кожної бібліотеки, зокрема: проблеми з вирівнюванням, де вона виходить з ладу, якщо ви не використовуєте певні макроси кожного разу, коли у вас є члени, і на те, що вони поширюють функціональні можливості для окремих класи в декількох заголовках. Поодинці це може не завадити мені обрати його, але надсилається трохи червоного прапора.
Catskul

1
Вирівнювання, і цей макрос має значення лише в тому випадку, якщо ви використовуєте SSE, що ні в якому разі не потрібно. І якщо ви користуєтесь SIMD, ці проблеми виникнуть у будь-якій бібліотеці, яку ви використовуєте. Принаймні, Eigen не просто виходить з ладу, але надає змістовні повідомлення про помилки, які безпосередньо вказують на проблему.
има

І є простий спосіб уникнути вирівнювання макросу - використовувати покажчики або посилання як члени.
има

1
Я не думаю, що це правда. Я не використовував спеціальних опцій SSE і отримав кілька збоїв після використання його з контейнерами stl. Так, я знаю, що це дає вам корисні повідомлення, і так, я знаю, що є спеціальні інструкції, але це моя суть. Я не хочу обтяжувати інших розробників спеціальними інструкціями для кожної включеної бібліотеки. Наприклад, те, що не минає за значенням, є занадто великим.
Catskul

Щойно я з’ясував, що в останній галузі розробок є деякі визначення, які можна використовувати для вимкнення вирівнювання та уникнення пов'язаних з цим проблем.
Catskul

4

Гаразд, я думаю, я знаю, що ти шукаєш. Схоже, що GGT є досить хорошим рішенням, як запропонував Рід Копсі.

Особисто ми розгорнули власну маленьку бібліотеку, бо багато маємо справу з раціональними пунктами - багато раціональних НУРБ та Безьє.

Виявляється, більшість бібліотек 3D графіки роблять обчислення з проективними точками, які не мають основи в проективній математиці, тому що саме так ви отримуєте потрібну відповідь. Ми закінчилися з використанням точок Грассмана, які мають суцільну теоретичну основу та зменшили кількість типів балів. Точки Грассмана - це в основному ті самі обчислення, які зараз використовують люди, з користю від надійної теорії. Найголовніше - це робить речі яснішими в нашій свідомості, тому у нас менше помилок. Рон Голдман написав документ про точки Грассмана в комп'ютерній графіці під назвою "Про алгебраїчні та геометричні основи комп'ютерної графіки" .

Не пов’язаний безпосередньо з вашим запитанням, але цікавим прочитаним.


Навмисно відкритим є те, що я не знаю, що таке компроміс. Напевно, справедливо сказати, що геометрія - це наше головне питання, що розмірність геометрії не є чіткою. Наразі це 2/3 (2 + час) і може гіпотетично бути досить високим (3dims + time + multi-dim-costmaps).
Catskul

Я згоден з питанням. Наприклад, багато застосувань такого типу потребують продуктивності в режимі реального часу (послідовної поведінки в часі), тоді як багато інших просто відмовляються від послідовності та / або швидкості для точності.
ТЕД

Так ви кажете, що з бібліотек, які ви досліджували, жодна не подбала про НУРБ та Безьє? Будь-яка конкретна причина для того, щоб не взяти одну з існуючих бібліотек та створити підтримку NURBS та Bezier поряд з нею?
Catskul

Що я намагався сказати, це те, що раціональні NURBS та Beziers використовують раціональні контрольні точки набагато більше, ніж більшість 3d-програм, тому ми робили більше помилок. Зазвичай у більшості 3D-додатків є лише ванільні 3d точки та вектори до тих пір, поки вони не пройдуть перспективну трансформацію. Багато наших алгоритмів повинні вміти правильно обробляти зважені / раціональні / прогнозні та декартові точки, ідучи вперед-назад тощо.
tfinniga


0

Я знайшов цю бібліотеку досить простою та функціональною ( http://kirillsprograms.com/top_Vectors.php ). Це голі кісткові вектори, реалізовані за допомогою шаблонів C ++. Немає фантазійних речей - лише те, що потрібно робити з векторами (додавання, віднімання множення, крапка тощо).


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