Как выполнить свертку в python с гауссовской переменной ширины?

Мне нужно выполнить свертку с использованием Гаусса, однако ширина Гаусса должна измениться. Я не занимаюсь традиционной обработкой сигналов, но вместо этого мне нужно взять мою идеальную функцию плотности вероятности (PDF) и «размазать» ее в зависимости от разрешения моего оборудования.

Например, предположим, что мой PDF-файл начинается как пик/дельта-функция. Я смоделирую это как очень узкую гауссиану. После прогона моего оборудования оно будет размазано по какому-то гауссову разрешению. Я могу рассчитать это, используя функции свертки scipy.signal.

    import numpy as np
    import matplotlib.pylab as plt

    import scipy.signal as signal
    import scipy.stats as stats

    # Create the initial function. I model a spike
    # as an arbitrarily narrow Gaussian
    mu = 1.0 # Centroid
    sig=0.001 # Width
    original_pdf = stats.norm(mu,sig)

    x = np.linspace(0.0,2.0,1000) 
    y = original_pdf.pdf(x)
    plt.plot(x,y,label='original')


    # Create the ``smearing" function to convolve with the
    # original function.
    # I use a Gaussian, centered at 0.0 (no bias) and
    # width of 0.5
    mu_conv = 0.0 # Centroid
    sigma_conv = 0.5 # Width
    convolving_term = stats.norm(mu_conv,sigma_conv)

    xconv = np.linspace(-5,5,1000)
    yconv = convolving_term.pdf(xconv)

    convolved_pdf = signal.convolve(y/y.sum(),yconv,mode='same')

    plt.plot(x,convolved_pdf,label='convolved')
    plt.ylim(0,1.2*max(convolved_pdf))
    plt.legend()
    plt.show()

Это все работает без проблем. Но теперь предположим, что мой исходный PDF — это не всплеск, а какая-то более широкая функция. Например, гауссиана с сигмой = 1,0. А теперь предположим, что мое разрешение на самом деле варьируется в зависимости от x: при x=0,5 функция размытия является гауссовой с sigma_conv=0,5, а при x=1,5 функция размытия является гауссовой с sigma_conv=1,5. И предположим, что я знаю функциональную форму зависимости от x моей размытой гауссианы. Наивно, я думал, что изменю строку выше на

    convolving_term = stats.norm(mu_conv,lambda x: 0.2*x + 0.1)

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

Итак, есть ли способ сделать это с функциями, уже определенными в Python? У меня есть код для этого, который я написал сам... но я хочу убедиться, что не изобрел велосипед заново.

Заранее спасибо!

Мэтт


person Matt Bellis    schedule 04.09.2013    source источник
comment
Ваш шаг xconv ​​(last - first) / (length - 1) отличается от шага x, что делает ширину масштабируемой (т. Е. Сигмы не в одной и той же единице), вы действительно этого хотите?   -  person H.D.    schedule 10.09.2013
comment
У меня есть код для этого, который я написал сам => можете ли вы показать нам этот код? Это может быть полезно.   -  person H.D.    schedule 10.09.2013


Ответы (1)


Вопрос вкратце:
Как свернуться с нестационарным ядром, например, с гауссианом, который меняет ширину для разных мест в данных, и делает ли Python существующим инструментом для этого?

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

Один трюк, который может сработать для вас, заключается в том, что вместо изменения размера ядра в зависимости от положения растяните данные в обратном масштабе (т. базовая ширина, растяните данные в 2 раза). Таким образом, вы можете выполнить одну операцию деформации данных, стандартную свертку с фиксированной шириной Гаусса, а затем развернуть данные до исходного масштаба.

Преимущество этого подхода в том, что его очень легко написать, он полностью векторизован и, следовательно, довольно быстро работает.

Деформация данных (с использованием, скажем, метода интерполяции) вызовет некоторую потерю точности, но если вы выберете вещи так, чтобы данные всегда расширялись, а не уменьшались в вашей начальной операции деформации, потери должны быть минимальными.

person tom10    schedule 12.06.2014