📚 The CoCalc Library - books, templates and other resources
License: OTHER
"""This file contains code used in "Think DSP",1by Allen B. Downey, available from greenteapress.com23Copyright 2014 Allen B. Downey4License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html5"""67from __future__ import print_function, division89import thinkdsp10import thinkplot11import thinkstats212import numpy as np1314PI2 = 2 * np.pi151617def make_sine(offset):18"""Makes a 440 Hz sine wave with the given phase offset.1920offset: phase offset in radians2122returns: Wave objects23"""24signal = thinkdsp.SinSignal(freq=440, offset=offset)25wave = signal.make_wave(duration=0.5, framerate=10000)26return wave272829def corrcoef(xs, ys):30"""Coefficient of correlation.3132ddof=0 indicates that we should normalize by N, not N-1.3334xs: sequence35ys: sequence3637returns: float38"""39return np.corrcoef(xs, ys, ddof=0)[0, 1]404142def plot_sines():43"""Makes figures showing correlation of sine waves with offsets.44"""45wave1 = make_sine(0)46wave2 = make_sine(offset=1)4748thinkplot.preplot(2)49wave1.segment(duration=0.01).plot(label='wave1')50wave2.segment(duration=0.01).plot(label='wave2')5152corr_matrix = np.corrcoef(wave1.ys, wave2.ys, ddof=0)53print(corr_matrix)5455thinkplot.save(root='autocorr1',56xlabel='Time (s)',57ylim=[-1.05, 1.05])5859offsets = np.linspace(0, PI2, 101)6061corrs = []62for offset in offsets:63wave2 = make_sine(offset)64corr = corrcoef(wave1.ys, wave2.ys)65corrs.append(corr)6667thinkplot.plot(offsets, corrs)68thinkplot.save(root='autocorr2',69xlabel='Offset (radians)',70ylabel='Correlation',71xlim=[0, PI2],72ylim=[-1.05, 1.05])737475def plot_shifted(wave, offset=0.002, start=0.2):76"""Plots two segments of a wave with different start times.7778wave: Wave79offset: difference in start time (seconds)80start: start time in seconds81"""82thinkplot.preplot(num=2)83segment1 = wave.segment(start=start, duration=0.01)84segment1.plot(linewidth=2, alpha=0.8)8586segment2 = wave.segment(start=start-offset, duration=0.01)87segment2.shift(offset)88segment2.plot(linewidth=2, alpha=0.4)8990corr = segment1.corr(segment2)91text = r'$\rho =$ %.2g' % corr92thinkplot.text(start+0.0005, -0.8, text)93thinkplot.config(xlabel='Time (s)', ylim=[-1.05, 1.05])949596def serial_corr(wave, lag=1):97"""Computes serial correlation with given lag.9899wave: Wave100lag: integer, how much to shift the wave101102returns: float correlation coefficient103"""104n = len(wave)105y1 = wave.ys[lag:]106y2 = wave.ys[:n-lag]107corr = corrcoef(y1, y2)108return corr109110111def plot_serial_corr():112"""Makes a plot showing serial correlation for pink noise.113"""114np.random.seed(19)115116betas = np.linspace(0, 2, 21)117corrs = []118119for beta in betas:120signal = thinkdsp.PinkNoise(beta=beta)121wave = signal.make_wave(duration=1.0, framerate=11025)122corr = serial_corr(wave)123corrs.append(corr)124125thinkplot.plot(betas, corrs)126thinkplot.config(xlabel=r'Pink noise parameter, $\beta$',127ylabel='Serial correlation',128ylim=[0, 1.05])129thinkplot.save(root='autocorr3')130131132def autocorr(wave):133"""Computes and plots the autocorrelation function.134135wave: Wave136"""137lags = range(len(wave.ys)//2)138corrs = [serial_corr(wave, lag) for lag in lags]139return lags, corrs140141142def plot_pink_autocorr(beta, label):143"""Makes a plot showing autocorrelation for pink noise.144145beta: parameter of pink noise146label: string label for the plot147"""148signal = thinkdsp.PinkNoise(beta=beta)149wave = signal.make_wave(duration=1.0, framerate=11025)150lags, corrs = autocorr(wave)151thinkplot.plot(lags, corrs, label=label)152153154def plot_autocorr():155"""Plots autocorrelation for pink noise with different parameters156"""157np.random.seed(19)158thinkplot.preplot(3)159160for beta in [1.7, 1.0, 0.3]:161label = r'$\beta$ = %.1f' % beta162plot_pink_autocorr(beta, label)163164thinkplot.config(xlabel='Lag',165ylabel='Correlation',166xlim=[-5, 1000],167ylim=[-0.05, 1.05])168thinkplot.save(root='autocorr4')169170171def plot_singing_chirp():172"""Makes a spectrogram of the vocal chirp recording.173"""174wave = thinkdsp.read_wave('28042__bcjordan__voicedownbew.wav')175wave.normalize()176177duration = 0.01178segment = wave.segment(start=0.2, duration=duration)179180# plot two copies of the wave with a shift181plot_shifted(wave, start=0.2, offset=0.0023)182thinkplot.save(root='autocorr7')183184# plot the autocorrelation function185lags, corrs = autocorr(segment)186thinkplot.plot(lags, corrs)187thinkplot.config(xlabel='Lag (index)',188ylabel='Correlation',189ylim=[-1.05, 1.05],190xlim=[0, 225])191thinkplot.save(root='autocorr8')192193# plot the spectrogram194gram = wave.make_spectrogram(seg_length=1024)195gram.plot(high=4200)196197thinkplot.config(xlabel='Time (s)',198ylabel='Frequency (Hz)',199xlim=[0, 1.4],200ylim=[0, 4200])201thinkplot.save(root='autocorr5')202203# plot the spectrum of one segment204spectrum = segment.make_spectrum()205spectrum.plot(high=1000)206thinkplot.config(xlabel='Frequency (Hz)', ylabel='Amplitude')207thinkplot.save(root='autocorr6')208209210def plot_correlate():211"""Plots the autocorrelation function computed by np.212"""213wave = thinkdsp.read_wave('28042__bcjordan__voicedownbew.wav')214wave.normalize()215segment = wave.segment(start=0.2, duration=0.01)216217lags, corrs = autocorr(segment)218219N = len(segment)220corrs2 = np.correlate(segment.ys, segment.ys, mode='same')221lags = np.arange(-N//2, N//2)222thinkplot.plot(lags, corrs2)223thinkplot.config(xlabel='Lag',224ylabel='Correlation',225xlim=[-N//2, N//2])226thinkplot.save(root='autocorr9')227228229def main():230plot_sines()231plot_serial_corr()232plot_autocorr()233plot_singing_chirp()234plot_correlate()235236237if __name__ == '__main__':238main()239240241