2

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?

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:

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...:

    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...

1
  • 32/390625 == 0, it's integer division. Write 32.0/390625 Commented May 4, 2013 at 20:44

2 Answers 2

1

Your error might come from the way you define x(t) :

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

When Python executes the first line, it assigns to the variable x_t the value of the formula you're given it using the current value of t ( scipy.linspace(0.01, 32/390625, samples, False) ). It doesn't interpret t as a variable.

To fix this change the second line by this :

acc = lambda t: cos(6.72*(10**7*t) + 3.2*sin(5*(10**5*t)))

EDIT : Just noticed you did the same with signal. Writing : signal = acc(t) (even if you fixed acc) will just assign the result of the function acc(t) (with the current value of t) to the variable signal. It won't be a function. (Why don't you just use acc instead of signal as acc is a function of t anyway ?)

Sign up to request clarification or add additional context in comments.

15 Comments

That makes sense, but it still isn't working. I'm essentially seeing a horizontal line at 20 dB if that helps in anything...
Please read my edit. (You're doing the same with signal so signal is a constant value and not a function)
This gives me all kinds of errors... Can't multiply by window because illegal operation "*" of function and float, it won't take the fft() of acc: Traceback (most recent call last): File "/home/hollis/Documents/ELEN 322/ELEN_322_#2.py", line 31, in <module> acc = scipy.fft(acc) #Take the FFT File "/usr/lib/python2.7/dist-packages/numpy/fft/fftpack.py", line 164, in fft return _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftf, _fft_cache) File "/usr/lib/python2.7/dist-packages/numpy/fft/fftpack.py", line 48, in _raw_fft n = a.shape[axis] IndexE tuple index out of range
Why would you do that : signal = lambda t: abs(20*log10(scipy.fft(acc*window))) ? Isn't acc supposed to be a function ?
Because it yells at me if I don't... Like I said, I'm not fully understanding something here. What can I do to make this plot the amplitude spectrum?
|
0

Not sure if you are still working on this. I did found this post: FFT in Matlab and numpy / scipy give different results which may shed some light.

The post suggest that use the transpose within Scipy as Matlab applies the fft over the columns of the matrix, numpy applies the fft over the last axis (the rows) by default

Hope that helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.