什么是最广泛使用的C ++vector/matrixmath/线性代数库,以及它们的成本和收益折衷?

似乎很多项目慢慢需要做matrix运算,陷入了先构build一些向量类并慢慢增加function的陷阱,直到被抓住build立一个半自定义的线性代数库,并依赖于它。

我想避免这种情况,而不是build立在一些切线相关的库(例如OpenCV,OpenSceneGraph)上。

那里常用的matrixmath/线性代数库是什么,为什么会决定使用另一个呢? 有什么会因为某种原因被build议不要使用? 我特别在几何/时间上下文*(2,3,4 Dim)*中使用它,但将来可能会使用更高维的数据。

我正在寻找关于API,速度,内存使用,宽度/完整性,狭窄/特定性,可扩展性和/或成熟度/稳定性的差异。

更新

我结束了使用Eigen3,我非常满意。

为此,有相当多的项目已经在通用graphics工具包中得到了解决。 在那里的GMTL是不错的 – 它是相当小,非常实用,并被广泛使用,是非常可靠的。 OpenSG,VRJuggler和其他项目已经全部切换到使用它而不是自己的手卷翻转matrix/matrixmath。

我发现它非常好 – 它通过模板完成所有工作,所以它非常灵活,速度非常快。


编辑:

在评论讨论和编辑之后,我想我会提供一些关于特定实现的好处和缺点的信息,以及为什么你可以select一个在另一个之上,根据你的情况。

GMTL –

优点:简单的API,专门为graphics引擎devise。 包含许多适合渲染的基本types(例如平面,AABB,具有多重插值的区域等),这些types不在任何其他包中。 非常低的内存开销,相当快,易于使用。

缺点:API非常专注于渲染和graphics。 不包括通用(NxM)matrix,matrix分解和求解等,因为它们超出了传统graphics/几何应用领域。

Eigen –

好处: 干净的API ,相当容易使用。 包括具有四元数和几何变换的几何模块 。 低内存开销。 充分, 高性能地解决大型NxNmatrix和其他通用math例程。

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

IMSL –

优点:非常完整的数字图书馆。 非常,非常快(据说是最快的求解器)。 迄今为止最大,最完整的mathAPI。 商业上的支持,成熟和稳定。

缺点:成本 – 并不便宜。 非常less的几何/渲染特定的方法,所以你需要在自己的线性代数类的顶部。

NT2 –

优点:提供更熟悉的语法,如果你习惯于MATLAB。 为大型matrix提供完整的分解和求解

缺点:math,没有渲染的重点。 可能不如Eigen性能。

LAPACK –

优点:非常稳定,经过validation的algorithm。 已经在很长一段时间了。 完成matrix求解,等等。

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

就我个人而言,这归结为一个问题 – 你打算如何使用这个问题。 如果您只关注渲染和graphics,那么我喜欢通用graphics工具包 ,因为它运行良好,并且支持许多有用的渲染操作,而无需实现自己的渲染。 如果你需要通用matrix求解(即:大matrix的SVD或LU分解),我会使用Eigen ,因为它可以处理这个问题,提供一些几何操作,而且对于大型matrix求解非常有效。 你可能需要写更多的自己的graphics/几何操作(在他们的matrix/向量之上),但这并不可怕。

所以我是一个非常关键的人物,并且想知道如果我要去投资一个图书馆,我最好知道自己要做什么。 我觉得在审议时要重视批评和恭维奉承, 它有什么问题,对未来有更多的影响。 所以我会在这里稍微放下一点,以提供一些帮助我的答案,我希望能帮助那些可能走上这条道路的人。 请记住,这是基于我对这些库进行的less量检查/testing。 哦,我偷了里德的一些积极的描述。

我会提到我与GMTL一起去的顶端,尽pipe它是特质,因为Eigen2不安全是一个太大的缺点。 但是我最近了解到,Eigen2的下一个版本将包含定义,将closuresalignment代码,并使其安全。 所以我可以切换。

更新 :我已经切换到Eigen3。 尽pipe它的特质,它的范围和优雅是太难以忽视,并使其不安全的优化可以closures一个定义。

EIGEN2 / Eigen3

好处: LGPL MPL2,干净,devise良好的API,相当容易使用。 似乎与充满活力的社区保持良好。 低内存开销。 高性能。 用于一般线性代数,但也提供良好的几何function。 所有头文件lib,不需要链接。

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

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

GMTL

好处:LGPL,相当简单的API,专门为graphics引擎devise的。 包含许多适合渲染的基本types(例如平面,AABB,具有多重插值的区域等),这些types不在任何其他包中。 非常低的内存开销,相当快,易于使用。 所有标题为基础,没有必要的链接。

Idiocyncracies /缺点:

  • API是古怪的
    • 什么可能是myVec.x()在另一个库只能通过myVec [0](可读性问题)
      • 一个数组或点的向量stl ::向量可能会导致你做类似pointsList [0] [0]来访问第一个点的x分量
    • 在一个天真的尝试优化,删除交叉(vec,vec),并取代makeCross(vec,vec,vec)时,编译器消除不必要的临时工
    • 正常的math运算不会返回正常types,除非你closures了一些优化特性,例如: vec1 - vec2不返回一个法向量,所以length( vecA - vecB )失败,即使vecC = vecA - vecB工作。 你必须像: length( Vec( vecA - vecB ) )
    • 向量上的操作是由外部function而不是成员提供的。 这可能会要求您在各处使用范围parsing,因为常见的符号名称可能会发生碰撞
    • 你必须做
      length( makeCross( vecA, vecB ) )
      要么
      gmtl::length( gmtl::makeCross( vecA, vecB ) )
      否则你可能会尝试
      vecA.cross( vecB ).length()
  • 维护得不好
    • 仍然声称“testing版”
    • 文档缺less使用正常function所需的基本信息
      • Vec.h不包含Vectors的操作,VecOps.h包含一些,其他的在Generate.h中。 VecOps.h中的交叉(vec&,vec&,vec&),Generate.h中的交叉(vec&,vec&)
  • 不成熟/不稳定的API; 仍在变化。
    • 例如“cross”已经从“VecOps.h”移动到“Generate.h”,然后名称改为“makeCross”。 文档示例失败,因为仍旧指的是不再存在的旧版本的函数。

NT2

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

2年前的最新发布。

显然没有英文的文件,尽pipe据说法文在某个地方是有的。

不能在项目周围find一个社区的痕迹。

LAPACK&BLAS

好处:老而成熟。

缺点:

  • 像恐龙一样蹩脚的API

如果您正在寻找英特尔处理器上的高性能matrix/线性代数/优化,那么可以查看英特尔的MKL库。

MKL经过精心优化,可实现快速运行性能 – 其中大部分基于非常成熟的BLAS / LAPACK fortran标准。 它的性能随着可用内核的数量而变化。 可用内核的免提可扩展性是计算的未来,我不会使用任何math库,因为新项目不支持多核处理器。

简而言之,它包括:

  1. 基本的vectorvector,vectormatrix和matrixmatrix运算
  2. matrix分解(LU分解,厄密,稀疏)
  3. 最小二乘拟合和特征值问题
  4. 稀疏线性系统求解器
  5. 非线性最小二乘法求解器(信赖区域)
  6. Plus信号处理例程,如FFT和卷积
  7. 非常快的随机数发生器(mersenne twist)
  8. 更多….请参阅: 链接文本

缺点是MKL API可能相当复杂,具体取决于您需要的例程。 你也可以看看他们的IPP(综合性能原语)库,它是面向高性能的image processing操作,但相当广泛。

保罗

CenterSpace软件,.NETmath库,centerspace.net

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

特征优点:1.完全独立 – 不依赖外部BLAS或LAPACK。 2.文件体面。 据说很快,尽pipe我还没有做好testing。

缺点:QRalgorithm只返回一个matrix,Rmatrixembedded在上三angular形中。 不知道matrix的其余部分来自哪里,没有Qmatrix可以被访问。

犰狳优点:1.广泛的分解和其他function(包括QR)。 2.合理的速度(使用expression式模板),但我再也没有真正把它推到高维度。

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

如果开放源代码库是独立和直接使用的将是很好的。 我已经遇到了同样的问题已经有10年了,这让人感到沮丧。 有一次,我用C语言的GSL编写了C ++包装器,但是现代的C ++ – 特别是使用expression式模板的优点 – 我们不应该在21世纪弄乱C语言。 只是我的tuppencehapenny。

我听说过Eigen和NT2的好东西,但是还没有亲自用过。 还有Boost.UBLAS ,我相信这会让牙齿变得有点长。 NT2的开发者正在构build下一个版本,目的是将其join到Boost中,以便可以计算出一些东西。

我的林。 ALG。 需求不超出4×4matrix的情况,所以我不能评论先进的function; 我只是指出了一些select。