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

发布于 2024-08-04 02:24:26 字数 1539 浏览 7 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

乙白 2024-08-11 02:24:26

为此,有相当多的项目选择了通用图形工具包。那里的 GMTL 很好 - 它非常小,功能强大,并且被广泛使用,非常可靠。 OpenSG、VRJuggler 和其他项目都已转而使用它,而不是他们自己的手动向量/矩阵数学。

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


编辑:

在评论讨论和编辑之后,我想我应该抛出一些有关特定实现的优点和缺点的更多信息,以及考虑到您的情况,为什么您可能会选择其中一种。

GMTL -

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

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

Eigen -

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

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

IMSL -

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

缺点:成本——不便宜。很少有几何/渲染特定的方法,因此您需要在线性代数类的基础上推出自己的方法。

NT2 -

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

缺点:数学性强,不以渲染为重点。可能不如 Eigen 性能好。

LAPACK -

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

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

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

There are quite a few projects that have settled on the Generic Graphics Toolkit for 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.

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.

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.

Eigen -

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

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).

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.

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 -

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

Downsides: Mathematical, not rendering focused. Probably not as performant as 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.

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.

苦妄 2024-08-11 02:24:26

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

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

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

Eigen2/Eigen3

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

独特之处/缺点:(可以通过当前开发分支 Eigen3中的一些定义来避免其中一些/所有)

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

GMTL

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

独特之处/缺点:

  • API 很古怪
    • 另一个库中的 myVec.x() 只能通过 myVec[0] 获得(可读性问题)
      • 点的数组或 stl::vector 可能会导致您执行类似pointsList[0][0] 的操作来访问第一个点的 x 分量
    • 在一次天真的优化尝试中,删除了 cross(vec,vec) 和
      当编译器消除时替换为 makeCross(vec,vec,vec)
      无论如何不必要的临时工
    • 正常的数学运算不会返回正常类型,除非你关闭
      关闭一些优化功能,例如:vec1 - vec2 不返回
      法向量,因此即使 vecC = vecA - length( vecA - vecB ) 也会失败
      vecB 有效。您必须像这样换行:length( Vec( vecA - vecB ) )
    • 向量上的操作是由外部函数提供的,而不是
      成员。这可能需要您在任何地方都使用范围解析
      因为常见的符号名称可能会发生冲突
    • 你必须做
        length( makeCross( vecA, vecB ) )

       gmtl::length( gmtl::makeCross( vecA, vecB ) )
      否则你可以尝试什么
        vecA.cross( vecB ).length()


  • 维护得不好
    • 仍声称为“测试版”
    • 文档缺少基本信息,例如需要哪些标头
      使用正常功能

      • Vec.h 不包含向量的操作,VecOps.h 包含
        例如,有些,其他在Generate.h中。交叉(vec&,vec&,vec&) in
        VecOps.h,Generate.h 中的 [make]cross(vec&,vec&)
  • API不成熟/不稳定;仍在变化。
    • 例如,“cross”已从“VecOps.h”移至“Generate.h”,并且
      然后名称改为“makeCross”。文档示例失败
      因为仍然引用不再存在的旧版本函数。

NT2

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

2年前的最新版本。

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

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

拉帕克BLAS的

优点:年老、成熟。

缺点:

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

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.

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.

Eigen2/Eigen3

Benefits: LGPL MPL2, 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.

Idiocyncracies/downsides: (Some/all of these can be avoided by some defines that are available in the current development branch 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)

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.

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 - vec2 does not return a
      normal vector so length( vecA - vecB ) fails even though vecC = vecA -
      vecB
      works. 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()
  • 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
  • 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.

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.

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

Benefits: Old and mature.

Downsides:

  • old as dinosaurs with really crappy APIs
揽清风入怀 2024-08-11 02:24:26

就其价值而言,我尝试过 Eigen 和 Armadillo。下面简单评价一下。

本征
优点:
1. 完全独立——不依赖外部BLAS或LAPACK。
2. 文档得体。
3.据说速度很快,虽然我还没有测试过。

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

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

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

如果有一个独立且易于使用的开源库,那就太好了。十年来我一直遇到同样的问题,这让人沮丧。曾经,我将 GSL 用于 C,并围绕它编写了 C++ 包装器,但是有了现代 C++——尤其是使用表达式模板的优势——我们不应该在 21 世纪与 C 发生冲突。只是我的两便士。

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

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.

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.

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.

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).

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.

ゃ懵逼小萝莉 2024-08-11 02:24:26

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

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

简单来说,它包括:

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

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

Paul

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

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

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.

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

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.

Paul

CenterSpace Software ,.NET Math libraries, centerspace.net

倾城°AllureLove 2024-08-11 02:24:26

GLM 怎么样?

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

What about GLM?

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

兮颜 2024-08-11 02:24:26

我听说过关于 EigenNT2,但个人也没有使用过。还有 Boost.UBLAS,我相信牙齿已经有点长了。 NT2 的开发人员正在构建下一个版本,目的是将其纳入 Boost,因此这可能会有所作为。

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

I've heard good things about Eigen and 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.

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.

聆听风音 2024-08-11 02:24:26

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

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

I'm new to this topic, so I can't say a whole lot, but BLAS is 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.

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

独享拥抱 2024-08-11 02:24:26

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

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

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.

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).

痴意少年 2024-08-11 02:24:26

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

就个人而言,我们推出了自己的小库,因为我们经常处理理性点 - 很多理性 NURBS 和贝塞尔曲线。

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

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

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

Personally, we rolled our own little library, because we deal with rational points a lot - lots of rational NURBS and 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".

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

千柳 2024-08-11 02:24:26

FLENS

http://flens.sf.net

也实现了很多LAPACK的功能。

FLENS

http://flens.sf.net

It also implements a lot of LAPACK functions.

情独悲 2024-08-11 02:24:26

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

I found this library quite simple and functional (http://kirillsprograms.com/top_Vectors.php). These are bare bone vectors implemented via C++ templates. No fancy stuff - just what you need to do with vectors (add, subtract multiply, dot, etc).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文