Skip to main content

Discrete-Time Fourier Transform

  • Chapter
  • First Online:
Python for Signal Processing

Abstract

The Fourier Transform is ubiquitous, but it has singular standing in signal processing because of the way sampling imposes a bandwidth-centric view of the world. The Discrete-Time Fourier Transform (DFT) is the primary analysis tool for exploring this perspective. Our development unconventionally starts with a matrix/vector representation of the DFT because that facilitates our visual approach which in turn is designed to develop intuition about the operation and usage of the DFT in practice.

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

Chapter
USD 29.95
Price excludes VAT (USA)
  • Available as PDF
  • Read on any device
  • Instant download
  • Own it forever
eBook
USD 84.99
Price excludes VAT (USA)
  • Available as EPUB and PDF
  • Read on any device
  • Instant download
  • Own it forever
Softcover Book
USD 109.99
Price excludes VAT (USA)
  • Compact, lightweight edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info
Hardcover Book
USD 159.99
Price excludes VAT (USA)
  • Durable hardcover edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info

Tax calculation will be finalised at checkout

Purchases are for personal use only

Institutional subscriptions

Notes

  1. 1.

    The H superscript indicates the conjugate transpose.

Author information

Authors and Affiliations

Authors

Appendix

Appendix

Listing 3.1: Listing corresponding to Fig. 3.1. The yaxis.set_label_position function places the y-label on the right side of the figure instead of on the default left side. Using set_xticks to set the tick labels list to the empty list ([]) removes all the tick marks on the x-axis. The set_xticklabels functions sets the labels on the tickmarks to the specified list of LaTeX formatted strings. Matplotlib’s gridspec is a generalization of subplot that allows more precise control of the layout of nested plots. The art3d module holds the codes for converting 2D elements into 3D elements that can be added to 3D axes. The Poly3DCollection object is a container for 3D elements.

1 # must start notebook with --pylab flag

2

3 from matplotlib.patches import FancyArrow

4 import mpl_toolkits.mplot3d.art3d as art3d

5 from mpl_toolkits.mplot3d.art3d import Poly3DCollection

6 import matplotlib.gridspec as gridspec

7

8 def dftmatrix(Nfft=32,N=None):

9     ’construct DFT matrix’

10     k= np.arange(Nfft)

11     if N is None: N = Nfft

12     n = arange(N)

13     U = matrix(exp(1j* 2*pi/Nfft *k*n[:,None])) # use numpy broadcasting to

14     create matrix return U/sqrt(Nfft)

15

16 Nfft=16

17 v = ones((16,1))

18 U = dftmatrix(Nfft=Nfft,N=16)

19 # ---

20 # hardcoded constants to format complicated figure

21

22 gs = gridspec.GridSpec(8,12)

23 gs.update( wspace=1, left=0.01)

24

25 fig =figure(figsize=(10,5))

26 ax0 = subplot(gs[:,:3])

27 fig.add_subplot(ax0)

28

29 ax0.set_aspect(1)

30 a=2*pi/Nfft*arange(Nfft)

31

32 colors = [’k’,’b’,’r’,’m’,’g’,’Brown’,’DarkBlue’,’Tomato’,’Violet’, ’Tan’,

33           ’Salmon’,’Pink’,’SaddleBrown’, ’SpringGreen’, ’RosyBrown’,’Silver’,]

34 for j,i in enumerate(a):

35   ax0.add_patch(FancyArrow(0,0,cos(i),sin(i),width=0.02,

36                             length_includes_head=True,edgecolor=colors[j]))

37

38 ax0.text(1,0.1,’0’,fontsize=16)

39 ax0.text(0.1,1,r’\(\frac{\pi}{2}\)’,fontsize=22)

40 ax0.text(-1,0.1,r’$\pi$’,fontsize=18)

41 ax0.text(0.1,-1.2,r’\(\frac{3\pi}{2}\)’,fontsize=22)

42 ax0.axis(array([-1,1,-1,1])*1.45)

43 ax0.set_title(’Radial Frequency’,fontsize=18)

44 ax0.set_xlabel(’Real’)

45 ax0.set_ylabel(’Imaginary’)

46 # plots in the far right column

47 for i in range(8):

48   ax=subplot(gs[i,8:])

49   ax.set_xticks([]);  ax.set_yticks([])

50   ax.set_ylabel(r’\(\omega_{%d}=%d\times\frac{2\pi}{16}\)’%(i+8,i+8),fontsize=16,

51                 rotation=’horizontal’)

52   ax.plot(U.real[:,i+8],’-o’,color=colors[i+8])

53   ax.plot(U.imag[:,i+8],’--o’,color=colors[i+8],alpha=0.2)

54   ax.axis(ymax=4/Nfft*1.1,ymin=-4/Nfft*1.1)

55   ax.yaxis.set_label_position(’right’)

56 ax.set_xticks(arange(16))

57 ax.set_xlabel(’n’)

Listing 3.2: Listing corresponding to Fig. 3.2. The set_xticklabels function changes the labeling of the tick marks to the given string, here with extra LaTeX formatting.

1 U = dftmatrix(64,16)

2 x = ones((16,1))

3 X = U.H*x

4

5 fig,ax=subplots()

6 fig.set_size_inches((8,4))

7 ax.set_aspect(0.8)

8 ax.grid()

9 ax.plot(arange(0,64)*2*pi/64.,abs(X),’o-’)

10 ax.set_ylabel(r’$|X(\omega)|$’,fontsize=18)

11 ax.set_xticks([0, pi/2., pi, 3*pi/2,2*pi])

12 ax.set_xlabel(r’$\omega$’,fontsize=16)

13 ax.axis([0, 2*pi,0,2.1])

14 ax.set_xticklabels([’0’,r’\(\frac{\pi}{2}\)’, r’$\pi$’,r’\(\frac{3\pi}{2}\)’,

15                     r’$2\pi$’], fontsize=18);

Listing 3.3: Listing corresponding to Fig. 3.3.

1 U = dftmatrix(64,16)

2 x = ones((16,1))

3 X = U.H*x

4

5 fig,ax=subplots()

6 fig.set_size_inches((8,4))

7

8 ax.set_aspect(0.8) # aspect ratio

9 ax.plot(arange(0,64)*2*pi/64.,abs(X),’o-’,label=’zero padded’)

10 ax.stem(arange(0,16)*2*pi/16.,abs(dftmatrix(16).H*x),

11         markerfmt=’gs’, basefmt=’g-’,linefmt=’g-’,

12         label=’no padding’)

13 ax.set_xlabel(r’$\omega$’,fontsize=18)

14 ax.set_ylabel(r’$|X(\omega)|$’,fontsize=18)

15 ax.set_xticks([0, pi/2., pi, 3*pi/2,2*pi])

16 ax.axis([-.1, 2*pi,-.1,4.1])

17 ax.legend(loc=0,fontsize=18)

18 ax.set_xticklabels([’0’,r’\(\frac{\pi}{2}\)’, r’$\pi$’,r’\(\frac{3\pi}{2}\)’,

19                    r’$2\pi$’], fontsize=18);

20 ax.set_title(’Zero padding samples more frequencies’);

Listing 3.4: Listing corresponding to Fig. 3.5.

1 v = U[:,6].real

2 ax1,ax2=drawInOut(U.H*v,v,return_axes=1)

3 ax1.set_title(r’\(\omega=\frac{2\pi 5}{16}\)’)

Listing 3.5: Listing corresponding to Fig. 3.7.

1 v = matrix(cos(pi*arange(0,16))).T

2 ax1,ax2=drawInOut(U.H*v,v,return_axes=1)

3 ax1.set_title(’Highest Frequency’)

4 v = ones((16,1))

5 ax1,ax2=drawInOut(U.H*v,v,return_axes=1)

6 ax1.set_title(’Lowest Frequency’)

Listing 3.6: Listing corresponding to Fig. 3.4.

1 a=2*pi/64.*arange(64)

2 d=vstack([cos(a),sin(a),array(abs(X)).flatten()]).T

3

4 fig = plt.figure()

5 fig.set_size_inches(6,6)

6 ax = fig.add_subplot(1, 1, 1, projection=’3d’)

7 ax.axis([-1,1,-1,1])

8 ax.set_zlim([0,d[:,2].max()])

9 ax.set_aspect(1)

10 ax.view_init(azim=-30)

11

12 ax.set_xlabel(’real’)

13 ax.set_ylabel(’imag’)

14 ax.set_zlabel(’Abs’)

15 ax.set_title(’64-Point DFT Magnitude’)

16

17 def facet_filled(x,alpha=0.5,color=’b’):

18     ’construct 3D facet from adjacent points filled to zero’

19     a,b=x

20     a0= a*array([1,1,0])

21     b0= b*array([1,1,0])

22     ve = vstack([a,a0,b0,b])      # create closed polygon facet

23     poly = Poly3DCollection([ve]) # create facet

24     poly.set_alpha(alpha)

25     poly.set_color(color)

26     return poly

27

28 sl=[slice(i,i+2) for i in range(d.shape[0]-2)] # collect neighboring points

29 for s in sl:

30   poly=facet_filled(d[s,:])

31   ax.add_collection3d(poly)

32

33 # edge polygons

34 ax.add_collection3d(facet_filled(d[[-1,0],:]))

35 ax.add_collection3d(facet_filled(d[[-2,-1],:]))

36

37 # add 0 and pi/2 arrows for reference

38 a=FancyArrow(0,0,1,0,width=0.02,length_includes_head=True)

39 ax.add_patch(a)

40 b=FancyArrow(0,0,0,1,width=0.02,length_includes_head=True)

41 ax.add_patch(b)

42 art3d.patch_2d_to_3d(a)

43 art3d.patch_2d_to_3d(b)

44 plt.show()

Rights and permissions

Reprints and permissions

Copyright information

© 2014 Springer International Publishing Switzerland

About this chapter

Cite this chapter

Unpingco, J. (2014). Discrete-Time Fourier Transform. In: Python for Signal Processing. Springer, Cham. https://doi.org/10.1007/978-3-319-01342-8_3

Download citation

  • DOI: https://doi.org/10.1007/978-3-319-01342-8_3

  • Published:

  • Publisher Name: Springer, Cham

  • Print ISBN: 978-3-319-01341-1

  • Online ISBN: 978-3-319-01342-8

  • eBook Packages: EngineeringEngineering (R0)

Publish with us

Policies and ethics