在问题中排版列向量,给出了一个非常好的解决方案,用于排版具有任意行数的列向量。我试图修改代码以生成行向量而不是列向量。我做了“明显”的更改,即用 替换 ,&
如\\
以下代码片段所示:
\newcount\colveccount
\newcommand*\colvec[1]{
\global\colveccount#1
\begin{pmatrix}
\colvecnext
}
\def\colvecnext#1{
#1
\global\advance\colveccount-1
\ifnum\colveccount>0
&
\expandafter\colvecnext
\else
\end{pmatrix}
\fi
}
然而,我的修改无法编译,而且错误当然没有什么帮助。所以我的问题是,如何修改\colvec
和\colvecnext
宏来生成行向量?
答案1
您必须事先收集行,因为在数组环境中执行此操作非常困难,因为 TeX 一旦看到就会结束一个单元&
。我更喜欢使用令牌寄存器和\count255
暂存计数器来执行此操作。
我们收集两个参数:第一个是条目数,第二个是第一个条目,以便用它初始化令牌寄存器。我们将计数器设置为请求元素的数量(因为我们已经收集了一个,所以我们立即将其降低)。
然后我们开始递归;宏\rowvectnexta
检查计数器的值;如果它仍然大于 0,它会调用\rowvecnextb
收集另一个参数,将其存储到令牌寄存器中(添加一个&
)并降低计数器;否则它pmatrix
通过释放寄存器的内容来构建。
\newtoks\rowvectoks
\newcommand{\rowvec}[2]{%
\rowvectoks={#2}\count255=#1\relax
\advance\count255 by -1
\rowvecnexta}
\newcommand{\rowvecnexta}{%
\ifnum\count255>0
\expandafter\rowvecnextb
\else
\begin{pmatrix}\the\rowvectoks\end{pmatrix}
\fi}
\newcommand\rowvecnextb[1]{%
\rowvectoks=\expandafter{\the\rowvectoks}%
\advance\count255 by -1
\rowvecnexta}
事实上,您至少需要一个元素,这不应该是一个很大的限制:
\rowvec{1}{a}
\rowvec{2}{a}{b}
\rowvec{3}{a}{b}{c}
注意:\usepackage{amsmath}
是必需的。因此,一个最小示例可能如下。
\documentclass{article}
\usepackage{amsmath}
\newtoks\rowvectoks
\newcommand{\rowvec}[2]{%
\rowvectoks={#2}\count255=#1\relax
\advance\count255 by -1
\rowvecnexta}
\newcommand{\rowvecnexta}{%
\ifnum\count255>0
\expandafter\rowvecnextb
\else
\begin{pmatrix}\the\rowvectoks\end{pmatrix}
\fi}
\newcommand\rowvecnextb[1]{%
\rowvectoks=\expandafter{\the\rowvectoks}%
\advance\count255 by -1
\rowvecnexta}
\begin{document}
$\rowvec{1}{a}$
$\rowvec{2}{a}{b}$
$\rowvec{3}{a}{b}{c}$
\end{document}
可以推广到列向量的完全不同的解决方案使用xparse
LaTeX3。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\Rowvec}{ O{,} m }
{
\vector_main:nnnn { p } { & } { #1 } { #2 }
}
\NewDocumentCommand{\Colvec}{ O{,} m }
{
\vector_main:nnnn { p } { \\ } { #1 } { #2 }
}
\seq_new:N \l__vector_arg_seq
\cs_new_protected:Npn \vector_main:nnnn #1 #2 #3 #4
{
\seq_set_split:Nnn \l__vector_arg_seq { #3 } { #4 }
\begin{#1matrix}
\seq_use:Nnnn \l__vector_arg_seq { #2 } { #2 } { #2 }
\end{#1matrix}
}
\ExplSyntaxOff
\begin{document}
$\Rowvec{a}\Rowvec{a,b}\Rowvec[;]{a;b;c}$
$\Colvec{a}\Colvec{a,b}\Colvec[;]{a;b;c}$
\end{document}
可选参数是用于分隔作为参数给出的列表中的条目的分隔符。
{ p }
在两个主要定义中将其改为{ b }
括号而不是圆括号就足够了。
注意:这要求expl3
日期为 2012 年 9 月或更晚。
答案2
我想建议一个肮脏的解决方案,我使用它:
\newcommand*{\rowvec}[1]{\left( #1\right)}
优点是它的使用很简单:\rowvec{a,b,c,d,e}
。我可以很容易地想象它并不强大...对我来说它是有效的。
答案3
这是一个老问题......但当它再次出现时,让我指出,人们可以在没有令牌寄存器或宏存储或计数寄存器的情况下完成这些事情。
\documentclass{article}
\usepackage{amsmath}
\makeatletter
% USAGE \Matrix { a,..,z; A,.., Z ; ... ; aA, ..., zZ}
% NO semi-colon for the last row.
\newcommand{\Matrix}[1]
{\begin{pmatrix}
\Matrix@r #1;\@bye;\Matrix@r
\end{pmatrix}}
\def\Matrix@r #1;{\@bye #1\Matrix@z\@bye\Matrix@s #1,\@bye, }%
\def\Matrix@s #1,{#1\Matrix@t }%
\def\Matrix@t #1,{\@bye #1\Matrix@y\@bye\@firstofone {}\Matrix@t}%
\def\Matrix@y #1\Matrix@t{\\ \Matrix@r }%
\def\Matrix@z #1\Matrix@r {}
\def\@bye #1\@bye {}% (the idea of \@bye is from xint code)
\makeatother
\begin{document}\thispagestyle{empty}
\[ \Matrix { a, b , c , d ; e ,f , 3, 5; 8, -1, x, y }\]
\[ \Matrix { abc , \mathrm{XYZ}; 7, 913; \alpha, \beta }\]
\end{document}
答案4
这是我对列向量建议的行向量的扩展,看这里。其想法是使用类似的纯 TeX 机制,并用管道分隔条目。同样,带括号的接口与 PSTricks 使用的相同。代码如下:
\def\coords(#1,#2){\!\left({\textstyle#1\coords@i#2,,}\right)}
\def\coords@i#1,{\if,#1,\else|{#1}\expandafter\coords@i\fi}
MWE 为:
\documentclass[margin=2pt]{standalone}
\makeatletter
\def\coords(#1,#2){\!\left({\textstyle#1\coords@i#2,,}\right)}
\def\coords@i#1,{\if,#1,\else|{#1}\expandafter\coords@i\fi}
\makeatother
\begin{document}
$P\coords(-3,+4,\frac51)$
\end{document}
因为宏使用了@i
符号,所以代码必须放在文档开始之前的\makeatletter
-包装内。\makeatother