dav*_*dsd 2 java performance interpolation scala spline
我用Java中的apache.commons.math 将这个样条插值算法转换成Scala,这是我能想到的最简单的方法(见下文).我最终运行的函数运行速度比原始Java代码慢2到3倍.我的猜测是问题源于来自调用的额外循环Array.fill,但我想不出一个直接的方法来摆脱它们.有关如何使此代码表现更好的任何建议?(以更简洁和/或更实用的方式编写它也会很好 - 在这方面的建议也会受到赞赏.)
type Real = Double
def mySplineInterpolate(x: Array[Real], y: Array[Real]) = {
if (x.length != y.length)
throw new DimensionMismatchException(x.length, y.length)
if (x.length < 3)
throw new NumberIsTooSmallException(x.length, 3, true)
// Number of intervals. The number of data points is n + 1.
val n = x.length - 1
// Differences between knot points
val h = Array.tabulate(n)(i => x(i+1) - x(i))
var mu: Array[Real] = Array.fill(n)(0)
var z: Array[Real] = Array.fill(n+1)(0)
var i = 1
while (i < n) {
val g = 2.0 * (x(i+1) - x(i-1)) - h(i-1) * mu(i-1)
mu(i) = h(i) / g
z(i) = (3.0 * (y(i+1) * h(i-1) - y(i) * (x(i+1) - x(i-1))+ y(i-1) * h(i)) /
(h(i-1) * h(i)) - h(i-1) * z(i-1)) / g
i += 1
}
// cubic spline coefficients -- b is linear, c quadratic, d is cubic (original y's are constants)
var b: Array[Real] = Array.fill(n)(0)
var c: Array[Real] = Array.fill(n+1)(0)
var d: Array[Real] = Array.fill(n)(0)
var j = n-1
while (j >= 0) {
c(j) = z(j) - mu(j) * c(j + 1)
b(j) = (y(j+1) - y(j)) / h(j) - h(j) * (c(j+1) + 2.0 * c(j)) / 3.0
d(j) = (c(j+1) - c(j)) / (3.0 * h(j))
j -= 1
}
Array.tabulate(n)(i => Polynomial(Array(y(i), b(i), c(i), d(i))))
}
Run Code Online (Sandbox Code Playgroud)
您可以摆脱所有Array.fill因为新数组始终使用0或null初始化,具体取决于它是值还是引用(布尔值初始化为false,字符为\0).
您可以通过压缩数组来简化循环,但是只会让它变慢.函数编程(无论如何在JVM上)的唯一方法是帮助你加快速度,如果你把它变得非常严格,比如使用a Stream或view,那么你就继续使用它而不是全部使用它.
| 归档时间: |
|
| 查看次数: |
1218 次 |
| 最近记录: |