java - 获取双变量函数的梯度

标签 java math apache-commons-math

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

f(x,y)=矩阵[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); 
        }
    }
  • 使用 xs,作为 x 索引的排序数组(0,1,...,matrix.getRowDimension() - 1)
  • 列维度相同(0,1,...,matrix.getColumnDimension() - 1)

问题是,对于 150X80 大小的典型矩阵,运行需要多达 1.4 秒,这使其与我的需求完全无关。因此,作为这个库的新手用户,以及一般的编程数值分析,我想知道:

  1. 我做错了什么吗?
  2. 还有其他更快的方法可以完成这项任务吗?
  3. 是否有另一个开源库(最好是 Maven 友好的)可以提供解决方案?

最佳答案

数值微分本身就是一个完整的主题,简单的谷歌应该会为您提供足够的 Material 供您使用(仅维基百科就足够了)。我不知道你的问题的一些参数,所以我只能在这里泛泛地说,但是有一些直接的方法可以确定给定点的梯度,即不需要插值的方法。有关公式,请参阅维基百科(范围从简单的 f(x+1)-f(x)(其中 h=1)到更高阶的公式) 。计算偏导数是一个简单的 O(NM) 循环,内部有一个 super 简单的公式(不需要插值)。

具体细节可能会很棘手:

  1. 需要针对边缘减少高阶公式,或者 完全丢弃。
  2. 您的精确速度要求可能会使更复杂的公式变得无用(取决于平台,有时高阶公式的查找时间会使它们太慢;同样,这取决于缓存等)。这个很容易测试,公式也简单;对它们进行编码并进行基准测试。
  3. 具体实现还取决于您的错误要求。该理论提供了误差范围,因此它将在您需要什么公式时发挥作用;但同样,速度要求也需要权衡。如果您知道要处理的矩阵类型的具体情况(如果已知的话),则实际上可以降低该值。

如果您有现有的卷积工具,那么实现会更容易(也许更快),因为这种方法实际上只是矩阵的卷积(注意;技术上称为互相关)。

关于java - 获取双变量函数的梯度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14402605/

相关文章:

java - 将对象转换为数组 [Java]?

javascript - 如何将最内矩形移到最外矩形内

java - 使用 Apache Commons Math 确定置信区间

android - Commons Math - 找不到类 org.apache.commons

ios - 为 iOS 或替代品编译 Apache 通用数学

java - Spring boot Gradle 不生成包装器并且不生成可运行的 jar

Spring中基于Java的依赖注入(inject)

java - 数组洗牌(具有相同的开始值和结束值)

haskell - 类型的标识是什么?

python - 如何计算矩阵的协方差?