用逗号 II 分隔参数的命令(通常是编写矩阵的简单方法)

用逗号 II 分隔参数的命令(通常是编写矩阵的简单方法)

由于我经常使用 2 x 2 矩阵,因此我想定义一个像这样工作的命令:\matr{a, b, c, d}将产生 $\begin{pmatrix} a & b \\ c & d \end{pmatrix}$

当然,我知道如何使用类似 的方法来获得这个结果\matr{a}{b}{c}{d},但关键是要有一个“逗号分隔的参数列表”。使用 的解决方案\matr{a, b}{c, d}也可能很有趣(尤其是它对 3 x 3 矩阵的推广)。

大多数答案来自这里那里或者那里似乎依赖于xparse包。但我对 LaTeX3 语法非常不熟悉,所以我不知道如何解决我的问题。

答案1

我对 LaTeX3 语法也非常不熟悉,所以我给你一个仅基于 TeX 基元的非 exp3 解决方案。你不需要任何 LaTeX 包(基本上你甚至不需要 LaTeX):

\documentclass[12pt]{article}

\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\matr#1{\def\matrL{}\matrA#1\end}
\def\matrA#1{\ifx\end#1\pmatrix{\matrL}\else 
   \ifx,#1\addto\matrL{&}\else
   \ifx;#1\addto\matrL{\cr}\else
   \addto\matrL{#1}\fi\fi
   \expandafter\matrA\fi
}

\begin{document}

$$
  \matr{a,b;c,d}\ne\matr{1,2,3;4,5,6;7,8,9;10,11,12}
$$

\end{document}

答案2

参数首先在逗号处拆分,按照考虑到位置的映射序列,因此我们可以根据需要添加&或。\\

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn
\NewDocumentCommand{\matr}{m}
 {
  \begin{pmatrix}
  \seq_set_from_clist:Nn \l__watson_matr_seq { #1 }
  \seq_indexed_map_function:NN \l__watson_matr_seq \__watson_matr_entry:nn
  \end{pmatrix}
 }

\seq_new:N \l__watson_matr_seq

\cs_new:Nn \__watson_matr_entry:nn
 {
  #2 % the entry
  \int_case:nn { #1 } { {1}{&} {2}{\\} {3}{&} }
 }
\ExplSyntaxOff

\begin{document}

\[
\matr{a,b,c,d}
\]

\end{document}

在此处输入图片描述

我们能概括一下吗?是的。

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn
\NewDocumentCommand{\matr}{O{2}m}
 {
  \int_set:Nn \l__watson_matr_size_int { #1 }
  \begin{pmatrix}
  \watson_matr:nn { #1 } { #2 }
  \end{pmatrix}
 }

\seq_new:N \l__watson_matr_seq
\int_new:N \l__watson_matr_size_int

\cs_new_protected:Nn \watson_matr:nn
 {
  \seq_set_from_clist:Nn \l__watson_matr_seq { #2 }
  \seq_indexed_map_function:NN \l__watson_matr_seq \__watson_matr_entry:nn
 }
\cs_new_protected:Nn \__watson_matr_entry:nn
 {
  #2 % the entry
  \int_compare:nTF { \int_mod:nn { #1 } { \l__watson_matr_size_int } = 0 }
   { \\ }
   { & }
 }
\ExplSyntaxOff

\begin{document}

\[
\matr{a,b,c,d}\ne\matr[3]{1,2,3,4,5,6,7,8,9}
\]

\end{document}

在此处输入图片描述

如果您愿意接受稍微不同的语法,以分号作为结束行,您可以轻松地生成具有不同形状和分隔符的矩阵。

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn
\NewDocumentCommand{\matr}{O{p}m}
 {
  \seq_set_split:Nnn \l__watson_matr_full_seq { ; } { #2 }
  \begin{#1matrix}
  \seq_map_function:NN \l__watson_matr_full_seq \__watson_matr_makerow:n
  \end{#1matrix}
 }

\seq_new:N \l__watson_matr_full_seq
\seq_new:N \l__watson_matr_row_seq

\cs_new_protected:Nn \__watson_matr_makerow:n
 {
  \seq_set_split:Nnn \l__watson_matr_row_seq { , } { #1 }
  \seq_use:Nn \l__watson_matr_row_seq { & }
  \\
 }
\ExplSyntaxOff

\begin{document}

\[
\matr{a,b;c,d}\ne\matr[b]{1,2,3;4,5,6;7,8,9;10,11,12}
\]

\end{document}

在此处输入图片描述

答案3

这里我使用分隔tokcycle符代替逗号&。虽然我展示的是 2x2 和 3x3,但只要矩阵包含 2 行或(可选)3 行,任何列数都是可以接受的。

\documentclass{article}
\usepackage{amsmath,tokcycle}
\newcommand\matr[1][2]{\tctestifnum{3=#1}{\matrTHREE}{\matrTWO}}
\newcommand\matrTWO[2]{%
  \tokcyclexpress{#1\\#2}%
  \begin{pmatrix}\the\cytoks\end{pmatrix}}
\newcommand\matrTHREE[3]{%
  \tokcyclexpress{#1\\#2\\#3}%
  \begin{pmatrix}\the\cytoks\end{pmatrix}}
\Characterdirective{\tctestifx{,#1}{\addcytoks{&}}{\addcytoks{#1}}}
\begin{document}
\[
\matr{a, b}{c, d}
\]
\[
\matr[3]{a, b,c}{d, e, f}{g, h, i}
\]
\end{document}

在此处输入图片描述

可选单一参数方法

这允许使用以下语法在单个参数内任意组合行和列,\matr{ a, b / c, d}其中,逗号作为列分隔符,而/标记作为行分隔符:

\documentclass{article}
\usepackage{amsmath,tokcycle}
\newcommand\matr[1]{\tokcyclexpress{#1}%
  \begin{pmatrix}\the\cytoks\end{pmatrix}}
\Characterdirective{\tctestifx{,#1}{\addcytoks{&}}{%
  \tctestifx{/#1}{\addcytoks{\\}}{\addcytoks{#1}}}}
\begin{document}
\[
\matr{a, b / c, d}
\]
\[
\matr{a, b,c / d, e, f/ g, h, i}
\]
\end{document}

答案4

有点晚了,但为了多样化,这里有一个基于 LuaLaTeX 的解决方案。关于输入语法,我假设,用作给定行中单元格之间的分隔符,而;用作行之间的分隔符。

在此处输入图片描述

\documentclass{article}
\usepackage{amsmath} % for 'pmatrix' environment
\usepackage{luacode} % for '\luaexec' macro

\luaexec{
    function matr ( s ) 
       s = s:gsub ( ";" , "\\\\" )
       s = s:gsub ( "," , "&" )
       tex.sprint ( "\\begin{pmatrix}" .. s .. "\\end{pmatrix}" )
    end
}
\newcommand\matr[1]{\directlua{ matr ( "#1" ) }}

\begin{document}
$\matr{ a, b ; c, d  }$
\end{document}

相关内容