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

243

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

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

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

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

Обновить

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

Catskul
источник
2
Поскольку вы упомянули OSG и OpenCV, я предполагаю, что вам просто нужны векторные / матрицы типа 3D-графики, то есть матрицы 3x3 и 4x4. Я основал свой ответ на этом, но вы можете указать, как именно вы используете это - вам нужно решение матрицы? Матрица высшей размерности математике? и т. д.
Рид Копси
Сейчас я занимаюсь только 2D-геометрией, но гипотетически вам иногда нужны операции 3x3 с 2D-данными, и неясно, могут ли понадобиться 3D-данные и, следовательно, операции 4x4. Мы хотели бы использовать общую библиотеку в компании. Я не понимаю, каким будет компромисс. Более общий будет лучше, но какой ценой это вопрос.
Catskul
1
Если вы просто делаете геометрические преобразования, я действительно рекомендую взглянуть на GGT, как я уже упоминал в своем ответе. Это очень полно для этого, но на самом деле ничего не делает, но это очень чистый и простой вариант. BLAS и LAPACK больше подходят для сложных комплексных матричных решений (т. Е. Матриц 50x50, разреженных матриц и т. Д.) Для научных и математических, а не геометрических преобразований.
Рид Копси

Ответы:

114

Есть довольно много проектов, которые остановились на 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? Поверхностное сравнение заставляет меня полагать, что Эйген был лучше поддержан, но это на основе обзора соответствующих веб-сайтов. Знаете ли вы какие-либо конкретные преимущества одного над другим?
Catskul
Эйген тоже хорошо работает. В то время, когда я проводил расследование, он был не таким зрелым, но я считаю, что на данном этапе это был бы хороший вариант. GMTL использовался довольно широко, и был очень зрелым и твердым, когда я решил использовать его.
Рид Копси
Я думаю, чтобы свести мой вопрос к самой сути: вы сделали свой выбор субъективно, как «Это выглядит лучше» или где есть определенные особенности (API, скорость, использование памяти, широта, узость, расширяемость), которые сделали разницу. Я полагаю, что срок погашения подпадает под этот критерий, но если бы срок погашения был единственным показателем, я думаю, вы бы выбрали вариант на основе BLAS или LAPACK.
Catskul
Я выбрал это после того, как попробовал несколько вариантов и основал их: производительность, удобство использования и низкие накладные расходы времени выполнения / компиляции. Эйген теперь выглядит намного лучше, чем в тот момент, поэтому я не могу судить между ними. Тем не менее, я был очень счастлив с GMTL для нашего использования.
Рид Копси
Это часть того, почему я люблю GMTL, и использовал его. Он просто был очень естественным в использовании, и с ним было очень легко работать. В этом случае он также поддерживал все, что мне было нужно, поскольку я просто беспокоился о непосредственной обработке геометрических преобразований и кватернионных вращений.
Рид Копси
38

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

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

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

Eigen2 / Eigen3

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

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

  • Небезопасная оптимизация производительности приводит к необходимости тщательного соблюдения правил. Несоблюдение правил приводит к сбоям.
    • вы просто не можете безопасно передать значение
    • использование типов Eigen в качестве членов требует специальной настройки распределителя (или вы зависаете)
    • использование с типами контейнеров 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. cross (vec &, vec &, vec &) в VecOps.h, [сделать] cross (vec &, vec &) в Generate.h
  • незрелый / нестабильный API; все еще меняется.
    • Например, «cross» переместился из «VecOps.h» в «Generate.h», а затем имя было изменено на «makeCross». Примеры документации терпят неудачу, потому что все еще ссылаются на старые версии функций, которые больше не существуют.

NT2

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

Последний релиз более 2 лет назад.

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

Не могу найти след сообщества вокруг проекта.

LAPACK & BLAS

Преимущества: старые и зрелые.

Недостатки:

  • старый как динозавры с действительно дерьмовыми API
Catskul
источник
1
Относительно утверждений, выровненных по Eigen: чтобы получить высокую производительность от операций SSE (1,2,3 или 4) для небольших наборов данных, вам абсолютно необходимы согласованные данные. Операции загрузки / хранения без выравнивания выполняются намного медленнее. Решение между выровненной или не выровненной загрузкой / хранением также требует времени. Любой реализации «общего назначения» было бы действительно непросто сделать правильные вещи для всех, если бы они не разделяли интерфейс и на «выровненные» и «выровненные» операции - и опять же это просто не очень общая цель.
Йорис Тиммерманс
@ Catskul Я хотел бы использовать Eigen3. Не могли бы вы рассказать о том, что «оптимизации, которые делают его небезопасным, можно отключить с помощью определения»? Другие вопросы , вы перечислите под Eigen2 тщательно детализированы в документе под тем , связанное с вопросами выравнивания . Я могу жить с этими проблемами.
Али
Проблемы с безопасностью я имею в виду все связанные с выравниванием и те же от Eigen2. Если вы в порядке с Eigen2, вы будете в порядке с Eigen3.
Catskul
2
BLAS и LAPACK на самом деле не библиотеки, а спецификации / API. Вы могли бы упомянуть их начальные реализации netlib или другими реализациями, такими как ATLAS и OpenBLAS.
Foad
12

Для чего это стоит, я пробовал и 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-м веке. Просто мой тапенсхапенный.

Фрэнсис Уркхарт
источник
2
Armadillo имеет продуманный Matlab-подобный синтаксис, поэтому его легко использовать. Я не уверен, что вы имеете в виду по поводу "документации не хватает ... специфики в отношении LAPACK". Документация четко документирует все доступные пользователю функции, а также примеры их использования. Весь смысл библиотеки обёрток C ++ состоит в том, чтобы абстрагироваться от сложности и многословности LAPACK. Вы всегда можете просмотреть источник, если хотите увидеть, как Armadillo называет LAPACK.
mtall
О разложении QR в Eigen, вы имеете в виду Eigen2 или Eigen3?
Qed
11

Если вы ищете высокопроизводительную матричную / линейную алгебру / оптимизацию для процессоров 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

Павел
источник
8

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

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

Джефф Харди
источник
По моему опыту (большие матрицы), Boost.UBLAS используется больше. Однако, когда я посмотрел на это, мне это не понравилось (в основном из-за документации), поэтому я сосредоточился на Eigen. У Эйгена есть модуль геометрии , но я не использовал его сам.
Джитс Нисен
Eigen, по-видимому, используют ROS (ивовый гараж), Celestia, Koffice и libmv. Я вижу некоторую болтовню об UBLAS, но мне было трудно найти проект, который рекламировал его. То же самое для NT2. Можете ли вы рассказать о том, что хорошего вы слышали?
Catskul
В списке рассылки Boost обсуждалась возможность добавления современной библиотеки LinAlg в Boost - Eigen и NT2 были упомянуты в качестве возможных кандидатов, но только разработчики NT2 выразили заинтересованность в этом. Обе библиотеки казались приличными; как вы сказали, Eigen немного более популярен, а также более C ++ - иш; NT2 разработан так, чтобы максимально имитировать MATLAB.
Джефф Харди
8

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

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

davidtbernal
источник
7

Как насчет GLM ?

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

user3742582
источник
ну, это обеспечивает графический вектор программирования и матрицы. он вносит большое количество накладных расходов, чтобы поддерживать совместимость с GLSL (если вы можете сделать это в GLSL, в большинстве случаев делать это в GLSL лучше, особенно с GL 4.x), и пропустить многие примитивы графического программирования (frustum, AABB, BB, ellipsoid). ). Его интерфейс Swizzle, это ожирение. Гораздо лучшая альтернатива была бы, если бы у нее были функции ".xyzz ()", сгенерированные с некоторой генерацией кода. Это прекрасно, когда вам нужно создать прототип приложения opengl, и он начинает показывать свои отрицательные стороны в больших проектах. никогда не используйте математическую библиотеку.
CoffeDeveloper
5

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

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

ИМА
источник
1
Вся вещь «если ты сделаешь это, то обязательно…» кажется мне чем-то вроде красного флага. До сих пор я дважды сталкивался с этими проблемами, и я только начал использовать его. Я действительно надеялся не обременять будущих разработчиков знанием всевозможных идиосинкразий каждой библиотеки, в частности: проблемы выравнивания при сбое, если вы не используете определенные макросы каждый раз, когда у вас есть члены, и тот факт, что они распространяют функциональность для отдельных классы по нескольким заголовкам. В одиночку это может не помешать мне выбрать его, но оно немного напоминает красный флаг.
Catskul
1
Выравнивание и этот макрос имеют значение только при использовании SSE, что ни в коем случае не требуется. И если вы используете SIMD, эти проблемы будут расти независимо от того, какую библиотеку вы используете. По крайней мере, Eigen не просто аварийно завершает работу, но предоставляет значимые сообщения об ошибках, которые прямо указывают на проблему.
Има
И есть простой способ избежать макроса выравнивания - используйте указатели или ссылки в качестве членов.
Има
1
Я не думаю, что это правда. Я не использовал никаких специальных параметров SSE и получил несколько сбоев после использования его с контейнерами stl. Да, я знаю, что это дает вам полезные сообщения, и да, я знаю, что есть специальные инструкции, но это моя точка зрения. Я не хочу обременять других разработчиков специальными инструкциями для каждой включенной библиотеки. Например, не передавайте по значению слишком много.
Catskul
Я только что узнал, что в последней ветке разработки есть некоторые определения, которые вы можете использовать, чтобы отключить выравнивание и избежать связанных с этим проблем.
Catskul
4

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

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

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

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

tfinniga
источник
Это намеренно открыто, потому что я не знаю, каковы компромиссы. Вероятно, справедливо будет сказать, что геометрия является нашей главной заботой, размерность геометрии не ясна. В настоящее время это 2/3 (2 + время) и может гипотетически быть довольно высоким (3dims + время + multi-dim-costmaps).
Catskul
Я согласен с вопросом. Например, многие приложения такого типа нуждаются в производительности в реальном времени (согласованное поведение времени), в то время как многие другие просто отлично отказываются от согласованности и / или скорости для точности.
TED
Так вы говорите, что ни одна из библиотек, которые вы исследовали, не заботилась о NURBS и Beziers? Есть ли какая-то конкретная причина не брать одну из существующих библиотек и не поддерживать поддержку NURBS и Bezier?
Catskul
Я пытался сказать, что рациональные NURBS и Безье используют рациональные контрольные точки гораздо чаще, чем большинство 3d-приложений, поэтому мы совершали больше ошибок. Обычно большинство 3d-приложений имеют только ванильные 3d-точки и векторы, пока не пройдут трансформацию перспективы. Многие из наших алгоритмов должны уметь правильно обрабатывать взвешенные / рациональные / проективные и декартовы точки, переходить назад и вперед и т. Д.
tfinniga
0

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

Кларк Гэмбл
источник
1
По состоянию на декабрь 2019 года связь, к сожалению, разорвана
10762409 говорит восстановить Monica