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.

3
  • 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, 2023 at 4:23
  • 1
    See here for an alternative syntax that I find helpful for small matrices
    – mbert
    Jun 28, 2023 at 4: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} Jun 28, 2023 at 8:30

2 Answers 2

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.

2
  • This is perfect! Exactly what I was looking for. Thank you
    – Dee
    Jun 28, 2023 at 14:45
  • 1
    @Dee: it is not exactly what you were looking for. Read your original post carefully.
    – wipet
    Jun 29, 2023 at 4:10
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}
}
1
  • 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, 2023 at 8:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .