Source code for deltasigma._synthesizeNTF

# -*- coding: utf-8 -*-
# Module providing the synthesizeNTF function
# Copyright 2013 Giuseppe Venturini
# This file is distributed with python-deltasigma.
# python-deltasigma is a 1:1 Python replacement of Richard Schreier's
# MATLAB delta sigma toolbox (aka "delsigma"), upon which it is heavily based.
# The delta sigma toolbox is (c) 2009, Richard Schreier.
# python-deltasigma is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# LICENSE file for the licensing terms.
# The following code has been (slightly) modified from pydsm, its original
# copyright notice follows:
# Copyright (c) 2012, Sergio Callegari
# All rights reserved.
# The py dsm code was ported from the MATLAB Delta Sigma toolbox
# Copyright (c) 2009, Richard Schreier
# The three software follow the same license, known as the 2-clause BSD.
# See the LICENSE file for details.

Module providing the main NTF synthesis function.

from warnings import warn

import numpy as np

from ._config import optimize_NTF
from ._synthesizeNTF0 import synthesizeNTF0
from ._synthesizeNTF1 import synthesizeNTF1

[docs]def 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 oversampling ratio, defaults to 64. opt : int or list of floats, optional flag to select which algorithm is to be used to place the zeros, defaults to 0. * 0 -> not optimized, * 1 -> optimized, * 2 -> optimized with at least one zero at band-center, * 3 -> optimized zeros (with optimizer) * 4 -> same as 3, but with at least one zero at band-center * [z] -> zero locations in complex form H_inf : float, optional maximum allowed value of the absolute value of the NTF. Defaults to 1.5. f0 : float, optional center frequency for band-pass modulators, or 0 for low-pass modulators. Defaults to 0. The frequency is normalized throughout the ``deltasigma`` package. The normalization is: 1 corresponds to the sampling frequency. Therefore 0.5 is the maximum value that can be assigned to ``f0``. **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 odd and therefore 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 low-pass NTF.', if the center frequency is different from zero, but so close to 0 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. The parameter ``H_inf`` is used to enforce the Lee stability criterion. **Example:** Fifth-order low-pass modulator; zeros optimized for an oversampling ratio of 32.:: from deltasigma import * H = synthesizeNTF(5, 32, 1) pretty_lti(H) Returns:: (z -1) (z^2 -1.997z +1) (z^2 -1.992z +0.9999) -------------------------------------------------------- (z -0.7778) (z^2 -1.796z +0.8549) (z^2 -1.613z +0.665) .. plot:: from deltasigma import * H = synthesizeNTF(5, 32, 1) DocumentNTF(H, 32) .. seealso:: :func:`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. :func:`synthesizeChebyshevNTF()` : Select a type-2 highpass Chebyshev NTF. This function does a better job than :func:`synthesizeNTF` if ``osr`` or ``H_inf`` is low. """ if f0 > 0.5: raise ValueError('Error. f0 must be less than 0.5.') if f0 != 0 and f0 < 0.25/osr: warn('Creating a lowpass ntf.') f0 = 0 if f0 != 0 and order % 2 != 0: raise ValueError('Order must be even for a bandpass modulator.') opt = np.asarray(opt) if opt.ndim > 1 or (opt.ndim == 1 and opt.size != order): raise ValueError('The opt vector must be of length %d.' % order) if not optimize_NTF: ntf = synthesizeNTF0(order, osr, opt, H_inf, f0) else: ntf = synthesizeNTF1(order, osr, opt, H_inf, f0) return ntf