获得双变量函数的梯度

时间:2013-01-18 15:52:56

标签: java math apache-commons-math

我正在进行一些视频处理,对于每个帧我需要获得双变量函数的渐变。 该函数表示为二维的双精度数组。其中domain是行和列索引,范围是相应索引值的double值。或者更简单地说,函数f是为double[][] matrix定义的:

f(x,y)=matrix[x][y]

我正在尝试使用Apache Commons Math库:

SmoothingPolynomialBicubicSplineInterpolator iterpolator = new SmoothingPolynomialBicubicSplineInterpolator();
BicubicSplineInterpolatingFunction f = iterpolator.interpolate(xs, ys, matrix.getData());
    for (int i = 0; i < ans.length; i++) {
        for (int j = 0; j < ans[0].length; j++) {
            ans[i][j] = f.partialDerivativeY(i, j); 
        }
    }
  • with xs,作为x indices (0,1,...,matrix.getRowDimension() - 1)
  • 的排序数组
  • 列维(0,1,...,matrix.getColumnDimension() - 1)
  • 上的内容相同

问题在于,对于大小为150X80的典型矩阵,运行时需要1.4秒,这使得它与我的需求完全无关。所以,作为这个库的新手用户,以及一般的程序化数值分析,我想知道:

  1. 我做错了吗?
  2. 我能用另一种更快的方式完成这项任务吗?
  3. 是否有其他开源库(最好是maven-friendly)提供解决方案?

1 个答案:

答案 0 :(得分:0)

数值差异本身就是一个完整的主题,一个简单的谷歌应该为你提供足够的材料(只需维基可能就足够了)。有一些我无法知道的问题参数,所以我只能在这里大致说一下,但是有一些直接的方法可以确定给定点的梯度,即不需要插值的梯度。有关公式,请参阅维基百科(范围从简单的f(x+1)-f(x),其中h=1到更高阶的公式。然后计算偏导数是一个简单的O(NM)循环,里面有一个简单的公式(不需要插值)。

具体细节可以得到坚定不移:

  1. 需要减少边缘的高阶公式,或 完全丢弃。
  2. 您的精确速度要求可能会使更复杂的公式无效(取决于平台,有时高阶公式的查找时间会使它们太慢;再次,它取决于缓存等)。这很容易测试,公式很简单;编码和基准。
  3. 具体实现还取决于您的错误要求。该理论提供了误差界限,因此它将在您需要的公式中发挥作用;但同样,还需要权衡速度要求。如果你知道你将要处理的矩阵类型的细节,如果知道这样的事情,那么反过来可以降低。
  4. 如果你有现有的卷积工具,实现可以更容易(也许更快),因为这种方法实际上只是矩阵的卷积(注意;技术上它称为互相关)。