scipy.ndimage.laplace中的边界模式

时间:2019-04-15 12:47:07

标签: python numpy matrix scipy

函数scipy.ndimage.laplace可用于计算应用于N维数组的Laplace运算符。例如,如果要使用此功能,例如在物理应用中,关键部分通常是如何处理边界。

查看功能文档,支持许多选项:

  • “反射”(d c b a | a b c d | d c b a)
  • “常数”(k k k k | a b c d | k k k k)
  • “最近”(a a a | a b c d | d d d d)
  • “镜子”(d c b | a b c d | c b a)
  • “包装”(a b c d | a b c d | a b c d)

我个人缺少的一件事是“流畅的延续” 选项。在上面的表示法中,它对应于mirror选项的稍作修改的版本:

  • “平滑延续”((a-d)(a-c)(a-b)| a b c d |(d-c)(d-b)(d-a))

这样做的动机是不要在边界处引入纽结,所有受支持的选项似乎都对任意输入起作用。

问题:有什么方法可以在scipy / numpy中执行此Laplace操作吗?

1 个答案:

答案 0 :(得分:1)

我深入研究了scipy源代码。 我发现的结果使我认为,仅使用python scypi / numpy添加自定义模式并不容易:您最终将用python重新编译scipy的所有主干代码。

您所指的模式将在底层Scipy的C代码中进行深入管理。 您将需要更改C枚举值,并使用自定义模式逻辑相应地更新源文件,并产生一个新包。

这可能是在github上打开的问题/演变:允许自定义构建数组方法或实现新模式。或每张一张。

请参见here。报价:

/* 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;
}

请注意,我绝对不是专家,所以也许我错过了很多东西,或者有很多有据可查的原因解释了所建议的模式。


编辑2019年4月24日,一些documentation here 我没有得到所有细节,但是据我了解:

  • 它指的是Philippe Thevenez博士的学术工作,是某些算法的潜在来源。
  • 该票证似乎表明将来可能会开发其他一些模式。

This ticket还处理新模式。

鉴于门票的开放日期,可能要花一些时间。