%Works well with \documentclass[12pt]{amsart} %: **************** %: description of \numericalmatrix % Make it easy to write matrices with all items flush right. % First argument optional - gives outer symbol and if it's missing you get bracket % bracket gives left/right bracket pair [ ] % brace gives left/right brace pair { } % parentheses gives left/right parentheses pair ( ) % line gives left/right vertical line | | % a space gives no left/right symbols % second and third argument are numbers m and n for an m\times n matrix (rows times columns) % The last entry is the elements in the matrix, across and then down. % Remark - The individual matrix entries are gobbled by the TeX input mechanism so if an % entry consists of more than one symbol you will need to { - } it. % Remark - if you usually want ()'s instead of []'s just change the [bracket] to what you want % Remark - You can also get pretty much what you want: [\left\{,\right]] will give a left brace % and a right bracket. % Remark - If you precede your entry in the [ ] by a +, the new value becomes global until % changed again. % Remark - If the last entry in the matrix is complicated you may need an extra set of {}'s % to avoid the last entry being split apart and the second part discarded. MAYBE FIXED % % There are two commands \entry and \CR. \entry has one variable and handles the display % of each matrix entry. The default value is \hfill #1 which gives right justification. % \CR by default is \cr and ends each matrix line. If you need a \noalign... at the end of % each line, just redefine \CR % When a given matrix entry is outputted by \entry, there are two global variables set, % \cR and \cC (current Row and current Column) which are set to these values and can be % used to adjust the display. For example % \renewcommand{\entry}[1]{\hfill \ifnum\cR=\cC{#1}_{\textcolor{red}{\the\cR \the\cC}}\else% % \ifnum\cR<\cC{#1}_{\textcolor{green}{\the\cR \the\cC}}\else% % {#1}_{\textcolor{blue}{\the\cR \the\cC}}\fi\fi} % typesets the i j-th entry and adds a subscript i j which is red for diagonal elements, blue below % the diagonal and green above. % There is a global list, \matrixlist which has the matrix encoded so to print it all one needs to % do is $\begin{matrix}\matrixlist\end{matrix}$ to print it a second time % The last used left deliminator is in \leftb and the right one is in \rightb % uniqueness string nbx % Means all the internal routines and variables have an nbx in them. %: \numericalmatrix % The last argument of \numericalmatrix and \NM is optional. If it is present, it consists % two dimensions separated by a comma. One or both can be missing. Examples are % [2pt, 3pt] [,5pt] [6pt,] % Missing dimensions are supplied by a default value. If either of the dimensions is preceded % by a +, that becomes the new default value % Matrices can be nested EXCEPT that auto from \rigidmatrix does not work. \def\rightb{}\gdef\rightmatrixdeliminatorskipSave{}\gdef\rightmatrixdeliminatorskip{}% \newcommand{\numericalmatrix}[4][\defaultmatrixdeliminator]{% \edef\rightBsave{\rightb}% \edef\rightmatrixdeliminatorskipSave{\rightmatrixdeliminatorskip}% \nbxsetBraces{#1}% \nbxsetMatrixList{#2}{#3}{#4}% \gdef\nbxA{#2}\gdef\nbxB{#3}\gdef\nbxC{#4}% \NMnbxcollectskips% } %: \NM % short form - uses \defaultmatrixdeliminator \newcommand{\NM}[3]{ \numericalmatrix[\defaultmatrixdeliminator]{#1}{#2}{#3}% } \newcount\cCSave %: \nbxNM % most of the work is here \newcommand{\nbxNM}[3]{% \def\nbxll##1{% set the macro that sets the matrix entries \nxbEntry{\hfill##1\hfill}% \global\advance\cC by 1 % \ifnum\cC>\maxCLRT \global\cC=1 \fi% \ifnum\cC=1 \relax\nxbCR\else&\fi}% % {\cCSave=\cC % \cC=1 % initialize \cC \edef\maxRLRT{\maxR}\edef\maxCLRT{\maxC}% \showMatrix% % \gdef\nxbEntry{\defaultentry}% \gdef\nxbCR{\defaultCR}% \global\cC = \cCSave }% } %: \showMatrix \newcommand{\showMatrix}[1][\matrixlist]{% \leftb\hskip\leftmatrixdeliminatorskip\begin{matrix} #1% \end{matrix}\hskip\rightmatrixdeliminatorskip\rightb% } %: \NMnbxcollectskips \newcommand{\NMnbxcollectskips}[1][,]{\def\nbxD{#1}% \expandafter\nbxlrmd\nbxD @% \nbxNM{\nbxA}{\nbxB}{\nbxC}% \xdef\rightb{\rightBsave}% \xdef\rightmatrixdeliminatorskip{\rightmatrixdeliminatorskipSave}% } %: \resetEntry \def\resetEntry#1{\gdef\nxbEntry{#1}} \resetEntry{\defaultentry} %: \resetCR \def\resetCR#1{\gdef\nxbCR{#1}} \resetCR{\defaultCR} % Outline of the code % The first subroutine determines the left and right deliminators % \nbxsetMatrixList is a loop which collects the entries. % At the end, \matrixlist is a list: { \nbxll{a_11} ... \nbxll{a_1n} ... % \nbxll{a_m1} ... \nbxll{a_m n} }. % \NMnbxcollectskips collects the last optional argument and gets the \hskip's % between the deliminators and the entries. % Then \nbxNM defines \nbxll and executes the list which in the default case puts an \hfill before % each entry and a & after all of them except the last one in each column for which it % inserts a \CR after the entry. % It also sets \cR to the current row and \cC to the current column so you can use % this data in your \entry macro if you wish. %%%%%%%%%%%%%%% %: **************** %: description of \rigidmatrix - \RM is the short version % Same as \numericalmatrix with 1 more variable % #5 gives the fixed column width % A value of auto for #5 will cause TeX to calculate all the natural column widths and then use the % maximum of them for all the column widths. % If the entry is preceded by a +, the value becomes global (including +auto). % There is a final, optional pair of dimensions just like \numericalmatrix %: \rigidmatrix \newcommand{\rigidmatrix}[5][\defaultmatrixdeliminator]{% \edef\rightBsave{\rightb}% \edef\rightmatrixdeliminatorskipSave{\rightmatrixdeliminatorskip}% \nbxsetBraces{#1}% \nbxsetMatrixList{#2}{#3}{#4}% \nbxsetColumnSkips{#5}% \gdef\nbxA{#2}\gdef\nbxB{#3}\gdef\nbxC{#4}% \RMnbxcollectskips% } %: \RM % short form - uses \defaultmatrixdeliminator and default spacings \newcommand{\RM}[3]{% \rigidmatrix[\defaultmatrixdeliminator]{#1}{#2}{#3}{}% } \newdimen\zznbxcolumnwidthSave %: \nbxRM % most of the work is here \newcommand{\nbxRM}[3]{ % \gdef\nbxll##1{% set the macro that sets the matrix entries \hbox to\zznbxcolumnwidth{$\nxbEntry{##1}$}% \global\advance\cC by 1 % \ifnum\cC>\maxC \global\cC=1 \fi% \ifnum\cC=1 \relax\nxbCR\else&\fi}% % {\cCSave=\cC % \zznbxcolumnwidthSave=\zznbxcolumnwidth% \cC=1 % initialize \cC \showMatrix% \gdef\nxbEntry{\defaultentry}% \gdef\nxbCR{\defaultCR}% \global\cC = \cCSave % \global\zznbxcolumnwidthSave=\zznbxcolumnwidth}% } %: \RMnbxcollectskips \newcommand{\RMnbxcollectskips}[1][,]{\def\nbxD{#1}% \expandafter\nbxlrmd\nbxD @% \nbxRM{\nbxA}{\nbxB}{\nbxC}% \xdef\rightb{\rightBsave}% \xdef\rightmatrixdeliminatorskip{\rightmatrixdeliminatorskipSave}% } %%%%%%%%%%%%%%%%%%% %: **************** %: \setMatrixList \newcommand{\setMatrixList}[4]{% \gdef#4{}% \gdef\maxR{#1}\gdef\maxC{#2}% \global\nbxms=\maxR \global\multiply\nbxms by \maxC% \nbxNRs=#1\relax\nbxNCs=#2\gdef\nbxMEs{#3@}% \nbxloop\ifnum\nbxms>0\relax\global\advance\nbxms by -1% \expandafter\nbxnV\nbxMEs{#4}\relax% \nbxrepeat% } %%%%%%%%%%%%%%%%%%% %: **************** %: \pushState \gdef\pushState{% \gdef\qnbxpush##1##2{\nbxsaveNumber\nbxstateNumber\of\nbxstateList\macro{##1}\label{##2}}% \global\let\exnbx=\qnbxpush% \gnbxmatrixg% \global\advance\nbxstateNumber by 1 % } %: \popState \gdef\popState{% \global\advance\nbxstateNumber by -1 % \gdef\qnbxpop##1##2{\nbxrestore\nbxstateNumber\list{nbxstateList}\label{##2}\to{##1}}% \global\let\exnbx=\qnbxpop% \gnbxmatrixg% } %: **************** %: \transpose \gdef\xxtransposematrix#1\tomatrix#2{\gdef#2{}% \let\xdf=\nbxll% % \def\nbxll##1{% \showthe\nbxIndex\show#2\showthe\nbxwhichIndex% \ifnum\nbxIndex=\nbxwhichIndex\relax% \nbxa={\nbxll{##1}}\nbxb=\expandafter{#2}\xdef#2{\the\nbxb\the\nbxa}\fi% \advance\nbxIndex by 1}% % \nbxXX=0% \nbxMM=\maxC \multiply\nbxMM by \maxR% \nbxCC=1\nbxRR=1% \CC + \maxC*\RR -\maxC \nbxloop% \ifnum\nbxXX< \nbxMM \advance\nbxXX by 1% \nbxwhichIndex=-\maxC% \advance \nbxwhichIndex by \nbxRR% \nbxTmpB=\nbxCC \multiply\nbxTmpB by\maxC% \advance \nbxwhichIndex by \nbxTmpB% \advance\nbxCC by 1 \ifnum\nbxCC>\maxR \nbxCC=1 \advance\nbxRR by 1\fi% \relax\nbxIndex=1\relax#1% \nbxrepeat% \let\nbxll=\xdf% \edef\nbxMM{\maxC}\xdef\maxC{\maxR}\xdef\maxR{\nbxMM}% \global\cC=1 \global\cR=1% } \gdef\transposematrix#1\tomatrix#2{\gdef#2{}% \let\xdf=\nbxll% % \def\nbxll##1{\relax% \ifnum\nbxIndex=\nbxwhichIndex\relax% \nbxa={\nbxll{##1}}\nbxb=\expandafter{#2}\xdef#2{\the\nbxb\the\nbxa}\fi% \advance\nbxIndex by 1}% % \nbxXX=0% \nbxMM=\maxC \multiply\nbxMM by \maxR% \nbxCC=1\nbxRR=1% \CC + \maxC*\RR -\maxC \nbxloop% \ifnum\nbxXX< \nbxMM \advance\nbxXX by 1% \nbxwhichIndex=-\maxC% \advance \nbxwhichIndex by \nbxCC% \nbxTmpB=\nbxRR \multiply\nbxTmpB by\maxC% \advance \nbxwhichIndex by \nbxTmpB% \advance\nbxRR by 1 \ifnum\nbxRR>\maxR \nbxRR=1 \advance\nbxCC by 1\fi% \relax\nbxIndex=1\relax#1% \nbxrepeat% \let\nbxll=\xdf% \edef\nbxMM{\maxC}\xdef\maxC{\maxR}\xdef\maxR{\nbxMM}% \global\cC=1 \global\cR=1% } %% %: **************** %: subroutines %: \nbxlrmd \gdef\nbxlrmd#1,#2@{% \def\xxnbx{#1}% \ifx\xxnbx\empty\gdef\leftmatrixdeliminatorskip{\defaultleftmatrixdeliminatorskip}\else% \expandafter\nbxPluser#1@{\leftmatrixdeliminatorskip}{\defaultleftmatrixdeliminatorskip}\fi% \def\xxnbx{#2}% \ifx\xxnbx\empty\gdef\rightmatrixdeliminatorskip{\defaultrightmatrixdeliminatorskip}\else% \expandafter\nbxPluser#2@{\rightmatrixdeliminatorskip}{\defaultrightmatrixdeliminatorskip}\fi% } %: \nbxleftright \def\nbxleftright#1,#2@{\gdef\leftb{#1}\gdef\rightb{#2}} %: \nbxsetBraces \def\nbxsetBraces#1{ \edef\xnbxx{#1}% \ifx\xnbxx\empty\relax\def\xnbxx{bracket}\else% \expandafter\nbxPluser#1@{\zzdefaultdeliminator}{\defaultmatrixdeliminator}% \xdef\xnbxx{\zzdefaultdeliminator}\fi% \ifx\xnbxx\nbxbr \gdef\leftb{\left[}\gdef\rightb{\right]}\else% \ifx\xnbxx\nbxbs \gdef\leftb{\left\{}\gdef\rightb{\right\}}\else% \ifx\xnbxx\nbxpt \gdef\leftb{\left(}\gdef\rightb{\right)}\else% \ifx\xnbxx\nbxv \gdef\leftb{\left\vert}\gdef\rightb{\right\vert}\else% \ifx\xnbxx\nbsp \gdef\leftb{}\gdef\rightb{}\else% \expandafter\nbxleftright\xnbxx @\relax% \fi\fi\fi\fi\fi% } %: \nbxPluser \def\nbxPluser#1#2@#3#4{\def\xnbxx{#1}\ifx\xnbxx\nbxPlus\relax\gdef#3{#2}% \gdef#4{#2}\else\gdef#3{#1#2}\fi} \def\nbxPlus{+} \def\nbxaa{auto} \newdimen\zznbxcolumnwidth \newbox\nbxmeasurebox %: \nbxsetColumnSkips \newcount\cXC \def\nbxsetColumnSkips#1{ \def\xnbxx{#1}\ifx\xnbxx\empty\relax\xdef\zznbxcolumnwidthmacro{\nbxcolumnwidthmacro}\else% \expandafter\nbxPluser#1@{\zznbxcolumnwidthmacro}{\nbxcolumnwidthmacro}\fi% % \ifx\zznbxcolumnwidthmacro\nbxaa\relax\global\zznbxcolumnwidth=0pt% % \global\cXC=1 % \edef\lrtmaxCX{\maxC}% \def\nbxll##1{% \setbox\nbxmeasurebox =\hbox{$\nxbEntry{##1}$}% \ifdim\wd\nbxmeasurebox>\zznbxcolumnwidth\relax% \global\zznbxcolumnwidth=\wd\nbxmeasurebox \fi% \global\advance\cXC by 1 % \ifnum\cXC>\lrtmaxCX \global\cXC=1 \fi}% % \matrixlist% \else% \global\zznbxcolumnwidth=\zznbxcolumnwidthmacro\fi% } \gdef\nbxcolumnwidthmacro{0pt} \gdef\nbxleftsideskip{0pt} \gdef\nbxrightsideskip{0pt} \newcount\nbxms %: \nbxsetMatrixList \def\nbxsetMatrixList#1#2#3{% \setMatrixList{#1}{#2}{#3}{\matrixlist}% } %: \nbxloop \def\nbxloop#1\nbxrepeat{\def\nbxbody{#1}\nbxiterate} \def\nbxiterate{\nbxbody\let\nbxnextB=\nbxiterate\else\let\nbxnextB=\relax\fi\nbxnextB} %: \nbxnV \def\nbxnV#1#2@#3{\nbxa={\nbxll{#1}}% \nbxb=\expandafter{#3}% \xdef#3{\the\nbxb\the\nbxa}% \ifnum\nbxms=1 \gdef\nbxMEs{{#2}@}\else\gdef\nbxMEs{#2@}\fi% } %%% Like a \pushState and \popState %: \nbxsaveNumber \gdef\nbxsaveNumber#1\of#2\macro#3\label#4{% \nbxmpC=#1% \long\def\\##1{\advance\nbxmpC-1 \ifnum\nbxmpC=0 \global\expandafter\let\csname##1#4\endcsname=#3\fi}#2} %: \nbxrestore \gdef\nbxrestore#1\list#2\label#3\to#4{% \nbxmpC=#1% \long\def\\##1{\advance\nbxmpC-1 \ifnum\nbxmpC=0 \global\let#4=##1\fi}\expandafter\csname#2#3\endcsname} %%%%%%%%% %: **************** %: variables, etc. \newcount\nbxNCs\newcount\nbxNRs\newcount\nbxmpC\newcount\nbxvtc \newtoks\nbxa\newtoks\nbxb \newtoks\nbxc\newtoks\nbxd \gdef\nbxstateList{\\{A}\\{B}\\{C}\\{D}\\{E}\\{F}\\{G}\\{H}\\{I}\\{J}\\{K}\\{L}\\{M}\\{N}} \gdef\nbxmoose{% \\{\csname A\the\nbxa\endcsname}% \\{\csname B\the\nbxa\endcsname}% \\{\csname C\the\nbxa\endcsname}% \\{\csname D\the\nbxa\endcsname}% \\{\csname E\the\nbxa\endcsname}% \\{\csname F\the\nbxa\endcsname}% \\{\csname G\the\nbxa\endcsname}% \\{\csname H\the\nbxa\endcsname}% \\{\csname I\the\nbxa\endcsname}% \\{\csname J\the\nbxa\endcsname}% \\{\csname K\the\nbxa\endcsname}% \\{\csname L\the\nbxa\endcsname}% \\{\csname M\the\nbxa\endcsname}% \\{\csname N\the\nbxa\endcsname}% } \gdef\gnbxmatrixg{\exnbx{\defaultentry}{defaultentry}\exnbx{\defaultCR}{defaultCR}% \exnbx{\maxR}{nbxmaxR}% \exnbx{\maxC}{nbxmaxC}\exnbx{\leftb}{nbxleftb}\exnbx{\rightb}{nbxrightb}% \exnbx{\defaultmatrixdeliminator}{nbxdefaultmatrixdeliminator}} \let\\=\relax \def\ww#1#2{% \nbxa={#2}% \expandafter\xdef\csname nbxstateList\the\nbxa\endcsname{% \nbxmoose}} \let\exnbx=\ww \gnbxmatrixg \newcount\nbxstateNumber\nbxstateNumber=1 \def\defaultentry#1{\hfill#1} \newcommand{\defaultCR}{\cr} \newcount\cR\newcount\cC \newcommand{\nbxll}[1]{} \newcommand{\nbxLL}[1]{} \gdef\defaultleftmatrixdeliminatorskip{0pt} \gdef\defaultrightmatrixdeliminatorskip{0pt} \newcommand{\defaultmatrixdeliminator}{} \def\nbxbr{bracket} \def\nbxbs{brace} \def\nbxpt{parentheses} \def\nbxv{line} \def\nbsp{blank} \newcount\nbxIndex\newcount\nbxwhichIndex \newcount\nbxXX\newcount\nbxCC\newcount\nbxRR\newcount\nbxMM \newcount\nbxTmpB %: \vstrut \newcommand{\vstrut}[2]{% \vrule height #1pt depth #2pt width 0pt}