Каковы наиболее широко используемые библиотеки векторной / матричной математики / линейной алгебры в C++, а также их соотношение цены и выгоды?

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

Я хотел бы избежать этого, не создавая зависимость от некоторой тангенциально связанной библиотеки (например, OpenCV, OpenSceneGraph).

Какие библиотеки матричной математики / линейной алгебры обычно используются, и почему вы решили использовать одну поверх другой? Есть ли что-то, что было бы рекомендовано не использовать по какой-то причине? Я специально использую это в геометрическом / временном контексте *(2,3,4 Dim)*, но, возможно, буду использовать более масштабные данные в будущем.

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

Обновить

Я закончил тем, что использовал Eigen3, которым я чрезвычайно доволен.

11 ответов

Решение

Есть довольно много проектов, которые остановились на Generic Graphics Toolkit для этого. GMTL там хорош - он довольно маленький, очень функциональный и использовался достаточно широко, чтобы быть очень надежным. OpenSG, VRJuggler и другие проекты все перешли на использование этого вместо собственной математики, созданной вручную.

Я нахожу это довольно хорошим - он делает все через шаблоны, поэтому он очень гибкий и очень быстрый.


Редактировать:

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

GMTL -

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

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

Эйген -

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

Недостатки: может быть немного больше, чем вы хотите (?). Меньше геометрических / специфических процедур рендеринга по сравнению с GMTL (т.е. определения углов Эйлера и т. Д.).

IMSL -

Преимущества: Очень полная числовая библиотека. Очень, очень быстро (предположительно, самый быстрый решатель). Безусловно самый большой, самый полный математический API. Коммерчески поддерживается, зрелый и стабильный.

Недостатки: Стоимость - не недорого. Очень мало геометрических / рендеринг-специфических методов, поэтому вам нужно будет накатывать свои собственные поверх их классов линейной алгебры.

NT2 -

Преимущества: Обеспечивает синтаксис, который более знаком, если вы привыкли к MATLAB. Обеспечивает полное разложение и решение для больших матриц и т. Д.

Недостатки: математический, не сфокусированный. Вероятно, не так производительно, как Эйген.

LAPACK -

Преимущества: очень стабильные, проверенные алгоритмы. Был вокруг в течение длительного времени. Полное решение матриц и т. Д. Множество вариантов неясной математики.

Недостатки: не так высокопроизводительный в некоторых случаях. Портировано из Фортрана, с нечетным API для использования.

Лично для меня все сводится к одному вопросу - как вы планируете это использовать. Если вы сосредоточены только на рендеринге и графике, мне нравится Generic Graphics Toolkit, поскольку он хорошо работает и поддерживает множество полезных операций рендеринга из коробки без необходимости реализовывать свои собственные. Если вам нужно решение матриц общего назначения (то есть: разложение больших матриц в SVD или LU), я бы пошел с Eigen, поскольку он обрабатывает это, предоставляет некоторые геометрические операции и очень эффективен с решениями больших матриц. Возможно, вам придется написать больше ваших собственных графических / геометрических операций (поверх их матриц / векторов), но это не ужасно.

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

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

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

Eigen2 / Eigen3

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

Идиосинкразии / недостатки: (Некоторых / всего этого можно избежать с помощью некоторых определений, доступных в текущей ветви разработки Eigen3)

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

GMTL

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

Idiocyncracies / МИНУСЫ:

  • API это странно
    • что может быть myVec.x() в другой библиотеке, доступно только через myVec[0] (проблема читаемости)
      • массив точек или stl::vector точек может заставить вас сделать что-то вроде pointsList[0][0] для доступа к компоненту x первой точки
    • в наивной попытке оптимизации убрал cross(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 не содержит операций для Векторов, некоторые содержат 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

Для чего это стоит, я пробовал и Eigen и Armadillo. Ниже приведена краткая оценка.

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

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

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

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

Было бы неплохо, если бы была доступна библиотека с открытым исходным кодом, которая была бы автономной и простой в использовании. Я сталкивался с этой проблемой в течение 10 лет, и это расстраивает. В какой-то момент я использовал GSL для C и написал обертки для C++, но с современным C++ - особенно с использованием преимуществ шаблонов выражений - нам не нужно было связываться с C в 21-м веке. Просто мой тапенсхапенный.

Если вы ищете высокопроизводительную матричную / линейную алгебру / оптимизацию для процессоров Intel, я бы посмотрел библиотеку Intel MKL.

MKL тщательно оптимизирован для быстрой работы во время выполнения - большая часть этого основана на очень зрелых стандартах BLAS/LAPACK fortran. И его производительность зависит от количества доступных ядер. Масштабируемость в режиме громкой связи с доступными ядрами - это будущее компьютеров, и я бы не стал использовать математическую библиотеку для нового проекта, который не поддерживает многоядерные процессоры.

Очень кратко, это включает в себя:

  1. Основные операции вектор-вектор, вектор-матрица и матрица-матрица
  2. Матричная факторизация (LU decomp, эрмитово, разреженно)
  3. Проблемы наименьших квадратов и собственные значения
  4. Решатели разреженной линейной системы
  5. Решатель нелинейных наименьших квадратов (трастовые регионы)
  6. Плюс процедуры обработки сигналов, такие как БПФ и свертка
  7. Очень быстрые генераторы случайных чисел (Mersenne Twist)
  8. Гораздо больше.... см.: текст ссылки

Недостатком является то, что MKL API может быть довольно сложным в зависимости от необходимых вам процедур. Вы также можете взглянуть на их библиотеку IPP (Integrated Performance Primitives), которая ориентирована на высокопроизводительные операции обработки изображений, но тем не менее довольно обширна.

Павел

Программное обеспечение CenterSpace, математические библиотеки.NET, centerspace.net

Как насчет GLM?

Он основан на спецификации языка шейдеров OpenGL (GLSL) и выпущен под лицензией MIT. Четко ориентированные на графических программистов

Я слышал хорошие вещи об Eigen и NT2, но лично не использовал ни того, ни другого. Есть также Boost.UBLAS, который, я считаю, становится немного длиннее в зубе. Разработчики NT2 строят следующую версию с намерением включить ее в Boost, так что это может что-то значить.

Мой лин. ALG. потребности не выходят за рамки матрицы 4х4, поэтому я не могу комментировать расширенную функциональность; Я просто указываю на некоторые варианты.

Я новичок в этой теме, поэтому не могу сказать много, но BLAS - это в значительной степени стандарт в научных вычислениях. BLAS на самом деле является стандартом API, который имеет много реализаций. Я честно не уверен, какие реализации наиболее популярны или почему.

Если вы хотите также иметь возможность выполнять обычные операции линейной алгебры (решения систем, регрессия наименьших квадратов, декомпозиция и т. Д.), Изучите LAPACK.

Я добавлю голос за Эйгена: я перенес много кода (трехмерная геометрия, линейная алгебра и дифференциальные уравнения) из разных библиотек в эту - улучшив как производительность, так и читабельность кода почти во всех случаях.

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

Ладно, думаю, я знаю, что ты ищешь. Похоже, что GGT является довольно хорошим решением, как предположил Рид Копси.

Лично мы развернули нашу собственную маленькую библиотеку, потому что мы много имеем дело с рациональными точками - множеством рациональных NURBS и Beziers.

Оказывается, что большинство библиотек трехмерной графики выполняют вычисления с проективными точками, которые не имеют оснований в проективной математике, потому что это то, что дает вам желаемый ответ. Мы в конечном итоге использовали точки Грассмана, которые имеют прочную теоретическую основу и уменьшили количество типов точек. Точки Грассмана - это в основном те же вычисления, которые люди используют сейчас, с преимуществом надежной теории. Самое главное, это проясняет ситуацию в наших умах, поэтому у нас меньше ошибок. Рон Голдман написал статью о точках Грассмана в компьютерной графике под названием "Об алгебраических и геометрических основах компьютерной графики".

Не имеет прямого отношения к вашему вопросу, но интересно читать.

FLENS

http://flens.sf.net/

Он также реализует множество функций LAPACK.

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

Другие вопросы по тегам