I want to generate a random sequence for instantaneous frequency with as little aliasing as possible (i.e I expect to see as close to constant amplitude as possible, with only the frequency varying). What I have so far seems close, but in some cases results in a few frequencies with less-than-expected amplitudes:

def ms(x):
    return (np.abs(x)**2.0).mean()

def normalize(y, x=None):
    if x is not None:
        x = ms(x)
        x = 1.0
    return y * np.sqrt( x / ms(y) )

def brown(N, state=None):
    state = np.random.RandomState() if state is None else state
    uneven = N%2
    X = state.randn(N//2+1+uneven) + 1j * state.randn(N//2+1+uneven)
    S = (np.arange(len(X))+1)# Filter
    y = (np.fft.irfft(X/S)).real
    if uneven:
        y = y[:-1]
    return normalize(y)

inst_freq = np.cumsum(brown(100))
inst_freq -= inst_freq.min() - 1
inst_freq /= inst_freq.max()
rectified_inst_freq = 1.0 / (np.floor(1.0 / inst_freq))

plt.plot(rectified_inst_freq, 'r')
plt.plot(np.cos(np.cumsum(np.pi * inst_freq)))
plt.plot(np.cos(np.cumsum(np.pi * rectified_inst_freq)))

The rectified_inst_freq variable is attempting to round the instantaneous frequencies to the a frequency with an integer period, this helps a lot with the aliasing, but not entirely. Results that show the strange high-frequency amplitude problem (the middle graph before rectification, and the bottom graph after):

enter image description here

The high frequency portion at the end of the rectified signal should have amplitude 1, but it is stuck at .75. I think this has to do with aliasing, but I am not sure how to fix it. In some scenarios (particularly ones that start at a high frequency) the amplitude is correct (see below)

enter image description here

  • $\begingroup$ okay, lemme get this straight... you're first creating a curve (from brownian random process) that is your instantaneous frequency. from that you are generating a sinusoid that has phase which is the integral (or cumulative sum) of the instantaneous frequency. then you "rectify" that instantaneous frequency but rounding to the nearest value that has a period that is an integer number of samples. and you plot both results. $$ $$ so what, exactly, is your question or problem? $\endgroup$ – robert bristow-johnson Jan 22 '17 at 5:53
  • $\begingroup$ the amplitude difference is a result of a low sample rate and a plotting function that only draws piecewise linear plots. either increase the sample rate or limit the instantaneous frequencies to much lower than 1/2 the sample rate. or get a better plotting function that does better than linear interpolation. $\endgroup$ – robert bristow-johnson Jan 22 '17 at 5:56
  • 1
    $\begingroup$ Robert, it is an imaging issue. sometimes people (even books or DSP articles) are imprecise with semantics and call the images "aliases" in the frequency domain. when you sample, the original signal (both positive and negative frequencies) is translated by integer multiples of the sampling frequency and overlapped and added. a true sinc() brickwall filter will kill those images, but linear interpolation will not kill them. so you actually have a constant amplitude cosine waveform with those samples but it looks like you don't. $\endgroup$ – robert bristow-johnson Jan 22 '17 at 6:21
  • 2
    $\begingroup$ try restricting your instantaneous frequency to less than 1/10 the sample rate and see how bad it looks with linear interpolation. $\endgroup$ – robert bristow-johnson Jan 22 '17 at 6:22
  • 1
    $\begingroup$ i'm too lazy for that. $\endgroup$ – robert bristow-johnson Jan 22 '17 at 6:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.