Получение градиента двухвариантной функции
Я делаю некоторую обработку видео, для каждого кадра мне нужно получить градиент функции бивариата. Функция представлена в виде двумерного массива значений типа 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);
}
}
- с хз, как отсортированный массив х индексов
(0,1,...,matrix.getRowDimension() - 1)
- То же самое в измерении столбцов
(0,1,...,matrix.getColumnDimension() - 1)
Проблема в том, что для типичной матрицы размером 150X80
это занимает столько же, сколько 1.4
секунд, чтобы бежать, что делает его совершенно неуместным для моих нужд. Итак, как начинающий пользователь этой библиотеки и программного числового анализа в целом, я хочу знать:
- Я делаю что-то неправильно?
- Есть ли другой, более быстрый, способ, которым я могу выполнить эту задачу?
- Есть ли еще одна библиотека с открытым исходным кодом (предпочтительно maven-friendly), которая предлагает решение?
1 ответ
Числовое разграничение - это целая тема, простой гугл должен собрать достаточно материала, чтобы вы могли с ним работать (может быть достаточно только вики). Есть параметры вашей проблемы, которые я не могу знать, поэтому я могу говорить здесь только широко, но есть прямые методы определения градиента в данной точке, то есть те, которые не требуют интерполяции. См. Википедию для формул (начиная от простого f(x+1)-f(x)
где h=1
для более высокого порядка). Расчет частных производных является простым O(NM)
цикл с простой формулой внутри (интерполяция не требуется).
Специфика может стать песчаной:
- Формулы более высокого порядка должны быть уменьшены для ребер или полностью исключены.
- Ваши точные требования к скорости могут сделать более сложные формулы бесполезными (в зависимости от платформы иногда время поиска формул более высокого порядка делает их слишком медленными; опять же, это зависит от кэша и т. Д.). Это легко проверить, формулы просты; код их и тест.
- Конкретная реализация также зависит от ваших требований к ошибкам. Теория предоставляет границы ошибок, так что они будут играть роль в том, какая формула вам нужна; но опять же, есть компромисс с требованиями к скорости. В свою очередь, это может быть практически снижено, если вы знаете особенности типов матриц, которые вы будете обрабатывать, если такая вещь известна.
Реализацию можно сделать еще проще (и, возможно, быстрее), если у вас есть существующие инструменты свертки, поскольку этот метод на самом деле является просто сверткой матрицы (обратите внимание; технически это называется взаимной корреляцией).