267

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

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

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

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

更新

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

4

11 回答 11

126

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

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


编辑:

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

格林威治标准时间-

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

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

特征-

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

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

IMSL -

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

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

NT2 -

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

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

-

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

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

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

于 2009-09-04T16:55:48.960 回答
40

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

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

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

特征 2/特征 3

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

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

  • 不安全的性能优化导致需要仔细遵循规则。不遵守规则会导致崩溃。
    • 您根本无法安全地按值传递
    • 使用 Eigen 类型作为成员需要特殊的分配器定制(或者你崩溃)
    • 与 stl 容器类型和可能需要特殊分配自定义的其他模板一起使用(否则您将崩溃)
    • 某些编译器需要特别小心以防止函数调用崩溃(GCC 窗口)

格林威治标准时间

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

异想天开/缺点:

  • 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 不包含 Vectors 的操作,VecOps.h 包含一些,例如在 Generate.h 中。VecOps.h 中的 cross(vec&,vec&,vec&),Generate.h 中的 [make]cross(vec&,vec&)
  • 不成熟/不稳定的 API;还在变化。
    • 例如“cross”已从“VecOps.h”移至“Generate.h”,然后名称更改为“makeCross”。文档示例失败,因为仍然引用不再存在的旧版本的函数。

NT2

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

2 年前的最新版本。

显然没有英文文档,尽管据说某处有法语的东西。

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

LAPACK & BLAS

优点:老而成熟。

缺点:

  • 像恐龙一样古老,API 非常糟糕
于 2009-09-21T04:57:18.213 回答
12

对于它的价值,我已经尝试过 Eigen 和 Armadillo。下面是一个简短的评价。

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

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

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

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

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

于 2012-10-01T19:13:06.080 回答
11

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

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

简而言之,它包括:

  1. 基本向量-向量、向量-矩阵和矩阵-矩阵运算
  2. 矩阵分解(LU decomp、hermitian、sparse)
  3. 最小二乘拟合和特征值问题
  4. 稀疏线性系统求解器
  5. 非线性最小二乘求解器(信任区域)
  6. 加上信号处理例程,例如 FFT 和卷积
  7. 非常快的随机数生成器(梅森扭曲)
  8. 更多......请参阅:链接文本

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

保罗

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

于 2009-10-15T05:38:03.263 回答
9

GLM呢?

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

于 2014-10-21T14:46:25.423 回答
8

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

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

于 2009-09-04T16:53:06.220 回答
8

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

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

于 2009-09-04T16:56:36.307 回答
6

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

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

于 2009-09-16T13:48:38.907 回答
4

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

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

事实证明,大多数 3D 图形库都使用没有投影数学基础的投影点进行计算,因为这就是你想要的答案。我们最终使用了 Grassmann 点,它具有坚实的理论基础并减少了点类型的数量。格拉斯曼点与人们现在使用的计算基本相同,具有稳健的理论。最重要的是,它让我们的思路更清晰,所以我们的 bug 更少。Ron Goldman 写了一篇关于计算机图形学中格拉斯曼点的论文,名为“计算机图形学的代数和几何基础”

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

于 2009-09-04T16:57:03.263 回答
0

弗伦斯

http://flens.sf.net

它还实现了很多LAPACK功能。

于 2012-09-03T13:43:21.020 回答
0

我发现这个库非常简单和实用(http://kirillsprograms.com/top_Vectors.php)。这些是通过 C++ 模板实现的裸骨向量。没有花哨的东西——只是你需要对向量做的事情(加、减、乘、点等)。

于 2014-09-24T21:23:08.227 回答