我想做与问题中相同的事情如何在 LaTeX 中按列创建表格?,除了我想在数学模式下做这件事。
准确地说:我想输入一个可能大小不同的项目数组,类似于环境matrix
,只是在 LaTeX 源代码中我想指定一列项目和下一列,依此类推,而不是像往常一样按行指定项目。我希望结果像环境一样垂直居中matrix
。
我还希望能够指定项目之间的水平和垂直空间量。
下面是一个例子来说明我的意思。
\documentclass{article}
\usepackage{amsmath}
\begin{document}
\begin{equation}
x =
\begin{matrix}
1 & 4 \\
2 & 5 \\
3 & \Big(6\Big) \\
\end{matrix}
\end{equation}
\end{document}
在这个 LaTeX 代码中,项目以 1、4、2、5、3、6 的顺序出现,但我想以 1、2、3、4、5、6 的顺序指定它们。
(实际上,更好的方案是按列排列 3、2、1、6、5、4,但列的顺序要相反。但我可以想象这很困难,并且对 1、2、3、4、5、6 的顺序就足够满意了。)
mwe 输出如下所示。
有一个相关问题,有没有办法自动转置用 Latex 编写的矩阵?,但由于该问题专门询问矩阵的转置,因此答案最终无法指定元素之间的空间。我希望得到一个更简单的解决方案,类似于如何在 LaTeX 中按列创建表格?,这更多的是将盒子堆叠在一起而不是进行繁重的工作。
答案1
\valign
primitive 是为这样的任务而设计的:
\def\iskip{\vskip2pt plus1fil}
$$
x =
\vcenter{\hbox{\valign{&\iskip\hbox to1.5em{\hss$#$\hss}\iskip\cr
1 & 2 & 3 \cr
4 & 5 & (6) \cr
}}}
$$
\bye
答案2
您甚至可以使用建议的语法(自下而上):
\documentclass{article}
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\rmatrix}{O{2}m}
{% #1 is the number of columns, default 2
% #2 is a comma separated list of items
\virgo_rmatrix:nn { #1 } { #2 }
}
\seq_new:N \l__virgo_rmatrix_items_seq
\tl_new:N \l__virgo_rmatrix_body_tl
\int_new:N \l__virgo_rmatrix_rows_int
\cs_new_protected:Nn \virgo_rmatrix:nn
{
% this will contain the body
\tl_clear:N \l__virgo_rmatrix_body_tl
% make a sequence from the items
\seq_set_from_clist:Nn \l__virgo_rmatrix_items_seq { #2 }
% check if the number of items is a multiple of #1
\int_compare:nF
{
\int_mod:nn { \seq_count:N \l__virgo_rmatrix_items_seq } { #1 } == 0
}
{% not a multiple, pad
\prg_replicate:nn
{ #1 - \int_mod:nn { \seq_count:N \l__virgo_rmatrix_items_seq } { #1 } }
{ \seq_put_right:Nn \l__virgo_rmatrix_items_seq { } }
}
% determine the number of rows
\int_set:Nn \l__virgo_rmatrix_rows_int
{
\int_div_truncate:nn { \seq_count:N \l__virgo_rmatrix_items_seq } { #1 }
}
% read the items
\int_step_inline:nnnn { \l__virgo_rmatrix_rows_int } { -1 } { 1 }
{% ##1 is the row index
\int_step_inline:nnn { 0 } { #1 - 1 }
{% ####1 is the column index minus 1
\tl_put_right:Nx \l__virgo_rmatrix_body_tl
{
\seq_item:Nn \l__virgo_rmatrix_items_seq { ##1 + ####1*\l__virgo_rmatrix_rows_int }
\int_compare:nTF { ####1 = #1 - 1 } { \exp_not:N \\ } { & }
}
}
}
\begin{matrix}
\tl_use:N \l__virgo_rmatrix_body_tl
\end{matrix}
}
\begin{document}
\[
x=
\rmatrix{3,2,1,\bigl(6\bigr),5,4}
\]
\[
x=
\rmatrix[3]{3,2,1,\bigl(6\bigr),5,4}
\]
\[
x=
\rmatrix[4]{3,2,1,\bigl(6\bigr),5,4,9,8,7,10}
\]
\end{document}
项目数是列数的倍数,行数由该数据计算得出。
然后从行数的每一个倍数开始向后遍历该序列。
答案3
这是一个不完美的自我答案,本质上是通过将答案包装到如何在 LaTeX 中按列创建表格?在\vcenter{\hbox{...}}
。
它并不完美,因为我只是在不真正理解它是如何工作的情况下对另一个答案进行修改,而且它并不是完全垂直居中——肯定有一些微妙之处\vecenter
我没有理解。此外,元素在其列中没有居中,但这对我来说不是什么大问题。
但从好的方面来看,它的行为符合我的要求,因为数组在源中是按列指定的,并且它提供了对间距的所需控制。
\documentclass{article}
\usepackage{amsmath}
\newenvironment{colarray}[2]{%
\vcenter\bgroup\hbox\bgroup\valign\bgroup&\vfil\vbox{\parindent=0pt\tabskip=#2\hsize=#1##}\vfil\cr}%
{\egroup\egroup\egroup}
\newcommand*\col[1]{#1\cr}
\begin{document}
\begin{equation}
x = \begin{colarray}{4mm}{2mm}
\col{1 & 2 & 3}
\col{4 & 5 & \Big(6\Big)}
\end{colarray}
\end{equation}
\end{document}
更新:我解决了垂直间距问题。需要有一个负的 vskip 来抵消最后一行的 tabskip。不幸的是,这意味着它必须是一个新的命令而不是一个新的环境,但它在这里:
\documentclass{article}
\usepackage{amsmath}
% this can't be an environment because the code for \end can't have parameters.
\newcommand{\colarray}[3]{
\vcenter{\hbox{\valign{&\vfil\vbox{\parindent=0pt\tabskip=#2\hsize=#1##}\vfil\cr%
#3%
}}\vskip-#2}%
}
\newcommand*\col[1]{#1\cr}
\begin{document}
\begin{equation}
x = \colarray{4mm}{2mm}{
\col{1 & 2 & 3}
\col{4 & 5 & \Big(6\Big)}
}
\end{equation}
\end{document}
现在我只需要弄清楚单元格内的水平居中。
答案4
这实际上不是一个答案,但评论太长了。希望它对某些人有用,也许有人可以为 lualatex 想出一个解决方案?
在 ConTeXt 中,转置矩阵已经有一段时间了。我们可以定义一个转置的矩阵类型(在 lua 中完成),如下所示
\definemathmatrix[virgomatrix][
action=transpose,
simplecommand=virgomatrix,
distance=4em,
]
完成后,我们可以添加一个转置矩阵
\dm{ x = \virgomatrix{1,2,3; 4,5,\Bigl( 6 \Bigr); 7,8} }
如果我们还想改变行的顺序,我们需要看看math-ali.lmt
它的定义位置。在那里我们找到
local actions = {
transpose = function(m)
local t = { }
for j=1,#m[1] do
local r = { }
for i=1,#m do
r[i] = m[i][j]
end
t[j] = r
end
return t
end,
...
}
其中三个点仅表示某些部分被遗漏了。
我们可以效仿这一点,定义自己的“处女座”动作(注意 中的小变化r[i]
)。
\startluacode
mathematics.registersimplematrix("Virgo",function(m)
local t = { }
for j=1,#m[1] do
local r = { }
for i=1,#m do
r[i] = m[i][#m[1]-j+1]
end
t[j] = r
end
return t
end)
\stopluacode
然后我们就可以使用它了。我们定义一种新的矩阵类型,Virgo
矩阵。
\definemathmatrix[Virgomatrix][
action={Virgo},
simplecommand=Virgomatrix,
distance=4em,
]
然后我们使用这个新类型:
\dm{ x = \Virgomatrix{1,2,3;4,5,\Bigl( 6 \Bigr);7,8} }