summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/dsptricks
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2014-07-25 21:05:22 +0000
committerKarl Berry <karl@freefriends.org>2014-07-25 21:05:22 +0000
commit2aa608cd9808e84c462362be9eb92a98a1b79e4d (patch)
treea2b6a17091695597883f496158d73b85c18ab32f /Master/texmf-dist/tex/latex/dsptricks
parent43255aab4df3eb4f9d71e5f80e9bab45f8bdad72 (diff)
dsptricks (25jul14)
git-svn-id: svn://tug.org/texlive/trunk@34724 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/dsptricks')
-rw-r--r--Master/texmf-dist/tex/latex/dsptricks/dspblocks.sty116
-rw-r--r--Master/texmf-dist/tex/latex/dsptricks/dspfunctions.sty258
-rw-r--r--Master/texmf-dist/tex/latex/dsptricks/dsptricks.sty1071
3 files changed, 1445 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/dsptricks/dspblocks.sty b/Master/texmf-dist/tex/latex/dsptricks/dspblocks.sty
new file mode 100644
index 00000000000..b7aba995a9e
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/dsptricks/dspblocks.sty
@@ -0,0 +1,116 @@
+%% This is the package dspblocks
+%%
+%% (c) Paolo Prandoni <paolo.prandoni _at_ epfl.ch>
+%%
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN archives
+%% in directory macros/latex/base/lppl.txt.
+%%
+%% DESCRIPTION:
+%% `dspblocks' is a companion package to dsptricks; it contains a
+%% set of macros to draw the types of block diagrams commonly
+%% used in DSP theory
+%%
+%% v1.0, July 2014
+%%
+
+% required packages:
+\RequirePackage{calc}
+\RequirePackage{fp}
+\RequirePackage{pst-xkey}
+\RequirePackage{fmtcount}
+\RequirePackage{ifthen}
+%
+\ProvidesPackage{dspblocks}[2014/07/24 package for signal processing graphics]
+
+
+% turn off FP messages
+\FPmessagesfalse
+
+\makeatletter
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Set up BLOCK DIAGRAM plot
+%
+% \begin{psdrawBDmatrix}[OPTIONS]{X_SPACING}{Y_SPACING}
+%
+% X_SPACING
+% Y_SPACING vertical and horizontal spacing
+%
+% Once in Block diagram mode the following commands are available
+% (they all create nodes)
+%
+% \BDadd adder
+% \BDmul multiplier
+% \BDdelay z^{-1} delay block
+% \BDdelayN{N} z^{-N} delay block
+% \BDfilter{text} filter box
+% \BDfilterMulti{text} multiline filter box
+% \BDsplit splitting point (dot)
+% \BDupsmp{K} upsampler by K
+% \BDdwsmp{K} downsampler by K
+%
+
+\def\BDwidth{1.2pt}
+\psset{xunit=1mm,yunit=1mm,linewidth=\BDwidth}
+\def\BDadd{[mnode=circle] +}%
+\def\BDsub{[mnode=circle] -}%
+\def\BDmul{[mnode=circle] $\times$}%
+\def\BDdelay{\psframebox[framesep=.3]{$z^{-1}$}}%
+\def\BDdelayN#1{\psframebox[framesep=.3]{$z^{-#1}$}}%
+\def\BDfilter#1{\psframebox[framesep=.3]{#1}}%
+\def\BDfilterMulti#1{\psframebox%
+ {\begin{tabular}{c} #1 \end{tabular}}}%
+\def\BDsplit{[mnode=dot,linewidth=1.5pt]}%
+\def\BDupsmp#1{[mnode=circle] $#1 \uparrow$}%
+\def\BDdwsmp#1{[mnode=circle] $#1 \downarrow$}%
+\def\BDsampler{\raisebox{-14.6pt}{
+ \psset{xunit=1em,yunit=1em,linewidth=1.2pt}%
+ \pspicture(-2.6,-1.8)(1,1.8)%
+ \psline(-3,0)(-1.6,0)(0.7,1.2)
+ \psline(0.8,0)(1,0)
+ \psarc[linewidth=1pt]{<-}(-1.2,0){1.4em}{-10}{55}
+ \endpspicture}}
+\newcommand{\BDsamplerFramed}[1][1em]{
+ \newskip\tmpLen \tmpLen=#1%
+ \raisebox{-1.5\tmpLen}{%
+ \psframebox[linewidth=1.2pt]{%
+ \psset{unit=#1,linearc=0}%
+ \pspicture(-3.1,-2)(3,2)%
+ \psline(-2.8,-0.2)(-1.6,-0.2)(1.2,1.4)%
+ \psline(1.1,-0.2)(1.8,-0.2)%
+ \psarc[linewidth=1pt]{<-}(-1.6,0){2}{-10}{55}%
+ \endpspicture}}}
+\newcommand{\BDlowpass}[1][1em]{%
+ \newskip\tmpLen \tmpLen=#1%
+ \raisebox{-1.5\tmpLen}{%
+ \psframebox[linewidth=1.2pt]{%
+ \psset{unit=#1,linearc=0}%
+ \pspicture(-3.1,-2)(3,2)%
+ \psline{->}(-2.8,-1)(2.8,-1)%
+ \psline{->}(0,-1.8)(0,2)%
+ \psline[linewidth=1.5pt](-1,-1)(-1,0.8)(1,0.8)(1,-1)%
+ \endpspicture}}}
+\newcommand{\BDsinc}[1][1em]{%
+ \newskip\tmpLen \tmpLen=#1%
+ \raisebox{-1.5\tmpLen}{%
+ \psframebox[linewidth=1.2pt]{%
+ \psset{unit=#1,linearc=0}%
+ \pspicture(-3.1,-2)(3,2)%
+ \psline{->}(-2.8,-.5)(2.8,-.5)%
+ \psline{->}(0,-1.8)(0,2)%
+ \psplot[linewidth=1pt, plotpoints=500,linejoin=1]{-2.5}{2.5}{x \dspSinc{0}{0.5} 1.5 mul .5 sub}%
+ \endpspicture}}}
+
+\newenvironment{dspBlocks}[2]{%
+ \begin{psmatrix}[colsep=#1,rowsep=#2,emnode=R] }{%
+ \end{psmatrix}
+}
+
+\newcommand{\BDConnH}[5][]{\ncline[#1]{->}{#2,#3}{#2,#4}\taput{#5}}
+\newcommand{\BDConnHNext}[2]{\FPupn\n{#2 1 add 0 trunc}\ncline{->}{#1,#2}{#1,\n}}
+\newcommand{\BDConnV}[5][]{\ncline[#1]{->}{#2,#3}{#4,#3}\tlput{#5}}
+
+\makeatother \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/dsptricks/dspfunctions.sty b/Master/texmf-dist/tex/latex/dsptricks/dspfunctions.sty
new file mode 100644
index 00000000000..ae63eccaa0d
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/dsptricks/dspfunctions.sty
@@ -0,0 +1,258 @@
+%% This is the package dspfunctions
+%%
+%% (c) Paolo Prandoni <paolo.prandoni _at_ epfl.ch>
+%%
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN archives
+%% in directory macros/latex/base/lppl.txt.
+%%
+%% DESCRIPTION:
+%% `dspfunctions' is a companion package to dsptricks; it contains a
+%% set of postscript macros to compute the value of various DSP
+%% common functions
+%%
+%% v1.0, July 2014
+%%
+
+\ProvidesPackage{dspfunctions}[2014/07/24 package for signal processing graphics]
+
+\def\dspToDeg{180 mul }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \dspRect{a}{b} rect((x-a)/b)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspRect#1#2{ #1 sub abs #2 div 0.5 gt {0} {1} ifelse }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \dspTri{a}{b} triangle((x-a)/b)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspTri#1#2{ #1 sub abs #2 div dup 1 gt {pop 0} {1 exch sub} ifelse }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \dspExpDec{a}{b} b^(x-a)u[x-a]
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspExpDec#1#2{ #1 sub dup 0 lt {pop 0} {#2 exch exp} ifelse }
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \dspQuad{a}{b} quadratic((x-a)/b)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspQuad#1#2{ #1 sub abs #2 div dup 1 gt {pop 0} {dup mul 1 exch sub } ifelse }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Porkpie hat shape (useful for spectral prototypes
+% \dspPorkpie{a}{b} phi((x-a)/b)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspPorkpie#1#2{ #1 sub #2 div dup abs 1 gt {pop 0}%
+ {32.4 mul dup cos exch %
+ dup 3 mul cos 2 mul exch %
+ 12 mul cos -0.7 mul %
+ add add 0.31 mul 0.017 add } ifelse }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Raised cosine
+% \dspRaisedCos{cutoff}{rolloff}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspRaisedCos#1#2{abs %
+ dup dup
+ 1 #2 sub #1 mul lt %
+ {pop pop 1} %
+ {1 #2 add #1 mul gt %
+ {pop 0} {1 #2 sub #1 mul sub 2 #2 #1 mul mul div 3.14 mul RadtoDeg cos 1 add 0.5 mul} ifelse } %
+ ifelse }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Raised cosine, better syntax
+% \dspRaisedCos{a}{b}{r} b = cutoff, r = rolloff
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspRaisedCosine#1#2#3{%
+ #1 sub abs #2 div
+ dup dup
+ 1 #3 sub lt
+ {pop pop 1}
+ {1 #3 add gt
+ {pop 0}
+ {1 #3 sub sub 2 #3 mul div 180 mul cos 1 add 0.5 mul}
+ ifelse}
+ ifelse }
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \dspSinc{a}{b} sinc((x-a)/b)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspSinc#1#2{ #1 sub #2 div dup 0 eq {pop 1} {dup 180 mul sin exch 3.1415 mul div} ifelse }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \dspSincN{a}{b} (1/b)sinc((x-a)/b)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspSincN#1#2{\dspSinc{#1}{#2} #2 div }
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Fourier transform of a symmetric 2N+1 tap rect
+% \dspSincS{a}{N} sin((x-a)(2N+1)/2)/sin((x-a)/2)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspSincS#1#2{ #1 sub 90 mul dup #2 2 mul 1 add mul sin exch sin dup 0 eq {pop pop #2 2 mul 1 add} {div} ifelse}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Fourier transform magnitude of a causal N tap rect
+% (phase is e^{-j\frac{N-1}{2}\omega})
+% \dspSincC{a}{N} sin((x-a)(N/2))/sin((x-a)/2)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspSincC#1#2{ #1 sub 90 mul dup #2 mul sin exch sin dup 0 eq {pop pop #2} {div} ifelse}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \dspRand % Random number uniformly distributed over [-1 1]
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspRand{rand 2147483647 div 0.5 sub 2 mul }
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Discrete Fourier Transform of an input sequence; input is
+% the integer value of the DFT coefficient.
+%
+% \dspDFTRE{a_0 a_1 ... a_{N-1}} (real part)
+% \dspDFTIM{a_0 a_1 ... a_{N-1}} (imaginary part)
+% \dspDFTMAG{a_0 a_1 ... a_{N-1}} (magnitude)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspDFT#1{%
+ cvi [#1] length mod % DFT is N periodic
+ 360 mul [#1] length div % w = (2k\pi)/N
+ 0 % index n
+ 0 % accumulator Re
+ 0 % accumulator Im
+ [#1] % data points
+ { % STACK:
+ % w n re im a_n
+ dup % w n re im a_n a_n
+ 5 index % w n re im a_n a_n w
+ 5 index % w n re im a_n a_n w n
+ mul dup % w n re im a_n a_n nw nw
+ sin exch cos % w n re im a_n a_n sin(nw) cos(nw)
+ 4 1 roll mul % w n re im cos(nw) a_n (a_n)sin(nw)
+ 3 1 roll mul % w n re im (a_n)sin(nw) (a_n)cos(nw)
+ 4 1 roll add % w n (a_n)cos(nw) re im'
+ 3 1 roll add exch % w n re' im'
+ 3 2 roll 1 add % w re' im' n'
+ 3 1 roll % w n re im
+ } forall
+ 4 2 roll pop pop % re im
+}
+\def\dspDFTRE#1{\dspDFT{#1} pop }
+\def\dspDFTIM#1{\dspDFT{#1} exch pop }
+\def\dspDFTMAG#1{\dspDFT{#1} dup mul exch dup mul add sqrt }
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Frequency response of a (2N+1)-tap Type-I FIR computed at a given
+% normalized frequency value. Frequency response is real for Type-I
+% The filter is considered zero-centered, so a_0 is the center tap
+%
+% \dspFIRI{a_0 a_1 ... a_{N-1}}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspFIRI#1{%
+ \dspToDeg % input to degrees
+ 0 % index n
+ 0 % accumulator A
+ [#1] % coefficients a_n
+ {
+ 3 index % x
+ 3 index % n [*** using index INCREASES stack size... so it's 3 3 rather than 3 2]
+ mul cos mul % a_n cos nx
+ add % accumulate
+ exch 1 add exch % i++
+ } forall
+ 3 1 roll pop pop
+ 2 mul % final value is 2A - a_0
+ [#1] 0 get sub
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Magnitude response of a generic digital filter defined by the
+% constant-coefficient difference equation:
+% y[n] = a_0 x[n] + a_1 x[n-1] + ... + a_{N-1} x[n-N+1]
+% - b_1 y[n-1] - ... - b_{M-1} y[n-M+1]
+%
+% The response is computed at the given normalized frequency value
+%
+% \dspTFM{a_0 a_1 ... a_{N-1}}{b_1 b_2 ... b_{M-1}}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspTFM#1#2{%
+ \dspToDeg % input to degrees
+ dup % save a copy for denominator
+ 0 % index n
+ 0 % accumulator Re
+ 0 % accumulator Im
+ [#1] % coefficients a_n
+ { % STACK (neglecting saved input at bottom):
+ % x n re im a_n
+ dup % x n re im a_n a_n
+ 5 index % x n re im a_n a_n x
+ 5 index % x n re im a_n a_n x n
+ mul dup % x n re im a_n a_n nx nx
+ sin exch cos % x n re im a_n a_n sin(nx) cos(nx)
+ 4 1 roll mul % x n re im cos(nx) a_n (a_n)sin(nx)
+ 3 1 roll mul % x n re im (a_n)sin(nx) (a_n)cos(nx)
+ 4 1 roll add % x n (a_n)cos(nx) re im'
+ 3 1 roll add exch % x n re' im'
+ 3 2 roll 1 add % x re' im' n'
+ 3 1 roll % x n re im
+ } forall
+ 4 2 roll pop pop % re im
+ dup mul exch dup mul add % (re^2 + im^2)
+ sqrt % mag of the numerator of transfer function
+ exch % bring up saved input copy
+ 0 % same loop for the b_n coefficients
+ 0
+ 0
+ [#2]
+ {
+ dup
+ 5 index
+ 5 index
+ mul dup
+ sin exch cos
+ 4 1 roll mul
+ 3 1 roll mul
+ 4 1 roll add
+ 3 1 roll add exch
+ 3 2 roll 1 add
+ 3 1 roll
+ } forall
+ 4 2 roll pop pop
+ dup mul exch dup mul add
+ sqrt
+ div %0 eq {pop pop 0} {div} ifelse
+}
+
diff --git a/Master/texmf-dist/tex/latex/dsptricks/dsptricks.sty b/Master/texmf-dist/tex/latex/dsptricks/dsptricks.sty
new file mode 100644
index 00000000000..5b075c043c1
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/dsptricks/dsptricks.sty
@@ -0,0 +1,1071 @@
+%% This is the package dsptricks
+%%
+%% (c) Paolo Prandoni <paolo.prandoni _at_ epfl.ch>
+%%
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN archives
+%% in directory macros/latex/base/lppl.txt.
+%%
+%% DESCRIPTION:
+%% `dsptricks' is a LaTeX package based on PSTricks to plot discrete- and continuous-time
+%% signals, pole-zero plots and DSP block diagrams. The package has been developed
+%% while writing the textbook "Signal Processing for Communication" by P. Prandoni
+%% and M. Vetterli, freely available at www.sp4comm.org
+%%
+%% v1.0, July 2014
+%%
+\RequirePackage{pstricks}
+\RequirePackage{pstricks-add}
+\RequirePackage{pst-xkey}
+\RequirePackage{calc}
+\RequirePackage{fp}
+\RequirePackage{ifthen}
+%
+\ProvidesPackage{dsptricks}[2014/07/24 package for signal processing graphics]
+
+% turn off FP messages
+\FPmessagesfalse
+
+\makeatletter
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Sizes and units:
+%%
+%% default values for plot size
+%%
+\newlength{\dspWidth}\setlength{\dspWidth}{0.7\textwidth}
+\newlength{\dspHeight}\setlength{\dspHeight}{0.43\dspWidth}
+\def\dspAxisColor{black}
+%
+%% Actual size (this is the size of the chart's frame, labels are extra)
+\newlength{\dspW}
+\newlength{\dspH}
+%% Basic Unit is a function of plot size
+\newlength{\dspBU}
+%% Derived units:
+\newlength{\dspLineWidth}
+\newlength{\dspStemWidth}
+\newlength{\dspDotSize}
+\newlength{\dspTickLen}
+\newlength{\dspXTickGap}
+\newlength{\dspYTickGap}
+\newlength{\dspTickLineWidth}
+\newlength{\dspFrameLineWidth}
+%% psTricks units
+\newlength{\dspUnitX}
+\newlength{\dspUnitY}
+\newlength{\dspTmpLen}
+%% booleans
+\newif\ifXTicks
+\newif\ifDoXTicks
+\newif\ifYTicks
+\newif\ifDoYTicks
+\newif\ifXLabel
+\newif\ifYLabel
+\newif\ifXAxisExp
+\newif\ifYAxisExp
+\newif\ifXAxisFreq
+\newif\ifXInside
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% dspPlot environment:
+%%
+%% \begin{dspPlot}[OPTIONS]{xMin, xMax}{yMin, yMAx}
+%%
+%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Keys for data plots :
+%%
+\define@key{dspDP}{width}{\setlength{\dspW}{#1}}
+\define@key{dspDP}{height}{\setlength{\dspH}{#1}}
+\define@key{dspDP}{xlabel}{\def\dspXLabel{#1}\XLabeltrue}
+\define@key{dspDP}{ylabel}{\def\dspYLabel{#1}\YLabeltrue}
+\define@key{dspDP}{rlabel}{\def\dspYLabelR{#1}\YLabeltrue} % right-side y-axis label
+\define@key{dspDP}{sidegap}{\def\sg{#1}}
+\define@choicekey*+{dspDP}{xtype}[\ll\ln]{time,freq}[time]{%
+ \ifcase\ln\relax
+ \XAxisFreqfalse
+ \or
+ \XAxisFreqtrue
+ \fi}{}
+\define@choicekey*+{dspDP}{xticks}[\ll\ln]{auto,none,custom}[auto]{%
+ \DoXTickstrue\XTickstrue\def\incX{-1}\def\piFrac{2}
+ \ifcase\ln\relax
+ \relax
+ \or
+ \DoXTicksfalse\XTicksfalse
+ \or
+ \DoXTicksfalse
+ \fi}{%
+ \DoXTickstrue\XTickstrue
+ \def\incX{#1}\def\piFrac{#1}}
+\define@choicekey*+{dspDP}{yticks}[\ll\ln]{auto,none,custom}[auto]{%
+ \DoYTickstrue\YTickstrue\def\incY{-1}
+ \ifcase\ln\relax
+ \relax
+ \or
+ \DoYTicksfalse\YTicksfalse
+ \or
+ \DoYTicksfalse
+ \fi}{%
+ \DoYTickstrue\YTickstrue
+ \def\incY{#1}}
+\newif\ifXTicksOut
+\define@key{dspDP}{xout}{\XTicksOuttrue}
+\define@key{dspDP}{inticks}{\XInsidetrue}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% dspPlot environment
+%%
+\newenvironment{dspPlot}[3][]{%
+% default values
+ \def\dspXlabel{}\XLabelfalse%
+ \def\dspYLabel{}\def\dspYLabelR{}\YLabelfalse%
+ \XAxisFreqfalse%
+ \XTicksOutfalse%
+ \setlength{\dspW}{\dspWidth}\setlength{\dspH}{\dspHeight}%
+
+ \presetkeys{dspDP}{xticks=auto,yticks=auto}{}%
+ \presetkeys{dspDP}{sidegap=-1}{}%
+ \setkeys{dspDP}{#1}%
+%%
+%% set up
+ \ifXAxisFreq\def\sg{0} \fi%
+ \dspSetDims#2,#3,\sg\relax%
+ \dspSetupAxes
+%%
+%% special x-axis for frequency plots
+ \ifXAxisFreq\FPset\incX{1}%
+ \ifXAxisExp%
+ % x-axis is not on bottom; skip last values
+ \FPupn\stX{\dspMinX{} \piFrac{} * 1 + 0 trunc}%
+ \FPupn\tlimX{\stX{} \dspMaxX{} \piFrac{} * - 0 trunc}%
+ \else%
+ \FPupn\stX{\dspMinX{} \piFrac{} * 0 trunc}%
+ \FPupn\tlimX{\stX{} \dspMaxX{} \piFrac{} * - 1 + 0 trunc}\relax\fi%
+ %
+ \ifXTicksOut% undo above if ticks explicitly out
+ \FPupn\stX{\dspMinX{} \piFrac{} * 0 trunc}%
+ \FPupn\tlimX{\stX{} \dspMaxX{} \piFrac{} * - 1 + 0 trunc}\relax\fi
+ %
+ \def\thisTickX##1{%
+ \FPupn\u{\piFrac{} ##1 /}%
+ \psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](\u,\haY)(\u,\tickEndX)}
+ \def\thisTickLabelX##1##2{%
+ \FPupn\u{\piFrac{} ##1 /}%
+ \rput*[B]{{0}}(\u,\tickTxtX){{\simplifyPiFrac{##1}{\piFrac}}}}%
+ \else
+ \def\thisTickX{\dspTickX}\def\thisTickLabelX{\dspTickLabelX}\relax\fi
+%%
+%% start the plot
+ \begin{pspicture}(\LX,\BY)(\RX,\TY)
+ %\showpointstrue
+ %\psframe[dimen=middle,linewidth=1pt,linecolor=red](\LX,\BY)(\RX,\TY)%
+ \ifXAxisExp\psline[linewidth=\dspFrameLineWidth,linecolor=\dspAxisColor](\dspMinX,0)(\dspMaxX,0)\fi
+ \dspPlotFrame
+%%
+%% draw ticks selectively according to user options
+ \ifDoXTicks\multido{\n=\stX+\incX}{\tlimX}{\thisTickX{\n}}\fi
+ \ifDoYTicks\multido{\n=\stY+\incY}{\tlimY}{\dspTickY{\n}}\fi
+}{%
+%% tick labels
+ \psset{xunit=\dspUnitX,yunit=\dspUnitY} %user may have changed those
+ \ifDoXTicks\multido{\n=\stX+\incX}{\tlimX}{\thisTickLabelX{\n}{$\n$}}\fi
+ \ifDoYTicks\multido{\n=\stY+\incY}{\tlimY}{\dspTickLabelY{\n}{$\n$}}\fi
+ \dspLabels
+\end{pspicture}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Custom ticks
+%%
+%% \dspCustomTicks[axis={x|y}]{value label ...}
+%%
+%% if using macros for values, enclose them in curly braces:
+%% \def\a{1 }
+%% \dspCustomTicks{{\a} 1}
+%%
+\define@choicekey*{dspCT}{axis}[\ll\ln]{x,y,ry}[x]{%
+ \def\dspCA{\ln}}
+\define@key{dspCT}{color}{\def\tickColor{#1}}
+\newcommand{\dspCustomTicks}[2][]{%
+ \presetkeys{dspCT}{axis=x,color=black}{}%
+ \setkeys{dspCT}{#1}%
+ \ifcase\dspCA\relax%
+ \def\dspMkTk##1##2{\dspTickX{##1}{\dspTickLabelX{##1}{##2}}}%
+ \or
+ \def\dspMkTk##1##2{\dspTickY{##1}{\dspTickLabelY{##1}{##2}}}%
+ \or
+ \def\dspMkTk##1##2{{\dspTickLabelYR{##1}{##2}}}%
+ \fi
+ \def\dspMakeTicks##1 ##2 ##3\relax{%
+ \ifx&##3&
+ \dspMkTk{##1}{##2} %
+ \else
+ \dspMkTk{##1}{##2} \relax %
+ \dspMakeTicks##3\relax%
+ \fi}%
+ \dspMakeTicks#2 \relax}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Draw legend
+%%
+%% \dspLegend(x,y){color label color label ...}
+%%
+\def\dspLegend(#1,#2)#3{%
+ \rput[lt](#1,#2){\fbox{%
+ \begin{tabular}{ll}
+ \@dsplegend#3 \@empty
+ \end{tabular}}}}
+\def\@dsplegend#1 #2 #3{%
+ {\color{#1}\rule[0.5ex]{2em}{2pt}} & #2\\ \space % fbox here to have a visual test
+ \ifx #3\@empty\else
+ \expandafter\@dsplegend
+ \fi
+ #3}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Redraw frame around plot
+%%
+\newcommand{\dspPlotFrame}{
+ \psframe[dimen=middle,linewidth=\dspFrameLineWidth,linecolor=black]%
+ (\dspMinX,\dspMinY)(\dspMaxX,\dspMaxY)}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Environment to clip plots to within the frame box. Do not leave
+%% spaces in the environment's body otherwise graph will shift
+%%
+\newenvironment{dspClip}{%
+ \psclip{\psframe[dimen=middle,linestyle=none](\dspMinX,\dspMinY)(\dspMaxX,\dspMaxY)}}{%
+ \endpsclip}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plotting discrete-time signals in the dspPlot environment:
+%%
+%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Keys for plotting functions (these are set together with pstricks keys
+%% so they must use the [psset] prefix and be declared)
+%%
+%% xmin=N,
+%% xmax=N range for the plotted signal
+%%
+\define@key[psset]{dspData}{xmin}{\def\dspXmin{#1}}
+\define@key[psset]{dspData}{xmax}{\def\dspXmax{#1}}
+\pst@addfams{dspData}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot discrete-time points
+%%
+%% \dspTaps[OPTIONS]{x1 y1 x2 y2 ...}
+%%
+\newcommand{\dspTaps}[2][]{%
+ \listplot[plotstyle=LineToXAxis, linestyle=solid,%
+ showpoints=true, dotstyle=*, linewidth=\dspStemWidth,%
+ dotsize=\dspDotSize, #1]{\expandafter\m@keList#2 \relax}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot discrete-time points starting at a given abscissa
+%% Data in this case is only ordinates
+%%
+%% \dspTapsAt{x0}{y0 y1 y2,...}
+%%
+\newcommand{\dspTapsAt}[3][]{%
+ % use postscript to iterate over space-separated list and create indices
+ \listplot[plotstyle=LineToXAxis, linestyle=solid,%
+ showpoints=true, dotstyle=*, linewidth=\dspStemWidth,%
+ dotsize=\dspDotSize, #1]{%
+ #2
+ [#3] { % n []
+ % n a0
+ 1 index % n a0 n
+ 1 add
+ } forall
+ pop
+}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot discrete-time signal from a data file
+%%
+%% \dspTapsFile[OPTIONS]{FILE}
+%%
+\newcommand{\dspTapsFile}[2][]{%
+ \readdata{\data}{#2}%
+ \listplot[plotstyle=LineToXAxis, linestyle=solid,%
+ showpoints=true, dotstyle=*,%
+ linewidth=\dspStemWidth, dotsize=\dspDotSize,%
+ #1]{\data}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot discrete-time signal
+%%
+%% \dspSignal[OPTIONS]{PS code}
+%%
+\newcommand{\dspSignal}[2][]{%
+ \presetkeys[psset]{dspData}{xmin=\dspMinActX, xmax=\dspMaxActX}{}%
+ \setkeys*[psset]{dspData}{#1}%
+ \FPupn\mn{{\dspXmin} 0 trunc clip }%
+ \FPupn\mx{{\dspXmax} 0 trunc clip }%
+ \FPupn\ntaps{\mn{} \mx{} - 1 + 0 trunc clip}%
+ \psplot[plotstyle=LineToXAxis, linestyle=solid,%
+ showpoints=true, dotstyle=*,%
+ linewidth=\dspStemWidth, dotsize=\dspDotSize,%
+ plotpoints=\ntaps, #1]%
+ {\mn}{\mx}{#2}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot discrete-time signal with postscript initialization options
+%%
+%\dspSignalOpt[OPTIONS]{PS init code}{PS code}
+%%
+\newcommand{\dspSignalOpt}[3][]{%
+ \presetkeys[psset]{dspData}{xmin=\dspMinActX, xmax=\dspMaxActX}{}%
+ \setkeys*[psset]{dspData}{#1}%
+ \FPupn\ntaps{\dspXmin{} \dspXmax{} - 1 + 0 trunc}%
+ \psplot[plotstyle=LineToXAxis, linestyle=solid,%
+ showpoints=true, dotstyle=*,%
+ linewidth=\dspStemWidth, dotsize=\dspDotSize,%
+ plotpoints=\ntaps, #1]%
+ {\dspXmin}{\dspXmax}[{#2}]{#3}}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plotting continuous-time signals in the dspPlot environment:
+%%
+%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot smooth function
+%%
+%% \dspFunc[OPTIONS]{PS code}
+%%
+\newcommand{\dspFunc}[2][]{%
+ \presetkeys[psset]{dspData}{xmin=\dspMinActX, xmax=\dspMaxActX}{}%
+ \setkeys*[psset]{dspData}{#1}%
+ \psplot[linewidth=\dspLineWidth, plotpoints=\dspPSPoints,%
+ linejoin=1,#1]{\dspXmin}{\dspXmax}{#2}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot smooth function with postscript initialization options
+%%
+%% \dspFuncOpt[OPTIONS]{PS init code}{PS code}
+%%
+\newcommand{\dspFuncOpt}[3][]{%
+ \presetkeys[psset]{dspData}{xmin=\dspMinActX, xmax=\dspMaxActX}{}%
+ \setkeys*[psset]{dspData}{#1}%
+ \psplot[linewidth=\dspLineWidth, plotpoints=\dspPSPoints,%
+ linejoin=1,#1]{\dspXmin}{\dspXmax}[{#2}]{#3}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot smooth function from a set of points
+%%
+%% \dspFuncData[OPTIONS]{x1 y1 x2 y2 ...}
+%%
+\newcommand{\dspFuncData}[2][]{%
+ \listplot[linewidth=\dspLineWidth,linejoin=1,plotstyle=line,#1]{\expandafter\m@keList#2 \relax}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot smooth function from a set of points starting at a given point
+%% Data in this case is only ordinates
+%%
+%% \dspFuncDataAt[OPTIONS]{x1}{y1 y2 ...}
+%%
+\newcommand{\dspFuncDataAt}[3][]{%
+ \listplot[linewidth=\dspLineWidth,linejoin=1,plotstyle=line,#1]{%
+ #2
+ [#3] { % n []
+ % n a0
+ 1 index % n a0 n
+ 1 add
+ } forall
+ pop
+}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot smooth function from a data file
+%% file must contain a list of space-separated abscissa and ordinate pairs
+%%
+%% \dspFuncFile[OPTIONS]{FILE}
+%%
+\newcommand{\dspFuncFile}[2][]{%
+ \readdata{\data}{#2}%
+ \listplot[linewidth=\dspLineWidth,linejoin=1,plotstyle=line,#1]{\data}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Plot Dirac deltas
+%%
+%% \dspDiracs[OPTIONS]{x1 y1 x2 y2 ...}
+%%
+\newcommand{\dspDiracs}[2][]{%
+ \def\dirac##1##2{\psline[linestyle=solid,linewidth=\dspLineWidth,#1]{->}(! ##1 0)(! ##1 ##2)}
+ \doOnPairs{dirac}{#2}}
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Periodize function over the [-1, 1] interval
+%
+\newcommand{\dspPeriod}[1]{ #1 sub #1 2 mul div dup floor sub #1 2 mul mul #1 sub }
+\newcommand{\dspPeriodize}{ \dspPeriod{1} }
+\newcommand{\dspMainPeriod}[1][]{%
+ \psframe[linecolor=lightgray,linewidth=0.4pt,#1](-1,\dspMinY)(1,\dspMaxY)}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Plot text
+% \dspText(x,y){text}
+\newcommand{\dspText}[2]{%
+ \rput*[B]{0}#1{#2}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Pole-Zero Plots
+%
+% Specialized options:
+%
+% circle=["true" | "false"] draw unit circle
+% clabel="text" set a label at circle unit
+% roc
+%
+\define@key{dspPZ}{width}{\setlength{\dspW}{#1}\setlength{\dspH}{#1}}
+\define@key{dspPZ}{height}{\setlength{\dspH}{#1}}
+\define@key{dspPZ}{circle}{\def\dspCircle{#1}}
+\define@key{dspPZ}{clabel}{\def\dspCircleLabel{#1}}
+\define@choicekey*+{dspPZ}{xticks}[\ll\ln]{auto,none}[auto]{%
+ \DoXTickstrue\def\incX{-1}
+ \ifcase\ln\relax
+ \relax
+ \or
+ \DoXTicksfalse
+ \fi}{%
+ \DoXTickstrue
+ \def\incX{#1}}
+\define@choicekey*+{dspPZ}{yticks}[\ll\ln]{auto,none}[auto]{%
+ \DoYTickstrue\def\incY{-1}
+ \ifcase\ln\relax
+ \relax
+ \or
+ \DoYTicksfalse
+ \fi}{%
+ \DoYTickstrue
+ \def\incY{#1}}
+\newif\ifComplexLabels
+\define@choicekey*{dspPZ}{cunits}[\ll\ln]{true,false}[true]{%
+ \ifcase\ln\relax
+ \ComplexLabelstrue
+ \or
+ \ComplexLabelsfalse
+ \fi}
+\define@key{dspPZ}{roc}{\def\PZCROC{#1}}
+\define@key{dspPZ}{antiroc}{\def\PZAROC{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newenvironment{dspPZPlot}[2][]{%
+ \setlength{\dspW}{\dspHeight}\setlength{\dspH}{\dspHeight}%
+ \ComplexLabelstrue%
+ \presetkeys{dspPZ}{xticks=auto,yticks=auto,circle=1,clabel={ },roc=-1,antiroc=-1}{}%
+ \setkeys{dspPZ}{#1}%
+%
+ %% set up
+ \dspSetDims{-#2},{#2},{-#2},{#2},0\relax%
+ \dspSetupAxes%
+%
+ \gdef\dspTickX##1{\psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](##1,-\tickEndX)(##1,\tickEndX)}%
+ \gdef\dspTickY##1{\psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](-\tickEndY,##1)(\tickEndY,##1)}%
+ \gdef\dspTickLabelY##1##2{\uput{{2\dspYTickGap}}[0]{{0}}(\tickEndY,##1){{##2}}}%
+ \gdef\dspTickLabelX##1##2{\rput[B]{{0}}(##1,\tickTxtX){{##2}}}%
+%
+ %% start the plot
+ \begin{pspicture}(\LX,\BY)(\RX,\TY)
+ \FPifpos\PZCROC%
+ \pscustom[fillstyle=vlines,hatchcolor=lightgray,linecolor=lightgray,linewidth=0]{%
+ \psarc(0,0){\PZCROC\dspUnitX}{0}{360}%
+ \psline[linecolor=\dspAxisColor](\dspMaxX,0)(\dspMaxX,\dspMinY)(\dspMinX,\dspMinY)%
+ (\dspMinX,\dspMaxY)(\dspMaxX,\dspMaxY)(\dspMaxX,0)}
+ \pscircle[linecolor=lightgray,dimen=middle]{\PZCROC\dspUnitX}\relax\fi
+ \FPifpos\PZAROC%
+ \pscircle[fillstyle=vlines,hatchcolor=lightgray,linecolor=lightgray,dimen=middle]{\PZAROC\dspUnitX}\relax\fi
+%%
+ \psline[linewidth=\dspFrameLineWidth,linecolor=\dspAxisColor](\dspMinX,0)(\dspMaxX,0)%
+ \psline[linewidth=\dspFrameLineWidth,linecolor=\dspAxisColor](0,\dspMinY,0)(0,\dspMaxY)%
+ \dspPlotFrame%
+ \FPifgt\dspCircle{0}%
+ \FPmul\r\dspCircle{\strip@pt\dspUnitX}%
+ \pscircle[linewidth=\dspFrameLineWidth,dimen=middle](0,0){{\r}pt}%
+ \ifx\@empty\dspCircleLabel%
+ \def\dspCircleLabel{\dspCircle}\relax\fi
+ \FPupn\r{0.6 \dspTSX{} mul \dspCircle{} add}%
+ \rput[b]{0}(\r,\tickTxtX){\dspCircleLabel}\relax\fi
+%
+ % draw ticks selectively according to user options
+ % but here skip zero and intersections with the circle (if any)
+ \FPupn\r{\tlimX{} 1 sub 2 div clip}%
+ \def\xt{%
+ \multido{\n=\stX+\incX}{\r}{\FPifeq\n{-\dspCircle}\relax\else\dspTickX{\n}\fi}%
+ \multido{\n=\incX+\incX}{\r}{\FPifeq\n\dspCircle\relax\else\dspTickX{\n}\fi}%
+ \multido{\n=\stX+\incX}{\r}{\FPifeq\n{-\dspCircle}\relax\else\dspTickLabelX{\n}{$\n$}\fi}%
+ \multido{\n=\incX+\incX}{\r}{\FPifeq\n\dspCircle\relax\else\dspTickLabelX{\n}{$\n$}\fi}}%
+ \def\yt{%
+ \multido{\n=\stY+\incY}{\r}{\FPifeq\n{-\dspCircle}\relax\else\dspTickY{\n}\fi}%
+ \multido{\n=\incY+\incY}{\r}{\FPifeq\n\dspCircle\relax\else\dspTickY{\n}\fi}%
+ \multido{\n=\stY+\incY}{\r}{\FPifeq\n{-\dspCircle}\relax\else\dspTickLabelY{\n}{$\n$}\fi}%
+ \multido{\n=\incY+\incY}{\r}{\FPifeq\n\dspCircle\relax\else\dspTickLabelY{\n}{$\n$}\fi}}%
+ \ifDoXTicks\xt\fi
+ \ifDoYTicks\yt\fi
+ \ifComplexLabels%
+ \rput[mr]{0}(\dspMaxX,1em){Re~}%
+ \FPupn\r{\dspMaxY{} 0.6 \dspTSY{} mul sub}%
+ \rput[t]{0}(-1.2em,\r){Im~}\relax\fi
+}{%
+ \end{pspicture}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Keyvals for poles and zeros
+%
+\newif\ifPZPole
+\define@choicekey*[psset]{dspPZP}{type}[\ll\ln]{zero,pole}[zero]{%
+ \ifcase\ln\relax
+ \PZPolefalse
+ \or
+ \PZPoletrue
+ \fi}
+\newif\ifPZLabel
+\define@choicekey*+[psset]{dspPZP}{label}[\ll\ln]{auto,none}[auto]{%
+ \def\PZLabel{}\relax%
+ \ifcase\ln\relax
+ \PZLabeltrue
+ \or
+ \PZLabelfalse
+ \fi}{%
+ \PZLabeltrue
+ \def\PZLabel{#1}}
+\define@key[psset]{dspPZP}{lpos}{\def\PZLP{#1}}
+\pst@addfams{dspPZP}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Plot pole-zero point
+%
+% \dspPZPoint[OPTIONS]{RE,IM}
+%
+% RE, IM coordinates
+%
+% Options:
+%
+% type = ["pole" | "zero"] circle or cross (default: pole)
+% label=["false" | TEXT ] the point's label (default: false)
+% lpos = ANGLE label position (default: 45)
+%
+\newcommand{\dspPZ}[2][]{%
+ \presetkeys[psset]{dspPZP}{type=pole,label=auto}{}%
+ \setkeys*[psset]{dspPZP}{#1}%
+ \ifPZPole
+ \psdot[dotstyle=+,dotsize=1.4ex,dotscale=1.5,dotangle=45, #1](\twoArgSplit#2) \else
+ \psdot[dotstyle=*,dotsize=1.4ex,#1](\twoArgSplit#2) \fi
+ \ifx\@empty\PZLabel \def\PZLabel{$(\twoArgSplit#2)$} \fi
+ % tricky bug in pstricks so we can't use presetkeys for angle... Could not understand
+ \ifdefined\PZLP \relax \else \def\PZLP{45} \fi
+ \ifPZLabel \uput[\PZLP]{0}(\twoArgSplit#2){\PZLabel} \fi}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\define@key{dspCP}{width}{\setlength{\dspCPW}{#1}\setlength{\dspCPH}{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% dspCP environment
+%
+% \begin{dspCP}[OPTIONS]{MAX}
+%
+%
+\newlength{\dspCPW}\newlength{\dspCPH}
+\newenvironment{dspCP}[3][]{%
+%% scale dimensions so that axes have equal units
+ \setlength{\dspCPW}{0.37\textwidth}\setlength{\dspCPH}{\dspCPW}
+ \setlength{\dspW}{\dspCPW}\setlength{\dspH}{\dspCPH}
+ \setkeys*{dspCP}{#1}%
+ \dspSetDims#2,#3,0\relax%
+ \FPupn\g{\dspRngY{} {\strip@pt\dspCPW} / \dspRngX{} * 0 trunc}%
+ \setlength{\dspCPH}{1pt*\g}%
+%%
+ \begin{dspPlot}[#1,sidegap=0,inticks=true,width=\dspCPW,height=\dspCPH]{#2}{#3}%
+ \ifYAxisExp\psline[linewidth=\dspFrameLineWidth,linecolor=\dspAxisColor](0,\dspMinY)(0,\dspMaxY)\fi
+}{%
+%% redo ticks and axes since images may overlap a little
+ \dspPlotFrame
+ \ifDoXTicks\multido{\n=\stX+\incX}{\tlimX}{\dspTickX{\n}}\fi
+ \ifDoYTicks\multido{\n=\stY+\incY}{\tlimY}{\dspTickY{\n}}\fi
+ \end{dspPlot}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Plot Dirac deltas
+%
+% \dspPoints[OPTIONS]{x1 y1 x2 y2 ...}
+%
+\newcommand{\dspPoints}[2][]{%
+ \listplot[plotstyle=dots,%
+ showpoints=true, dotstyle=*,%
+ dotsize=\dspDotSize, #1]{\m@keList#2 \relax}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Plot Dirac delta with value
+%
+% \dspDiracs[OPTIONS]{x, y}{text}
+%
+\newcommand{\dspPointValue}[3][]{%
+ \psdot[dotstyle=*, dotsize=\dspDotSize, #1](\twoArgSplit#2)%
+ \uput[45]{0}(\twoArgSplit#2){#3}}
+
+\newcommand{\dspPointValueSC}[3][]{%
+ \SpecialCoor
+ \psdot[dotstyle=*, dotsize=\dspDotSize, #1](#2)%
+ \uput[45]{0}(\twoArgSplit#2){#3}
+ \NormalCoor}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Plot image from file
+\newcommand{\dspImageFile}[1]{%
+ \FPupn\u{2 \dspRngX{} 1.01 * / \dspMinX{} + }\FPupn\v{2 \dspRngY{} 1.01 * / \dspMinY{} + }%
+ \setlength{\dspCPW}{1.01\dspW}\setlength{\dspCPH}{1.01\dspH}%
+ \rput(\u,\v){\includegraphics[width=\dspCPW,height=\dspCPH]{#1}}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Quick image plot, with frame but no additional space around it
+\newcommand{\dspShowImage}[2][0.37\textwidth]{%
+ \psset{xunit=#1,yunit=#1}%
+ \begin{pspicture}(0,0)(0,1)%
+ \includegraphics[width=#1,height=#1]{#2}%
+ \psframe[dimen=middle,linewidth=1.1pt](-0.01,0)(-.99,.99)
+ \end{pspicture}}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% Some geometrical primitives
+%
+\newif\ifPointToOrg
+\define@choicekey*[psset]{dspPZP}{toorg}[\ll\ln]{true,false}[false]{%
+ \ifcase\ln\relax
+ \PointToOrgtrue
+ \or
+ \PointToOrgfalse
+ \fi}
+
+% [opts]{x,y}{label}
+\newcommand{\dspCPPoint}[3][]{%
+ \setkeys*[psset]{dspPZP}{#1}%
+ \psdot[dotstyle=*, dotsize=\dspDotSize, #1](#2)%
+ \uput[45]{0}(#2){#3}%
+ \ifPointToOrg\psline[linewidth=\dspTickLineWidth, #1](0,0)(#2)\fi}
+
+% [opts]{x,y in special coor}{label}
+\newcommand{\dspCPPointSC}[3][]{%
+ \setkeys*[psset]{dspPZP}{#1}%
+ \SpecialCoor%
+ \psdot[dotstyle=*, dotsize=\dspDotSize, #1](#2)%
+ \uput[45]{0}(#2){#3}%
+ \ifPointToOrg\psline[linewidth=\dspTickLineWidth, #1](! 0 0 )(#2)\fi%
+ \NormalCoor}
+
+% [opts]{x,y}{r}
+\newcommand{\dspCPCircle}[3][]{%
+ \pscircle[#1](#2){#3\dspUnitX}}
+
+% [opts]{r}{a}{label}
+\newcommand{\dspCPCirclePoint}[4][]{%
+ \setkeys*[psset]{dspPZP}{#1}%
+ \SpecialCoor%
+ \def\pcorps{! #3 cos #2 mul #3 sin #2 mul}%
+ \FPupn\q{#2 1.1 * 2 trunc}%
+ \uput*{\q\dspUnitX}[#3]{0}(0,0){#4}%
+ \psdot[dotstyle=*, dotsize=\dspDotSize, #1](\pcorps)%
+ \ifPointToOrg\psline[linewidth=\dspTickLineWidth, #1](! 0 0 )(\pcorps)\fi%
+ \NormalCoor}
+
+% [opts] {r}{a}{b}{label}
+\newcommand{\dspCPArc}[5][]{%
+ \FPupn\p{#3 #4 + 0.5 * 2 trunc}%
+ \FPupn\q{#2 1.1 * 2 trunc}%
+ \uput*{\q\dspUnitX}[\p]{0}(0,0){#5}%
+ \psarc[linewidth=2\dspTickLineWidth, #1]{->}{#2\dspUnitX}{#3}{#4}}
+\newcommand{\dspCPArcn}[5][]{%
+ \FPupn\p{#3 #4 + 0.5 * 2 trunc}%
+ \FPupn\q{#2 1.1 * 2 trunc}%
+ \uput*{\q\dspUnitX}[\p]{0}(0,0){#5}%
+ \psarcn[linewidth=2\dspTickLineWidth, #1]{->}{#2\dspUnitX}{#3}{#4}}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Helpers
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This is called at each plot setup with xmin, xmax, ymin, ymax and sidegap
+%% and sets all lengths
+\def\dspSetDims#1,#2,#3,#4,#5\relax{%
+ \def\sideGap{#5}%
+ % default sidegap: 5% of range
+ \FPifneg\sideGap\FPupn\sideGap{#1 #2 - 0.05 * 0.5 + 2 trunc}\fi%
+ \FPifgt\sideGap{1}\FPtrunc\sideGap\sideGap{0}\fi%
+%%
+%% active range for the independent variable
+ \def\dspMinActX{#1}%
+ \def\dspMaxActX{#2}%
+%% axes range (including sidegap)
+ \FPupn\dspMinX{\sideGap{} #1 - clip}%
+ \FPupn\dspMaxX{\sideGap{} #2 + clip}%
+ \FPupn\dspRngX{#1 #2 - \sideGap{} 2 * + clip}%
+ \FPupn\dspMinY{#3 0 + clip}%
+ \FPupn\dspMaxY{#4 0 + clip}%
+ \FPupn\dspRngY{#3 #4 - clip}%
+%%
+% if y-range is across zero we'll need to draw the x-axis
+ \FPmul\u\dspMinY\dspMaxY%
+ \FPifneg\u\XAxisExptrue\else\XAxisExpfalse\fi%
+%% same for x (but usually we never draw the y axis)
+ \FPmul\u\dspMinX\dspMaxX%
+ \FPifneg\u\YAxisExptrue\else\YAxisExpfalse\fi%
+%%
+%% pstricks units: we scale the units so that coordinates are "real" coords on the axes
+ \FPupn\tmp{\dspRngX{} {\strip@pt\dspW} / }
+ \setlength{\dspUnitX}{\tmp pt}%
+ \FPupn\tmp{\dspRngY{} {\strip@pt\dspH} / }%
+ \setlength{\dspUnitY}{\tmp pt}%
+%%
+%% basic unit based on the size of the image: ~1pt for a 10x5 cm box
+ \FPupn\g{2 {\strip@pt\dspW} {\strip@pt\dspH} * root 0.005 * 0 round 1 max}%
+ \setlength{\dspBU}{1pt*\g}%
+%% derived sizes: lines and fonts
+ \setlength{\dspLineWidth}{1.8\dspBU}%
+ \setlength{\dspDotSize}{5\dspBU}%
+ \setlength{\dspStemWidth}{1.4\dspBU}%
+ \fontsize{9\dspBU}{10\dspBU}\selectfont%
+% %% ticks on axes
+ \setlength{\dspTickLen}{4\dspBU}%
+ \setlength{\dspTickLineWidth}{0.4\dspBU}%
+ \setlength{\dspXTickGap}{6\dspBU}\addtolength{\dspXTickGap}{2ex}%
+ \setlength{\dspYTickGap}{2\dspBU}%
+ \setlength{\dspFrameLineWidth}{2.2\dspTickLineWidth}%
+%%
+%% height of a line of text in psticks units
+ \setlength{\dspTmpLen}{1em}%
+ \FPupn\dspTSX{{\strip@pt\dspUnitX} {\strip@pt\dspTmpLen} / }%
+ \FPupn\dspTSY{{\strip@pt\dspUnitY} {\strip@pt\dspTmpLen} / }%
+%%
+%% find the coordinates of the plot's bounding box, including labels
+ \ifYLabel%
+ \FPupn\LX{\dspTSX{} 4 * \dspMinX{} -}%
+ \FPupn\RX{\dspTSX{} 4 * \dspMaxX{} +}%
+ \else%
+ \FPupn\LX{\dspTSX{} 2 * \dspMinX{} -}%
+ \FPupn\RX{\dspTSX{} 2 * \dspMaxX{} +}%
+ \fi
+ \FPupn\TY{\dspTSY{} \dspMaxY{} +}%
+ \def\outTicks{%
+ \ifXTicks\FPupn\BY{\dspTSY{} 2.5 * \dspMinY{} -}\else\FPupn\BY{\dspTSY{} \dspMinY{} -}\fi%
+ \ifXLabel\FPupn\BY{\dspTSY{} 1.5 * \BY{} -}\else\relax\fi }%
+ \ifXAxisExp % ticks are inside
+ \ifXLabel\FPupn\BY{\dspTSY{} 2.5 * \dspMinY{} -}\else\FPupn\BY{\dspTSY{} \dspMinY{} -}\fi%
+ \else% ticks are outside
+ \outTicks \fi%
+ % did we select explicit outside ticks?
+ \ifXTicksOut\outTicks \fi%
+%%
+%% x-axis resolution for plotting functions: ~60 values/cm
+ \FPupn\dspPSPoints{{\strip@pt\dspW} 2 * 0 trunc}%
+%%
+ \psset{xunit=\dspUnitX, yunit=\dspUnitY}%
+ \psset{linewidth=\dspLineWidth}%www
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Draw axis labels (if required) under x axis and to left and right of y axes
+%%
+\def\dspLabels{%
+ % horizontal label
+ \ifXTicksOut\XAxisExpfalse\fi%
+ \ifXLabel%
+ \FPupn\mid{\dspMinX{} \dspMaxX{} + 0.5 mul}%
+ \ifXAxisExp%
+ \FPupn\pos{\dspTSY{} 2 * \dspMinY{} -}%
+ \else%
+ \ifXTicks%
+ \FPupn\pos{\dspTSY{} 3 * \dspMinY{} -}%
+ \else%
+ \FPupn\pos{\dspTSY{} 2 * \dspMinY{} -}%
+ \fi%
+ \fi%
+ \rput[b]{0}(\mid,\pos){\dspXLabel}%
+ \fi%
+%
+ \FPupn\mid{\dspMinY{} \dspMaxY{} + 0.5 mul}%
+ \ifYTicks%
+ \FPupn\pos{\dspTSX{} 3.4 * \dspMinX{} -}%
+ \else%
+ \FPupn\pos{\dspTSX{} 1 * \dspMinX{} -}%
+ \fi%
+ \rput[b]{90}(\pos,\mid){\dspYLabel}
+%%
+ \FPupn\pos{\dspTSX{} 3 * \dspMaxX{} +}%
+ \rput[b]{-90}(\pos,\mid){\dspYLabelR}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This sets axes ticks (spacing and number) and prepares macros
+%% for plotting ticks and tick labels
+\def\dspSetupAxes{%
+%% tick increments; if incX/Y is zero, compute suitable value
+ \FPifgt\incX{0}\FPupn\incX{\incX{} 2 trunc}%
+ \else\FPupn\incX{\dspMinActX{} \dspMaxActX{} - 1 + 6 swap / 0 trunc 1 max}\relax\fi%
+ \FPifgt\incY{0}\FPupn\incY{\incY{} 2 trunc}%
+ \else\FPupn\incY{\dspMinY{} \dspMaxY{} - 1 + 6 swap / 0 trunc 1 max}\relax\fi%
+%%
+%% now find starting point and increment for ticks (and number of ticks)
+%% start with y-axis:
+ \ifXAxisExp% is y=0 explicit or does it coincide with the lower edge?
+ \def\haY{0}%
+ % make sure ticks hit zero; add small epsilons to avoid ticks at the limits
+ \FPupn\stY{\incY{} \dspMinY{} / 0.001 + 0 trunc \incY{} * 2 trunc}%
+ \FPupn\tlimY{\stY{} \dspMaxY{} - 0.001 - \incY{} swap / abs 1 + 0 trunc}%
+ \else%
+ \def\haY{\dspMinY}%
+ \FPupn\tlimY{\incY{} \dspRngY{} / abs 1 + 0 trunc}%
+ \FPupn\stY{\dspMinY{} 2 trunc}% \incY{} 1 \tlimY{} - * \dspRngY{} - 0.5 * \dspMinY{} + 2 trunc}%
+ \fi%
+ % x-ticks outside of the box anyway?
+ \ifXTicksOut\def\haY{\dspMinY}\relax\fi%
+ % round off to integer if possible:
+ \FPupn\v{\stY{} 0 trunc \stY{} - abs \incY{} 0 trunc \incY{} - abs + clip}%
+ \FPifeq\v{0}\FPtrunc\stY\stY{0}\FPtrunc\incY\incY{0}\relax\fi%
+%
+%% now x-axis:
+ \ifYAxisExp% we almost never draw the y-axis but need to see if x-axis spans zero
+ % make sure ticks hit zero; add small epsilons to avoid ticks at the limits
+ \FPupn\stX{\incX{} \dspMinX{} / 0 trunc \incX{} * 2 trunc}%
+ \FPupn\tlimX{\incX{} \stX{} \dspMaxX{} - / abs 1 + 0 trunc}%
+ \else%
+ \FPupn\tlimX{\incX{} \dspRngX{} / abs 1 + 0 trunc}%
+ \FPupn\stX{\dspMinX{} 2 trunc}% \FPupn\stX{\incX{} 1 \tlimX{} - * \dspRngX{} - 0.5 * \dspMinX{} + 2 trunc}%
+ \fi%
+ \FPupn\v{\stX{} 0 trunc \stX{} - abs \incX{} 0 trunc \incX{} - abs +}%
+ \FPifzero\v\FPtrunc\stX\stX{0}\FPtrunc\incX\incX{0}\relax\fi%
+%%
+%% macros for drawing x-ticks
+ \ifXInside%
+ \FPupn\tickEndX{{\strip@pt\dspUnitY} {\strip@pt\dspTickLen} /}%
+ \FPupn\tickTxtX{{\strip@pt\dspUnitY} {\strip@pt\dspXTickGap} 0.9 * / \dspMinY{} -}% tick label pos in PS units
+ \FPupn\tickXB{\tickEndX{} \dspMinY{} +}%
+ \FPupn\tickXT{\tickEndX{} \dspMaxY{} -}%
+ \gdef\dspTickX##1{%
+ \psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](##1,\dspMinY)(##1,\tickXB)%
+ \psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](##1,\dspMaxY)(##1,\tickXT)}%
+ % \gdef\dspTickLabelX##1##2{\uput{{2\dspYTickGap}}[180]{{0}}(\dspMinX,##1){{##2}}}%
+ \gdef\dspTickLabelX##1##2{\rput*[B]{{0}}(##1,\tickTxtX){{##2}}}%
+ \else%
+ \FPupn\tickEndX{{\strip@pt\dspUnitY} {\strip@pt\dspTickLen} / \haY{} -}% tick len in PS units
+ \FPupn\tickTxtX{{\strip@pt\dspUnitY} {\strip@pt\dspXTickGap} / \haY{} -}% tick label pos in PS units
+ \gdef\dspTickX##1{\psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](##1,\haY)(##1,\tickEndX)}%
+ \gdef\dspTickLabelX##1##2{\rput*[B]{{0}}(##1,\tickTxtX){{##2}}}%
+ \fi%
+%% macros for drawing y-ticks
+ \FPupn\tickEndY{{\strip@pt\dspUnitX} {\strip@pt\dspTickLen} /}%
+ \FPupn\tickXB{\tickEndY{} \dspMinX{} +}%
+ \FPupn\tickXT{\tickEndY{} \dspMaxX{} -}%
+ \gdef\dspTickY##1{%
+ \psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](\dspMinX,##1)(\tickXB,##1)%
+ \psline[linewidth=\dspTickLineWidth,linecolor=\dspAxisColor](\dspMaxX,##1)(\tickXT,##1)}%
+ \gdef\dspTickLabelY##1##2{\uput{{2\dspYTickGap}}[180]{{0}}(\dspMinX,##1){{##2}}}%
+ \gdef\dspTickLabelYR##1##2{\uput{{2\dspYTickGap}}[0]{{0}}(\dspMaxX,##1){{##2}}}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% simplify fractions of pi
+\newcount\dspNum \newcount\dspDen
+\def\simplifyPiFrac#1#2{%
+ \ifnum#1=0 $0$\else % zero is zero
+ \dspNum=#1 \dspDen=#2 %
+ \divide\dspNum by\dspDen \multiply\dspNum by\dspDen % see if frac is simply an integer
+ \ifnum\dspNum=#1 \divide\dspNum by\dspDen \ifnum\dspNum=1 $\pi$\else \ifnum\dspNum=-1 $-\pi$\else $\number\dspNum\pi$\fi\fi\else%
+ \dspNum=#1 %
+ \ifnum\dspNum<0 \multiply\dspNum by-1 \def\s{-}\else\def\s{}\fi % normalize sign
+ \divide\dspDen by\dspNum \multiply\dspDen by\dspNum % see if frac is of type 1/x
+ \ifnum\dspDen=#2 \divide\dspDen by\dspNum $\s\pi / \number\dspDen$\else %
+ \dspNum=#1\dspDen=#2 %
+ \removeFactor{10}\removeFactor{9}\removeFactor{8}% remove some common factors
+ \removeFactor{7}\removeFactor{6}\removeFactor{5}%
+ \removeFactor{4}\removeFactor{3}\removeFactor{2}%
+ $\number\dspNum \pi / \number\dspDen$\fi%
+ \fi %
+ \fi}
+
+%% simplify a fraction (not the full Euclid, but it's ok for our purposes)
+\newcount\dspTerm \newcount\dspFact
+\def\removeFactor#1{\dspFact=#1 \dspTerm=\dspNum%
+ \divide\dspTerm by\dspFact \multiply\dspTerm by\dspFact %
+ \ifnum\dspTerm=\dspNum %
+ \dspTerm=\dspDen %
+ \divide\dspTerm by\dspFact \multiply\dspTerm by\dspFact %
+ \ifnum\dspTerm=\dspDen %
+ \divide\dspNum by\dspFact \divide\dspDen by\dspFact %
+ \fi %
+ \fi}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% space-separated lists must have at least two pairs of elements.
+% Duplicate singletons
+%
+\def\m@keList#1 #2 #3\relax{%
+ \ifx&#3&
+ #1 #2 #1 #2
+ \else
+ #1 #2 #3
+ \fi
+}
+
+\def\twoArgSplit#1,#2{#1, #2}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% prepend the ordinal index to each element of a space-separated list
+%
+\def\m@keIndexedList#1#2{%
+ \count0=#1%
+ \expandafter\m@kixl\trim #2 |}
+\def\m@kixl#1 {%
+ \ifx#1|%
+ \let\next=\relax%
+ \else{\number\count0} \ #1\ \advance\count0 by1\let\next=\m@kixl\fi%
+\next}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% perform an action on all consecutive pairs in a space-separated list
+%
+\def\doOnPairs#1#2{%
+ \def\action{#1}%
+ \expandafter\p@rseB\trim #2 |}
+\def\p@rseB#1 #2 #3{%
+ \csname \action\endcsname{#1}{#2}%
+ \ifx#3|%
+ \let\next=\@gobble%
+ \else%
+ \let\next=\p@rseB\fi%
+ \next #3}
+\def\@gobble#1{}
+
+
+\def\trim#1{%
+ \romannumeral-`\.\expandafter\noexpand#1%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PsTricks overrides
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Lollipop line style, by Denis.Girou at idris.fr %%%%%%%%%%%%%%%%%%%%%%%%
+%%
+\let\beginplot@LineToXAxis\beginplot@line
+\def\endplot@LineToXAxis{\psLineToXAxis@ii}
+\let\beginqp@LineToXAxis\beginqp@line
+\let\doqp@LineToXAxis\doqp@line
+\let\endqp@LineToXAxis\endqp@line
+\let\testqp@LineToXAxis\testqp@line
+%
+\def\psLineToXAxis@ii{%
+\addto@pscode{\pst@cp \psline@iii \tx@LineToXAxis}%
+\end@OpenObj}
+%
+\def\tx@LineToXAxis{LineToXAxis }
+%
+% Adapted from Line
+\pst@def{LineToXAxis}<{%
+NArray
+n 0 eq not
+ { n 1 eq { 0 0 /n 2 def } if
+ ArrowA
+ /n n 2 sub def
+ CP 2 copy moveto pop 0 Lineto
+ n { 2 copy moveto pop 0 Lineto } repeat
+ CP
+ 4 2 roll
+ ArrowB
+ 2 copy moveto pop 0
+ L
+ pop pop } if}>
+
+
+\makeatother
+\endinput
+