diff options
Diffstat (limited to 'graphics/pstricks/contrib/dsptricks/dspTricksManual.tex')
-rw-r--r-- | graphics/pstricks/contrib/dsptricks/dspTricksManual.tex | 172 |
1 files changed, 117 insertions, 55 deletions
diff --git a/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex b/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex index 2b733a9faa..e8be7a5bf1 100644 --- a/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex +++ b/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex @@ -1,13 +1,13 @@ % User manual for the DSPTricks package -% (c) Paolo Prandoni, 2014 -% v1.0, July 2014 +% (c) Paolo Prandoni, 2014-2023 +% v1.1, November 2023 % For more information, authors@sp4comm.org -\documentclass[a4paper,10pt]{ltxdoc} +\documentclass[a4paper,14pt]{ltxdoc} \usepackage{float} \usepackage{fancyvrb} \usepackage{enumitem} -\usepackage[utopia]{mathdesign} +\usepackage{newpxtext,newpxmath} \usepackage{url} \usepackage{dsptricks,dspfunctions,dspblocks} @@ -41,29 +41,37 @@ \begin{document} -\title{\dspt \\ A Set of Macros for Digital Signal Processing Plots} +\title{\dspt: a Set of Macros \\ for Digital Signal Processing Plots} \author{Paolo Prandoni} -\date{} +%\date{} \maketitle -The package \dspt\ is a set of \LaTeX\ macros for plotting the kind of graphs and figures that are usually employed in digital signal processing publications\footnote{The original macros have been written by the author while working on the manuscript for~\cite{PV}.}; the package relies on \psTricks~\cite{TVZ93,HV} to generate its graphic output. +The package \dspt\ provides a set of \LaTeX\ macros for plotting the kind of graphs and figures that are usually employed in digital signal processing publications\footnote{The original macros have been written by the author while working on the manuscript for~\cite{PV}.}; the package relies on \psTricks~\cite{TVZ93,HV} to generate its graphic output. %\footnote{Please note that these macros have been written rather quickly and chiefly for personal use. Use at your own risk and caveat emptor.} +\\ + +The basic \dspt\ plot is a boxed chart displaying a discrete-time or a continuous-time signal, or a superposition of both; discrete-time signals are plotted using the ``lollipop'' formalism while continuous-time functions are rendered as smooth curves. Other types of plots that commonly occur in the signal processing literature, and for which \dspt\ offers macros, are frequency-domain plots and pole-zero plots. \dspt\ comes with two companion packages: +\begin{itemize} + \item \dspb\ provides a set of macros to design simple signal processing block diagrams; + \item \dspf\ provides a set of signal shapes commonly used in basic signal processing in terms of PostScript primitives (such as rect, sinc, etc), as well as macros to compute DFTs, frequency responses, and filter outputs on the fly. +\end{itemize} -The basic \dspt\ plot is a boxed chart displaying a discrete-time or a continuous-time signal, or a superposition of both; discrete-time signals are plotted using the ``lollipop'' formalism while continuous-time functions are rendered as smooth curves. Other types of plots that commonly occur in the signal processing literature, and for which \dspt\ offers macros, are frequency plots and pole-zero plots. The companion package \dspf\ defines some signals commonly used in basic signal processing in terms of PostScript primitives, while the package \dspb\ provides a set of macros to design simple signal processing block diagrams. + +The idea behind these macros is to be able to write a completely self-contained signal processing manuscript without the need of an external numerical package to precompute the necessary signals. \section{Drawing Signals} -Signal plots in \dspt\ are defined by a Cartesian grid enclosed by a box; there are three fundamental types of plots: +Signal plots in \dspt\ use a Cartesian grid enclosed by a box; there are three fundamental types of plots: \begin{itemize} \item discrete-time plots, \item continuous-time plots, \item frequency-domain plots; \end{itemize} -discrete- and continuous-time plots can be mixed, whereas frequency-domain plots involve a re-labeling of the horizontal axis in trigonometric units. +discrete- and continuous-time plots can be mixed in the same box, whereas frequency-domain plots involve a re-labeling of the horizontal axis using trigonometric units. \subsection{The {\tt dspPlot} environment} @@ -101,7 +109,7 @@ This sets up a data plot with the horizontal axis spanning the \meta{xmin}-\meta -Within a |dspPlot| environment you can use the plotting commands described in the next sections, as well as any \psTricks\ command; in the latter case, the \psTricks\ values for |xunit| and |yunit| are scaled to the axes (i.e., they correspond to the cartesian values of the plot). Other useful commands for all data plots are the following: +Within a |dspPlot| environment you can use the plotting commands described in the next sections, as well as any \psTricks\ command; in the latter case, the \psTricks\ values for |xunit| and |yunit| are equal to the units used for the axes. Other useful commands for all data plots are the following: \begin{itemize} \item \DescribeEnv{dspClip} in order to make sure that all drawing commands are clipped to the bounding box defined by the box chart, you can enclose them individually in a predefined |dspClip| environment. See section~\ref{clipEx} for an example. \item \DescribeMacro{dspPlotFrame} to redraw the framing box (useful to ``smooth out'' plots touching the frame) you can issue the command |\dspPlotFrame| @@ -109,7 +117,9 @@ Within a |dspPlot| environment you can use the plotting commands described in th \begin{quote} |\dspCustomTicks|\oarg{options}\marg{pos label pos label ...} \end{quote} - where the axis is specified in the options field as either |axis=x| (default) or |axis=y| and where the argument is a list of space-separated coordinate-label pairs. If you use math mode for the labels, \emph{do not use spaces in your formulas} since that will confuse the list-parsing macros. + where the axis is specified in the options field as either |axis=x| (default) or |axis=y| and where the argument is a list of space-separated coordinate-label pairs. If you use math mode for the labels, \emph{do not use spaces in your formulas} since that will confuse the list-parsing macros. + + \textbf{NOTE}: there is an incompatibility between |\dspCustomTicks| and the |tabular| environment. When using |\dspCustomTicks| in a table, enclose all lines between |\begin{dspPlot}| and |\end{dspPlot}| in a group (\{ ~\}). \item \DescribeMacro{dspText} place a text label anywhere in the plot using the axes coordinates: \begin{quote} |\dspText|(x, y)\marg{label} @@ -145,7 +155,7 @@ The following commands generate stem (or ``lollipop'') plots; available options \end{quote} The PostScript code must use the variable |x| as the independent variable; the |\dspPlot| environment sweeps |x| over all integers in the \meta{xmin}-\meta{xmax} interval defined for the plot; this can be changed for each individual signal by using the options \DescribeMacro{xmin,xmax} |xmin|=\meta{m} and/or |xmax|=\meta{n}. If you use \TeX\ macros in your PS code, make sure you include a space at the end of the macro definition. For instance, use |\def\gain\{0.75|\textvisiblespace|}|. - \item \DescribeMacro{dspSignalOpt} to perform a PostScript initialization sequence before evaluating the signal, use + \item \DescribeMacro{dspSignalOpt} to perform a PostScript initialization sequence before plotting the discrete-time signal, use \begin{quote} |\dspSignalOpt|\oarg{options}\marg{init}\marg{PostScript code} \end{quote} @@ -185,6 +195,12 @@ Continuous-time functions can be plotted with the following commands: |\dspFunc|\oarg{options}\marg{PostScript code} \end{quote} again, the PostScript code must use |x| as the independent variable; the range for |x| is the \meta{xmin}-\meta{xmax} interval and can be controlled for each signal independently via the|xmin| and |xmax| options. + + \item \DescribeMacro{\dspFuncOpt} to perform a PostScript initialization sequence before plotting the continuous-time signal, use + \begin{quote} + |\dspFuncOpt|\oarg{options}\marg{init}\marg{PostScript code} + \end{quote} + where \meta{init} is a valid PostScript sequence. \item \DescribeMacro{dspFuncData} To plot a smooth function obtained by interpolating a list of space separated time-value pairs use \begin{quote} @@ -192,6 +208,12 @@ Continuous-time functions can be plotted with the following commands: \end{quote} the interpolation is performed by the PostScript interpreter and can be controlled if necessary by using the appropriate \psTricks\ options. + \item \DescribeMacro{dspFuncDataAt} To plot a smooth function obtained by interpolating a list of space separated values use + \begin{quote} + |\dspFuncDataAt|\oarg{options}\marg{start}\marg{data} + \end{quote} + This macro works like |\dspFuncData| but the time indices are assumed to be increasing integers beginning at \meta{start}. + \item \DescribeMacro{dspFuncFile} For a continuous-time smooth interpolation of a pre-computed set of data points, use \begin{quote} |\dspFuncFile|\oarg{options}\marg{fileName} @@ -450,17 +472,16 @@ To plot analog spectra, just set up a plot environment as you would to plot a co \vblock \begin{dspPlot}[xtype=freq,xticks=custom,xlabel={freq. (Hz)},% - yticks=2,ylabel={$X(j\Omega)$}]{-10,10}{-1,5} + yticks=2,ylabel={$X(f)$}]{-10,10}{-1,5} \dspFunc{x abs 4 gt {0} {x abs 2 div dup mul 4 exch sub} ifelse} - \dspCustomTicks{-4 $-\Omega_N$ 0 $0$ 4 $\Omega_N$ 8 $\Omega_s$} + \dspCustomTicks[axis=x]{-4 $-f_N$ 0 $0$ 4 $f_N$ 8 $F_s$} \end{dspPlot} \end{Verbatim} \begin{centerfig} - \begin{dspPlot}[xtype=freq,xticks=custom,xlabel={freq. (Hz)},% - yticks=2,ylabel={$X(j\Omega)$}]{-10,10}{-1.5,5} + \begin{dspPlot}[xtype=freq,xticks=custom,xlabel={freq. (Hz)},yticks=2,ylabel={$X(f)$}]{-10,10}{0,5} \dspFunc{x abs 4 gt {0} {x abs 2 div dup mul 4 exch sub} ifelse} - \dspCustomTicks{-4 $-\Omega_N$ 0 $0$ 4 $\Omega_N$ 8 $\Omega_s$} + \dspCustomTicks[axis=x]{-4 $-f_N$ 0 $0$ 4 $f_N$ 8 $F_s$} \end{dspPlot} \end{centerfig} @@ -471,63 +492,73 @@ To facilitate the creation of plots that commonly occur in signal processing the \subsubsection*{Basic Shapes:} \begin{itemize} - \item |\dspRect{a}{b}| computes a rectangular (box) function centered in $a$ and with support $2b$, i.e. $\mbox{rect}((x-a)/b)$ where + \item \DescribeMacro{\dspRect} |\dspRect{a}{b}| computes the function $\mbox{rect}((x-a)/b)$ where \[ \mbox{rect}(x) = \left\{\begin{array}{ll} 1 & \mbox{if $|x|<1/2$} \\ 0 & \mbox{otherwise} \end{array}\right. \] - \item |\dspTri{a}{b}| computes a triangle function centered in $a$ and with support $2b$ - \item |\dspSinc{a}{b}| computes the scaled sinc function $\mbox{sinc}((x-a)/b)$, where + i.e. a rectangular (box) function centered in $a$ and with support $2b$. + \item \DescribeMacro{\dspTri} |\dspTri{a}{b}| computes a triangular function centered in $a$ and with support $2b$ + \item \DescribeMacro{\dspSinc} |\dspSinc{a}{b}| computes the scaled sinc function $\mbox{sinc}((x-a)/b)$, where \[ \mbox{sinc}(x) = \frac{\sin(\pi x)}{\pi x} \] - \item |\dspQuad{a}{b}| computes a quadratic function (inverted parabola) centered in $a$ and with support $2b$ - \item |\dspExpDec{a}{b}| computes the decaying exponential response $b^(x-a)u[x-a]$ - \item |\dspPorkpie{a}{b}| computes a ``porkpie hat'' shape centered in $a$ and with support $2b$ - \item |\dspRaisedCos{a}{b}{r}| computes a raised cosine centered in $a$ with cutoff $b$ and rolloff $r$ + \item \DescribeMacro{\dspQuad} |\dspQuad{a}{b}| computes a quadratic function (inverted parabola) centered in $a$ and with support $2b$ + \item \DescribeMacro{\dspExpDec} |\dspExpDec{a}{b}| computes the decaying exponential response $b^{(x-a)}u[x-a]$ + \item \DescribeMacro{\dspPorkpie} |\dspPorkpie{a}{b}| computes a ``porkpie hat'' shape centered in $a$ and with support $2b$ + \item \DescribeMacro{\dspRaisedCos} |\dspRaisedCos{a}{b}{r}| computes a raised cosine centered in $a$ with cutoff $b$ and rolloff $r$ + \item \DescribeMacro{\dspSincS} |\dspSincS{a}{N}| computes the function + \[ + \frac{\sin(\omega(2N+1)/2)}{\sin(\omega/2)} \qquad{\omega = \pi(x-a)} + \] + that is, the Discrete-Time Fourier transform (DTFT) of a zero-centered, symmetric $2N+1$-tap rectangular signal. This is used in frequency plots and in this case the free variable $x$, which ranges from $-1$ to $1$, is rescaled as $\omega = \pi x$. + The parameter $a$ can be used to shift the DTFT to the chosen center frequency over the $[-1, 1]$ interval. + \item \DescribeMacro{\dspSincC} |\dspSincC{a}{N}| computes the DTFT \textit{magnitude} for a causal $N$-tap rectangular signal: + \[ + \vert \frac{\sin(\omega(N/2))}{\sin(\omega/2)} \vert \qquad {\omega = \pi(x-a)} + \] + See |\dspSincS{a}{N}| for details on $x$ and $a$. \end{itemize} \subsubsection*{Discrete Fourier Transform:} \begin{itemize} - \item |\dspDFTMAG{x_0 x_1 ... x_{N-1}}| computes the magnitude of the Discrete Fourier transform (DFT) of the provided data points\footnote{Please note that the underlying implementation of the macro is not optimized; the computing time will be quadratic in the number of data points.}; the input value should be an integer. + \item \DescribeMacro{\dspDFTMAG} |\dspDFTMAG{a_0 a_1 ... a_{N-1}}| computes the magnitude of the Discrete Fourier transform (DFT) of the provided data points\footnote{Please note that the underlying implementation of the macro is not optimized; the computing time will be quadratic in the number of data points.}: \[ - X[k] = \vert \sum_{n=0}^{N-1}x[n]e^{j\frac{2\pi}{N}nk} \vert + \vert \sum_{n=0}^{N-1}a_n e^{j\frac{2\pi}{N}nk} \vert \qquad n = x; \] - \item |\dspDFTRE{x_0 x_1 ... x_{N-1}}| computes the real part of the DFT - \item |\dspDFTIM{x_0 x_1 ... x_{N-1}}| computes the imaginary part of the DFT + the value of $x$ should range over integers only. + \item |\dspDFTRE{a_0 a_1 ... a_{N-1}}| computes the real part of the DFT + \item |\dspDFTIM{a_0 a_1 ... a_{N-1}}| computes the imaginary part of the DFT \end{itemize} -\subsubsection*{Notable DTFTs:} -\begin{itemize} - \item |\dspSincS{a}{N}| computes the Discrete-Time Fourier transform (DTFT) of a zero-centered, symmetric $2N+1$-tap rectangular signal: - \[ - X(e^{j\omega}) = \frac{\sin(\omega(2N+1)/2)}{\sin(\omega/2)} - \] - The parameter $a$ can be used to shift the DTFT to the chosen center frequency. - \item |\dspSincC{a}{N}| computes the DTFT magnitude of a causal $N$-tap rectangular signal: - \[ - \vert X(e^{j\omega})\vert =\frac{\sin(\omega(N/2))}{\sin(\omega/2)} - \] - The parameter $a$ can be used to shift the DTFT to the chosen center frequency. -\end{itemize} \subsubsection*{Frequency Responses:} \begin{itemize} - \item |\dspFIRI{a_0 a_1 ... a_{N-1}}| computes the (real-valued) frequency response of a zero centered $(2N+1)$-tap Type-I FIR filter with coefficients + \item \DescribeMacro{\dspFIRI} |\dspFIRI{b_0 b_1 ... b_{N-1}}| computes the (real-valued) frequency response for $\omega = \pi x$ of a zero centered $(2N-1)$-tap Type-I FIR filter with coefficients \[ - a_{N-1}, a_{N-2}, \ldots, a_{1}, a_{0}, a_{1}, a_{2}, \ldots, a_{N-1}. + b_{N-1}, b_{N-2}, \ldots, b_{1}, b_{0}, b_{1}, b_{2}, \ldots, b_{N-1}. \] - The coefficient $a_0$ is the center tap and you need only specify the coefficients from $a_0$ to $a_{N-1}$. + The coefficient $b_0$ is the center tap and you need only specify the coefficients from $b_0$ to $b_{N-1}$. - \item |\dspTFM{a_0 a_1 ... a_{N-1}}{b_1 b_2 ... b_{M-1}}| computes the magnitude response of a generic digital filter defined by the constant-coefficient difference equation: + \item \DescribeMacro{\dspTFM} |\dspTFM{b_0 b_1 b_2 ... b_{M-1}}{a_1 ... a_{N-1}}| computes the magnitude response for $\omega = \pi x$ of a generic digital filter defined by the constant-coefficient difference equation: \[ - y[n] = a_0 x[n] + ... + a_{N-1} x[n-N+1] - b_1 y[n-1] - ... - b_{M-1} y[n-M+1] + y[n] = b_0 x[n] + ... + b_{N-1} x[n-N+1] - a_1 y[n-1] - ... - a_{M-1} y[n-M+1] \] \end{itemize} +\subsubsection*{Filtering Data:} +\begin{itemize} + \item \DescribeMacro{\dspFilter} |\dspFilter| computes the output of a generic IIR filter + \[ + y[n] = b_0 x + b_1 x[n-1] + ... + b_{N-1} x[n-N+1] - a_1 y[n-1] - ... - a_{M-1} y[n-M+1] + \] + The filter coefficients should be set in the initialization portion of either |\dspSignalOpt| or |\dspFuncOpt| via the macro:\\ |\dspSetFilter{b_0 b_1 ... b_{M-1}}{a_1 ... a_{N-1}}}| +\end{itemize} + + For instance: \vblock @@ -590,10 +621,9 @@ The magnitude of simple FIR and IIR filter can be graphed easily like so: \dspFunc{x \dspTFM{0.000008952611389 0.000071620891113 0.000250673118897 0.000501346237795 0.000626682797244 0.000501346237795 0.000250673118897 0.000071620891113 - 0.000008952611389}{ 1.000000000000000 -5.975292291885454 - 16.581223292021008 -27.714232735429224 30.395097583553124 - -22.347296704268793 10.745098004349103 -3.089246336974975 - 0.407076858898017}} + 0.000008952611389}{ -5.975292291885454 16.581223292021008 + -27.714232735429224 30.395097583553124 -22.347296704268793 + 10.745098004349103 -3.089246336974975 0.407076858898017}} \end{dspPlot} \end{Verbatim} @@ -604,14 +634,46 @@ The magnitude of simple FIR and IIR filter can be graphed easily like so: \dspFunc{x \dspTFM{0.000008952611389 0.000071620891113 0.000250673118897 0.000501346237795 0.000626682797244 0.000501346237795 0.000250673118897 0.000071620891113 - 0.000008952611389}{ 1.000000000000000 -5.975292291885454 - 16.581223292021008 -27.714232735429224 30.395097583553124 - -22.347296704268793 10.745098004349103 -3.089246336974975 - 0.407076858898017}} + 0.000008952611389}{ -5.975292291885454 16.581223292021008 + -27.714232735429224 30.395097583553124 -22.347296704268793 + 10.745098004349103 -3.089246336974975 0.407076858898017}} \end{dspPlot} \end{centerfig} +In this example we plot a triangular signal and its filtered version using the Chebyshev lowpass filter defined above: + +\vblock +\begin{dspPlot}[xtype=freq,xticks=4]{-1,1}{0,1.1} +\begin{dspPlot}[xout=true]{0,40}{-.4,1.1} + \dspSignal[linecolor=lightgray]{x \dspTri{5}{5}} + \dspSignalOpt[linecolor=blue!60]{ + \dspSetFilter{0.000008952611389 0.000071620891113 + 0.000250673118897 0.000501346237795 0.000626682797244 + 0.000501346237795 0.000250673118897 0.000071620891113 + 0.000008952611389}{ -5.975292291885454 16.581223292021008 + -27.714232735429224 30.395097583553124 -22.347296704268793 + 10.745098004349103 -3.089246336974975 0.407076858898017}} + {x \dspTri{5}{5} \dspFilter} +\end{dspPlot} +\end{Verbatim} + +\begin{centerfig} + \begin{dspPlot}[xout=true]{0,40}{-.4,1.1} + \dspSignal[linecolor=lightgray]{x \dspTri{5}{5}} + \dspSignalOpt[linecolor=blue!60]{\dspSetFilter{0.000008952611389 0.000071620891113 + 0.000250673118897 0.000501346237795 0.000626682797244 + 0.000501346237795 0.000250673118897 0.000071620891113 + 0.000008952611389}{ -5.975292291885454 16.581223292021008 + -27.714232735429224 30.395097583553124 -22.347296704268793 + 10.745098004349103 -3.089246336974975 0.407076858898017}} + {x \dspTri{5}{5} \dspFilter} + \end{dspPlot} +\end{centerfig} + + + + \section{Drawing Regions of Convergence, Poles and Zeros} |