web-dev-qa-db-fra.com

Quelles sont les bibliothèques d'algèbre linéaire vectorielles / matricielles C ++ les plus utilisées, ainsi que leurs compromis coûts / avantages?

Il semble que de nombreux projets ont lentement besoin de faire des calculs matriciels et tombent dans le piège de créer d’abord des classes de vecteurs et d’ajouter lentement des fonctionnalités jusqu’à ce qu’ils soient pris en train de construire une bibliothèque d’algèbre linéaire personnalisée à moitié assée, et cela dépend.

J'aimerais éviter cela sans créer de dépendance vis-à-vis d'une bibliothèque liée de manière tangentielle (par exemple, OpenCV, OpenSceneGraph).

Quelles sont les bibliothèques matricielles/algèbre linéaire les plus utilisées et pourquoi choisir d’en utiliser une sur l’autre? Y a-t-il des personnes qui seraient déconseillées d'utiliser pour une raison quelconque? J'utilise spécifiquement cela dans un contexte géométrique/temporel * (2,3,4 Dim) *, mais j'utilise peut-être des données dimensionnelles supérieures dans le futur.

Je recherche des différences en termes de: API, vitesse, utilisation de la mémoire, étendue/exhaustivité, étroitesse/spécificité, extensibilité et/ou maturité/stabilité.

Mise à jour

J'ai fini par utiliser Eigen3 dont je suis extrêmement heureux.

228
Catskul

De nombreux projets ont opté pour le Generic Graphics Toolkit pour cela. Le GMTL là-bas est Nice - il est assez petit, très fonctionnel et assez utilisé pour être très fiable. OpenSG, VRJuggler et d’autres projets ont tous opté pour cette solution au lieu de leur propre calcul mathématique vertor/matrix roulé à la main.

Je l’ai trouvé assez sympa - il fait tout via des modèles, il est donc très flexible et très rapide.


Modifier:

Après la discussion sur les commentaires et les modifications, j'ai décidé de divulguer davantage d'informations sur les avantages et les inconvénients d'une mise en œuvre spécifique et sur les raisons pour lesquelles vous pourriez choisir l'une plutôt que l'autre, en fonction de votre situation.

GMTL -

Avantages: API simple, spécialement conçue pour les moteurs graphiques. Inclut de nombreux types primitifs axés sur le rendu (tels que les plans, les AABB, les quatenrions avec interpolation multiple, etc.) qui ne figurent dans aucun autre package. Mémoire vive très faible, assez rapide, facile à utiliser.

Inconvénients: l'API est très axée sur le rendu et les graphiques. N'inclut pas les matrices d'usage général (NxM), la décomposition et la résolution de matrices, etc., car elles ne relèvent pas des applications graphiques/géométriques traditionnelles.

Eigen -

Avantages: API propre , assez facile à utiliser. Inclut un module Géométrie avec quaternions et transformations géométriques. Surcoût de mémoire faible. Résolution complète, très performante résolution de grandes matrices NxN et autres routines mathématiques à usage général.

Inconvénients: Peut-être une portée un peu plus grande que ce que vous voulez (?). Moins de routines géométriques/de rendu spécifiques par rapport à GMTL (c'est-à-dire: définitions d'angle d'Euler, etc.).

IMSL -

Avantages: Bibliothèque numérique très complète. Très, très rapide (soi-disant le plus rapide des solveurs). De loin la plus grande et la plus complète des API mathématiques. Soutenu commercialement, mature et stable.

Inconvénients: coût - pas bon marché. Très peu de méthodes géométriques/de rendu spécifiques, vous aurez donc besoin de vous surpasser de leurs classes d'algèbre linéaire.

NT2 -

Avantages: Fournit une syntaxe plus familière si vous êtes habitué à MATLAB. Permet une décomposition et une résolution complètes pour les grandes matrices, etc.

Inconvénients: mathématique, non centrée sur le rendu. Probablement pas aussi performant qu'Eigen.

LAPACK -

Avantages: algorithmes très stables et éprouvés. Ça fait longtemps que je suis là. Résolution complète de la matrice, etc. Nombreuses options pour les mathématiques obscures.

Inconvénients: Pas aussi performant dans certains cas. Porté depuis Fortran, avec une API impaire pour une utilisation.

Personnellement, pour moi, cela revient à une seule question: comment comptez-vous l'utiliser? Si vous vous concentrez uniquement sur le rendu et les graphiques, j'aime Generic Graphics Toolkit , car il fonctionne bien et prend en charge de nombreuses opérations de rendu pratiques prêtes à l'emploi sans avoir à implémenter les vôtres. Si vous avez besoin d’une résolution matricielle générale (par exemple: SVD ou LU décomposition de grandes matrices), je préférerais Eigen , car il gère cela, fournit certaines opérations géométriques, et est très performant avec les grandes solutions matricielles. Vous devrez peut-être écrire davantage de vos propres opérations graphiques/géométriques (au-dessus de leurs matrices/vecteurs), mais ce n'est pas horrible.

107
Reed Copsey

Donc, je suis une personne assez critique et je pense que si je devais investir dans une bibliothèque, je ferais mieux de savoir dans quoi je m'embarquais. Je pense qu'il est préférable de peser lourdement sur les critiques et d'éclaircir les flatteries lors de l'examen approfondi; ce qui ne va pas avec cela a beaucoup plus d’implications pour l’avenir que ce qui est juste. Donc, je vais un peu exagérer ici pour fournir le genre de réponse qui me serait utile et j'espère, aidera les autres qui pourraient suivre cette voie. Gardez à l'esprit que cela est basé sur le peu de critiques/tests que j'ai faits avec ces libs. Oh et j'ai volé une partie de la description positive de Reed.

Je mentionnerai tout de suite que j’ai opté pour GMTL malgré ses particularités, car le manque de sécurité de Eigen2 était un inconvénient trop important. Mais j'ai récemment appris que la prochaine version de Eigen2 contiendrait des définitions qui éteindront le code d'alignement et le sécuriseront. Je peux donc basculer.

Mise à jour: Je suis passé à Eigen3. En dépit de ses particularités, sa portée et son élégance sont trop difficiles à ignorer, et les optimisations qui le rendent peu sûr peuvent être désactivées avec une définition.

Eigen2/Eigen3

Avantages: LGPL MPL2, API propre, bien conçue, assez facile à utiliser. Semble être bien entretenu avec une communauté dynamique. Surcoût de mémoire faible. Haute performance. Conçu pour l'algèbre linéaire générale, mais une bonne fonctionnalité géométrique est également disponible. Tout l'en-tête lib, aucun lien requis.

Idiocyncracies/inconvénients: (Certains/tous peuvent être évités par certaines définitions disponibles dans la branche de développement actuelle Eigen3)

  • Les optimisations de performances non sécurisées nécessitent de suivre scrupuleusement les règles. Le non respect des règles provoque des plantages.
    • vous ne pouvez tout simplement pas passer par valeur en toute sécurité
    • l'utilisation de types Eigen en tant que membres nécessite une personnalisation spéciale de l'allocateur (ou un blocage)
    • utiliser avec les types de conteneur stl et éventuellement d'autres modèles nécessitait une personnalisation d'allocation spéciale (ou vous planteriez)
    • certains compilateurs ont besoin d'attention particulière pour éviter les plantages lors d'appels de fonction (fenêtres GCC)

GMTL

Avantages: LGPL, API assez simple, spécialement conçue pour les moteurs graphiques. Inclut de nombreux types primitifs axés sur le rendu (tels que les plans, les AABB, les quatenrions avec interpolation multiple, etc.) qui ne figurent dans aucun autre package. Mémoire vive très faible, assez rapide, facile à utiliser. Tous les en-têtes sont basés, aucun lien nécessaire.

Idiocyncracies/inconvénients:

  • L'API est bizarre
    • ce qui pourrait être myVec.x () dans une autre bibliothèque n'est disponible que via myVec [0] (problème de lisibilité)
      • un tableau ou stl :: vector de points peut vous amener à faire quelque chose comme pointsList [0] [0] pour accéder à la composante x du premier point
    • dans une tentative naïve d'optimisation, suppression de cross (vec, vec) et remplacement par makeCross (vec, vec, vec) lorsque le compilateur élimine malgré tout les temps inutiles
    • les opérations mathématiques normales ne renvoient pas les types normaux à moins que vous ne désactiviez certaines fonctions d'optimisation, par exemple: vec1 - vec2 ne renvoie pas de vecteur normal. length( vecA - vecB ) échoue même si vecC = vecA - vecB fonctionne. Vous devez envelopper comme: length( Vec( vecA - vecB ) )
    • les opérations sur les vecteurs sont fournies par des fonctions externes plutôt que par des membres. Cela peut vous obliger à utiliser la résolution de l’étendue partout car des noms de symboles communs peuvent entrer en collision.
    • tu dois faire
        length( makeCross( vecA, vecB ) )
      ou
        gmtl::length( gmtl::makeCross( vecA, vecB ) )
      Où sinon vous pourriez essayer
        vecA.cross( vecB ).length()
  • pas bien entretenu
    • toujours revendiqué comme "beta"
    • documentation manquante avec des informations de base telles que les en-têtes nécessaires pour utiliser une fonctionnalité normale
      • Vec.h ne contient pas d'opérations pour les vecteurs, VecOps.h en contient, d'autres sont dans Generate.h par exemple. cross (vec &, vec &, vec &) à VecOps.h, [make] cross (vec &, vec &) à Generate.h
  • aPI immature/instable; toujours en train de changer.
    • Par exemple, "cross" est passé de "VecOps.h" à "Generate.h", puis le nom a été remplacé par "makeCross". Les exemples de documentation échouent car ils font toujours référence à d'anciennes versions de fonctions qui n'existent plus.

NT2

Je ne peux pas le dire car ils semblent être plus intéressés par l'en-tête de l'image fractale de leur page Web que par le contenu. Cela ressemble plus à un projet académique qu’à un projet logiciel sérieux.

Dernière version il y a plus de 2 ans.

Apparemment, il n'y a pas de documentation en anglais, alors qu'il est supposé qu'il y a quelque chose en français quelque part.

Impossible de trouver une trace d'une communauté autour du projet.

LAPACK & BLAS

Avantages: vieux et mature.

Inconvénients:

  • vieux comme des dinosaures avec des API vraiment merdiques
33
Catskul

Pour ce que ça vaut, j'ai essayé à la fois Eigen et Armadillo. Vous trouverez ci-dessous une brève évaluation.

Avantages propres: 1. Complètement autonome - pas de dépendance vis-à-vis de BLAS ou de LAPACK externe. 2. Documentation décente. 3. soi-disant rapide, bien que je ne l'ai pas mis à l'épreuve.

Inconvénient: l'algorithme QR renvoie une seule matrice, la matrice R étant incorporée dans le triangle supérieur. Aucune idée d'où provient le reste de la matrice et aucune matrice Q n'est accessible.

Avantages de tatou: 1. Large gamme de décompositions et d'autres fonctions (y compris QR). 2. Raisonnablement rapide (utilise des modèles d'expression), mais encore une fois, je ne l'ai pas vraiment poussé vers les grandes dimensions.

Inconvénients: 1. Dépend de BLAS externes et/ou de LAPACK pour les décompositions matricielles. 2. La documentation manque à mon humble avis (y compris les détails de LAPACK, autres que la modification d'une instruction #define).

Ce serait bien si une bibliothèque open source était disponible, autonome et simple à utiliser. Je suis confronté au même problème depuis 10 ans et cela devient frustrant. À un moment donné, j'ai utilisé GSL pour le C et écrit des wrappers C++ autour de celui-ci, mais avec le C++ moderne - en particulier en utilisant les avantages des modèles d'expression - nous ne devrions pas avoir à jouer au C au 21e siècle. Juste mon tuppencehapenny.

12
Francis Urquhart

Si vous recherchez une algèbre matricielle/linéaire hautes performances/une optimisation sur les processeurs Intel, jetez un œil à la bibliothèque MKL d’Intel.

MKL est soigneusement optimisé pour des performances d’exécution rapides, en grande partie basées sur les normes très avancées BLAS/LAPACK fortran. Et ses performances sont proportionnelles au nombre de cœurs disponibles. L’évolutivité mains libres avec les cœurs disponibles est l’avenir de l’informatique et je n’utiliserais aucune bibliothèque mathématique car un nouveau projet ne prend pas en charge les processeurs multicœurs.

Très brièvement, cela comprend:

  1. Opérations vectorielles de base, vectorielles et matricielles
  2. Factorisation matricielle (décomposition de LU, hermitienne, clairsemée)
  3. Problème d’ajustement et valeur propre des moindres carrés
  4. Solveurs de systèmes linéaires clairsemés
  5. Solveur des moindres carrés non linéaire (régions de confiance)
  6. Des routines de traitement de signal plus telles que FFT et convolution
  7. Générateurs de nombres aléatoires très rapides (torsion de Mersenne)
  8. Beaucoup plus .... voir: texte du lien

Un inconvénient est que l'API MKL peut être assez complexe en fonction des routines dont vous avez besoin. Vous pouvez également consulter leur bibliothèque IPP (Integrated Performance Primitives), conçue pour les opérations de traitement d’images haute performance, mais néanmoins assez large.

Paul

Logiciel CenterSpace, bibliothèques de mathématiques .NET, centrespace.net

11
Paul

J'ai entendu de bonnes choses à propos de Eigen et NT2 , mais je ne les ai pas personnellement utilisés non plus. Il y a aussi Boost.UBLAS , qui, je crois, est un peu long dans la dent. Les développeurs de NT2 construisent la prochaine version avec l'intention de l'intégrer à Boost, afin que cela puisse compter pour quelque chose.

Mon lin alg. les besoins n'existent pas au-delà du cas de la matrice 4x4, je ne peux donc pas commenter les fonctionnalités avancées; Je ne fais que souligner quelques options.

8
Jeff Hardy

Je suis nouveau dans ce sujet, je ne peux donc pas en dire beaucoup, mais BLAS est à peu près la norme en informatique scientifique. BLAS est en fait un standard API, qui a de nombreuses implémentations. Honnêtement, je ne sais pas trop quelles sont les implémentations les plus populaires ni pourquoi.

Si vous voulez aussi pouvoir faire des opérations d’algèbre linéaire communes (systèmes de résolution, régression des moindres carrés, décomposition, etc.), examinez LAPACK .

8
davidtbernal

Qu'en est-il de GLM ?

Il est basé sur la spécification GLSL (OpenGL Shading Language) et est publié sous la licence MIT. Clairement destiné aux programmeurs graphiques

6
user3742582

J'ajouterai vote pour Eigen: j'ai transféré beaucoup de code (géométrie 3D, algèbre linéaire et équations différentielles) de différentes bibliothèques sur celle-ci - améliorant à la fois les performances et la lisibilité du code.

Un avantage qui n’a pas été mentionné: il est très facile d’utiliser SSE avec Eigen, ce qui améliore considérablement les performances des opérations 2D-3D (où tout peut être bourré à 128 bits).

5
ima

Ok, je pense que je sais ce que tu cherches. Il semble que GGT soit une très bonne solution, comme l’a suggéré Reed Copsey.

Personnellement, nous avons créé notre propre petite bibliothèque, car nous traitons beaucoup de points rationnels - beaucoup de NURBS et de Béziers rationnels.

Il s’avère que la plupart des bibliothèques graphiques 3D effectuent des calculs avec des points projectifs qui n’ont aucune base en mathématiques projectives, car c’est ce qui vous donne la réponse que vous souhaitez. Nous avons finalement utilisé des points de Grassmann, qui reposent sur une base théorique solide et qui ont réduit le nombre de types de points. Les points de Grassmann sont fondamentalement les mêmes calculs que ceux que les gens utilisent maintenant, avec l'avantage d'une théorie robuste. Plus important encore, cela rend les choses plus claires dans notre esprit, nous avons donc moins de bugs. Ron Goldman a écrit un article sur les points Grassmann en infographie appelé "Sur les fondements algébrique et géométrique de l’infographie" .

Pas directement lié à votre question, mais une lecture intéressante.

4
tfinniga

J'ai trouvé cette bibliothèque assez simple et fonctionnelle ( http://kirillsprograms.com/top_Vectors.php ). Ce sont des vecteurs nus osseux implémentés via des modèles C++. Aucune astuce - juste ce que vous devez faire avec les vecteurs (additionner, soustraire multiplier, dot, etc.).

0
Clark Gamble

FLENS

http://flens.sf.net

Il implémente également de nombreuses fonctions LAPACK.

0
Michael Lehn