Nano Hash - криптовалюты, майнинг, программирование

Постройте преобразование Фурье sin wav с помощью matplotlib

Я пытаюсь построить преобразование Фурье знаковой волны на основе документация scipy

import numpy as np
import matplotlib.pyplot as plt
import scipy.fft

def sinWav(amp, freq, time, phase=0):
    return amp * np.sin(2 * np.pi * (freq * time - phase))

def plotFFT(f, speriod, time):
    """Plots a fast fourier transform

    Args:
        f (np.arr): A signal wave
        speriod (int): Number of samples per second
        time ([type]): total seconds in wave
    """

    N = speriod * time
    # sample spacing
    T = 1.0 / 800.0
    x = np.linspace(0.0, N*T, N, endpoint=False)

    yf = scipy.fft.fft(f)
    xf = scipy.fft.fftfreq(N, T)[:N//2]
    plt.plot(xf, 2.0/N * np.abs(yf[0:N//2]))
    plt.grid()
    plt.xlim([1,3])
    plt.show()


speriod = 1000
time  = {
    0: np.arange(0, 4, 1/speriod),
    1: np.arange(4, 8, 1/speriod),
    2: np.arange(8, 12, 1/speriod)
}

signal = np.concatenate([
    sinWav(amp=0.25, freq=2, time=time[0]),
    sinWav(amp=1, freq=2, time=time[1]),
    sinWav(amp=0.5, freq=2, time=time[2])
])   # generate signal

plotFFT(signal, speriod, 12)

Желаемый результат

Я хочу получить график преобразования Фурье, который выглядит так

введите здесь описание изображения

Текущий вывод

Но вместо этого это выглядит так

введите здесь описание изображения


Дополнительно

Это волна греха, с которой я работаю.

введите здесь описание изображения


Ответы:


1
import numpy as np
import matplotlib.pyplot as plt
import scipy.fft

def sinWav(amp, freq, time, phase=0):
    return amp * np.sin(2 * np.pi * (freq * time - phase))

def plotFFT(f, speriod, time):
    """Plots a fast fourier transform

    Args:
        f (np.arr): A signal wave
        speriod (int): Number of samples per second
        time ([type]): total seconds in wave
    """

    N = speriod * time
    # sample spacing
    T = 1.0 / 800.0
    x = np.linspace(0.0, N*T, N, endpoint=False)

    yf = scipy.fft.fft(f)
    xf = scipy.fft.fftfreq(N, T)[:N//2]

    amplitudes = 1/speriod* np.abs(yf[:N//2])
  
    plt.plot(xf, amplitudes)
    plt.grid()
    plt.xlim([1,3])
    plt.show()


speriod = 800
time  = {
    0: np.arange(0, 4, 1/speriod),
    1: np.arange(4, 8, 1/speriod),
    2: np.arange(8, 12, 1/speriod)
}

signal = np.concatenate([
    sinWav(amp=0.25, freq=2, time=time[0]),
    sinWav(amp=1, freq=2, time=time[1]),
    sinWav(amp=0.5, freq=2, time=time[2])
])   # generate signal

plotFFT(signal, speriod, 12)

Вы должны иметь то, что хотите. Ваши амплитуды не были рассчитаны должным образом, так как ваше разрешение и период несовместимы.

Вывод

Более длительный сбор данных:

import numpy as np
import matplotlib.pyplot as plt
import scipy.fft

def sinWav(amp, freq, time, phase=0):
    return amp * np.sin(2 * np.pi * (freq * time - phase))

def plotFFT(f, speriod, time):
    """Plots a fast fourier transform

    Args:
        f (np.arr): A signal wave
        speriod (int): Number of samples per second
        time ([type]): total seconds in wave
    """

    N = speriod * time
    # sample spacing
    T = 1.0 / 800.0
    x = np.linspace(0.0, N*T, N, endpoint=False)

    yf = scipy.fft.fft(f)
    xf = scipy.fft.fftfreq(N, T)[:N//2]

    amplitudes = 1/(speriod*4)* np.abs(yf[:N//2])
  
    plt.plot(xf, amplitudes)
    plt.grid()
    plt.xlim([1,3])
    plt.show()


speriod = 800
time  = {
    0: np.arange(0, 4*4, 1/speriod),
    1: np.arange(4*4, 8*4, 1/speriod),
    2: np.arange(8*4, 12*4, 1/speriod)
}

signal = np.concatenate([
    sinWav(amp=0.25, freq=2, time=time[0]),
    sinWav(amp=1, freq=2, time=time[1]),
    sinWav(amp=0.5, freq=2, time=time[2])
])   # generate signal

plotFFT(signal, speriod, 48)

Вывод

11.01.2021
  • Это должно выглядеть как тот график, который я разместил, где амплитуда 3,5, на частоте 2 11.01.2021
  • см. правки должны быть в порядке 11.01.2021
  • Почему это не работает с другими частотами дискретизации? Разве частоты не должны зависеть от частоты дискретизации? Я думал, что sr просто определил размер по оси x, на который был разделен сигнал. 11.01.2021
  • Что ж, если вы работаете с непрерывными данными, вы правы (то есть в математике). Но в физике данные не непрерывны. И FFT относится к дискретному FT в этом конкретном физическом контексте. Причину моих изменений можно найти здесь: en.wikipedia.org/wiki/Nyquist_frequency. все об этих отношениях. Фактически, ваш сдвиг происходит из-за свертывания спектра, потому что вы недостаточно соответствуете соотношению Найквиста. 11.01.2021
  • Я пытаюсь сделать свой график более непрерывным, но получаю один и тот же блочный график. 11.01.2021
  • Другими словами, я хочу, чтобы ось x была разделена на более мелкие участки. 11.01.2021
  • Что ж, вам обязательно стоит поработать над своими лекциями :). Для этого вам нужно больше точек времени. Смотрите мое редактирование для изменений. 11.01.2021
  • Разве я не хотел бы просто увеличить speriod? Чтобы время было разделено на более мелкие куски? Я пытался сделать это, но получаю те же результаты. Я также заметил, что обновления, которые вы только что сделали, изменили значения амплитуды. 11.01.2021
  • Да извините поправил. На самом деле амплитуды рассчитываются как 1/n_samples, где n_samples = speriod * nb_period. Таким образом, вы увеличиваете количество выборок, но не период/частоту выборки. Как правило, чем длиннее ваша волна во временной области, тем лучше разрешение. 11.01.2021
  • Так что это не работает правильно, когда я меняю частоту синусоидальных волн (если, скажем, я меняю их на частоту 1 вместо 2) 11.01.2021
  • Я учусь этому самостоятельно. Я прошел курс udemy и учебник, и все равно все кажется иностранным 11.01.2021
  • Ну, кстати: если вы установите частоту на 1, пик будет на 1, что вы и ожидаете (1 Гц). Так что работает :). 11.01.2021

  • 2

    Вы также можете построить это в интерактивном режиме. Возможно, вам потребуется установить pip install scikit-dsp-comm

    # !pip install scikit-dsp-comm
    # Make an interactive version of the above
    from ipywidgets import interact, interactive
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy import fftpack
    
    plt.rcParams['figure.figsize'] = [10, 8]
    
    font = {'weight' : 'bold',
            'size'   : 14}
    plt.rc('font', **font)
    
    
    def pulse_plot(fm = 1000, Fs = 2010):
        tlen = 1.0  # length in seconds
        # generate time axis
        tt = np.arange(np.round(tlen*Fs))/float(Fs)
        # generate sine
        xt = np.sin(2*np.pi*fm*tt)
        plt.subplot(211)
        plt.plot(tt[:500], xt[:500], '-b')
        plt.plot(tt[:500], xt[:500], 'or', label='xt values')
        plt.ylabel('$x(t)$')
        plt.xlabel('t [sec]')
        strt2 = 'Sinusoidal Waveform $x(t)$'
        strt2 = strt2 + ', $f_m={}$ Hz, $F_s={}$ Hz'.format(fm, Fs)
        plt.title(strt2)
        plt.legend()
        plt.grid()
        X = fftpack.fft(xt)
        freqs = fftpack.fftfreq(len(xt)) * Fs
        plt.subplot(212)
        N = xt.size
        # DFT
        X = np.fft.fft(xt)
        X_db = 20*np.log10(2*np.abs(X)/N)
        #f = np.fft.fftfreq(N, 1/Fs)
        f = np.arange(0, N)*Fs/N
        plt.plot(f, X_db, 'b')
        plt.xlabel('Frequency in Hertz [Hz]')
        plt.ylabel('Frequency Domain\n (Spectrum) Magnitude')
        plt.grid()
        plt.tight_layout()
        
        
    interactive_plot = interactive(pulse_plot,fm = (1000,20000,1000), Fs = (1000,40000,10));
    output = interactive_plot.children[-1]
    # output.layout.height = '350px'
    interactive_plot    
    

    введите здесь описание изображения

    15.01.2021
  • почему от -300 до 0? 15.01.2021
  • @ Сэм, потому что ось Y - это просто величина спектра. Вы можете сделать это линейным, если хотите. 15.01.2021
  • Разве не должно быть 350? 15.01.2021
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

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

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..