DETECTOR

In review

This page runs a BASIC program that detects the frequency of a periodic function. The program is rewritten in Python and runs right here in your browser. Edit the code and press Run to redraw the graph; Reset brings back the original program.

The function is \(f(t) = 3\sin(5t)\). For each frequency ω between 0 and 3, the program computes the average value of \(f(t)\sin(2\pi\omega t)\) over \(0 \le t \le 10\),

\[ \frac{1}{b - a} \int_a^b f(t)\, \sin(2\pi \omega t)\, dt, \]

and graphs that average against ω. When \(\sin(2\pi\omega t)\) rises and falls in step with \(f(t)\), the product is mostly positive and the average is large; at other frequencies the product keeps changing sign and the average stays near 0. The peak should sit at \(2\pi\omega = 5\), that is \(\omega = 5/(2\pi) \approx 0.796\), with height about 1.5, half of f’s amplitude.

There are two loops. The outer one, FOR j = 1 TO omegasteps, moves ω across from 0 to 3 in 1024 steps. The inner one, FOR k = 1 TO numberofsteps, finds the integral with a Riemann sum of 128 pieces. It starts at t = a + deltat / 2, the middle of the first piece, so this is a midpoint sum. Each pass of the outer loop draws a segment from the previous point (oldomega, oldaccum) to the new one.

Try changing fnf to 2 * math.sin(3 * t) + math.sin(8 * t) and look for two peaks, or shorten the time interval b to see the peak spread out.

QBasic lets a FUNCTION be written at the end of the program, after the code that uses it. Python needs a function to be defined before it is called, so in the Python the def comes first, and return gives back the value that BASIC sets with fnf = .... SIN becomes math.sin. The program gets \(2\pi\) as 8 * ATN(1), because the arctangent of 1 is \(\pi/4\) and QBasic has no built-in π; in Python that is 8 * math.atan(1), which is the same as 2 * math.pi.

Notes from the textbook

Add notes here.

 1  DEFDBL A-Z
 2  SCREEN 12
 3  WINDOW (0, -1)-(3, 2)
 4  startomega = 0
 5  endomega = 3
 6  omegasteps = 2 ^ 10
 7  deltaomega = (endomega - startomega) / omegasteps
 8  twopi = 8 * ATN(1)
 9  a = 0
10  b = 10
11  numberofsteps = 2 ^ 7
12  deltat = (b - a) / numberofsteps
13  omega = startomega
14  oldomega = omega
15  oldaccum = 0
16  FOR j = 1 TO omegasteps
17          t = a + deltat / 2
18          accum = 0
19          FOR k = 1 TO numberofsteps
20                  deltaS = (fnf(t) * SIN(twopi * omega * t) * deltat) / (b - a)
21                  accum = accum + deltaS
22                  t = t + deltat
23          NEXT k
24          omega = omega + deltaomega
25          LINE (oldomega, oldaccum)-(omega, accum)
26          oldomega = omega
27          oldaccum = accum
28  NEXT j
29  FUNCTION fnf (t)
30          fnf = 3 * SIN(5 * t)
31  END FUNCTION

Graph

Each line(...) draws one straight segment, like BASIC's LINE, and window(...) sets the visible range, like WINDOW. Hover over the graph to read coordinates.

Loading Python. The first run takes a few seconds.

Python code

Press Run (or Ctrl/⌘ + Enter) to redraw the graph. Press Esc, then Tab, to leave the editor.

Loading Python…