%pylab inline
Populating the interactive namespace from numpy and matplotlib
from __future__ import division
from deltasigma import *
Demonstration of the synthesizeNTF
function, as done in the MATLAB Delta Sigma Toolbox, employing its Python port deltasigma
.
The Noise Transfer Function (NTF) is synthesized for a 5th-order, low-pass modulator.
opt=0
),opt=1
).Then we move on to the synthesis of an 8th-order band-pass modulator with optimized zeros.
General parameters:
order = 5
OSR = 32
The synthesis of an NTF can be performed with the synthesizeNTF(order, OSR, opt)
.
We intentionally disable the zeros optimization, setting opt=0
.
# Synthesize!
H0 = synthesizeNTF(order, OSR, opt=0)
# 1. Plot the singularities.
subplot(121)
plotPZ(H0, markersize=5)
title('NTF Poles and Zeros')
f = np.concatenate((np.linspace(0, 0.75/OSR, 100), np.linspace(0.75/OSR, 0.5, 100)))
z = np.exp(2j*np.pi*f)
magH0 = dbv(evalTF(H0, z))
# 2. Plot the magnitude responses.
subplot(222)
plot(f, magH0)
figureMagic([0, 0.5], 0.05, None, [-100, 10], 10, None, (16, 8))
xlabel('Normalized frequency ($1\\rightarrow f_s)$')
ylabel('dB')
title('NTF Magnitude Response')
# 3. Plot the magnitude responses in the signal band.
subplot(224)
fstart = 0.01
f = np.linspace(fstart, 1.2, 200)/(2*OSR)
z = np.exp(2j*np.pi*f)
magH0 = dbv(evalTF(H0, z))
semilogx(f*2*OSR, magH0)
axis([fstart, 1.2, -100,- 30])
grid(True)
sigma_H0 = dbv(rmsGain(H0, 0, 0.5/OSR))
#semilogx([fstart, 1], sigma_H0*np.array([1, 1]))
semilogx([fstart, 1], sigma_H0*np.array([1, 1]),'-o')
text(0.15, sigma_H0 + 5, 'rms gain = %5.0fdB' % sigma_H0)
xlabel('Normalized frequency ($1\\rightarrow f_B$)')
ylabel('dB')
tight_layout()
This time we enable the zeros optimization, setting opt=1
when calling synthesizeNTF(), then replot the NTF as above.
# Synthesize again!
H0 = None
H1 = synthesizeNTF(order, OSR, opt=1)
# 1. Plot the singularities.
subplot(121)
plotPZ(H1, markersize=5)
title('NTF Poles and Zeros')
f = np.concatenate((np.linspace(0, 0.75/OSR, 100), np.linspace(0.75/OSR, 0.5, 100)))
z = np.exp(2j*np.pi*f)
magH1 = dbv(evalTF(H1, z))
# 2. Plot the magnitude responses.
subplot(222)
plot(f, magH1)
figureMagic([0, 0.5], 0.05, None, [-100, 10], 10, None, (16, 8))
xlabel('Normalized frequency ($1\\rightarrow f_s)$')
ylabel('dB')
title('NTF Magnitude Response')
# 3. Plot the magnitude responses in the signal band.
subplot(224)
fstart = 0.01
f = np.linspace(fstart, 1.2, 200)/(2*OSR)
z = np.exp(2j*np.pi*f)
magH1 = dbv(evalTF(H1, z))
semilogx(f*2*OSR, magH1)
axis([fstart, 1.2, -100,- 30])
grid(True)
sigma_H1 = dbv(rmsGain(H1, 0, 0.5/OSR))
#semilogx([fstart, 1], sigma_H1*np.array([1, 1]))
semilogx([fstart, 1], sigma_H1*np.array([1, 1]),'-o')
text(0.15, sigma_H1 + 5, 'RMS gain = %5.0fdB' % sigma_H1)
xlabel('Normalized frequency ($1\\rightarrow f_B$)')
ylabel('dB')
tight_layout()
Overlayed plots follow to ease comparison of the two synthetization approaches.
# Synthesize!
H0 = synthesizeNTF(order, OSR, opt=0)
H1 = synthesizeNTF(order, OSR, opt=1)
# 1. Plot the singularities.
subplot(121)
# we plot the singularities of the optimized NTF in light
# green with slightly bigger markers so that we can better
# distinguish the two NTF's when overlayed.
plotPZ(H1, markersize=7, color='#90EE90')
hold(True)
plotPZ(H0, markersize=5)
title('NTF Poles and Zeros')
f = np.concatenate((np.linspace(0, 0.75/OSR, 100), np.linspace(0.75/OSR, 0.5, 100)))
z = np.exp(2j*np.pi*f)
magH0 = dbv(evalTF(H0, z))
magH1 = dbv(evalTF(H1, z))
# 2. Plot the magnitude responses.
subplot(222)
plot(f, magH0, label='All zeros in z=1')
hold(True)
plot(f, magH1, label='Optimized zeros')
figureMagic([0, 0.5], 0.05, None, [-100, 10], 10, None, (16, 8))
xlabel('Normalized frequency ($1\\rightarrow f_s)$')
ylabel('dB')
legend(loc=4)
title('NTF Magnitude Response')
# 3. Plot the magnitude responses in the signal band.
subplot(224)
fstart = 0.01
f = np.linspace(fstart, 1.2, 200)/(2*OSR)
z = np.exp(2j*np.pi*f)
magH0 = dbv(evalTF(H0, z))
magH1 = dbv(evalTF(H1, z))
semilogx(f*2*OSR, magH0, label='All zeros in z=1')
hold(True)
semilogx(f*2*OSR, magH1, label='Optimized zeros')
axis([fstart, 1.2, -100,- 30])
grid(True)
sigma_H0 = dbv(rmsGain(H0, 0, 0.5/OSR))
sigma_H1 = dbv(rmsGain(H1, 0, 0.5/OSR))
#semilogx([fstart, 1], sigma_H0*np.array([1, 1]))
plot([fstart, 1], sigma_H0*np.array([1, 1]), 'o-')
text(0.15, sigma_H0 + 5, 'RMS gain = %5.0fdB' % sigma_H0)
#semilogx([fstart, 1], sigma_H1*np.array([1, 1]))
plot([fstart, 1], sigma_H1*np.array([1, 1]), 'o-')
text(0.15, sigma_H1 + 5, 'RMS gain = %5.0fdB' % sigma_H1)
xlabel('Normalized frequency ($1\\rightarrow f_B$)')
ylabel('dB')
legend(loc=4)
tight_layout()
In the following, we synthesize an 8th-order modulator with optimized zeros.
order = 8
OSR = 64
opt = 2
f0 = 0.125
H = synthesizeNTF(order, OSR, opt, 1.5, f0)
subplot(121)
plotPZ(H)
title('Bandpass NTF Poles and Zeros')
f = np.concatenate((np.linspace(0, f0 - 1./(2.*OSR), 50),
np.linspace(f0 - 1./ (2 * OSR), f0 + 1./(2.*OSR), 100),
np.linspace(f0 + 1./(2.*OSR), 0.5, 50)))
z = np.exp(2j * pi * f)
magH = dbv(evalTF(H, z))
subplot(222)
plot(f, magH)
hold(True)
G = (np.zeros((order/2,)), H[1], 1)
k = 1./np.abs(evalTF(G, np.exp(2j*np.pi*f0)))
G = (G[0], G[1], k)
magG = dbv(evalTF(G, z))
plot(f, magG, 'r')
figureMagic([0, 0.5], 0.05, None, [-100, 10], 10, None, (16, 8))
#axis([0, 0.5, -100, 10])
grid(True)
xlabel('Normalized frequency ($1 \\rightarrow fs$)')
ylabel('dB')
title('Bandpass NTF/STF Magnitude Response')
f = np.linspace(f0 - 0.3/OSR, f0 + 0.3/OSR)
z = np.exp(2j*np.pi*f)
magH = dbv(evalTF(H, z))
subplot(224)
fstart = -.5
plot(2*OSR*(f - f0), magH)
axis([- 0.6, 0.6, -100, -60])
grid(True)
sigma_H = dbv(rmsGain(H, f0 - 0.25/OSR, f0 + 0.25/OSR))
hold(True)
#plot([-0.5, 0.5], sigma_H*np.array([1, 1]))
plot([-0.5, 0.5], sigma_H*np.array([1, 1]), 'o-')
text(-.2, sigma_H + 5, 'rms gain = %5.0fdB' % sigma_H)
xlabel('Normalized frequency offset')
ylabel('dB')
tight_layout()
Help on function synthesizeNTF in module deltasigma._synthesizeNTF:
synthesizeNTF(order=3, osr=64, opt=0, H_inf=1.5, f0=0.0)
Synthesize a noise transfer function for a delta-sigma modulator.
Parameters:
order : int, optional the order of the modulator, defaults to 3
osr : float, optional the oversamping ratio, defaults to 64
opt : int or list of floats, optional flag for optimized zeros, defaults to 0
H_inf : real, optional max allowed peak value of the NTF. Defaults to 1.5
f0 : real, optional center frequency for BP modulators, or 0 for LP modulators. Defaults to 0.
1 corresponds to the sampling frequency, so that 0.5 is the
maximum value. A value of 0 specifies an LP modulator.
Returns:
ntf : tuple noise transfer function in zpk form.
Raises:
ValueError
'Error. f0 must be less than 0.5' if f0 is out of range
'Order must be even for a bandpass modulator.' if the order is incompatible with the modulator type.
'The opt vector must be of length xxx' if opt is used to explicitly pass the NTF zeros and these are in the wrong number.
Warns:
'Creating a lowpass ntf.' if the center frequency is different from zero, but so low that a low pass modulator must be designed.
'Unable to achieve specified H_inf ...' if the desired H_inf cannot be achieved.
'Iteration limit exceeded' if the routine converges too slowly.
Notes:
This is actually a wrapper function which calls the appropriate version
of synthesizeNTF, based on the module control flag optimize_NTF
which
determines whether to use optimization tools.
Parameter H_inf
is used to enforce the Lee stability criterion.
See also:
clans()
: Closed-Loop Analysis of Noise-Shaper.An alternative method for selecting NTFs based on the 1-norm of the impulse response of the NTF
synthesizeChebyshevNTF()
: Select a type-2 highpass Chebyshev NTF.This function does a better job than synthesizeNTF if osr or H_inf is low.
#%install_ext http://raw.github.com/jrjohansson/version_information/master/version_information.py
%load_ext version_information
%reload_ext version_information
%version_information numpy, scipy, matplotlib, deltasigma
Software | Version |
---|---|
Python | 2.7.8 (default, Jul 26 2014, 17:29:00) [GCC 4.9.1] |
IPython | 2.1.0 |
OS | posix [linux2] |
numpy | 1.8.1 |
scipy | 0.13.3 |
matplotlib | 1.3.1 |
deltasigma | 0.1-5 |
Mon Aug 11 21:50:24 2014 CEST |