测试数学导向方法的正确性

时间:2014-11-01 21:30:41

标签: unit-testing math testing

我正在实施二维Lanczos插值算法,我刚刚完成。作为现代绅士,在我向公众发布这种方法之前,我想对它进行单元测试。但是,与一般方法相比,我总是发现单元测试数学方法非常困难。

正如有些人所知,lanczos插值的结果取决于多个因素,即插值的值和目标 x 值。这使得很难像常规方法那样测试“已知的角落情况”等。

我想到的一件事是采用Lanczos插值的另一个实现,然后取一些随机值并计算它们,看看结果是否相同,但这使我依赖于另一个库的正确性。

任何人都有任何提示或可以将我推荐给任何文献?

编辑:这是代码:

private val Radius = 3 // Taken from GDAL

private def lanczos(v: Double) =
    if (v == 0) 1
    else if (math.abs(v) > 0 && math.abs(v) < Radius)
      (Radius * math.sin(math.Pi * v) *
        math.sin(math.Pi * v / Radius) / math.pow(math.Pi * v, 2))
    else 0

override def cubicInterpolation(
    p: Array[Array[Double]],
    x: Double,
    y: Double): Double = {
    val xs = x.toInt - Radius + 1
    val xe = x.toInt + Radius

    val ys = y.toInt - Radius + 1
    val ye = y.toInt + Radius

    var accum = 0.0

    for (i <- xs to xe; j <- ys to ye) {
       accum += p(i)(j) * lanczos(y - j) * lanczos(x - i)
    }

    accum
}

谢谢,

约翰

3 个答案:

答案 0 :(得分:1)

一些想法。

(1)您可以直接从定义计算结果,如计算机代数系统所示。例如。写S(X, y) = sum(sum(s[i, j] * L(x - i) * L(y - j), j, floor(y) - a + 1, floor(y) + a), i, floor(x) - a + 1, floor(x) + a)(根据维基百科;也许你正在使用不同的定义),然后用它来计算预期的结果。这个想法是这种方法从人类阅读公式到计算机代码有一个较短的飞跃,此后可能是一个更可靠的翻译。我会倾向于使用Maxima,因为我对它很熟悉,但你也可以使用Sympy或Maple等。如果你沿着这条路走下去需要一些Maxima的帮助,我'我很乐意帮忙。

(2)是否存在先验已知结果的案例?例如。有没有在这种变换下不变的函数?或者以一种众所周知的方式改变?例如。常数函数,线性函数,多项式,触发函数会发生什么?

答案 1 :(得分:0)

如果您不确定您的实施是否正确,则针对已知正确的来源编写测试(单元与否)听起来是个好主意。根据定义,这些测试不会进行单元测试,但在这种情况下,我不会关心它。

这就引出了一个问题:你为什么要为已经解决的问题编写自己的解决方案?如果你必须自己实现它,我想有很多单元测试要写。

你为什么不发布你的代码?

答案 2 :(得分:0)

  

我想到的一件事是采用Lanczos插值的另一个实现,然后取一些随机值并计算它们,看看结果是否相同(...)

这是你应该做的。实际上,这是您在其他单元测试时最有可能做的事情 - 您计算期望值并对其进行测试。不同的是,对于大多数单元测试,计算需要你的大脑或(最多)一些基本的计算器。

  

(...)但这使我依赖另一个图书馆的正确性

与其他所有测试案例一样。您依赖于正确确定方法流的能力,解析字符串和预测结果的能力,使用XPath查询XML的能力以及许多其他方法。这些是截止点 - 你认为它们是正确的并且不再深入挖掘。否则,我们最终都会陷入永无止境的测试螺旋。