帮助编写软件:一般准则,特别是计算和可视化的分离

计算科学 软件 可视化 效率 绘图
2021-12-03 19:53:57

虽然我已经在理论和模拟的交叉领域做了一些工作,但我对这个领域还是很陌生,我需要一些指导。如果有人可以就有关计算科学的介绍性文献以及如何规划科学软件提供一些建议,我将不胜感激。下面是一些更具体的问题。

在我的论文工作期间,我做过并且仍在做量子力学系统的数值模拟,我遇到了以下问题。基本上,这些模拟的三个重要步骤是:求解 ODE 系统,使用该解决方案计算物理可观察量,以及绘制可观察量。我的第一个问题是,在编写软件时,分离这些步骤的最佳实践是什么?程序应该执行所有这些步骤,还是在不同脚本之间划分步骤并在其间保存数据更好?

我担心的是我目前的方法混乱且效率不高。我的第一个脚本一次完成了所有步骤。当 ODE 求解器花费大量时间来求解时,我更改了脚本以保存原始解以供以后使用。我目前的方法是一次性计算解决方案和感兴趣的数量,并将数据保存到文本文件中。绘图由单独的脚本完成。目前,修改一个数字大约需要 0.5-3 小时,恕我直言,这非常慢。

由于参数很多,所以选择哪些变量是固定的、哪些是可变的、x轴是什么等等都有很大的空间。这导致我编写了许多小脚本,每个脚本都针对参数空间的特定区域和特定的 observables 选择而定制,这随后导致了复杂且碎片化的文件夹和文件结构。这是一种好的风格还是应该选择编写涵盖所有可能情况和可观察的程序?

2个回答

我的第一个问题是,在编写软件时,分离这些步骤的最佳实践是什么?程序应该执行所有这些步骤,还是在不同脚本之间划分步骤并在其间保存数据更好?

如何分离这些步骤取决于很多因素,例如求解 ODE 需要多长时间、您使用的软件环境等。

一般来说,在保持生产力的同时,让事情尽可能简单。如果您在 MATLAB 或 Python 中编写 ODE 求解器代码,只要 ODE 求解速度不会慢到令人无法接受的程度,那么将可视化步骤保持在同一个脚本中是相当容易的。在编译语言中,通常更容易编写输出然后使用第三方绘图工具。

我担心的是我目前的方法混乱且效率不高。我的第一个脚本一次完成了所有步骤。当 ODE 求解器花费大量时间来求解时,我更改了脚本以保存原始解以供以后使用。我目前的方法是一次性计算解决方案和感兴趣的数量,并将数据保存到文本文件中。绘图由单独的脚本完成。目前,修改一个数字大约需要 0.5-3 小时,恕我直言,这非常慢。

这种迭代方法正是您应该做的。作为第一次 hack,一次完成所有步骤是有意义的。这就像一份文件的初稿;将所有内容都写在代码中可以帮助您了解需要做什么以及可以改进什么。有时,一些设计工作可以提前完成,但总的来说,无论写什么都需要修改。

由于参数很多,所以选择哪些变量是固定的、哪些是可变的、x轴是什么等等都有很大的空间。这导致我编写了许多小脚本,每个脚本都针对参数空间的特定区域和特定的 observables 选择而定制,这随后导致了复杂且碎片化的文件夹和文件结构。这是一种好的风格还是应该选择编写涵盖所有可能情况和可观察的程序?

我想说,一般来说,选择适合你的工具。如果您发现您正在编写的许多脚本都是剪切和粘贴的,这可能表明您可以使您的脚本更通用。

你知道一些关于 scicomp 或设计科学软件的文献吗?

Software Carpentry维护一个建议材料的列表我已经阅读了一些建议的作品(例如,Code Complete)并发现它们很有帮助。一些资源更侧重于一般的软件工程,并且很有用,因为它们传授了软件工程师在最佳实践方面的数十年经验。一本可能有用的书是《编写科学软件:良好风格指南》

(免责声明:我教过两次软件木工研讨会。)

程序应该执行所有这些步骤,还是在不同脚本之间划分步骤并在其间保存数据更好?

将它们分开。

考虑集成模拟(求解 ODE)和分析的原因是避免将数据写入磁盘然后重新加载以进行分析。如果您的 ODE 难以求解(超过 O(N))并且您定期更改分析,则从磁盘加载旧结果将比重新生成新结果快得多。

这是一种好的风格还是应该选择编写涵盖所有可能情况和可观察的程序?

您的工具应该有多宽或多窄取决于具体情况。特别是,它取决于:

  • 你想做什么
  • 您正在使用哪些 3rd 方程序/库(gnuplot、matplotlib 等)
  • 你是多么优秀的程序员

您应该尝试在投入时间构建使您的科学更容易的工具和进行实际科学之间取得平衡。如果您更愿意编写相对大量的专用工具,那并没有错。另一方面,如果您可以花 5 分钟概括一个绘图脚本,以消除其他 10 个脚本并节省您的时间,那么您应该这样做。