Смущающие артефакты в комплексе PyWavelet-Morlet для анализа сигнала 1 кГц

У меня есть некоторые артефакты в преобразовании PyWavelets, которые действительно меня смущают. Я использую версию 0.5.2. Может кто-нибудь объяснить, что здесь происходит?

Я начинаю с создания сигнала с частотой 1 кГц, а затем пытаюсь проанализировать этот сигнал с помощью комплексного непрерывного вейвлет-преобразования Морле. Я делаю это с 3 октавами: от 0,5 кГц до 1 кГц, от 1 кГц до 2 кГц и от 2 кГц до 4 кГц, каждая с 40 логарифмическими шкалами. Моя интуиция говорит, что должен быть один пик при y=40 (эквивалентно 1 кГц), и что любая разница во времени должна быть минимальной. Вместо этого я получаю пик около y = от 35 до 37 (от 0,92 до 0,95 кГц), и есть некоторый периодический эффект. (Как ни странно, этот эффект, кажется, возникает только в реальном компоненте преобразования - мнимый компонент выглядит ближе к тому, как я представлял, как он должен выглядеть, хотя он все еще не центрирован правильно. Я считаю, что реальный компонент и мнимый компонент должны выглядеть как сдвинутые во времени версии друг друга, если смотреть на чистую синусоидальную волну.)

Я неправильно использую PyWavelets? Есть ли здесь ошибка? Любая помощь приветствуется.

import numpy
import pywt
import matplotlib.pyplot as plt

# makes a 1-kHz signal
def make_data(length, quality):
    tau = 2*numpy.pi
    x = numpy.arange(length)
    y = numpy.sin(tau * x/(quality/1000)) # the 1000 is for 1 kHz
    return y

# does the continuous wavelet transform, outputting pic
def do_transform(data, base_freq, num_octaves, voices_per_octave, quality):
    # calculate the scales, based on the desired frequencies
    base_scale = quality / (2*base_freq)
    far_scale = base_scale / 2**num_octaves
    scales = numpy.geomspace(base_scale, far_scale, num=num_octaves*voices_per_octave+1, endpoint=True)

    # actual calculation
    coeffs, freqs = pywt.cwt(data, scales, "cmor", 1/quality)

    print("freqs: " +str(freqs))

    # output
    truncated = coeffs[:, 100:200]
    plt.imshow(abs(truncated), origin='lower', interpolation='none')
    #plt.imshow(truncated.real, origin='lower', interpolation='none')
    #plt.imshow(truncated.imag, origin='lower', interpolation='none')
    plt.subplots_adjust(left=0.01, right=0.99, top=0.99, bottom=0.05)
    plt.show()

data = make_data(1000, 44100)
do_transform(data, 500, 3, 40, 44100)

Величины преобразования Величины преобразования

Реальные компоненты преобразования Реальные компоненты преобразования

Мнимые компоненты преобразования Мнимые компоненты преобразования

1 ответ

Оказывается, это известная проблема. (Пока не ясно, является ли это ошибкой или просто неожиданным поведением, но обсуждение здесь: https://github.com/PyWavelets/pywt/issues/307.)

Спасибо всем, кто смотрел на это и обдумывал.

Другие вопросы по тегам