不将库用于标准数值算法是否很常见,为什么?

计算科学 图书馆 C
2021-12-04 19:32:43

许多数值算法(积分、微分、插值、特殊函数等)在GSL等科学计算库中可用。但我经常看到这些函数的“手动”实现的代码。对于不一定用于公共分发的小程序,计算科学家的常见做法是在需要时自己实现数值算法(我的意思是从网站、数值食谱或类似网站复制或转录)?如果是这样,是否有特别的理由避免链接到 GSL 之类的东西,或者它只是比其他任何东西都更“传统”?

我问是因为我是代码重用的忠实粉丝,这表明我应该尽可能尝试使用现有的实现。但我很好奇是否有理由认为原则在科学计算中的价值不如在一般编程中的价值。


忘了提一下:我特别问的是 C 和 C++,而不是像 Python 这样的语言,使用库有明显的好处(执行速度)。

4个回答

我曾经自己实现一切,但最近开始更多地使用库。我认为使用库有几个非常重要的优势,不仅仅是你是否必须自己编写例程的问题。如果你使用图书馆,你会得到

  • 经过数百/数千/更多用户测试的代码
  • 未来将继续更新改进的代码,无需您进行任何工作
  • 优化后的代码比您第一次尝试编写的代码更高效且可能更具可扩展性
  • 根据库的不同,通过在代码中建立与它的接口,您可以访问许多您当前不使用但将来可能想要使用的算法

在上面的最后一个要点中,我正在考虑像TrilinosPETSc这样的大型库。我可以通过PyClaw开发中的几个具体的个人示例来加强这一点尽管将Clawpack与 MPI 调用并行化很简单,但我们选择使用 PETSc。这使我们能够将包中的并行代码限制为少于 300 行 Python,但更好的是,通过将我们的数据以 PETSc 的格式放置,我们可以立即访问 PETSc 的隐式求解器,从而启用 PyClaw 中隐式求解器的当前工作。作为第二个例子,PyClaw 最初包括手动编码五阶 WENO 重建,但我们最终决定依赖PyWENO包这个。这是一个巨大的收获,因为 PyWENO 可以自动生成多种语言的任何顺序的 WENO 例程。

最后,如果您使用库,您可以通过开发改进或发现错误来回馈他人,这将使许多其他人受益,而调试或改进自己的代码只会使您受益。

链接到库函数会涉及大量程序员开销,特别是如果该库对程序员来说是新的。重写简单的算法通常比找出特定库的细节更简单。随着算法变得更加复杂,这种行为会发生变化。

Python 擅长使用 pip/easy_install 等工具和统一的数据结构接口(即每个库似乎都采用并生成一个 numpy 数组)来减少这种开销。

我现在参与的一个项目是为一类粒子物理探测器编写一个灵活的模拟和分析包。该项目的目标之一是提供在未来几十年用于这些事物的代码库。

在这一点上,我们已经有两打依赖项,这使得构建过程变得如此噩梦,以至于它从费米实验室计算中心剥离了一个单独的项目,只是为了提供一个可靠的工具链。

现在想象一下,您需要一些不在该工具链中的工具(上个月刚刚发生在我身上)。你有三个选择

  1. 滚动你拥有。伴随着所有涉及的风险和麻烦。
  2. 从某处的库中抓取一些代码并将其包含在项目中。这意味着您必须继续进行维护,并且在发生这种情况时您必须了解其他人的代码。
  3. 去找维护工具链的人,向他们请求你需要的东西,然后等待发布周期来获得它。这些人反应灵敏,但是您必须在没有工作代码完成 (1) 或 (2) 之后为其提供理由。

很容易选择(1)。也许太容易了。

我认为这常见,有些算法比其他算法更有可能被重新实现。

在安装一个库有多烦人、自己实现算法有多难、优化它有多难以及库如何满足您的需求之间存在一个棘手的权衡。此外,有时使用库只是矫枉过正:我在我的一个程序中使用了慢速二分算法,因为我只调用了几次并且我不想为此添加库。

你写一个优化好的版本容易吗?如果是的话,你最好还是这样做。你会得到你所需要的,你不会依赖任何人的工作。但是当然你真的需要知道你在做什么:即使是简单的算法也很难实现。

我很想看到这方面的研究,但从我有偏见的角度来看,科学家们经常使用用于线性代数和随机数生成器的库,剩下的大部分代码都是自制的。