How to generate a matrix from an arbitrary sequence of arguments?
Perhaps less attractive than hand-made recursive macros, here is an implementation in expl3
.
I also added an optional argument (default empty) for producing different matrix types; the optional argument should be among p
, b
, B
, v
or V
, for the corresponding type.
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\setcounter{MaxMatrixCols}{20} % or maybe more
\ExplSyntaxOn
\NewDocumentCommand{\twolinematrix}{O{}m}
{
\twoline_matrix:nn { #1 } { #2 }
}
\seq_new:N \l__twoline_i_seq
\seq_new:N \l__twoline_ii_seq
\cs_new_protected:Nn \twoline_matrix:nn
{
\seq_clear:N \l__twoline_i_seq
\seq_clear:N \l__twoline_ii_seq
\clist_map_function:nN { #2 } \twoline_add:n
\begin{#1matrix}
\seq_use:Nn \l__twoline_i_seq { & }
\\
\seq_use:Nn \l__twoline_ii_seq { & }
\end{#1matrix}
}
\cs_new_protected:Nn \twoline_add:n
{
\__twoline_add:w #1 \q_stop
}
\cs_new_protected:Npn \__twoline_add:w #1/#2 \q_stop
{
\seq_put_right:Nn \l__twoline_i_seq { #1 }
\seq_put_right:Nn \l__twoline_ii_seq { #2 }
}
\ExplSyntaxOff
\begin{document}
\[
\twolinematrix{1/6, 2/7, 3/8, 4/9, 5/10}
\qquad
\twolinematrix[b]{1/6, 2/7, 3/8, 4/9, 5/10, 6/11, 7/12, 8/13, 9/14, 10/15}
\]
\end{document}
This isn't really so different from wipet's code.
- We clear the containers for the rows (here sequences)
- We map the input given as a comma separated list, calling the internal function
\__twoline_add:w
that splits each item at the slash and adds the pieces to the sequences - We use the sequences, placing
&
between items
There is no need to do different things for the first item and the others, this is taken care of by \seq_use:Nn
, which only adds between items.
The advantage over the seemingly more compact code is that we don't need to reinvent the wheel, but just to give an appropriate definition for the action on each item of the comma separated list.
For a deeper explanation of the code, see this: https://tug.org/TUGboat/tb39-1/tb121gregorio-expl3.pdf
For example, you can use this code:
\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\autotwolinematrix#1{\def\firstrow{}\def\secondrow{}\atwolmA#1,/,}
\def\atwolmA#1/#2,{\ifx,#2,\pmatrix{\firstrow\cr\secondrow}\else
\ifx\firstrow\empty \def\firstrow{#1}\def\secondrow{#2}\else
\addto\firstrow{}\addto\secondrow{}\fi
\expandafter \atwolmA \fi
}
test:
$$
\autotwolinematrix{1/6, 2/7, 3/8, 4/9, 5/10}
$$
\bye
First step: \firstrow
and \secondrow
are set in the loop while parameters are read. Second step: these macros are used in \pmatrix
.
Inside alignments it is best to use an expandable loop construct, so using expl3
or here I just code it directly.
\documentclass{article}
\makeatletter
\def\autotwolinematrix#1{%
\begin{bmatrix}%
\firstrow,#1,\relax/%
\secondrow,#1,\relax/%
}
\def\firstrow#1,#2/{\ifx\relax#2\\\else\ifx\relax#1\relax\else&\fi#2\expandafter\firstrow\fi}
\def\secondrow#1,#2/{\ifx\relax#2#1\end{bmatrix}\else#1\ifx\relax#1\relax\else&\fi\expandafter\secondrow\fi}
\makeatother
\usepackage{amsmath}
\begin{document}
$\autotwolinematrix{1/6, 2/7, 3/8, 4/9, 5/10}$
\end{document}