似乎许多项目慢慢需要进行矩阵数学运算,并陷入首先构建一些向量类并缓慢添加功能的陷阱,直到它们被捕获构建一个半定制的自定义线性代数库,并且依赖于在上面。
我想避免这种情况,而不依赖于某些与切向相关的库(例如OpenCV,OpenSceneGraph)。
那里常用的矩阵数学/线性代数库是什么,为什么决定使用另一个?有什么建议不要因某些原因使用?我特意在几何/时间上下文*(2,3,4 Dim)*中使用它,但将来可能会使用更高维数据。
我正在寻找以下任何方面的差异:API,速度,内存使用,广度/完整性,狭隘/特异性,可扩展性和/或成熟度/稳定性。
我最终使用了Eigen3,我非常满意。
答案 0 :(得分:105)
为此,有很多项目已经确定Generic Graphics Toolkit。那里的GMTL非常好 - 它非常小,非常实用,并且被广泛使用,非常可靠。 OpenSG,VRJuggler和其他项目都转而使用它而不是自己的手动滚动/矩阵数学。
我发现它非常好 - 它通过模板完成所有工作,所以它非常灵活,速度非常快。
编辑:
在评论讨论和编辑之后,我想我会抛出一些关于具体实施的好处和缺点的更多信息,以及为什么你可以根据你的情况选择一个而不是另一个。
GMTL -
优点:简单的API,专为图形引擎而设计。包括许多面向渲染的原始类型(例如平面,AABB,具有多个插值的quatenrions等),这些类型不在任何其他包中。内存开销非常低,速度非常快,易于使用。
缺点:API非常专注于渲染和图形。不包括通用(NxM)矩阵,矩阵分解和求解等,因为它们不在传统图形/几何应用领域。
Eigen -
好处:Clean API,相当容易使用。包括带有四元数和几何变换的Geometry module。内存开销低。完整的,highly performant求解大型NxN矩阵和其他通用数学例程。
缺点:可能比你想要的范围更广(?)。与GMTL相比较少的几何/渲染特定例程(即:欧拉角定义等)。
IMSL -
好处:非常完整的数字库。非常非常快(据说是最快的解算器)。迄今为止最大,最完整的数学API。商业支持,成熟和稳定。
下行:成本 - 并不便宜。很少有几何/渲染特定的方法,所以你需要在它们的线性代数类之上自己动手。
NT2 -
好处:如果您习惯使用MATLAB,则提供更熟悉的语法。为大型矩阵等提供完全分解和求解。
下行:数学,而不是重点。可能不像Eigen那样高效。
LAPACK -
优点:非常稳定,经过验证的算法。已经很久了。完整的矩阵求解等。模糊数学的许多选项。
缺点:在某些情况下表现不佳。从Fortran移植,使用奇怪的API。
就我个人而言,它归结为一个问题 - 你打算如何使用它。如果你专注于渲染和图形,我喜欢Generic Graphics Toolkit,因为它表现良好,并支持许多有用的渲染操作,而无需实现自己的渲染。如果你需要通用矩阵求解(即:大矩阵的SVD或LU分解),我会选择Eigen,因为它处理它,提供一些几何运算,并且对大矩阵解决方案非常有效。您可能需要编写更多自己的图形/几何操作(在它们的矩阵/向量之上),但这并不可怕。
答案 1 :(得分:32)
所以我是一个非常挑剔的人,如果我打算投资一个图书馆,我会更清楚自己是在做什么。我认为,在仔细审查时,最好是对批评和对奉承的谴责;它的错误对未来有更多的影响而不是正确的。所以我会在这里稍微过一点,提供一些可以帮助我的答案,我希望能帮助那些可能沿着这条道路走下去的人。请记住,这是基于我对这些库所做的很少的审查/测试。哦,我从里德那里偷走了一些积极的描述。
我会提到我用GMTL去的顶部,尽管它的特质是因为Eigen2的不安全性太大了。但我最近了解到,Eigen2的下一个版本将包含将关闭对齐代码并使其安全的定义。所以我可以转换。
更新:我已切换到Eigen3。尽管它具有特殊性,但它的范围和优雅都难以忽视,并且可以通过定义来关闭使其不安全的优化。
好处: LGPL MPL2,干净,设计精良的API,相当容易使用。似乎与充满活力的社区保持良好的关系。内存开销低。高性能。适用于一般线性代数,但也有良好的几何功能。所有标题库,无需链接。
Idiocyncracies / downsides: (当前开发分支 Eigen3中可用的某些定义可以避免部分/全部
优点:LGPL,Fairly Simple API,专为图形引擎而设计。 包括许多适合渲染的原始类型(例如 飞机,AABB,具有多个插值的quatenrions等) 没有任何其他包裹。内存开销非常低,非常快, 使用方便。所有标题均基于,无需链接。
Idiocyncracies /缺点:
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()
无法分辨,因为他们似乎对其网页的分形图像标题比内容更感兴趣。看起来更像是一个学术项目,而不是一个严肃的软件项
2年前的最新版本。
显然没有英文文档,虽然据说某处有法语版本。
无法找到项目周围社区的踪迹。
好处:古老而成熟。
缺点:
答案 2 :(得分:11)
如果您正在寻找英特尔处理器上的高性能矩阵/线性代数/优化,我会看看英特尔的MKL库。
MKL经过精心优化,具有快速的运行时间性能 - 大部分基于非常成熟的BLAS / LAPACK fortran标准。其性能随可用内核数量而变化。具有可用内核的免提可扩展性是计算的未来,我不会将任何数学库用于新项目,也不支持多核处理器。
非常简短,它包括:
缺点是MKL API可能非常复杂,具体取决于您需要的例程。您还可以查看他们的IPP(Integrated Performance Primitives)库,该库面向高性能图像处理操作,但是相当广泛。
保罗CenterSpace Software,.NET Math libraries,centerspace.net
答案 3 :(得分:11)
为了它的价值,我已经尝试了Eigen和Armadillo。以下是一个简短的评估。
本征 好处: 1.完全独立 - 不依赖于外部BLAS或LAPACK。 2.文件体面。 虽然我还没有对它进行测试,但据称速度很快。
缺点: QR算法仅返回单个矩阵,R矩阵嵌入在上三角形中。不知道矩阵的其余部分来自何处,也无法访问Q矩阵。
犰狳 好处: 1.广泛的分解和其他功能(包括QR)。 2.合理快速(使用表达模板),但同样,我还没有把它推到高维度。
缺点: 1.取决于外部BLAS和/或LAPACK以进行矩阵分解。 2.文档缺少恕我直言(除了更改#define语句之外,还包括LAPACK的具体内容)。
如果有一个自包含且易于使用的开源库,那将会很不错。我已经遇到了同样的问题已有10年了,而且令人沮丧。有一次,我使用GSL for C并在其周围编写了C ++包装器,但是使用现代C ++ - 特别是利用表达模板的优点 - 我们不应该在21世纪弄乱C语言。只是我的tuppencehapenny。
答案 4 :(得分:8)
我听说过有关Eigen和NT2的好消息,但还没有亲自使用过。还有Boost.UBLAS,我认为这有点长。 NT2的开发人员正在构建下一个版本,目的是将其纳入Boost,因此这可能算是事情。
我的林。 ALG。需求不超出4x4矩阵的情况,所以我不能评论高级功能;我只是指出了一些选择。
答案 5 :(得分:8)
我是这个话题的新手,所以我不能说很多,但BLAS几乎是科学计算的标准。 BLAS实际上是一个API标准,它有许多实现。老实说,我不确定哪种实现最受欢迎或为什么。
如果您还希望能够进行常见的线性代数运算(求解系统,最小二乘回归,分解等),请查看LAPACK。
答案 6 :(得分:6)
GLM怎么办?
它基于OpenGL着色语言(GLSL)规范,并在MIT许可下发布。 明确针对图形程序员
答案 7 :(得分:5)
我将为Eigen添加投票:我将大量代码(3D几何,线性代数和微分方程)移植到不同的库中 - 几乎在所有情况下都提高了性能和代码可读性。
未提及的一个优点:使用带有Eigen的SSE非常容易,这显着提高了2D-3D操作的性能(所有内容都可以填充到128位)。
答案 8 :(得分:4)
好的,我想我知道你在找什么。看来GGT是一个非常好的解决方案,正如Reed Copsey建议的那样。
就个人而言,我们推出了自己的小型图书馆,因为我们经常处理理性点 - 很多理性的NURBS和Beziers。
事实证明,大多数3D图形库都使用在投影数学中没有基础的投影点进行计算,因为这就是为您提供所需答案的原因。我们最终使用了Grassmann点,它具有坚实的理论基础并减少了点类型的数量。 Grassmann点基本上与人们现在使用的计算相同,具有强大的理论。最重要的是,它使我们的思想更加清晰,因此我们减少了错误。罗恩·戈德曼(Ron Goldman)写了一篇关于计算机图形学中格拉斯曼点的文章"On the Algebraic and Geometric Foundations of Computer Graphics"。
与您的问题没有直接关系,但是有趣的阅读。
答案 9 :(得分:0)
答案 10 :(得分:0)
我发现这个库非常简单和实用(http://kirillsprograms.com/top_Vectors.php)。这些是通过C ++模板实现的裸骨矢量。没有花哨的东西 - 只是你需要做的向量(加,减乘,点等)。