Граничные режимы в scipy.ndimage.laplace

1

Функция scipy.ndimage.laplace может использоваться для вычисления оператора Лапласа, применяемого к N-мерным массивам. Если кто-то хочет использовать эту функцию, например, для приложений в физике, то решающей частью часто является то, как обрабатывать границы.

Изучив документацию по функциям, мы поддерживаем ряд опций:

  • 'отражение (dcba | abcd | dcba)
  • 'постоянная (kkkk | abcd | kkkk)
  • 'ближайший (aaaa | abcd | dddd)
  • 'зеркало (dcb | abcd | cba)
  • 'wrap (abcd | abcd | abcd)

Одна вещь, которую мне лично не хватает, - это вариант "плавного продолжения". В приведенной выше записи это будет соответствовать слегка измененной версии опции зеркала:

  • "гладкое продолжение" ((ad) (ac) (ab) | abcd | (dc) (db) (da))

Мотивация для этого состоит в том, чтобы не вводить изломы на границе, что, кажется, все поддерживаемые опции делают для произвольного ввода.

Вопрос: Есть ли способ сделать в scipy/numpy?

Теги:
numpy
matrix
scipy

1 ответ

0

Я немного копался в исходном коде scipy. То, что я нашел, заставляет меня думать, что добавить свой пользовательский режим будет нелегко.

Режим, на который вы ссылаетесь, управляется глубоко в базовом C-коде. Вам нужно будет изменить значение C enum, обновить исходный файл, создать новый пакет.

Смотрите здесь Цитирование:

/* Extend a line in memory to implement boundary conditions: */
int NI_ExtendLine(double *buffer, npy_intp line_length,
                  npy_intp size_before, npy_intp size_after,
                  NI_ExtendMode extend_mode, double extend_value)
{
    double *first = buffer + size_before;
    double *last = first + line_length;
    double *src, *dst, val;

    switch (extend_mode) {
        /* aaaaaaaa|abcd|dddddddd */
        case NI_EXTEND_NEAREST:
            src = first;
            dst = buffer;
            val = *src;
            while (size_before--) {
                *dst++ = val;
            }
            src = last - 1;
            dst = last;
            val = *src;
            while (size_after--) {
                *dst++ = val;
            }
            break;
        /* abcdabcd|abcd|abcdabcd */
        case NI_EXTEND_WRAP:
            src = last - 1;
            dst = first - 1;
            while (size_before--) {
                *dst-- = *src--;
            }
            src = first;
            dst = last;
            while (size_after--) {
                *dst++ = *src++;
            }
            break;
        /* abcddcba|abcd|dcbaabcd */
        case NI_EXTEND_REFLECT:
            src = first;
            dst = first - 1;
            while (size_before && src < last) {
                *dst-- = *src++;
                --size_before;
            }
            src = last - 1;
            while (size_before--) {
                *dst-- = *src--;
            }
            src = last - 1;
            dst = last;
            while (size_after && src >= first) {
                *dst++ = *src--;
                --size_after;
            }
            src = first;
            while (size_after--) {
                *dst++ = *src++;
            }
            break;
        /* cbabcdcb|abcd|cbabcdcb */
        case NI_EXTEND_MIRROR:
            src = first + 1;
            dst = first - 1;
            while (size_before && src < last) {
                *dst-- = *src++;
                --size_before;
            }
            src = last - 2;
            while (size_before--) {
                *dst-- = *src--;
            }
            src = last - 2;
            dst = last;
            while (size_after && src >= first) {
                *dst++ = *src--;
                --size_after;
            }
            src = first + 1;
            while (size_after--) {
                *dst++ = *src++;
            }
            break;
        /* kkkkkkkk|abcd]kkkkkkkk */
        case NI_EXTEND_CONSTANT:
            val = extend_value;
            dst = buffer;
            while (size_before--) {
                *dst++ = val;
            }
            dst = last;
            while (size_after--) {
                *dst++ = val;
            }
            break;
        default:
            PyErr_Format(PyExc_RuntimeError,
                         "mode %d not supported", extend_mode);
            return 0;
    }
    return 1;
}
  • 0
    Большое спасибо за ваш ответ, это очень полезно! Ответ «это будет трудно» с очень продуктивными предложениями, подобными вашим, может быть более полезным, чем ответ «делай это» иногда. Пока что я проголосовал и буду назначать награду до того, как она истечет, но я подожду с галочкой принятия, если кто-то еще придет.
  • 0
    Пожалуйста. Я хочу верить, что за режимами по умолчанию есть некоторые теоретические / академические причины, но это далеко от моего прямого понимания. У экспертов по обработке изображений / сигналов могут быть подсказки, или, возможно, спросить на GitHub?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню