%% %% This is file `bodeplot.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% bodeplot.dtx (with options: `package') %% This is a generated file. %% Copyright (C) 2021 by Rushikesh Kamalapurkar %% This file may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3c of this license or (at your option) any later %% version. The latest version of this license is in: %% http://www.latex-project.org/lppl.txt %% and version 1.3c or later is part of all distributions of %% LaTeX version 2006/05/20 or later. \NeedsTeXFormat{LaTeX2e}[2006/05/20] \ProvidesPackage{bodeplot} \RequirePackage{tikz} \RequirePackage{pdftexcmds} \RequirePackage{ifplatform} \RequirePackage{pgfplots} \pgfplotsset{compat=1.18} \usepgfplotslibrary{groupplots} \RequirePackage{ifluatex}% \ifluatex \let\pdfstrcmp\pdf@strcmp \fi \newif\if@pgfarg\@pgfargfalse \DeclareOption{pgf}{% \@pgfargtrue } \ProcessOptions\relax \if@pgfarg \newcommand{\n@pow}[2]{(#1)^(#2)}% \newcommand{\n@mod}[2]{mod((#1),(#2))}% \else \newcommand{\n@pow}[2]{(#1)**(#2)}% \newcommand{\n@mod}[2]{(#1)-(floor((#1)/(#2))*(#2))}% \newcounter{gnuplot@id}% \setcounter{gnuplot@id}{0}% \tikzset{% gnuplot@prefix/.style={% id=\arabic{gnuplot@id}, prefix=gnuplot/\jobname }% } \pgfplotsset{% gnuplot@degrees/.code={% \ifnum\value{gnuplot@id}=1 \xdef\pgfplots@gnuplot@format{\pgfplots@gnuplot@format set angles degrees;}% \fi }% } \ifwindows\else \immediate\write18{mkdir -p gnuplot}% \fi \fi \pgfplotsset{% bode@style/.style = {% label style={font=\footnotesize}, tick label style={font=\footnotesize}, grid=both, major grid style={color=gray!80}, minor grid style={color=gray!20}, x label style={at={(ticklabel cs:0.5)},anchor=near ticklabel}, y label style={at={(ticklabel cs:0.5)},anchor=near ticklabel}, scale only axis, samples=200, width=5cm, }% } \newcommand*{\MagK}[2]{(20*log10(abs(#1)))} \newcommand*{\MagKAsymp}{\MagK} \newcommand*{\MagKLin}{\MagK} \newcommand*{\PhK}[2]{(#1<0?-180:0)} \newcommand*{\PhKAsymp}{\PhK} \newcommand*{\PhKLin}{\PhK} \newcommand*{\MagDel}[2]{0} \newcommand*{\PhDel}[2]{-#1*180*t/pi} \newcommand*{\MagPole}[2] {(-20*log10(sqrt(\n@pow{#1}{2} + \n@pow{t - (#2)}{2})))} \newcommand*{\MagPoleLin}[2]{(t < sqrt(\n@pow{#1}{2} + \n@pow{#2}{2}) ? -20*log10(sqrt(\n@pow{#1}{2} + \n@pow{#2}{2})) : -20*log10(t) )} \newcommand*{\MagPoleAsymp}{\MagPoleLin} \newcommand*{\PhPole}[2]{(#1 > 0 ? (#2 > 0 ? (\n@mod{-atan2((t - (#2)),-(#1))+360}{360}) : (-atan2((t - (#2)),-(#1)))) : (-atan2((t - (#2)),-(#1))))} \newcommand*{\PhPoleLin}[2]{% (abs(#1)+abs(#2) == 0 ? -90 : (t < (sqrt(\n@pow{#1}{2} + \n@pow{#2}{2}) / (\n@pow{10}{sqrt(\n@pow{#1}{2}/(\n@pow{#1}{2} + \n@pow{#2}{2}))})) ? (-atan2(-(#2),-(#1))) : (t >= (sqrt(\n@pow{#1}{2} + \n@pow{#2}{2}) * (\n@pow{10}{sqrt(\n@pow{#1}{2}/(\n@pow{#1}{2} + \n@pow{#2}{2}))})) ? (#2>0?(#1>0?270:-90):-90) : (-atan2(-(#2),-(#1)) + (log10(t/(sqrt(\n@pow{#1}{2} + \n@pow{#2}{2}) / (\n@pow{10}{sqrt(\n@pow{#1}{2}/(\n@pow{#1}{2} + \n@pow{#2}{2}))}))))*((#2>0?(#1>0?270:-90):-90) + atan2(-(#2),-(#1)))/ (log10(\n@pow{10}{sqrt((4*\n@pow{#1}{2})/ (\n@pow{#1}{2} + \n@pow{#2}{2}))}))))))} \newcommand*{\PhPoleAsymp}[2]{(t < (sqrt(\n@pow{#1}{2} + \n@pow{#2}{2})) ? (-atan2(-(#2),-(#1))) : (#2>0?(#1>0?270:-90):-90))} \newcommand*{\MagZero}{0-\MagPole} \newcommand*{\MagZeroLin}{0-\MagPoleLin} \newcommand*{\MagZeroAsymp}{0-\MagPoleAsymp} \newcommand*{\PhZero}{0-\PhPole} \newcommand*{\PhZeroLin}{0-\PhPoleLin} \newcommand*{\PhZeroAsymp}{0-\PhPoleAsymp} \newcommand*{\MagCSPoles}[2]{(-20*log10(sqrt(\n@pow{\n@pow{#2}{2} - \n@pow{t}{2}}{2} + \n@pow{2*#1*#2*t}{2})))} \newcommand*{\MagCSPolesLin}[2]{(t < #2 ? -40*log10(#2) : - 40*log10(t))} \newcommand*{\MagCSPolesAsymp}{\MagCSPolesLin} \newcommand*{\PhCSPoles}[2]{(-atan2((2*(#1)*(#2)*t),(\n@pow{#2}{2} - \n@pow{t}{2})))} \newcommand*{\PhCSPolesLin}[2]{(t < (#2 / (\n@pow{10}{abs(#1)})) ? 0 : (t >= (#2 * (\n@pow{10}{abs(#1)})) ? (#1>0 ? -180 : 180) : (#1>0 ? (-180*(log10(t*(\n@pow{10}{#1})/#2))/(2*#1)) : (180*(log10(t*(\n@pow{10}{abs(#1)})/#2))/(2*abs(#1))))))} \newcommand*{\PhCSPolesAsymp}[2]{(#1>0?(t<#2?0:-180):(t<#2?0:180))} \newcommand*{\MagCSZeros}{0-\MagCSPoles} \newcommand*{\MagCSZerosLin}{0-\MagCSPolesLin} \newcommand*{\MagCSZerosAsymp}{0-\MagCSPolesAsymp} \newcommand*{\PhCSZeros}{0-\PhCSPoles} \newcommand*{\PhCSZerosLin}{0-\PhCSPolesLin} \newcommand*{\PhCSZerosAsymp}{0-\PhCSPolesAsymp} \newcommand*{\MagCSPolesPeak}[3][]{% \draw[#1,->] (axis cs:{#3},{-40*log10(#3)}) -- (axis cs:{#3},{-40*log10(#3)-20*log10(2*abs(#2))}) } \newcommand*{\MagCSZerosPeak}[3][]{% \draw[#1,->] (axis cs:{#3},{40*log10(#3)}) -- (axis cs:{#3},{40*log10(#3)+20*log10(2*abs(#2))}) } \newcommand*{\MagSOPoles}[2]{% (-20*log10(sqrt(\n@pow{#2 - \n@pow{t}{2}}{2} + \n@pow{#1*t}{2})))} \newcommand*{\MagSOPolesLin}[2]{% (t < sqrt(abs(#2)) ? -20*log10(abs(#2)) : - 40*log10(t))} \newcommand*{\MagSOPolesAsymp}{\MagSOPolesLin} \newcommand*{\PhSOPoles}[2]{(-atan2((#1)*t,((#2) - \n@pow{t}{2})))} \newcommand*{\PhSOPolesLin}[2]{(#2>0 ? \PhCSPolesLin{(#1/(2*sqrt(#2)))}{(sqrt(#2))} : (#1>0 ? -180 : 180))} \newcommand*{\PhSOPolesAsymp}[2]{(#2>0 ? \PhCSPolesAsymp{(#1/(2*sqrt(#2)))}{(sqrt(#2))} : (#1>0 ? -180 : 180))} \newcommand*{\MagSOZeros}{0-\MagSOPoles} \newcommand*{\MagSOZerosLin}{0-\MagSOPolesLin} \newcommand*{\MagSOZerosAsymp}{0-\MagSOPolesAsymp} \newcommand*{\PhSOZeros}{0-\PhSOPoles} \newcommand*{\PhSOZerosLin}{0-\PhSOPolesLin} \newcommand*{\PhSOZerosAsymp}{0-\PhSOPolesAsymp} \newcommand*{\MagSOPolesPeak}[3][]{% \draw[#1,->] (axis cs:{sqrt(abs(#3))},{-20*log10(abs(#3))}) -- (axis cs:{sqrt(abs(#3))},{-20*log10(abs(#3)) - 20*log10(abs(#2/sqrt(abs(#3))))}); } \newcommand*{\MagSOZerosPeak}[3][]{% \draw[#1,->] (axis cs:{sqrt(abs(#3))},{20*log10(abs(#3))}) -- (axis cs:{sqrt(abs(#3))},{20*log10(abs(#3)) + 20*log10(abs(#2/sqrt(abs(#3))))}); } \newcommand{\BodeZPK}[4][approx/true]{% \parse@opt{#1}% \gdef\func@mag{}% \gdef\func@ph{}% \build@ZPK@plot{\func@mag}{\func@ph}{\opt@approx}{#2}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{groupplot}[% bode@style, xmin={#3}, xmax={#4}, domain=#3:#4, height=2.5cm, xmode=log, group style = {group size = 1 by 2,vertical sep=0.25cm}, \opt@group ]% }% \temp@cmd \if@pgfarg \expandafter\nextgroupplot\expandafter[ytick distance=20, ylabel={Gain (dB)},xmajorticks=false,\optmag@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optmag@plot]}% \temp@cmd {\func@mag}; \optmag@commands \expandafter\nextgroupplot\expandafter[ytick distance=45, ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optph@plot]}% \temp@cmd {\func@ph}; \optph@commands \else \stepcounter{gnuplot@id} \expandafter\nextgroupplot\expandafter[ytick distance=20, ylabel={Gain (dB)},xmajorticks=false,\optmag@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optmag@plot]}% \temp@cmd gnuplot[gnuplot@degrees,gnuplot@prefix] {\func@mag}; \optmag@commands \stepcounter{gnuplot@id} \expandafter\nextgroupplot\expandafter[ytick distance=45, ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optph@plot]}% \temp@cmd gnuplot[gnuplot@degrees,gnuplot@prefix] {\func@ph}; \optph@commands \fi \end{groupplot} \end{tikzpicture} } \newcommand{\BodeTF}[4][]{% \parse@opt{#1}% \gdef\func@mag{}% \gdef\func@ph{}% \build@TF@plot{\func@mag}{\func@ph}{#2}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{groupplot}[% bode@style, xmin={#3}, xmax={#4}, domain=#3:#4, height=2.5cm, xmode=log, group style = {group size = 1 by 2,vertical sep=0.25cm}, \opt@group ]% }% \temp@cmd \if@pgfarg \expandafter\nextgroupplot\expandafter[ytick distance=20, ylabel={Gain (dB)},xmajorticks=false,\optmag@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optmag@plot]}% \temp@cmd {\func@mag}; \optmag@commands \expandafter\nextgroupplot\expandafter[ytick distance=45, ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optph@plot]}% \temp@cmd {\func@ph}; \optph@commands \else \stepcounter{gnuplot@id}% \expandafter\nextgroupplot\expandafter[ytick distance=20, ylabel={Gain (dB)},xmajorticks=false,\optmag@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optmag@plot]}% \temp@cmd gnuplot[gnuplot@degrees,gnuplot@prefix] {\func@mag}; \optmag@commands \stepcounter{gnuplot@id}% \expandafter\nextgroupplot\expandafter[ytick distance=45, ylabel={Phase ($^{\circ}$)},xlabel={Frequency (rad/s)},\optph@axes] \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\optph@plot]}% \temp@cmd gnuplot[gnuplot@degrees,gnuplot@prefix] {\func@ph}; \optph@commands \fi \end{groupplot} \end{tikzpicture} } \newcommand{\addBodeZPKPlots}[3][true/{}]{% \foreach \approx/\opt in {#1} {% \gdef\plot@macro{}% \gdef\temp@macro{}% \ifnum\pdfstrcmp{#2}{phase}=0 \build@ZPK@plot{\temp@macro}{\plot@macro}{\approx}{#3}% \else \build@ZPK@plot{\plot@macro}{\temp@macro}{\approx}{#3}% \fi \if@pgfarg \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\opt]}% \temp@cmd {\plot@macro}; \else \stepcounter{gnuplot@id}% \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\opt]} \temp@cmd gnuplot[gnuplot@degrees,gnuplot@prefix] {\plot@macro}; \fi }% } \newcommand{\addBodeTFPlot}[3][thick]{% \gdef\plot@macro{}% \gdef\temp@macro{}% \ifnum\pdfstrcmp{#2}{phase}=0 \build@TF@plot{\temp@macro}{\plot@macro}{#3}% \else \build@TF@plot{\plot@macro}{\temp@macro}{#3}% \fi \if@pgfarg \addplot[variable=t,#1]{\plot@macro}; \else \stepcounter{gnuplot@id}% \addplot[variable=t,#1] gnuplot[gnuplot@degrees, gnuplot@prefix] {\plot@macro}; \fi } \newcommand{\addBodeComponentPlot}[2][thick]{% \if@pgfarg \addplot[variable=t,#1]{#2}; \else \stepcounter{gnuplot@id}% \addplot[variable=t,#1] gnuplot[gnuplot@degrees,gnuplot@prefix] {#2}; \fi } \newenvironment{BodePlot}[3][]{% \parse@env@opt{#1}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}] \noexpand\begin{semilogxaxis}[% bode@style, xmin={#2}, xmax={#3}, domain=#2:#3, height=2.5cm, xlabel={Frequency (rad/s)}, \unexpanded\expandafter{\opt@axes} ]% }% \temp@cmd }{ \end{semilogxaxis} \end{tikzpicture} } \newcommand*{\add@feature}[3]{% \ifcat$\detokenize\expandafter{#1}$% \xdef#1{\unexpanded\expandafter{#1 0+#2}}% \else \xdef#1{\unexpanded\expandafter{#1+#2}}% \fi \foreach \y [count=\n] in #3 {% \xdef#1{\unexpanded\expandafter{#1}{\y}}% \xdef\Last@LoopValue{\n}% }% \ifnum\Last@LoopValue=1% \xdef#1{\unexpanded\expandafter{#1}{0}}% \fi } \newcommand{\build@ZPK@plot}[4]{% \foreach \feature/\values in {#4} {% \ifnum\pdfstrcmp{\feature}{z}=0 \foreach \z in \values {% \ifnum\pdfstrcmp{#3}{linear}=0 \add@feature{#2}{\PhZeroLin}{\z}% \add@feature{#1}{\MagZeroLin}{\z}% \else \ifnum\pdfstrcmp{#3}{asymptotic}=0 \add@feature{#2}{\PhZeroAsymp}{\z}% \add@feature{#1}{\MagZeroAsymp}{\z}% \else \add@feature{#2}{\PhZero}{\z}% \add@feature{#1}{\MagZero}{\z}% \fi \fi }% \fi \ifnum\pdfstrcmp{\feature}{p}=0 \foreach \p in \values {% \ifnum\pdfstrcmp{#3}{linear}=0 \add@feature{#2}{\PhPoleLin}{\p}% \add@feature{#1}{\MagPoleLin}{\p}% \else \ifnum\pdfstrcmp{#3}{asymptotic}=0 \add@feature{#2}{\PhPoleAsymp}{\p}% \add@feature{#1}{\MagPoleAsymp}{\p}% \else \add@feature{#2}{\PhPole}{\p}% \add@feature{#1}{\MagPole}{\p}% \fi \fi }% \fi \ifnum\pdfstrcmp{\feature}{k}=0 \ifnum\pdfstrcmp{#3}{linear}=0 \add@feature{#2}{\PhKLin}{\values}% \add@feature{#1}{\MagKLin}{\values}% \else \ifnum\pdfstrcmp{#3}{asymptotic}=0 \add@feature{#2}{\PhKAsymp}{\values}% \add@feature{#1}{\MagKAsymp}{\values}% \else \add@feature{#2}{\PhK}{\values}% \add@feature{#1}{\MagK}{\values}% \fi \fi \fi \ifnum\pdfstrcmp{\feature}{d}=0 \ifnum\pdfstrcmp{#3}{linear}=0 \PackageError {bodeplot} {Linear approximation for pure delays is not supported.} {Plot the true Bode plot using `true' instead of `linear'.} \else \ifnum\pdfstrcmp{#3}{asymptotic}=0 \PackageError {bodeplot} {Asymptotic approximation for pure delays is not supported.} {Plot the true Bode plot using `true' instead of `asymptotic'.} \else \ifdim\values pt < 0pt \PackageError {bodeplot} {Delay needs to be a positive number.} \fi \add@feature{#2}{\PhDel}{\values}% \add@feature{#1}{\MagDel}{\values}% \fi \fi \fi }% } \newcommand{\build@TF@plot}[3]{% \gdef\num@real{0}% \gdef\num@im{0}% \gdef\den@real{0}% \gdef\den@im{0}% \gdef\loop@delay{0}% \foreach \feature/\values in {#3} {% \ifnum\pdfstrcmp{\feature}{num}=0 \foreach \numcoeff [count=\numpow] in \values {% \xdef\num@degree{\numpow}% }% \foreach \numcoeff [count=\numpow] in \values {% \pgfmathtruncatemacro{\currentdegree}{\num@degree-\numpow}% \ifnum\currentdegree = 0 \xdef\num@real{\num@real+\numcoeff}% \else \ifodd\currentdegree \xdef\num@im{\num@im+(\numcoeff*(\n@pow{-1}{(\currentdegree-1)/2})*% (\n@pow{t}{\currentdegree}))}% \else \xdef\num@real{\num@real+(\numcoeff*(\n@pow{-1}{(\currentdegree)/2})*% (\n@pow{t}{\currentdegree}))}% \fi \fi }% \fi \ifnum\pdfstrcmp{\feature}{den}=0 \foreach \dencoeff [count=\denpow] in \values {% \xdef\den@degree{\denpow}% }% \foreach \dencoeff [count=\denpow] in \values {% \pgfmathtruncatemacro{\currentdegree}{\den@degree-\denpow}% \ifnum\currentdegree = 0 \xdef\den@real{\den@real+\dencoeff}% \else \ifodd\currentdegree \xdef\den@im{\den@im+(\dencoeff*(\n@pow{-1}{(\currentdegree-1)/2})*% (\n@pow{t}{\currentdegree}))}% \else \xdef\den@real{\den@real+(\dencoeff*(\n@pow{-1}{(\currentdegree)/2})*% (\n@pow{t}{\currentdegree}))}% \fi \fi }% \fi \ifnum\pdfstrcmp{\feature}{d}=0 \xdef\loop@delay{\values}% \fi }% \xdef#2{(\n@mod{atan2((\num@im),(\num@real))-atan2((\den@im),% (\den@real))+360}{360}-\loop@delay*180*t/pi)}% \xdef#1{(20*log10(sqrt((\n@pow{\num@real}{2})+(\n@pow{\num@im}{2})))-% 20*log10(sqrt((\n@pow{\den@real}{2})+(\n@pow{\den@im}{2}))))}% } \newcommand{\parse@opt}[1]{% \gdef\optmag@axes{}% \gdef\optph@axes{}% \gdef\optph@plot{}% \gdef\optmag@plot{}% \gdef\opt@group{}% \gdef\opt@approx{}% \gdef\optph@commands{}% \gdef\optmag@commands{}% \gdef\opt@tikz{}% \foreach \obj/\typ/\opt in {#1} {% \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{plot}=0 \ifnum\pdfstrcmp{\unexpanded\expandafter{\typ}}{mag}=0 \xdef\optmag@plot{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\typ}}{ph}=0 \xdef\optph@plot{\unexpanded\expandafter{\opt}}% \else \xdef\optmag@plot{\unexpanded\expandafter{\opt}}% \xdef\optph@plot{\unexpanded\expandafter{\opt}}% \fi \fi \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{axes}=0 \ifnum\pdfstrcmp{\unexpanded\expandafter{\typ}}{mag}=0 \xdef\optmag@axes{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\typ}}{ph}=0 \xdef\optph@axes{\unexpanded\expandafter{\opt}}% \else \xdef\optmag@axes{\unexpanded\expandafter{\opt}}% \xdef\optph@axes{\unexpanded\expandafter{\opt}}% \fi \fi \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{group}=0 \xdef\opt@group{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{approx}=0 \xdef\opt@approx{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{commands}=0 \ifnum\pdfstrcmp{\unexpanded\expandafter{\typ}}{ph}=0 \xdef\optph@commands{\unexpanded\expandafter{\opt}}% \else \xdef\optmag@commands{\unexpanded\expandafter{\opt}}% \fi \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{tikz}=0 \xdef\opt@tikz{\unexpanded\expandafter{\opt}}% \else \xdef\optmag@plot{\unexpanded\expandafter{\optmag@plot}, \unexpanded\expandafter{\obj}}% \xdef\optph@plot{\unexpanded\expandafter{\optph@plot}, \unexpanded\expandafter{\obj}}% \fi \fi \fi \fi \fi \fi }% } \newcommand{\parse@env@opt}[1]{% \gdef\opt@axes{}% \gdef\opt@tikz{}% \foreach \obj/\opt in {#1} {% \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{axes}=0 \xdef\opt@axes{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{tikz}=0 \xdef\opt@tikz{\unexpanded\expandafter{\opt}}% \else \xdef\opt@axes{\unexpanded\expandafter{\opt@axes}, \unexpanded\expandafter{\obj}}% \fi \fi }% } \newcommand{\NyquistZPK}[4][]{% \parse@N@opt{#1}% \gdef\func@mag{}% \gdef\func@ph{}% \build@ZPK@plot{\func@mag}{\func@ph}{}{#2}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{axis}[% bode@style, domain=#3:#4, height=5cm, xlabel={$\Re$}, ylabel={$\Im$}, samples=500, \unexpanded\expandafter{\opt@axes} ]% }% \temp@cmd \addplot [only marks,mark=+,thick,red] (-1 , 0); \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\unexpanded\expandafter{\opt@plot}]}% \if@pgfarg \temp@cmd ( {\n@pow{10}{((\func@mag)/20)}*cos(\func@ph)}, {\n@pow{10}{((\func@mag)/20)}*sin(\func@ph)} ); \opt@commands \else \stepcounter{gnuplot@id}% \temp@cmd gnuplot[parametric,gnuplot@degrees,gnuplot@prefix] {% \n@pow{10}{((\func@mag)/20)}*cos(\func@ph), \n@pow{10}{((\func@mag)/20)}*sin(\func@ph)}; \opt@commands \fi \end{axis} \end{tikzpicture} } \newcommand{\NyquistTF}[4][]{% \parse@N@opt{#1}% \gdef\func@mag{}% \gdef\func@ph{}% \build@TF@plot{\func@mag}{\func@ph}{#2}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{axis}[% bode@style, domain=#3:#4, height=5cm, xlabel={$\Re$}, ylabel={$\Im$}, samples=500, \unexpanded\expandafter{\opt@axes} ]% }% \temp@cmd \addplot [only marks,mark=+,thick,red] (-1 , 0); \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\unexpanded\expandafter{\opt@plot}]}% \if@pgfarg \temp@cmd ( {\n@pow{10}{((\func@mag)/20)}*cos(\func@ph)}, {\n@pow{10}{((\func@mag)/20)}*sin(\func@ph)} ); \opt@commands \else \stepcounter{gnuplot@id}% \temp@cmd gnuplot[parametric,gnuplot@degrees,gnuplot@prefix]{% \n@pow{10}{((\func@mag)/20)}*cos(\func@ph), \n@pow{10}{((\func@mag)/20)}*sin(\func@ph)}; \opt@commands \fi \end{axis} \end{tikzpicture} } \newcommand{\addNyquistZPKPlot}[2][]{% \gdef\func@mag{}% \gdef\func@ph{}% \build@ZPK@plot{\func@mag}{\func@ph}{}{#2}% \if@pgfarg \addplot[variable=t,#1] ( {\n@pow{10}{((\func@mag)/20)}*cos(\func@ph)}, {\n@pow{10}{((\func@mag)/20)}*sin(\func@ph)} ); \else \stepcounter{gnuplot@id}% \addplot[variable=t,#1] gnuplot[parametric,gnuplot@degrees,gnuplot@prefix]{% \n@pow{10}{((\func@mag)/20)}*cos(\func@ph), \n@pow{10}{((\func@mag)/20)}*sin(\func@ph)}; \fi } \newcommand{\addNyquistTFPlot}[2][]{% \gdef\func@mag{}% \gdef\func@ph{}% \build@TF@plot{\func@mag}{\func@ph}{#2}% \if@pgfarg \addplot[variable=t,#1] ( {\n@pow{10}{((\func@mag)/20)}*cos(\func@ph)}, {\n@pow{10}{((\func@mag)/20)}*sin(\func@ph)} ); \else \stepcounter{gnuplot@id}% \addplot[variable=t,#1] gnuplot[parametric,gnuplot@degrees,gnuplot@prefix]{% \n@pow{10}{((\func@mag)/20)}*cos(\func@ph), \n@pow{10}{((\func@mag)/20)}*sin(\func@ph)}; \fi } \newenvironment{NyquistPlot}[3][]{% \parse@env@opt{#1}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{axis}[% bode@style, height=5cm, domain=#2:#3, xlabel={$\Re$}, ylabel={$\Im$}, \unexpanded\expandafter{\opt@axes} ]% }% \temp@cmd \addplot [only marks,mark=+,thick,red] (-1 , 0); }{% \end{axis} \end{tikzpicture} } \newcommand{\parse@N@opt}[1]{% \gdef\opt@axes{}% \gdef\opt@plot{}% \gdef\opt@commands{}% \gdef\opt@tikz{} \foreach \obj/\opt in {#1} {% \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{axes}=0 \xdef\opt@axes{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{plot}=0 \xdef\opt@plot{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{commands}=0 \xdef\opt@commands{\unexpanded\expandafter{\opt}}% \else \ifnum\pdfstrcmp{\unexpanded\expandafter{\obj}}{tikz}=0 \xdef\opt@tikz{\unexpanded\expandafter{\opt}}% \else \xdef\opt@plot{\unexpanded\expandafter{\opt@plot}, \unexpanded\expandafter{\obj}}% \fi \fi \fi \fi }% } \newcommand{\NicholsZPK}[4][]{% \parse@N@opt{#1}% \gdef\func@mag{}% \gdef\func@ph{}% \build@ZPK@plot{\func@mag}{\func@ph}{}{#2}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{axis}[% bode@style, domain=#3:#4, height=5cm, xlabel={Phase (degrees)}, ylabel={Gain (dB)}, samples=500, \unexpanded\expandafter{\opt@axes} ]% }% \temp@cmd \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\opt@plot]}% \if@pgfarg \temp@cmd ( {\func@ph} , {\func@mag} ); \opt@commands \else \stepcounter{gnuplot@id}% \temp@cmd gnuplot[parametric, gnuplot@degrees, gnuplot@prefix] { \func@ph , \func@mag }; \opt@commands \fi \end{axis} \end{tikzpicture} } \newcommand{\NicholsTF}[4][]{% \parse@N@opt{#1}% \gdef\func@mag{}% \gdef\func@ph{}% \build@TF@plot{\func@mag}{\func@ph}{#2}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{axis}[% bode@style, domain=#3:#4, height=5cm, xlabel={Phase (degrees)}, ylabel={Gain (dB)}, samples=500, \unexpanded\expandafter{\opt@axes} ]% }% \temp@cmd \edef\temp@cmd{\noexpand\addplot[variable=t,thick,\opt@plot]}% \if@pgfarg \temp@cmd ( {\func@ph} , {\func@mag} ); \opt@commands \else \stepcounter{gnuplot@id}% \temp@cmd gnuplot[parametric, gnuplot@degrees, gnuplot@prefix] { \func@ph , \func@mag }; \opt@commands \fi \end{axis} \end{tikzpicture} } \newenvironment{NicholsChart}[3][]{% \parse@env@opt{#1}% \edef\temp@cmd{\noexpand\begin{tikzpicture}[\unexpanded\expandafter{\opt@tikz}]% \noexpand\begin{axis}[% bode@style, domain=#2:#3, height=5cm, xlabel={Phase (degrees)}, ylabel={Gain (dB)}, \unexpanded\expandafter{\opt@axes} ]% }% \temp@cmd }{ \end{axis} \end{tikzpicture} } \newcommand{\addNicholsZPKChart}[2][]{% \gdef\func@mag{}% \gdef\func@ph{}% \build@ZPK@plot{\func@mag}{\func@ph}{}{#2}% \if@pgfarg \addplot[variable=t,#1] ( {\func@ph} , {\func@mag} ); \else \stepcounter{gnuplot@id}% \addplot[variable=t,#1] gnuplot[parametric,gnuplot@degrees,gnuplot@prefix] {\func@ph , \func@mag}; \fi } \newcommand{\addNicholsTFChart}[2][]{% \gdef\func@mag{}% \gdef\func@ph{}% \build@TF@plot{\func@mag}{\func@ph}{#2}% \if@pgfarg \addplot[variable=t,#1] ( {\func@ph} , {\func@mag} ); \else \stepcounter{gnuplot@id}% \addplot[variable=t,#1] gnuplot[gnuplot@degrees,gnuplot@prefix] {\func@ph , \func@mag}; \fi } \endinput %% %% End of file `bodeplot.sty'.