什么是最广泛使用的 C++ 向量/矩阵数学/线性代数库,以及它们的成本和收益权衡?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1380371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:46:58  来源:igfitidea点击:

What are the most widely used C++ vector/matrix math/linear algebra libraries, and their cost and benefit tradeoffs?

c++mathmatrixlinear-algebra

提问by Catskul

It seems that many projects slowly come upon a need to do matrix math, and fall into the trap of first building some vector classes and slowly adding in functionality until they get caught building a half-assed custom linear algebra library, and depending on it.

似乎许多项目慢慢地需要做矩阵数学,并陷入首先构建一些向量类然后慢慢添加功能的陷阱,直到他们被发现构建一个半途而废的自定义线性代数库,并依赖于它。

I'd like to avoid that while not building in a dependence on some tangentially related library (e.g. OpenCV, OpenSceneGraph).

我想避免这种情况,同时不依赖于一些切线相关的库(例如 OpenCV、OpenSceneGraph)。

What are the commonly used matrix math/linear algebra libraries out there, and why would decide to use one over another? Are there any that would be advised against using for some reason? I am specifically using this in a geometric/time context*(2,3,4 Dim)* but may be using higher dimensional data in the future.

什么是常用的矩阵数学/线性代数库,为什么要决定使用一个而不是另一个?有没有出于某种原因建议不要使用的?我专门在几何/时间上下文*(2,3,4 Dim)* 中使用它,但将来可能会使用更高维度的数据。

I'm looking for differences with respect to any of: API, speed, memory use, breadth/completeness, narrowness/specificness, extensibility, and/or maturity/stability.

我正在寻找以下方面的差异:API、速度、内存使用、广度/完整性、狭窄性/特异性、可扩展性和/或成熟度/稳定性。

Update

更新

I ended up using Eigen3 which I am extremely happy with.

我最终使用了我非常满意的 Eigen3。

采纳答案by Reed Copsey

There are quite a few projects that have settled on the Generic Graphics Toolkitfor this. The GMTL in there is nice - it's quite small, very functional, and been used widely enough to be very reliable. OpenSG, VRJuggler, and other projects have all switched to using this instead of their own hand-rolled vertor/matrix math.

有很多项目为此选择了通用图形工具包。那里的 GMTL 很好 - 它非常小,非常实用,并且被广泛使用,非常可靠。OpenSG、VRJuggler 和其他项目都已转而使用它,而不是他们自己的手卷 vertor/matrix 数学。

I've found it quite nice - it does everything via templates, so it's very flexible, and very fast.

我发现它非常好 - 它通过模板完成所有工作,因此非常灵活,而且速度非常快。



Edit:

编辑:

After the comments discussion, and edits, I thought I'd throw out some more information about the benefits and downsides to specific implementations, and why you might choose one over the other, given your situation.

在评论讨论和编辑之后,我想我会抛出更多关于特定实现的优点和缺点的信息,以及为什么你可以根据你的情况选择一个而不是另一个。

GMTL-

通用语言-

Benefits: Simple API, specifically designed for graphics engines. Includes many primitive types geared towards rendering (such as planes, AABB, quatenrions with multiple interpolation, etc) that aren't in any other packages. Very low memory overhead, quite fast, easy to use.

优点:简单的 API,专为图形引擎设计。包括许多其他包中没有的面向渲染的基本类型(例如平面、AABB、具有多重插值的四元数等)。非常低的内存开销,相当快,易于使用。

Downsides: API is very focused specifically on rendering and graphics. Doesn't include general purpose (NxM) matrices, matrix decomposition and solving, etc, since these are outside the realm of traditional graphics/geometry applications.

缺点:API 非常专注于渲染和图形。不包括通用 (NxM) 矩阵、矩阵分解和求解等,因为这些超出了传统图形/几何应用程序的范围。

Eigen-

本征-

Benefits: Clean API, fairly easy to use. Includes a Geometry modulewith quaternions and geometric transforms. Low memory overhead. Full, highly performantsolving of large NxN matrices and other general purpose mathematical routines.

优点:干净的 API,相当容易使用。包括具有四元数和几何变换的几何模块。低内存开销。大型 NxN 矩阵和其他通用数学例程的完整、高性能求解。

Downsides: May be a bit larger scope than you are wanting (?). Fewer geometric/rendering specific routines when compared to GMTL (ie: Euler angle definitions, etc).

缺点:可能比您想要的范围更大(?)。与 GMTL 相比,更少的几何/渲染特定例程(即:欧拉角定义等)。

IMSL-

IMSL-

Benefits: Very complete numeric library. Very, very fast (supposedly the fastest solver). By far the largest, most complete mathematical API. Commercially supported, mature, and stable.

优点: 非常完整的数字库。非常非常快(据说是最快的求解器)。迄今为止最大、最完整的数学 API。商业支持,成熟,稳定。

Downsides: Cost - not inexpensive. Very few geometric/rendering specific methods, so you'll need to roll your own on top of their linear algebra classes.

缺点:成本 - 不便宜。很少有几何/渲染特定的方法,因此您需要在其线性代数类之上滚动自己的方法。

NT2-

NT2-

Benefits: Provides syntax that is more familiar if you're used to MATLAB. Provides full decomposition and solving for large matrices, etc.

优点:如果您习惯了 MATLAB,则提供更熟悉的语法。为大型矩阵等提供完整的分解和求解。

Downsides: Mathematical, not rendering focused. Probably not as performant as Eigen.

缺点:数学,不专注于渲染。可能不如 Eigen 性能好。

LAPACK-

背包-

Benefits: Very stable, proven algorithms. Been around for a long time. Complete matrix solving, etc. Many options for obscure mathematics.

优点:非常稳定、经过验证的算法。呆了很长时间了。完整的矩阵求解等。晦涩数学的许多选项。

Downsides: Not as highly performant in some cases. Ported from Fortran, with odd API for usage.

缺点:在某些情况下性能不高。从 Fortran 移植,使用奇怪的 API。

Personally, for me, it comes down to a single question - how are you planning to use this. If you're focus is just on rendering and graphics, I like Generic Graphics Toolkit, since it performs well, and supports many useful rendering operations out of the box without having to implement your own. If you need general purpose matrix solving (ie: SVD or LU decomposition of large matrices), I'd go with Eigen, since it handles that, provides some geometric operations, and is very performant with large matrix solutions. You may need to write more of your own graphics/geometric operations (on top of their matrices/vectors), but that's not horrible.

就我个人而言,这归结为一个问题——你打算如何使用它。如果您只关注渲染和图形,我喜欢Generic Graphics Toolkit,因为它性能良好,并且支持许多开箱即用的有用渲染操作,而无需您自己实现。如果您需要通用矩阵求解(即:大矩阵的 SVD 或 LU 分解),我会选择Eigen,因为它可以处理该问题,提供一些几何运算,并且对于大矩阵解决方案非常高效。您可能需要编写更多自己的图形/几何操作(在它们的矩阵/向量之上),但这并不可怕。

回答by Catskul

So I'm a pretty critical person, and figure if I'm going to invest in a library, I'd better know what I'm getting myself into. I figure it's better to go heavy on the criticism and light on the flattery when scrutinizing; what's wrong with it has many more implications for the future than what's right. So I'm going to go overboard here a little bit to provide the kind of answer that would have helped me and I hope will help others who may journey down this path. Keep in mind that this is based on what little reviewing/testing I've done with these libs. Oh and I stole some of the positive description from Reed.

所以我是一个非常挑剔的人,如果我要投资一个图书馆,我最好知道我要做什么。我认为在时,最好重批评,轻奉承;它的错误对未来的影响比正确的要多得多。因此,我将在这里有点过火,以提供对我有帮助的那种答案,我希望能帮助可能沿着这条道路前进的其他人。请记住,这是基于我对这些库所做的很少的/测试。哦,我从里德那里偷了一些正面的描述。

I'll mention up top that I went with GMTL despite it's idiosyncrasies because the Eigen2 unsafeness was too big of a downside. But I've recently learned that the next release of Eigen2 will contain defines that will shut off the alignment code, and make it safe. So I may switch over.

我会提到最重要的是,尽管 GMTL 有其特质,但我还是选择了它,因为 Eigen2 的不安全性太大了。但我最近了解到 Eigen2 的下一个版本将包含关闭对齐代码并使其安全的定义。所以我可以切换。

Update: I've switched to Eigen3. Despite it's idiosyncrasies, its scope and elegance are too hard to ignore, and the optimizations which make it unsafe can be turned off with a define.

更新:我已经切换到 Eigen3。尽管它有一些特点,但它的范围和优雅是难以忽视的,并且可以通过定义关闭使其不安全的优化。

Eigen2/Eigen3

特征2/特征3

Benefits: LGPLMPL2, Clean, well designed API, fairly easy to use. Seems to be well maintained with a vibrant community. Low memory overhead. High performance. Made for general linear algebra, but good geometric functionality available as well. All header lib, no linking required.

优点:LGPLMPL2,干净,设计良好的API,相当容易使用。似乎在一个充满活力的社区中得到了很好的维护。低内存开销。高性能。适用于一般线性代数,但也提供良好的几何功能。所有标头库,无需链接。

Idiocyncracies/downsides: (Some/all of these can be avoided by some defines that are available in the current development branchEigen3)

特性/缺点:(某些/所有这些可以通过当前开发分支Eigen3中可用的一些定义来避免)

  • Unsafe performance optimizations result in needing careful following of rules. Failure to follow rules causes crashes.
    • you simply cannot safely pass-by-value
    • use of Eigen types as members requires special allocator customization (or you crash)
    • use with stl container types and possibly other templates required special allocation customization (or you will crash)
    • certain compilers need special care to prevent crashes on function calls (GCC windows)
  • 不安全的性能优化导致需要仔细遵循规则。不遵守规则会导致崩溃。
    • 你根本无法安全地传递值
    • 使用特征类型作为成员需要特殊的分配器自定义(否则会崩溃)
    • 与 stl 容器类型和可能需要特殊分配自定义的其他模板一起使用(否则您会崩溃)
    • 某些编译器需要特别注意以防止函数调用崩溃(GCC 窗口)

GMTL

通用语言

Benefits: LGPL, Fairly Simple API, specifically designed for graphics engines. Includes many primitive types geared towards rendering (such as planes, AABB, quatenrions with multiple interpolation, etc) that aren't in any other packages. Very low memory overhead, quite fast, easy to use. All header based, no linking necessary.

优点:LGPL,相当简单的 API,专为图形引擎设计。包括许多其他包中没有的面向渲染的基本类型(例如平面、AABB、具有多重插值的四元数等)。非常低的内存开销,相当快,易于使用。所有基于标题,无需链接。

Idiocyncracies/downsides:

特质/缺点:

  • API is quirky
    • what might be myVec.x() in another lib is only available via myVec[0] (Readability problem)
      • an array or stl::vector of points may cause you to do something like pointsList[0][0] to access the x component of the first point
    • in a naive attempt at optimization, removed cross(vec,vec) and replaced with makeCross(vec,vec,vec) when compiler eliminates unnecessary temps anyway
    • normal math operations don't return normal types unless you shut off some optimization features e.g.: vec1 - vec2does not return a normal vector so length( vecA - vecB )fails even though vecC = vecA - vecBworks. You must wrap like: length( Vec( vecA - vecB ) )
    • operations on vectors are provided by external functions rather than members. This may require you to use the scope resolution everywhere since common symbol names may collide
    • you have to do
        length( makeCross( vecA, vecB ) )
      or
        gmtl::length( gmtl::makeCross( vecA, vecB ) )
      where otherwise you might try
        vecA.cross( vecB ).length()
  • 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()
  • not well maintained
    • still claimed as "beta"
    • documentation missing basic info like which headers are needed to use normal functionalty
      • Vec.h does not contain operations for Vectors, VecOps.h contains some, others are in Generate.h for example. cross(vec&,vec&,vec&) in VecOps.h, [make]cross(vec&,vec&) in Generate.h
  • 保养不好
    • 仍声称为“测试版”
    • 文档缺少基本信息,例如使用正常功能需要哪些标头
      • Vec.h 不包含 Vectors 的操作,VecOps.h 包含一些,例如其他在 Generate.h 中。VecOps.h 中的 cross(vec&,vec&,vec&),Generate.h 中的 [make]cross(vec&,vec&)
  • immature/unstable API; still changing.
    • For example "cross" has moved from "VecOps.h" to "Generate.h", and then the name was changed to "makeCross". Documentation examples fail because still refer to old versions of functions that no-longer exist.
  • API 不成熟/不稳定;还在变化。
    • 例如“cross”已从“VecOps.h”移动到“Generate.h”,然后名称更改为“makeCross”。文档示例失败,因为仍然引用不再存在的旧版本函数。

NT2

NT2

Can't tell because they seem to be more interested in the fractal image header of their web page than the content. Looks more like an academic project than a serious software project.

无法判断,因为他们似乎对网页的分形图像标题比内容更感兴趣。看起来更像是一个学术项目而不是一个严肃的软件项目。

Latest release over 2 years ago.

2 年前的最新版本。

Apparently no documentation in English though supposedly there is something in French somewhere.

显然没有英文文件,尽管据说某处有法文。

Cant find a trace of a community around the project.

在项目周围找不到社区的踪迹。

LAPACK & BLAS

LAPACK & BLAS

Benefits: Old and mature.

优点:老而成熟。

Downsides:

缺点:

  • old as dinosaurs with really crappy APIs
  • 像恐龙一样古老,API 非常糟糕

回答by Francis Urquhart

For what it's worth, I've tried both Eigen and Armadillo. Below is a brief evaluation.

对于它的价值,我已经尝试了 Eigen 和犰狳。下面是一个简单的评价。

Eigen Advantages: 1. Completely self-contained -- no dependence on external BLAS or LAPACK. 2. Documentation decent. 3. Purportedly fast, although I haven't put it to the test.

Eigen 优点: 1. 完全独立——不依赖于外部 BLAS 或 LAPACK。2.文档体面。3. 据称速度很快,虽然我还没有对其进行测试。

Disadvantage: The QR algorithm returns just a single matrix, with the R matrix embedded in the upper triangle. No idea where the rest of the matrix comes from, and no Q matrix can be accessed.

缺点:QR 算法仅返回单个矩阵,R 矩阵嵌入在上三角形中。不知道矩阵的其余部分来自哪里,也无法访问 Q 矩阵。

Armadillo Advantages: 1. Wide range of decompositions and other functions (including QR). 2. Reasonably fast (uses expression templates), but again, I haven't really pushed it to high dimensions.

Armadillo 优点: 1. 广泛的分解和其他功能(包括QR)。2. 相当快(使用表达式模板),但同样,我还没有真正将其推到高维度。

Disadvantages: 1. Depends on external BLAS and/or LAPACK for matrix decompositions. 2. Documentation is lacking IMHO (including the specifics wrt LAPACK, other than changing a #define statement).

缺点: 1. 依赖于外部 BLAS 和/或 LAPACK 进行矩阵分解。2. 文档缺乏恕我直言(包括 LAPACK 的细节,除了更改 #define 语句)。

Would be nice if an open source library were available that is self-contained and straightforward to use. I have run into this same issue for 10 years, and it gets frustrating. At one point, I used GSL for C and wrote C++ wrappers around it, but with modern C++ -- especially using the advantages of expression templates -- we shouldn't have to mess with C in the 21st century. Just my tuppencehapenny.

如果有一个自包含且易于使用的开源库,那就太好了。我遇到了同样的问题 10 年了,这让我很沮丧。有一次,我将 GSL 用于 C 并围绕它编写了 C++ 包装器,但是使用现代 C++——尤其是利用表达式模板的优势——我们不应该在 21 世纪与 C 混淆。只是我的 tupencehapenny。

回答by Paul

If you are looking for high performance matrix/linear algebra/optimization on Intel processors, I'd look at Intel's MKL library.

如果您正在寻找英特尔处理器上的高性能矩阵/线性代数/优化,我会查看英特尔的 MKL 库。

MKL is carefully optimized for fast run-time performance - much of it based on the very mature BLAS/LAPACK fortran standards. And its performance scales with the number of cores available. Hands-free scalability with available cores is the future of computing and I wouldn't use any math library for a new project doesn't support multi-core processors.

MKL 针对快速运行时性能进行了精心优化——其中大部分基于非常成熟的 BLAS/LAPACK fortran 标准。它的性能随着可用内核的数量而扩展。具有可用内核的免提可扩展性是计算的未来,我不会将任何数学库用于不支持多核处理器的新项目。

Very briefly, it includes:

非常简单,它包括:

  1. Basic vector-vector, vector-matrix, and matrix-matrix operations
  2. Matrix factorization (LU decomp, hermitian,sparse)
  3. Least squares fitting and eigenvalue problems
  4. Sparse linear system solvers
  5. Non-linear least squares solver (trust regions)
  6. Plus signal processing routines such as FFT and convolution
  7. Very fast random number generators (mersenne twist)
  8. Much more.... see: link text
  1. 基本的向量-向量、向量-矩阵和矩阵-矩阵运算
  2. 矩阵分解(LU decomp、hermitian、sparse)
  3. 最小二乘拟合和特征值问题
  4. 稀疏线性系统求解器
  5. 非线性最小二乘求解器(信任区域)
  6. 加上信号处理例程,如FFT和卷积
  7. 非常快的随机数生成器(梅森扭曲)
  8. 更多....见:链接文本

A downside is that the MKL API can be quite complex depending on the routines that you need. You could also take a look at their IPP (Integrated Performance Primitives) library which is geared toward high performance image processing operations, but is nevertheless quite broad.

缺点是 MKL API 可能非常复杂,具体取决于您需要的例程。您还可以查看他们的 IPP(集成性能基元)库,该库面向高性能图像处理操作,但内容非常广泛。

Paul

保罗

CenterSpace Software ,.NET Math libraries, centerspace.net

CenterSpace 软件,.NET 数学库,centerspace.net

回答by davidtbernal

I'm new to this topic, so I can't say a whole lot, but BLASis pretty much the standard in scientific computing. BLAS is actually an API standard, which has many implementations. I'm honestly not sure which implementations are most popular or why.

我是这个话题的新手,所以我不能说很多,但BLAS几乎是科学计算的标准。BLAS实际上是一个API标准,它有很多实现。老实说,我不确定哪些实现最受欢迎或为什么。

If you want to also be able to do common linear algebra operations (solving systems, least squares regression, decomposition, etc.) look into LAPACK.

如果您还想进行常见的线性代数运算(求解系统、最小二乘回归、分解等),请查看LAPACK

回答by Jeff Hardy

I've heard good things about Eigenand NT2, but haven't personally used either. There's also Boost.UBLAS, which I believe is getting a bit long in the tooth. The developers of NT2 are building the next version with the intention of getting it into Boost, so that might count for somthing.

我听说过关于EigenNT2 的好消息,但也没有亲自使用过。还有Boost.UBLAS,我相信它在牙齿上有点长了。NT2 的开发人员正在构建下一个版本,打算将其引入 Boost,因此这可能很重要。

My lin. alg. needs don't exteed beyond the 4x4 matrix case, so I can't comment on advanced functionality; I'm just pointing out some options.

我的琳 算法 需求不会超出 4x4 矩阵情况,因此我无法评论高级功能;我只是指出一些选项。

回答by user3742582

What about GLM?

什么GLM

It's based on the OpenGL Shading Language (GLSL) specification and released under the MIT license. Clearly aimed at graphics programmers

它基于 OpenGL 着色语言 (GLSL) 规范并在 MIT 许可下发布。明确针对图形程序员

回答by ima

I'll add vote for Eigen: I ported a lot of code (3D geometry, linear algebra and differential equations) from different libraries to this one - improving both performance and code readability in almost all cases.

我将为 Eigen 添加一票:我将来自不同库的大量代码(3D 几何、线性代数和微分方程)移植到这个库中 - 在几乎所有情况下都提高了性能和代码可读性。

One advantage that wasn't mentioned: it's very easy to use SSE with Eigen, which significantly improves performance of 2D-3D operations (where everything can be padded to 128 bits).

一个没有提到的优点:将 SSE 与 Eigen 一起使用非常容易,这显着提高了 2D-3D 操作的性能(所有内容都可以填充到 128 位)。

回答by tfinniga

Okay, I think I know what you're looking for. It appears that GGT is a pretty good solution, as Reed Copsey suggested.

好的,我想我知道你在找什么。正如 Reed Copsey 建议的那样,GGT 似乎是一个很好的解决方案。

Personally, we rolled our own little library, because we deal with rational points a lot - lots of rational NURBS and Beziers.

就个人而言,我们推出了自己的小库,因为我们经常处理有理点——很多有理 NURBS 和 Beziers。

It turns out that most 3D graphics libraries do computations with projective points that have no basis in projective math, because that's what gets you the answer you want. We ended up using Grassmann points, which have a solid theoretical underpinning and decreased the number of point types. Grassmann points are basically the same computations people are using now, with the benefit of a robust theory. Most importantly, it makes things clearer in our minds, so we have fewer bugs. Ron Goldman wrote a paper on Grassmann points in computer graphics called "On the Algebraic and Geometric Foundations of Computer Graphics".

事实证明,大多数 3D 图形库都使用没有投影数学基础的投影点进行计算,因为这就是您想要的答案。我们最终使用了 Grassmann 点,它具有坚实的理论基础并减少了点类型的数量。Grassmann 点与人们现在使用的计算基本相同,但受益于稳健的理论。最重要的是,它让我们头脑中的事情更清晰,因此我们的错误更少。罗恩戈德曼写了一篇关于计算机图形学中格拉斯曼点的论文,名为计算机图形学的代数和几何基础”

Not directly related to your question, but an interesting read.

与您的问题没有直接关系,但很有趣。

回答by Michael Lehn

FLENS

弗伦斯

http://flens.sf.net

http://flens.sf.net

It also implements a lot of LAPACK functions.

它还实现了很多 LAPACK 功能。