[Tex/LaTex] Change how to enter a matrix in Latex

ampersanddelimitersmatricessyntax

In Matlab I can create a matrix by typing A = [1 2 3; 4 5 6; 7 8 9], for this the space is a delimiter between the entries of the matrix. I am wondering if there is a package which makes it possible to input a numerical array in a similar way directly into LaTeX?

For example, I would want to use the syntax:

$\SpaceDelimMat[c]{1 2 3; 4 5 6; 7 8 9}$,

instead of typing & (ampersand) 6 times like this:

$\left[\begin{array}[c]{rrr} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\end{array}\right]$;

as to do the latter is very time consuming and makes LaTeX document less readable, especially when presenting a course about Matrices.

Best Answer

It's quite easy with LaTeX3 macros.

\documentclass{article}
\usepackage{xparse,amsmath}

\ExplSyntaxOn
\NewDocumentCommand{\matlabmatrix}{ O{b} m }
 {
  \strategy_matlabmatrix:nn { #1 } { #2 }
 }

\seq_new:N \l_strategy_rows_seq
\seq_new:N \l_strategy_a_row_seq
\tl_new:N \l_strategy_matrix_tl

\cs_new_protected:Npn \strategy_matlabmatrix:nn #1 #2
 {
  \tl_clear:N \l_strategy_matrix_tl
  \seq_set_split:Nnn \l_strategy_rows_seq { ; } { #2 }
  \seq_map_inline:Nn \l_strategy_rows_seq
   {
    \seq_set_split:Nnn \l_strategy_a_row_seq { ~ } { ##1 }
    \tl_put_right:Nx \l_strategy_matrix_tl { \seq_use:Nn \l_strategy_a_row_seq { & } }
    \tl_put_right:Nn \l_strategy_matrix_tl { \\ }
   }
  \begin{#1matrix}
  \tl_use:N \l_strategy_matrix_tl
  \end{#1matrix}
 }
\ExplSyntaxOff

\begin{document}
\[
\matlabmatrix{1 2 3; 4 5 6; 7 8 9}
\ne
\matlabmatrix[p]{1 2 3; 4 5 6; 7 8 9}
\]
\end{document}

We first split the argument at the semicolons, then process each item, by splitting at spaces. A token list variable containing the body of the matrix is filled row by row and then delivered in the suitable amsmath environment. The optional argument (default b, brackets) can be p (parentheses), v (single bar), V (double bar), B (braces) or even empty (no delimiter).

enter image description here


Customizable version

One can also define a very customizable \xmatlabmatrix, taking as optional argument key-value options; the options are

alignment = t | c | b  % vertical alignment
columns = <column specifiers> % default all centered
delimiters = brackets | parens | braces | bars | doublebars | empty % fences
colsep = <character>
rowsep = <character>

The default for colsep is a space, but it can be customized locally with the key, or globally with \matlabmatrixsetup in the preamble. In the example it is in the body; indeed it can be issued everywhere and obeys the scoping rules (remember to issue colsep={,} for a comma and colsep={ } for a space, with braces).

Here's the code

\documentclass{article}
\usepackage{xparse,amsmath,delarray}

\ExplSyntaxOn
\NewDocumentCommand{\matlabmatrix}{ O{b} m }
 {
  \strategy_matlabmatrix:nn { #1 } { #2 }
 }
\NewDocumentCommand{\matlabmatrixsetup}{m}
 {
  \keys_set:nn { strategy/matrix } { #1 }
 }

\seq_new:N \l_strategy_rows_seq
\seq_new:N \l_strategy_a_row_seq
\tl_new:N \l_strategy_matrix_tl

\cs_new_protected:Npn \strategy_matlabmatrix:nn #1 #2
 {
  \strategy_build_matrix:n { #2 }
  \begin{#1matrix}
  \tl_use:N \l_strategy_matrix_tl
  \end{#1matrix}
 }

\cs_new_protected:Npn \strategy_build_matrix:n #1
 {
  \tl_clear:N \l_strategy_matrix_tl
  \seq_set_split:NVn \l_strategy_rows_seq \l_strategy_rowsep_tl  { #1 }
  \seq_map_inline:Nn \l_strategy_rows_seq
   {
    \seq_set_split:NVn \l_strategy_a_row_seq \l_strategy_colsep_tl { ##1 }
    \tl_put_right:Nx \l_strategy_matrix_tl { \seq_use:Nn \l_strategy_a_row_seq { & } }
    \tl_put_right:Nn \l_strategy_matrix_tl { \\ }
   }
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { NV }

\NewDocumentCommand{\xmatlabmatrix}{ O{} m }
 {
  \group_begin:
  \keys_set:nn { strategy/matrix } { #1 }
  \strategy_xmatlabmatrix:n { #2 }
  \group_end:
 }

\keys_define:nn { strategy/matrix }
 {
  alignment .tl_set:N = \l_strategy_matrix_alignment_tl,
  alignment .initial:n = c,
  columns .tl_set:N = \l_strategy_matrix_columns_tl,
  columns .initial:n = *{100}{c},
  delimiters .choice:,
  delimiters / brackets .code:n = 
   \tl_set:Nn \l_strategy_ldel_tl { \lbrack }
   \tl_set:Nn \l_strategy_rdel_tl { \rbrack },
  delimiters / parens .code:n = 
   \tl_set:Nn \l_strategy_ldel_tl { ( }
   \tl_set:Nn \l_strategy_rdel_tl { ) },
  delimiters / braces .code:n = 
   \tl_set:Nn \l_strategy_ldel_tl { \lbrace }
   \tl_set:Nn \l_strategy_rdel_tl { \rbrace },
  delimiters / bars .code:n = 
   \tl_set:Nn \l_strategy_ldel_tl { \lvert }
   \tl_set:Nn \l_strategy_rdel_tl { \rvert },
  delimiters / doublebars .code:n = 
   \tl_set:Nn \l_strategy_ldel_tl { \lVert }
   \tl_set:Nn \l_strategy_rdel_tl { \rVert },
  delimiters / empty .code:n = 
   \tl_set:Nn \l_strategy_ldel_tl { }
   \tl_set:Nn \l_strategy_rdel_tl { },
  rowsep .tl_set:N = \l_strategy_rowsep_tl,
  rowsep .initial:n = ;,
  colsep .tl_set:N = \l_strategy_colsep_tl,
  colsep .initial:n = {~},
 }
\tl_new:N \l_strategy_ldel_tl
\tl_new:N \l_strategy_rdel_tl
\tl_set:Nn \l_strategy_ldel_tl { \lbrack }
\tl_set:Nn \l_strategy_rdel_tl { \rbrack }

\cs_new_protected:Npn \strategy_xmatlabmatrix:n #1
 {
  \strategy_build_matrix:n { #1 }
  \use:x
   {
    \exp_not:N \begin {array}
    [ \l_strategy_matrix_alignment_tl ]
    \exp_not:V \l_strategy_ldel_tl
    { @{} \exp_not:V \l_strategy_matrix_columns_tl @{} }
    \exp_not:V \l_strategy_rdel_tl
    \exp_not:V \l_strategy_matrix_tl
    \exp_not:N \end{array}
   }
 }

\ExplSyntaxOff

\begin{document}
\[
\matlabmatrix{1 2 3; 4 5 6; 7 8 9}
\ne
\matlabmatrix[p]{1 2 3; 4 5 6; 7 8 9}
\]

\[
\xmatlabmatrix[columns=ccc]{1 2 3; 4 5 6; 7 8 9}
+
\xmatlabmatrix[
  alignment=t,
  delimiters=parens,
  columns=lcr
]{100 100 100; 2 2 2; -3 -3 -3}
\]

\matlabmatrixsetup{
  colsep={,}
}

\[
\matlabmatrix{1,2,3; 4,5,6; 7,8,9}
\ne
\matlabmatrix[p]{1,2,3;4,5,6;7,8,9}
\]

\end{document}

enter image description here