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

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

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

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

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

更新

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

201839 次浏览

我听说过特征NT2的优点,但我个人没有使用过它们。还有提振。UBLAS,我认为它在牙齿上变得有点长。NT2的开发人员正在构建下一个版本,目的是将其纳入Boost,所以这可能是有意义的。

我林。alg。需求不会超出4x4矩阵的情况下,所以我不能评论高级功能;我只是指出一些选择。

有相当多的项目已经解决了通用图形工具包。这里的GMTL非常好——它非常小,功能非常强大,并且被广泛使用,非常可靠。OpenSG、VRJuggler和其他项目都改用了这种方法,而不是他们自己手工制作的vertor/矩阵数学。

我发现它非常好——它通过模板完成所有的事情,所以它非常灵活,非常快。


编辑:

在评论讨论和编辑之后,我想我应该介绍一些关于特定实现的优点和缺点的更多信息,以及根据您的情况选择其中一种而不是另一种的原因。

GMTL -

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

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

特征 -

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

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

IMSL -

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

缺点:成本——并不便宜。很少有特定的几何/渲染方法,所以你需要在他们的线性代数类之上滚动你自己的方法。

NT2 -

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

缺点:数学化,不聚焦渲染。可能没有Eigen表现得好。

LAPACK -

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

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

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

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

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

好吧,我知道你在找什么了。正如Reed Copsey所建议的,GGT似乎是一个相当好的解决方案。

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

事实证明,大多数3D图形库都是用投影点进行计算的,而这些点在投影数学中是没有基础的,因为这就是你想要的答案。我们最终使用了格拉斯曼点,它有坚实的理论基础,并减少了点类型的数量。格拉斯曼点基本上和人们现在使用的计算方法是一样的,这得益于强大的理论。最重要的是,它使我们头脑中的事情更清晰,所以我们的bug更少。Ron Goldman写了一篇关于计算机图形学中的Grassmann点的论文,名为论计算机图形学的代数与几何基础

和你的问题没有直接关系,但是很有趣。

我把很多代码(3D几何、线性代数和微分方程)从不同的库移植到Eigen中——几乎在所有情况下都提高了性能和代码的可读性。

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

所以我是一个非常挑剔的人,我想如果我要投资一个图书馆,我最好知道我要做什么。我认为,在仔细审查时,最好多批评,少奉承;它的错误之处比正确之处对未来的影响更大。所以在这里,我要做的有点过火,提供一些能帮助到我的答案,我希望也能帮助到其他可能走上这条路的人。请记住,这是基于我对这些库所做的一些审查/测试。我还偷了里德的一些正面描述。

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

更新:我已经切换到特征3。尽管它有自己的特性,但它的范围和优雅性是很难忽视的,并且可以通过define关闭使其不安全的优化。

Eigen2 / Eigen3

优点:LGPL MPL2,干净,设计良好的API,相当容易使用。似乎维护得很好,社区也很活跃。低内存开销。高性能。适用于一般线性代数,但也有很好的几何功能。所有头库,不需要链接。

Idiocyncracies /缺点:(部分/全部可以通过在the current development branch Eigen3)中可用的一些定义来避免

  • 不安全的性能优化导致需要仔细遵循规则。不遵守规则会导致崩溃。
    • 你根本不能安全地传递值
    • 使用特征类型作为成员需要特殊的分配器定制(否则会崩溃)
    • 用于STL容器类型和可能需要的其他模板 特殊的分配定制(否则会崩溃) 某些编译器需要特别注意,以防止函数调用崩溃(GCC窗口)

GMTL

优点:LGPL,非常简单的API,专门为图形引擎设计。 包括许多面向呈现的原语类型(例如 平面,AABB,具有多重插值的四元数等) 不在其他包裹里。内存开销很低,速度很快, 使用方便。

Idiocyncracies /缺点:

  • API很古怪
    • 可能是myVec.x()在另一个lib中只能通过myVec[0](可读性问题)
      • 一个数组或stl::vector of points可能会导致您执行类似pointsList[0][0]的操作来访问第一个点的x分量
    • 在一个天真的优化尝试中,删除了交叉(vec,vec)和 当编译器消除时替换为makcross (vec,vec,vec) 没有必要的临时工作
    • 正常数学运算不返回正常类型,除非关闭 关闭一些优化特性,例如:vec1 - vec2不返回一个 因此length( vecA - vecB )失败,即使vecC = vecA - vecB > < /代码的工作原理。你必须像这样包装:length( Vec( vecA - vecB ) ) 向量上的
    • 操作由外部函数提供,而不是 成员。这可能要求您在任何地方都使用范围解析 由于常用符号名称可能发生冲突
    • 你必须做
        length( makeCross( vecA, vecB ) ) < br > 或< br >   gmtl::length( gmtl::makeCross( vecA, vecB ) ) < br > 否则你可以尝试
        vecA.cross( vecB ).length() < br >
  • 维护不好
    • 仍然声称是“beta”
    • 文档缺少基本信息,例如需要哪些头文件 使用正常功能
      • Vec.h不包含向量的操作,VecOps.h包含 例如,有些在Generate.h中。十字架(vec vec vec) VecOps.h, [make]cross(vec&,vec&)在Generate.h
  • 不成熟/不稳定的API;仍然发生变化。
    • 例如,“cross”已经从“VecOps.h”移动到“Generate.h”,并且 后来更名为“makcross”。文档示例失败 因为仍然引用不再存在的函数的旧版本。

NT2

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

最新版本发布于2年前。

显然没有英语文档,尽管据说在某个地方有法语文档。

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

Lapack & blas

优点:年老成熟。

缺点:

  • 像恐龙一样老,api非常糟糕

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

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

简单地说,它包括:

  1. 基本向量向量,向量矩阵, 矩阵-矩阵运算
  2. 矩阵分解(LU分解,厄米化,稀疏化)
  3. 最小二乘拟合和特征值问题
  4. 稀疏线性系统求解器
  5. 非线性最小二乘求解器(信赖域)
  6. 加上信号处理程序,如FFT和卷积
  7. 非常快速的随机数发生器(梅森扭曲)
  8. 更多的……看:链接文本

一个缺点是MKL API可能非常复杂,具体取决于所需的例程。您还可以看看他们的IPP(集成性能原语)库,该库面向高性能图像处理操作,但仍然相当广泛。

保罗

CenterSpace软件公司。NET数学库,centerspace.net

FLENS

< a href = " http://flens.sf.net " rel =“nofollow”> http://flens.sf.net < / >

它还实现了许多LAPACK函数。

不管怎样,艾根和犰狳我都试过了。下面是一个简短的评价。

< p >特征 优点: 1. 完全独立-不依赖于外部BLAS或LAPACK。 2. 良好的文档。 3.据说很快,虽然我还没有测试过 < p >劣势: QR算法只返回一个矩阵,R矩阵嵌入在上面的三角形中。不知道剩下的矩阵从哪里来,没有Q矩阵可以访问 < p >犰狳 优点: 1. 广泛的分解和其他功能(包括QR)。 2. 相当快(使用表达式模板),但同样,我没有真正将它推到高维 < p >缺点: 1. 依赖于外部BLAS和/或LAPACK进行矩阵分解。 2. 以我之见,缺少文档(包括wrt LAPACK的细节,除了更改#define语句)

如果有一个开放源码库,它是自包含的,并且易于使用,那就太好了。我已经遇到同样的问题10年了,这很令人沮丧。有一次,我使用GSL来编写C语言,并围绕它编写c++包装器,但是使用现代c++——特别是使用表达式模板的优点——我们不应该在21世纪搞乱C语言。只有我的两便士。

我发现这个库非常简单和实用(http://kirillsprograms.com/top_Vectors.php)。这些是通过c++模板实现的基本向量。没有花哨的东西-只是你需要做的向量(加,减,乘,点,等等)。

全球语言监测机构呢?

它基于OpenGL Shading Language (GLSL)规范,并在MIT许可下发布。 显然是针对图形程序员