0

Currently, I am able to make a command shortcut that produces a matrix given a fixed amount of arguments. For example, the command

\newcommand{\MAT}[4]{\begin{bmatrix}
#1 & #2 \\
#3 & #4 \\
\end{bmatrix}
}

produces a matrix with arguments inputted row by row. My question is: is there a way to define a similar matrix but for any dimension, especially for nonsquare matrices?

I'd like to be able to have two arguments that defines the dimensions of the matrix, and then an arbitrary amount of arguments where each entry is added along the rows. Something like \MAT{2}{2}{a}{b}{c}{d} that outputs a 2x2 matrix with entries a, b, c, d would be very nice.

Dee
  • 103
  • Welcome to TeX.SE community! I wouldn't do that. Better is to use standard, deliberately defined syntax for writing of matrices. BTW, desired code change is not so significant shorter, but may be unclear to others who eventually will have a deal with your code ... – Zarko Jun 28 '23 at 04:23
  • 1
    See here for an alternative syntax that I find helpful for small matrices – mbert Jun 28 '23 at 04:57
  • by default you only need one character to separate cells & or two at end of line \\ and your shortcut requires two }{ so it takes more markup especially for larger matricies. \newcommand\MAT[1]{begin{bmatrix}#1\end{bmatrix}} allows \MAT{a&b\\c&d} which is shorter and easier to read than \MAT{2}{2}{a}{b}{c}{d} – David Carlisle Jun 28 '23 at 08:30

2 Answers2

4

I contend that

\MAT{a,b;c,d}

is much shorter than

\MAT{2}{2}{a}{b}{c}{d}

and doesn't even require specifying the number of rows and columns.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\MAT}{m} { \begin{bmatrix} __dee_mat_rows:n { #1 } \end{bmatrix} }

\cs_new_protected:Nn __dee_mat_rows:n { \seq_set_split:Nnn \l_tmpa_seq { ; } { #1 } \seq_map_function:NN \l_tmpa_seq __dee_mat_cols:n }

\cs_new_protected:Nn __dee_mat_cols:n { \clist_use:nn { #1 } { & } \ }

\ExplSyntaxOff

\begin{document}

\begin{gather} \MAT{a,b;c,d} \quad \MAT{a,b,c} \quad \MAT{a;b;c} \ \MAT{11,12,13,14,15,16;21,22,23,24,25,26} \quad \MAT{11,12;21,22;31,32;41,42} \end{gather}

\end{document}

enter image description here

The idea is to split the argument at the semicolons. Then we map over the chunks: each chunk is a comma separated list and & is inserted between items; a final \\ ends the row.

Note that nothing prevents you from inputting

\MAT{
  11 , 12 , 13 ;
  21 , 22 , 23 ;
  31 , 32 , 33
}

Spaces around commas or semicolons and newlines in the argument (but not blank lines) are optional.

egreg
  • 1,121,712
2

For example, your macro \MAT can look like this:

\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\newcount\MATcol \newcount\MATitems

\def\MAT#1#2{\def\MATc{#2}\MATcol=#2 \MATitems=#1 \multiply\MATitems by\MATcol \def\MATbuf{}\MATa} \def\MATa#1{% \addto\MATbuf{#1} \advance\MATcol by-1 \advance\MATitems by-1 \ifnum\MATcol=0 \addto\MATbuf{\cr}\MATcol=\MATc\relax \else \addto\MATbuf{&}\fi \ifnum\MATitems>0 \expandafter\MATa \else \expandafter\MATb \fi } \def\MATb{ \begin{bmatrix} \MATbuf \end{bmatrix} }

wipet
  • 74,238
  • 3
    This is for LaTeX and you shouldn't use \def. For instance, if babel is loaded in the document, your code would clobber \addto and problems might ensue. – egreg Jun 28 '23 at 08:25