A squaring block is something that multiplies a signal by itself, as the name suggests.

3.14. Mimic the code in speccos with Ts=1/1000 to find the spectrum of y(t), a squaring of the signals:

1. x(t) = cos(2pif*t) for f = 100Hz
2. cos(2pif1t)+cos(2pif2t) for f1=100Hz, f2=150Hz
3. filtered noise with spectrum between 100 and 300Hz.
In [7]:
import scipy.signal

def plotspec(x, Ts):
fig = figure()
ax1.plot(x)

q = fft.fft(x)
ax2.plot(fft.fftfreq(len(x), Ts), abs(q))

def arbspec(s, time, Ts):
t = linspace(0.0, time, time/Ts)
x = s(t)
plotspec(x, Ts)

In [12]:
arbspec(lambda t: cos(2*pi*100.0*t)**2, 2.0, 1.0/1000.0)
arbspec(lambda t: (cos(2*pi*100.0*t)+cos(2*pi*150.0*t))**2, 2.0, 1.0/1000.0)

def genbandpassf(ntaps, bottomf, topf, Ts):
q = bottomf/(1/Ts)
r = topf/(1/Ts)

b = scipy.signal.remez(ntaps, [0,q*0.98,q,r,r*1.02,0.5], [0,1,0])
return b

b = genbandpassf(100, 100, 300, 1.0/1000.0)
x = random.uniform(-1.0,1.0, 3.0*1000.0)
y = scipy.signal.lfilter(b,1,x)
plotspec(y**2, 1.0/1000.0)


3.15. (skipped)

3.17. Suppose y(t) = g(x(t)) is a posterizer: +1 if x(t) > 0, -1 if x(t) <= 0. Find the spectrum of its output when the input is:

1. x(t) = cos(2pif*t) for f = 100Hz
2. x(t) = cos(2pif1t) + cos(2pif2t) for f1=100 and f2=150Hz
In [18]:
def posterize(f):
def s(t):
return sign(f(t))
return s

arbspec( posterize(lambda t: cos(2*pi*100*t)), 2.0, 1.0/1000.0)
arbspec( posterize(lambda t: cos(2*pi*100*t)+cos(2*pi*150*t)), 2.0, 1.0/1000.0)


3.18. Suppose the output of a nonlinear block with input x(t) is y(t) = x**2(t)

1. cos(2pif*t+phi), f=100, phi=0.5
2. cos(2pif1t)+cos(2pif2t), f1=100, f2=150Hz
3. cos(2pif*t+phi) + n(t), f=100Hz, phi=0.5, n is white noise
In [21]:
def squaring(f):
def s(t):
return (f(t))**2
return s

Ts=1.0/1000.0
arbspec( squaring(lambda t: cos(2*pi*100*t+0.5)), 2.0, Ts)
arbspec( squaring(lambda t: cos(2*pi*100*t)+cos(2*pi*150*t)), 2.0, Ts)

# Do it once without squaring, to see how the noise looks
arbspec( squaring(lambda t: cos(2*pi*100*t+0.5) + random.uniform(-1.0,1.0,len(t))), 2.0, Ts)

arbspec( lambda t: cos(2*pi*100*t+0.5) + random.uniform(-1.0,1.0,len(t)), 2.0, Ts)


3.19. Using the quantalph() function, given x(t) = a vector of length n, taken via randn (the standard normal distribution). Quantize to [-3,-1,1,3].

1. What percentage of the values are 1 or 3?
2. Plot the spectrum of the input and the output.
3. Now let x=3*randn(1,n) and do the above.
In [26]:
def quantalph(x, alphabet):
alphabet.sort()

n = len(alphabet)

untouched = x < (x + 1)

y = copy(x)

for i in range(n):
candidates = logical_and(untouched, (x < alphabet[i]))
y[candidates] = alphabet[i]
untouched = logical_and(untouched, logical_not(candidates))

y[untouched] = alphabet[-1]
return y

In [28]:
x = random.normal(0,1, 100)
alphabet = [-3,3,-1,1]
y = quantalph(x, alphabet)
hist(y)

plotspec(x, 1.0/100.0)
plotspec(y, 1.0/100.0)

In [30]:
x = 3.0*random.normal(0,1, 100)
alphabet = [-3,3,-1,1]
y = quantalph(x, alphabet)
hist(y)

plotspec(x, 1.0/100.0)
plotspec(y, 1.0/100.0)


3.20. Modulate the following signals with a carrier wave of frequency 1kHz

1. x(t) = 100Hz + 150Hz
2. square wave of 150Hz
3. noise signal with all energy below 300Hz
4. noise between 2000 and 2300 Hz
5. noise below 1500Hz
In [33]:
def modulate(fc, x):
def s(t):
return x(t) * cos(2*pi*fc*t)
return s

arbspec(modulate(1000.0, lambda t: cos(2*pi*100*t)+cos(2*pi*150*t)), 2.0, 1.0/10000.0)

In [35]:
arbspec(modulate(1000.0, lambda t: sign(cos(2*pi*150*t))), 2.0, 1.0/10000.0)

In [37]:
def q(t):
b = genbandpassf(100, 0.001, 300, 1.0/1000.0)
x = random.uniform(-1.0,1.0, len(t))
y = scipy.signal.lfilter(b,1,x)
return y

arbspec(modulate(1000.0, q), 2.0, 1.0/10000.0)

In [40]:
def q(t):
b = genbandpassf(100, 2000, 2300, 1.0/10000.0)
x = random.uniform(-1.0,1.0, len(t))
y = scipy.signal.lfilter(b,1,x)
return y

arbspec(modulate(1000.0, q), 2.0, 1.0/10000.0)

In [41]:
def q(t):
b = genbandpassf(100, 0.001, 1500, 1.0/10000.0)
x = random.uniform(-1.0,1.0, len(t))
y = scipy.signal.lfilter(b,1,x)
return y

arbspec(modulate(1000.0, q), 2.0, 1.0/10000.0)