% pdiag.sty Style for drawing permutation diagrams % % coded by Jason B. Hill (Jason.B.Hill@Colorado.edu / http://www.jasonbhill.com) % % This package attempts to provide an environment for drawing permutation diagrams, % with no claim that it works well, or works at all. For usage, see pdiag.tex/pdf % \RequirePackage{ifthen,calc,fp} % \ProvidesPackage{pdiag} % % % \newcommand{\pdmap}[3][0] { % Given two x-coordinates, draw a line, record vertices as mapped % #1 (optional) = 0 (default) draws a line, #1 = 1 draws a bezier % #2 = x-coordinate of domain % #3 = x-coordinate of image \if0#1 % In this case (0=#1), draw a line \FPset{\pdiagxdot}{#2}\FPsub{\pdiagxdot}{\pdiagxdot}{\pdiaghalf}\FPclip{\pdiagxdot}{\pdiagxdot} % Calculate x-coordinate of domain \FPset{\pdiagxim}{#3}\FPsub{\pdiagxim}{\pdiagxim}{\pdiaghalf}\FPclip{\pdiagxim}{\pdiagxim} % Calculate x-coordinate of image \qbezier(\pdiagxdot,\thepdiagthisrow)(\pdiagxdot,\thepdiagthisrow)(\pdiagxim,\thepdiagnextrow) % Draw line between points \put(\pdiagxdot,\thepdiagthisrow){{\circle*{0.2}}}\put(\pdiagxim,\thepdiagnextrow){{\circle*{0.2}}} % Make dot at vertices \else % % Define points along bezier curve a,b,c,d,e \def\@pdiagax{}\def\@pdiagbx{}\def\@pdiagcx{}\def\@pdiagdx{}\def\@pdiagex{} % Define x-coordinate commands \def\@pdiagay{}\def\@pdiagby{}\def\@pdiagcy{}\def\@pdiagdy{}\def\@pdiagey{} % Define y-coordinate commands % \FPset{\pdiagax}{#2}\FPsub{\pdiagax}{\pdiagax}{\pdiaghalf}\FPclip{\pdiagax}{\pdiagax} % Set x-coord for a \FPset{\pdiagbx}{\pdiagax} % Set x-coord for b \FPset{\pdiagex}{#3}\FPsub{\pdiagex}{\pdiagex}{\pdiaghalf}\FPclip{\pdiagex}{\pdiagex} % Set x-coord for e \FPset{\pdiagdx}{\pdiagex} % Set x-coord for d \FPeval{\pdiagcx}{(\pdiagax+\pdiagex)/2} % Set x-coord for c % \FPset{\pdiagay}{\thepdiagthisrow} % Set y-coord for a \FPeval{\pdiagby}{\thepdiagthisrow-\pdiagbezbshift} % Set y-coord for b \FPset{\pdiagey}{\thepdiagnextrow} % Set y-coord for e \FPeval{\pdiagdy}{\thepdiagthisrow-\pdiagbezdshift} % Set y-coord for d \FPeval{\pdiagcy}{(\pdiagby+\pdiagdy)/2} % Set y-coord for c % \qbezier(\pdiagax,\pdiagay)(\pdiagbx,\pdiagby)(\pdiagcx,\pdiagcy) % Draw first section of bezier curve \qbezier(\pdiagcx,\pdiagcy)(\pdiagdx,\pdiagdy)(\pdiagex,\pdiagey) % Draw first section of bezier curve % \put(\pdiagax,\pdiagay){{\circle*{0.2}}}\put(\pdiagex,\pdiagey){{\circle*{0.2}}} % Make dot at vertices \fi % % \pdcountvertex{#2} % Count the domain vertex so it is not automatically mapped down on \pdendmapfill % \@pdresetbez % Reset bezier coordinate parameters } % % % % ---------------------------- Command to draw a single transposition \newcommand{\pdtrans}[3][0] % { % #1 is same as #1 in \pdmap definition % #2 = x-coord of domain % #3 = x-coord of range % if \pdmbez has been called, the mappings in the transposition will be mirror copies of each other \if0#1 % Draw lines \pdmap[#1]{#2}{#3}\pdmap[#1]{#3}{#2} % \else % Draw beziers % Save bezier information since it will be used twice \def\@pdiagbezbtemp{}\FPset{\pdiagbezbtemp}{\pdiagbezbshift} \def\@pdiagbezdtemp{}\FPset{\pdiagbezdtemp}{\pdiagbezdshift} \pdmap[#1]{#2}{#3} % Draw first bezier in permutation \FPset{\pdiagbezbshift}{\pdiagbezbtemp}\FPset{\pdiagbezdshift}{\pdiagbezdtemp} % Reset bezier parameters \pdmap[#1]{#3}{#2} % Draw second bezier in permutation \fi % } % % ---------------------------- End command to draw a single transposition % % % ---------------------------- Command to draw a single braid permutation \newcommand{\pdbraid}[2][0] % { % Draw a single brain permutation, i.e. something like (1 2) or (5 6) % #1 is same as #1 in \pdmap definition % #2 = first x-coordinate to be mapped (other is #1 + 1) \ifthenelse{#2=\thepdiagcolnum} { % \pdtrans[#1]{#2}{1} % Draw braid }{ % \def\@pdiagnextx{}\FPset{\pdiagnextx}{#2}\FPadd{\pdiagnextx}{\pdiagnextx}{1} % Calculate second braid vertex \pdtrans[#1]{#2}{\pdiagnextx} % Draw braid } % } % % ---------------------------- End command to draw a single braid permutation % % % ---------------------------- Command to set bezier parameters \newcommand{\pdmbez}[2] % { % set the amount that a bezier is shifted up/down on either side % #1 will control the placement of point b vertically (-1 is at point a, 1 is at point e) % #2 will control the placement of point d vertically (-1 is at point a, 1 is at point e) \def\@pdiagbezbshift{}\FPset{\pdiagbezbshift}{#1}\FPadd{\pdiagbezbshift}{\pdiagbezbshift}{1} % Point b is 0.7 below point a and 1.3 above point e \def\@pdiagbezdshift{}\FPset{\pdiagbezdshift}{#2}\FPadd{\pdiagbezdshift}{\pdiagbezdshift}{1} % Point d is 0.7 above point e and 1.3 below point a } % % ---------------------------- End command to set bezier parameters % % % ---------------------------- Command to reset bezier parameters \newcommand{\@pdresetbez} % { % reset the amount that a bezier is shifted up/down on either side \def\@pdiagbezbshift{}\FPset{\pdiagbezbshift}{0.7} % Point b is 0.7 below point a and 1.3 above point e \def\@pdiagbezdshift{}\FPset{\pdiagbezdshift}{1.3} % Point d is 0.7 above point e and 1.3 below point a } % % ---------------------------- End command to reset bezier parameters % % % ---------------------------- Command to end a row and draw lines representing unmapped vertices \newcommand{\@pdemptymap}[1] { % An input will be a roman numeral command representing a vertex in the current row % if the command is set to zero, draw a line \if#1\thepdiagj % check for zero \FPset{\pdiagxdot}{\thepdiagi}\FPsub{\pdiagxdot}{\pdiagxdot}{\pdiaghalf}\FPclip{\pdiagxdot}{\pdiagxdot} % Calculate x-coordinate \qbezier(\pdiagxdot,\thepdiagthisrow)(\pdiagxdot,\thepdiagthisrow)(\pdiagxdot,\thepdiagnextrow) % Draw line \put(\pdiagxdot,\thepdiagthisrow){{\circle*{0.2}}}\put(\pdiagxdot,\thepdiagnextrow){{\circle*{0.2}}}\fi % Make dot at vertices } % % ---------------------------- Command to end a row and draw lines representing unmapped vertices % % % ---------------------------- Command to end a map and decide/map unmapped vertices \newcommand{\pdendmapfill} { % Go from left to right across columns and see if each vertex has been used in this map % If it has been used, go to next vertex % If it has not been used, map a line down to next row \setcounter{pdiagi}{\value{pdiagcolnum}} % Counter to iterate over columns \setcounter{pdiagj}{0} % Something set to zero to check conditionals \whiledo{\value{pdiagi}>0} { % \ifcase\thepdiagi % \or\@pdemptymap{\@pdiagverti} % \or\@pdemptymap{\@pdiagvertii} % \or\@pdemptymap{\@pdiagvertiii} % \or\@pdemptymap{\@pdiagvertiv} % \or\@pdemptymap{\@pdiagvertv} % \or\@pdemptymap{\@pdiagvertvi} % \or\@pdemptymap{\@pdiagvertvii} % \or\@pdemptymap{\@pdiagvertviii} % \or\@pdemptymap{\@pdiagvertix} % \or\@pdemptymap{\@pdiagvertx} % \or\@pdemptymap{\@pdiagvertxi} % \or\@pdemptymap{\@pdiagvertxii} % \or\@pdemptymap{\@pdiagvertxiii} % \or\@pdemptymap{\@pdiagvertxiv} % \or\@pdemptymap{\@pdiagvertxv} % \or\@pdemptymap{\@pdiagvertxvi} % \or\@pdemptymap{\@pdiagvertxvii} % \or\@pdemptymap{\@pdiagvertxviii} % \or\@pdemptymap{\@pdiagvertxix} % \or\@pdemptymap{\@pdiagvertxx} % \or\@pdemptymap{\@pdiagvertxxi} % \or\@pdemptymap{\@pdiagvertxxii} % \or\@pdemptymap{\@pdiagvertxxiii} % \or\@pdemptymap{\@pdiagvertxxiv} % \or\@pdemptymap{\@pdiagvertxxv} % \or\@pdemptymap{\@pdiagvertxxvi} % \or\@pdemptymap{\@pdiagvertxxvii} % \or\@pdemptymap{\@pdiagvertxxviii} % \or\@pdemptymap{\@pdiagvertxxix} % \or\@pdemptymap{\@pdiagvertxxx} % \or\@pdemptymap{\@pdiagvertxxxi} % \or\@pdemptymap{\@pdiagvertxxxii} % \or\@pdemptymap{\@pdiagvertxxxiii} % \or\@pdemptymap{\@pdiagvertxxxiv} % \or\@pdemptymap{\@pdiagvertxxxv} % \or\@pdemptymap{\@pdiagvertxxxvi} % \or\@pdemptymap{\@pdiagvertxxxvii} % \or\@pdemptymap{\@pdiagvertxxxviii} % \or\@pdemptymap{\@pdiagvertxxxix} % \or\@pdemptymap{\@pdiagvertxl} % \or\@pdemptymap{\@pdiagvertxli} % \or\@pdemptymap{\@pdiagvertxlii} % \or\@pdemptymap{\@pdiagvertxliii} % \or\@pdemptymap{\@pdiagvertxliv} % \or\@pdemptymap{\@pdiagvertxlv} % \or\@pdemptymap{\@pdiagvertxlvi} % \or\@pdemptymap{\@pdiagvertxlvii} % \or\@pdemptymap{\@pdiagvertxlviii} % \or\@pdemptymap{\@pdiagvertxlix} % \or\@pdemptymap{\@pdiagvertl} % \fi % \setcounter{pdiagi}{\value{pdiagi}-1} % } % endwhile \setcounter{pdiagthisrow}{\value{pdiagthisrow}-2} % Move to next map in diagram \setcounter{pdiagnextrow}{\value{pdiagnextrow}-2} % Move to next map in diagram \pdresetrow % } % % ---------------------------- End command to end a map and decide/map unmapped vertices % % % ---------------------------- Command to end a map and not map unmapped vertices \newcommand{\pdendmap} % { % \setcounter{pdiagthisrow}{\value{pdiagthisrow}-2} % Move to next map in diagram \setcounter{pdiagnextrow}{\value{pdiagnextrow}-2} % Move to next map in diagram \pdresetrow % } % \newcommand{\pdblankmap}{\pdendmap} % Make an alias % ---------------------------- End command to end a map and not map unmapped vertices % % % ---------------------------- Command to label a permutation \newcommand{\pdname}[1] % If called (optional), puts the name #1 at the side of the row { % \put(-0.3,\value{pdiagnextrow}){\makebox(0.4,2){{\footnotesize $#1$}}} % } % % ---------------------------- End command to label a permutation % % % ---------------------------- Command to reset vertex information \newcommand{\pdresetrow} % variables to keep track of which vertices are used { % \def\@pdiagverti{0}\def\@pdiagvertii{0}\def\@pdiagvertiii{0}\def\@pdiagvertiv{0}\def\@pdiagvertv{0} % \def\@pdiagvertvi{0}\def\@pdiagvertvii{0}\def\@pdiagvertviii{0}\def\@pdiagvertix{0}\def\@pdiagvertx{0} % \def\@pdiagvertxi{0}\def\@pdiagvertxii{0}\def\@pdiagvertxiii{0}\def\@pdiagvertxiv{0}\def\@pdiagvertxv{0} % \def\@pdiagvertxvi{0}\def\@pdiagvertxvii{0}\def\@pdiagvertxviii{0}\def\@pdiagvertxix{0}\def\@pdiagvertxx{0} % \def\@pdiagvertxxi{0}\def\@pdiagvertxxii{0}\def\@pdiagvertxxiii{0}\def\@pdiagvertxxiv{0}\def\@pdiagvertxxv{0} % \def\@pdiagvertxxvi{0}\def\@pdiagvertxxvii{0}\def\@pdiagvertxxviii{0}\def\@pdiagvertxxix{0}\def\@pdiagvertxxx{0} % \def\@pdiagvertxxxi{0}\def\@pdiagvertxxxii{0}\def\@pdiagvertxxxiii{0}\def\@pdiagvertxxxiv{0}\def\@pdiagvertxxxv{0} % \def\@pdiagvertxxxvi{0}\def\@pdiagvertxxxvii{0}\def\@pdiagvertxxxviii{0}\def\@pdiagvertxxxix{0}\def\@pdiagvertxl{0} % \def\@pdiagvertxli{0}\def\@pdiagvertxlii{0}\def\@pdiagvertxliii{0}\def\@pdiagvertxliv{0}\def\@pdiagvertxlv{0} % \def\@pdiagvertxlvi{0}\def\@pdiagvertxlvii{0}\def\@pdiagvertxlviii{0}\def\@pdiagvertxlix{0}\def\@pdiagvertl{0} % } % % ---------------------------- End command to reset vertex information % % % ---------------------------- Command to count a vertex \newcommand{\pdcountvertex}[1] % { % given x-coordinate of vertex, add one to that vertex's count % #1 = x-coordinate of vertex \ifcase#1 % \or\def\@pdiagverti{1} % \or\def\@pdiagvertii{1} % \or\def\@pdiagvertiii{1} % \or\def\@pdiagvertiv{1} % \or\def\@pdiagvertv{1} % \or\def\@pdiagvertvi{1} % \or\def\@pdiagvertvii{1} % \or\def\@pdiagvertviii{1} % \or\def\@pdiagvertix{1} % \or\def\@pdiagvertx{1} % \or\def\@pdiagvertxi{1} % \or\def\@pdiagvertxii{1} % \or\def\@pdiagvertxiii{1} % \or\def\@pdiagvertxiv{1} % \or\def\@pdiagvertxv{1} % \or\def\@pdiagvertxvi{1} % \or\def\@pdiagvertxvii{1} % \or\def\@pdiagvertxviii{1} % \or\def\@pdiagvertxix{1} % \or\def\@pdiagvertxx{1} % \or\def\@pdiagvertxxi{1} % \or\def\@pdiagvertxxii{1} % \or\def\@pdiagvertxxiii{1} % \or\def\@pdiagvertxxiv{1} % \or\def\@pdiagvertxxv{1} % \or\def\@pdiagvertxxvi{1} % \or\def\@pdiagvertxxvii{1} % \or\def\@pdiagvertxxviii{1} % \or\def\@pdiagvertxxix{1} % \or\def\@pdiagvertxxx{1} % \or\def\@pdiagvertxxxi{1} % \or\def\@pdiagvertxxxii{1} % \or\def\@pdiagvertxxxiii{1} % \or\def\@pdiagvertxxxiv{1} % \or\def\@pdiagvertxxxv{1} % \or\def\@pdiagvertxxxvi{1} % \or\def\@pdiagvertxxxvii{1} % \or\def\@pdiagvertxxxviii{1} % \or\def\@pdiagvertxxxix{1} % \or\def\@pdiagvertxl{1} % \or\def\@pdiagvertxli{1} % \or\def\@pdiagvertxlii{1} % \or\def\@pdiagvertxliii{1} % \or\def\@pdiagvertxliv{1} % \or\def\@pdiagvertxlv{1} % \or\def\@pdiagvertxlvi{1} % \or\def\@pdiagvertxlvii{1} % \or\def\@pdiagvertxlviii{1} % \or\def\@pdiagvertxlix{1} % \or\def\@pdiagvertl{1} % \fi % } % % ---------------------------- End command to count a vertex % % % % The pdiag environment will use either straight lines of bezier curves. A straight line will be defined % as a bezier with midpoint equal to one of the endpoints. For a bezier curve that is not straight, the % point c will be calculated as the midpoint of b and d. Points b and d will have the same x-coordinates % as points a and e respectively. So, modifying the bezier curve can be done by moving the y-coordinates % and points b and e. By default, there is 2 units of space vertically between point a and point e. By % default, b will be 0.6 below a and d will be 1.4 below a. % a % | % b---c---d % | % e % \newenvironment{pdiag}[3][1] % { % Creates a picture environment with scale #1*0.5cm % #2 is number of vertices wide (add 1 and put 0.5 space on each side, vertex 1 is at x-coord 0.5) % #3 is the height of the diagram (given in number of permutations, add empty rows between rows for readability) % % Add generic counters \@ifundefined{c@pdiagi}{\newcounter{pdiagi}}{} % counter names pdiagi \@ifundefined{c@pdiagj}{\newcounter{pdiagj}}{} % counter names pdiagj \@ifundefined{c@pdiagk}{\newcounter{pdiagk}}{} % counter names pdiagk % % Add counters to record diagram dimensions \@ifundefined{c@pdiagcolnum}{\newcounter{pdiagcolnum}}{} % counter to save column dimension \@ifundefined{c@pdiagrownum}{\newcounter{pdiagrownum}}{} % counter to save row dimension % % Add counter to track current row (and next row) \@ifundefined{c@pdiagthisrow}{\newcounter{pdiagthisrow}}{} % \@ifundefined{c@pdiagnextrow}{\newcounter{pdiagnextrow}}{} % % % Set column and row dimensions for diagram \setcounter{pdiagcolnum}{#2}\setcounter{pdiagrownum}{#3*\real{2}} % % % Set current row and nextrow counters (start at top of diagram) \setcounter{pdiagthisrow}{#3*\real{2}} % \setcounter{pdiagnextrow}{#3*\real{2}-2} % % % Set default y-coordinates (shifts) for 2nd (b) and 4th (d) bezier points \def\@pdiagbyshift{}\FPset{\pdiagbyshift}{0.6} % Set to 0.6 below y-coord of a \def\@pdiagdyshift{}\FPset{\pdiagdyshift}{1.4} % Set to 1.4 below y-coord of a % % Set default y-coordinate (shift) for 3rd (c) bezier point \def\@pdiagcyshift{}\FPeval{\pdiagcyshift}{(\pdiagbyshift + \pdiagdyshift)/2}\FPclip{\pdiagcyshift}{\pdiagcyshift} % % % Create variables to hold x-coordinate information \def\@pdiagxdot{}\def\@pdiagxim{} % % % Create variables to store default bezier coordinate information \def\@pdiagbezbshift{}\FPset{\pdiagbezbshift}{0.7} % point b is 0.7 below point a and 1.3 above point e \def\@pdiagbezdshift{}\FPset{\pdiagbezdshift}{1.3} % point d is 0.7 above point e and 1.3 below point a % % Create a variable to hold 1/2 value (all x-coordinates are 1/2 shifted in diagram to create space on sides of diagram) \def\@pdiaghalf{}\FPeval{\pdiaghalf}{1/2} % % % Set unitlength for picture environment \setlength{\unitlength}{0.5cm*\real{#1}} % % Begin picture environment \begin{array}{c}\begin{picture}(\thepdiagcolnum,\thepdiagrownum) % \pdresetrow % }{\end{picture}\end{array}} %