#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    1
    Rep Power
    0

    Something Wrong with my fft()


    I have a function I am supposed to plot the amplitude spectrum of between 10MHz and 11.4MHz. This is the function: cos(6.72*(10**7*t) + 3.2*sin(5*(10**5*t))) I know what the plot is supposed to look like, but mine is completely wrong. I'm pretty sure it's a programming error, not a math/theory error because I'm doing exactly what a MatLab example is showing, but I feel like Python is doing something I'm not understanding. I'm supposed to sample this function 8192 times at 10ns apart, multiply it by a Hamming window, and plot the amplitude spectrum in dB between 10MHz and 11.4MHz. The carrier (10.7MHz) should be around 55 dB. The second pair of sidebands is the greatest amplitude at 60 dB. Then, the fifth pair of sidebands is the 20 dB point, so around 40 dB. Can anyone spot something wrong with this code that explains why mine doesn't show this?


    Code:
    import numpy
        import scipy
        import scipy.fftpack
        import matplotlib
        import matplotlib.pyplot as plt
        from scipy import pi
        import pylab
        from pylab import *
        import cmath
        import sys
        sys.setrecursionlimit(10000)
        
        samples = 8192
        
        #Defining the test function
        t = scipy.linspace(0.01, 32/390625, samples, False)   #Sample samples times at 10ns apart
        #The samples is non-inclusive, it goes from 0 to samples-1.
        x_t = cos(6.72*(10**7*t) + 3.2*sin(5*(10**5*t)))  #Define x(t)
        acc = lambda t: (x_t)                             #Define x[t] in terms of t as a variable in Python's eyes 
        
        signal = acc(t)                 #Make signal a function of t
        plt.subplot(211)                #Set up a plot
        plt.xlabel('Ohmega (Hz)')       #Label x axis
        plt.ylabel('Amplitude of sampled x(t) (dB)')  #Label y axis
        
        window = numpy.hamming(samples)    #Make a hamming window 
                                           
        
        w = scipy.linspace(0, 100*10**6, samples, False)   #Create Ohmega between 1/(10ns)
        signal = signal * window        #Multiply by the hamming window
        signal = scipy.fft(signal)      #Take the FFT
        signal = abs(20*log10(signal))  #Get the magnitude in dB scale
        
        plt.xlabel('Ohmega')            #Label x axis
        plt.ylabel('|F[w]|')            #Label y axis
        #marker, stemlines, baseline = stem(w,signal, 'b-..')    #Plot with stemlines
        plot(w,signal, 'b-')
        plt.xlim(10*10**6, 11.4*10**6)  #Set x-limits
        
        plt.show()                      #Show the plot
    Thanks for any help!

    EDIT:

    My code now:

    Code:
    import numpy
        import scipy
        import scipy.fftpack
        import matplotlib
        import matplotlib.pyplot as plt
        from scipy import pi
        import pylab
        from pylab import *
        import cmath
        import sys
        sys.setrecursionlimit(10000)
        
        samples = 8192
        
        #Defining the test function
        t = scipy.linspace(0.01, 32/390625, samples, False)         #Sample samples times at 10ns apart
        #The samples is non-inclusive, it goes from 0 to samples-1.
        x_t = cos(6.72*(10**7*t) + 3.2*sin(5*(10**5*t)))            #Define x(t)
        acc = lambda t: cos(6.72*(10**7*t) + 3.2*sin(5*(10**5*t)))  #Define x[t] in terms of t as a variable in Python's eyes 
        
        #signal = acc(t)                 #Make signal a function of t
        plt.subplot(211)                #Set up a plot
        plt.xlabel('Ohmega (Hz)')       #Label x axis
        plt.ylabel('Amplitude of sampled x(t) (dB)')  #Label y axis
        
        window = numpy.hamming(samples)    #Make a hamming window 
                                           
        
        w = scipy.linspace(0.01, 100*10**6, samples, False)   #Create Ohmega between 1/(10ns)
        signal = lambda t: abs(20*log10(scipy.fft(acc*window)))
        #acc = acc * window        #Multiply by the hamming window
        #acc = scipy.fft(acc)      #Take the FFT
        #acc = abs(20*log10(acc))  #Get the magnitude in dB scale
        
        plt.xlabel('Ohmega')            #Label x axis
        plt.ylabel('|F[w]|')            #Label y axis
        #marker, stemlines, baseline = stem(w,signal, 'b-..')    #Plot with stemlines
        
        plot(w,signal, 'b-')
        plt.xlim(10*10**6, 11.4*10**6)  #Set x-limits
        
        plt.show()                      #Show the plot
    And the error...:

    Code:
     Traceback (most recent call last):
          File "/home/hollis/Documents/ELEN 322/ELEN_322_#2.py", line 39, in <module>
            plot(w,signal, 'b-')
          File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2467, in plot
            ret = ax.plot(*args, **kwargs)
          File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 3893, in plot
            for line in self._get_lines(*args, **kwargs):
          File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 322, in _grab_next_args
            for seg in self._plot_args(remaining, kwargs):
          File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 300, in _plot_args
            x, y = self._xy_from_xy(x, y)
          File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 240, in _xy_from_xy
            raise ValueError("x and y must have same first dimension")
        ValueError: x and y must have same first dimension
    While I've seen and fixed this error before, I have no idea how to fix it now. Apparently a signal sampled 8192 times and the variable determining where it was sampled are different dimensions. I'm so lost on this one...
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,854
    Rep Power
    481
    signal is a function, so that's wrong.

    plot(w,signal)



    We next try
    plot(w,signal(w), 'b-')


    which doesn't work because acc is a function. You've tried to multiply a function by an array.

    signal = lambda t:abs(
    20*log10(scipy.fft(acc*window)))


    acc = lambda t: cos(6.72*(10**7*t) + 3.2*sin(5*(10**5*t))) #Define x[t] in terms of t as a variable in Python's eyes


    At some point I expect you'll need to evaluate these functions as in
    acc(something)


    Programming in functional style is quite possible, see my fun post 4 here
    http://forums.devshed.com/python-programming-11/need-help-with-this-problem-python-3-2-1-1t-939983.html
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo