2014-11-01 53 views
2

我正在實施二維Lanczos插值算法,我剛剛完成。作爲現代的紳士,在我向公衆發佈此方法之前,我想單元測試它。然而,與一般方法相比,我總是發現單元測試數學方法非常困難。測試數學導向方法的正確性

正如有些人所知,lanczos插值的結果取決於多種事物,包括您要插值的值和目標值。這樣就很難測試「已知角落案例」等,就像你使用常規方法一樣。

我想過的一件事是採取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 
} 

感謝,

約翰

+0

無論是否需要外部庫,您總是依賴於測試的正確性。 – 2014-11-01 21:32:33

+0

這是真的。但是如果您想用多個輸入參數測試一個數學方法,而您找不到任何清晰的*角落案例*,我該如何決定測試參數?我如何有效地測試它們? – 2014-11-01 21:36:54

+1

嗯,我想單元測試的目的是(a)文檔,和(b)幫助你確定你的代碼是否正確,(c)在未來維護期間防止迴歸。你的代碼有哪些失敗模式? – 2014-11-01 21:38:37

回答

0

一件事是採取蘭克澤斯插值的另一種實現方式,然後採取一些隨機值,並計算出它們,看看結果是相同的(...)

這是你應該做的。事實上,這是您在其他單元測試時最有可能做的 - 您計算預期值並對它們進行測試。不同的是,對於大多數單元測試來說,計算需要你的大腦或(最多)一些基本的計算器。

(...),但是這讓我依賴於其他庫的正確性

正如所有其他測試用例。您取決於您​​正確確定方法流程的能力,解析字符串和預測結果的能力,使用XPath和許多其他方法查詢XML的能力。這些都是切入點 - 你認爲它們是正確的,並停止深入挖掘。否則,我們都會以無盡的測試螺旋結束。

+0

謝謝,你是對的,否則總會有一個參考點必須是正確的。 – 2014-11-01 23:02:20

0

如果你不知道,如果你的實現是正確與否,編寫測試(單元與否)反對已知的正確源代碼聽起來像是個好主意。根據定義,這些測試不會是單元測試,但在那種情況下,我不會在意這一點。

這種問題導致了這樣一個問題:你爲什麼要爲已解決的問題編寫自己的解決方案?如果你必須自己實現它,我想有很多單元測試可以寫出來。

你爲什麼不發佈你的代碼?我曾想過

+0

嗨,我已經發布我的代碼。問題在於它在Scala中,我不想僅爲此引入巨大的依賴關係,順便說一下,我沒有在Scala中找到任何lanczos插值實現。 – 2014-11-01 22:17:44

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)有沒有先驗知道結果的情況?例如。這種變換下的函數是不變的嗎?或者可能以一種衆所周知的方式改變?例如。常數函數,線性函數,多項式,三角函數會發生什麼?

+0

在過去幾天裏,我已經實現了許多不同的插值,除了Lanczos插值之外,所有插值都有一個穩定的MATLAB實現來比較,或者像每手計算一樣簡單。我一直在想這個,順便說一下,我使用維基百科公式,我只是覺得我可以在我編寫的其他代碼中犯錯誤,即使* I *認爲它看起來與定義相同。正如其他答案中所建議的那樣,我寧願採取完全成熟的實現方式,並生成一個數據源來與之比較。雖然謝謝! – 2014-11-02 09:52:22