测试导数近似

计算科学 测试
2021-12-24 16:37:30

我正在编写一个涉及变分微积分问题的一些近似值的库。每当我实施例程来评估动作函数的导数或 HessianA,我写了一个测试来检查这些是否正常工作。为此,我评估了使用动作的一阶和二阶导数计算目标函数的局部二次逼近的误差:

E=A(u+δv)(A(u)+δdA(u)v+12δ2(d2A(u)v)v)

并检查E/δ3不为δ=21,,2N对于一些足够大的N.

这适用于中等大小N(最多 16 个左右),但对于N太大,截断误差开始占主导地位,近似误差变得更糟。

面对截断误差,测试导数近似的好方法是什么?

在我看来,我只有不好的选择:

  1. 编写打印近似误差的测试的初始版本,找到N截断错误接管,然后使用这个N作为单元测试最终版本的截止点。
  2. 有某种方法可以自动诊断截断错误接管的位置,然后丢弃所有结果。
  3. 不要让我的单元测试返回失败,除非它真的很明显。绘制结果并让用户决定。
  4. 通过分析确定可能发生截断错误的位置。

我不喜欢选项 1,因为这感觉就像是在挑选我的测试以便它们通过。我不喜欢选项 2,因为真正失败的实现的固有数学错误可能会被错误地评估为截断错误,因此自动回归测试会错过该错误。以这种速度,我必须手动检查结果,在这种情况下,我不妨选择选项 3。但我不喜欢选项 3,因为我想要自动化测试。我认为选项 4 对于单个变量的函数是实用的——评估ϵ|f(x)/f(x)|其中是机器 epsilon 为您提供了一个很好的上限 - 但对于未知数是具有数千个变量的字段的大型 PDE 问题,不是那么多。ϵ

1个回答

好吧,我可以告诉你我在做什么,但这有点不令人满意。

  1. 使用检查 u) 。我更喜欢四阶有限差分方案,但我检查与近似值dA(u)A(u)dA(u)δu

dA(u)δuA(u2ϵδu)8A(uϵδu)+8A(u+ϵδu)A(u+2ϵδu)12

  1. 一旦我们知道是准确的,检查与近似值 这和上面没有什么不同,除了我们现在有一个向量而不是一个标量,所以误差是用范数而不是绝对值计算的。dA(u)d2A(u)δu
    d2A(u)δudA(u2ϵδu)8dA(uϵδu)+8dA(u+ϵδu)dA(u+2ϵδu)12

正如您上面提到的,很难知道何时在截断和舍入错误之间切换。因此,我对的几个值运行它并寻找两件事ϵ

  1. 的近似最小误差达到可接受的水平ϵ

  2. 的值减小,误差会出现从高到低到高的曲线ϵ

在单元测试中,我通常只使用 1。当手动验证函数时,我会寻找 2。从技术上讲,1 可能会导致错误的通过,以防万一我们走运而一切都取消了。我从来没有见过这种情况,所以我不担心。