11

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.

  • Not that I disagree with you but matlab notation is not any better as far as readability is concerned. I recommend latexindent from @cmhughes. – percusse Aug 26 '13 at 14:31
  • 1
    Welcome to TeX.SX! You can have a look on our our starter page to familiarize yourself further with our format. – Claudio Fiandrino Aug 26 '13 at 14:46
16

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.