由于在 LaTeX 中编写矩阵是一项极其耗时的活动,我想知道是否存在可以自动给出矩阵转置形式的软件或网站,也就是说,给定一个矩阵:
\begin{bmatrix}
0 & -1 & -1 \\
-1 & -1 & 0 \\
-1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 0 & -1 \\
-1 & 2 & 1
\end{bmatrix}
它将产生一个转置矩阵,其中的列代替了行,反之亦然......
这将特别节省时间!
答案1
这是一个实现expl3
:
\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{environ}
\ExplSyntaxOn
\NewEnviron{bmatrixT}
{
\marine_transpose:V \BODY
}
\int_new:N \l_marine_transpose_row_int
\int_new:N \l_marine_transpose_col_int
\seq_new:N \l_marine_transpose_rows_seq
\seq_new:N \l_marine_transpose_arow_seq
\prop_new:N \l_marine_transpose_matrix_prop
\tl_new:N \l_marine_transpose_last_tl
\tl_new:N \l_marine_transpose_body_tl
\cs_new_protected:Nn \marine_transpose:n
{
\seq_set_split:Nnn \l_marine_transpose_rows_seq { \\ } { #1 }
\int_zero:N \l_marine_transpose_row_int
\prop_clear:N \l_marine_transpose_matrix_prop
\seq_map_inline:Nn \l_marine_transpose_rows_seq
{
\int_incr:N \l_marine_transpose_row_int
\int_zero:N \l_marine_transpose_col_int
\seq_set_split:Nnn \l_marine_transpose_arow_seq { & } { ##1 }
\seq_map_inline:Nn \l_marine_transpose_arow_seq
{
\int_incr:N \l_marine_transpose_col_int
\prop_put:Nxn \l_marine_transpose_matrix_prop
{
\int_to_arabic:n { \l_marine_transpose_row_int }
,
\int_to_arabic:n { \l_marine_transpose_col_int }
}
{ ####1 }
}
}
\tl_clear:N \l_marine_transpose_body_tl
\int_step_inline:nnnn { 1 } { 1 } { \l_marine_transpose_col_int }
{
\int_step_inline:nnnn { 1 } { 1 } { \l_marine_transpose_row_int }
{
\tl_put_right:Nx \l_marine_transpose_body_tl
{
\prop_item:Nn \l_marine_transpose_matrix_prop { ####1,##1 }
\int_compare:nF { ####1 = \l_marine_transpose_row_int } { & }
}
}
\tl_put_right:Nn \l_marine_transpose_body_tl { \\ }
}
\begin{bmatrix}
\l_marine_transpose_body_tl
\end{bmatrix}
}
\cs_generate_variant:Nn \marine_transpose:n { V }
\cs_generate_variant:Nn \prop_put:Nnn { Nx }
\ExplSyntaxOff
\begin{document}
\[
\begin{bmatrix}
0 & -1 & -1 \\
-1 & -1 & 0 \\
-1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 0 & -1 \\
-1 & 2 & 1
\end{bmatrix}^T
=
\begin{bmatrixT}
0 & -1 & -1 \\
-1 & -1 & 0 \\
-1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 0 & -1 \\
-1 & 2 & 1
\end{bmatrixT}
\]
\end{document}
答案2
如果你将数学和 LaTeX 混合使用,那么你应该熟悉该sagetex
软件包。CTAN 链接是这里。这为您在使用 LaTeX 时提供了计算机代数系统的强大功能。
\documentclass{article}
\usepackage{amsmath,amsfonts,amssymb}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
latex.matrix_delimiters(left='[', right=']')
A = Matrix([[0,-1,-1],[-1,-1,0],[-1,0,1],[1,0,0],[0,0,-1],[-1,2,1]])
\end{sagesilent}
If $A = \sage{A}$ and $A^{\intercal} = \sage{A.transpose()}$ then
$A \cdot A^{\intercal} = \sage{A*A.transpose()}$ and
$A^{\intercal}\cdot A = \sage{A.transpose()*A}$
\end{document}
数学定义和计算通常在sagesilent
模式下进行。当您需要计算时,请使用 \sage{} 来获取它。
如您所见,根据您输入的矩阵 A,Sage 负责确定转置和矩阵乘法,从而最大限度地减少错误。LaTex 和 Sage 都有文档记录这里。可以找到一些有关矩阵的 Sage 文档这里和这里。
唯一的缺点是你需要访问 Sage。你可以下载并安装在你的电脑上,但让它工作并不总是那么简单。但如果你不介意在云端工作,那么你可以获得一个免费的 Sagemath Cloud 帐户这里。这真的很简单,您只需几分钟就可以启动并运行。
答案3
更新:更好的注释代码,带有\Mar@
前缀的更安全的内部宏名称,添加表格,“宏”和“文件”示例。
这是一个基于可扩展宏的方法\Transpose
。可以在pmatrix
、、bmatrix
... 或tabular
类似环境中使用它。
该宏的用途是,\Transpose {rows separated by \\}
每行都用分隔符书写&
,最后一行应该有不 \\
。
扩展\Transpose
分为两个步骤。有些项目可以移除括号,我并没有深入讨论细节,无论如何,表格单元格具有局部范围。
但我认为使用文本编辑器宏会更好;对于 e-Lisp 知识渊博的人来说,在 Emacs 缓冲区中肯定可以做到这一点。事实上,我猜典型的用例是使用大型表格材料,需要在转置后进一步编辑,然后重新插入 TeX 源。
作为学习 e-Lisp 的替代方法,人们可以使用\Transpose
它在草稿运行中将其输出写入某个辅助文件,以便用户可以恢复转置的数据。这也在下一个代码示例中进行了说明。
\documentclass{article}
\usepackage{amsmath}
\usepackage{array}
\makeatletter
\catcode`! 3
\catcode0 12
% The update chooses safer macro names.
% It could be useful to allow #1 to be itself a macro expanding
% to some rows. One could replace \Mar@DoOneRow by
% \expandafter\Mar@DoOneRow but then general usage must be aware
% of this one-expansion of contents.
% Usage: \Transpose { &-separated cells \\ &-separated cells \\ ...
% ...\\&-separated cells and *no* final \\ }
% Can be used inside amsmath matrices as well as inside LaTeX tabular's
%
\def\Transpose #1{\romannumeral0\expandafter
\Mar@Transpose@a\romannumeral`^^@\Mar@DoOneRow #1\\!\\}
\def\Mar@DoOneRow #1\\{\Mar@DoOneRow@a {}#1&^^@&}%
\def\Mar@DoOneRow@a #1#2&{%
\if^^@\detokenize{#2}\expandafter\@gobble\fi
\Mar@DoOneRow@a {#1#2\\}%
}%
% unbraced #1 here will end in \\^^@\\
\def\Mar@Transpose@a #1#2\\{\ifx!#2\expandafter\Mar@FinishTranspose\fi
\expandafter\Mar@Transpose@b\romannumeral`^^@\Mar@DoOneRow@a {}#2&^^@}
% unbraced #1 here will end with \\^^@\\
% It represents a new transposed row with an extra ^^@ cell.
% The #2 here ends in \\. It holds the first already transposed rows.
\def\Mar@Transpose@b #1#2^^@\\{\Mar@Join {}#2^^@!#1}
% when #3=^^@ happens after #4\\ there is still ^^@\\
% update slightly simplifies \Mar@Join.
\def\Mar@Join #1#2\\#3!#4\\%
{\if^^@\detokenize{#3}\expandafter\Mar@EndJoin\fi
\Mar@Join {#1#2\\}#3!}%
% unbraced #1 ends with \\
\def\Mar@EndJoin\Mar@Join #1^^@!^^@\\{\Mar@Transpose@a {#1^^@\\}}
\def\Mar@FinishTranspose
#1&^^@\\^^@\\{ #2}% the \\^^@\\ pattern helps removing a final \\
\catcode`! 12
\catcode0 15 % null character "invalid": this is default LaTeX setting.
\makeatother
\begin{document}
A bmatrix example:
\[
\begin{bmatrix}
0 & -1 & -1 \\
-1 & -1 & 0 \\
-1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 0 & -1 \\
-1 & 2 & 1
\end{bmatrix}\longrightarrow
\begin{bmatrix}
\Transpose {
0 & -1 & -1 \\
-1 & -1 & 0 \\
-1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 0 & -1 \\
-1 & 2 & 1 }
\end{bmatrix}
\]
% works the same.
% \[
% \begin{pmatrix}
% \Transpose {
% 0 & -1 & -1 \\
% -1 & -1 & 0 \\
% -1 & 0 & 1 \\
% 1 & 0 & 0 \\
% 0 & 0 & -1 \\
% -1 & 2 & 1 }
% \end{pmatrix}
% \]
A tabular example:
\begin{center}
\begin{tabular}{c|>{\bfseries}c|>{\itshape}c}
L1 & L2 & L3 \\
M1 & M2 & M3 \\
N1 & N2 & N3
\end{tabular}
${}\longrightarrow{}$
\begin{tabular}{c|>{\bfseries}c|>{\itshape}c}
\Transpose{
L1 & L2 & L3 \\
M1 & M2 & M3 \\
N1 & N2 & N3
}% <- this to avoid a spurious space which tabular does not remove
\end{tabular}
\end{center}
A macro-level example to illustrate that two expansion steps are enough and
that contents are not prematurely expanded:
% spaces from endlines and around tabs
% which disappear in tabular/matrix treatments
% are not trimmed by \Transpose itself
\def\www {
\Arbitrary L1 & \Stuff L2 & \Here L3 \\
M1 & M2 & M3 \\
N1 & N2 & N3
}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\zzz
\expandafter\expandafter\expandafter{\Transpose {
\Arbitrary L1 & \Stuff L2 & \Here L3 \\
M1 & M2 & M3 \\
N1 & N2 & N3
}}
\ttfamily
\meaning\www
becomes
\meaning\zzz
% And finally a "write to file" example
\newwrite\testout
\immediate\openout\testout=\jobname-tranpose.out
\immediate\write\testout{\unexpanded\expandafter\expandafter\expandafter
{\Transpose {
\Arbitrary L1 & \Stuff L2 & \Here L3 \\
M1 & M2 & M3 \\
N1 & N2 & N3
}}}
\end{document}
“filename-transpose.out”文件包含:
\Arbitrary L1 & M1 & N1 \\ \Stuff L2 & M2 & N2 \\ \Here L3 & M3 & N3
答案4
不是一个真正的 TeX 答案,但对某些人可能仍然有用。使用 Emacs,您可以从 LaTeX/AUCTeX 切换到 Calc 模式,执行矩阵运算并返回。
假设我们有一个要转置的 bmatrix
\[
\begin{bmatrix}
0 & -1 & -1 \\
-1 & -1 & 0 \\
-1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 0 & -1 \\
-1 & 2 & 1
\end{bmatrix}
\]
将光标放在环境内并按C-x * e
进入 Calc 嵌入模式
\[
\begin{pmatrix} 0 & -1 &
-1 \\ -1 & -1 & 0 \\ -1 & 0 & 1 \\ 1 & 0 & 0 \\ 0 & 0 & -1 \\ -1 & 2 & 1 \end{pmatrix}
\]
Calc 理解 LaTeX 语法,但搞乱了对齐,变成bmatrix
了pmatrix
。我们稍后再讨论这个问题。
按下d N
可切换到正常的 Calc 显示模式,您可能会发现这种模式更适合工作
% [calc-mode: language: nil]
\[
[ [ 0, -1, -1 ]
[ -1, -1, 0 ]
[ -1, 0, 1 ]
[ 1, 0, 0 ]
[ 0, 0, -1 ]
[ -1, 2, 1 ] ]
\]
v t
转置
% [calc-mode: language: nil]
\[
[ [ 0, -1, -1, 1, 0, -1 ]
[ -1, -1, 0, 0, 0, 2 ]
[ -1, 0, 1, 0, -1, 1 ] ]
\]
C-2
d L
让我们回到 LaTeX 语法,C-2
是一个可选的前缀,将其格式化为具有正确对齐的二维矩阵
% [calc-mode: language: (latex 2)]
\[
\begin{pmatrix}
0 & -1 & -1 & 1 & 0 & -1 \\
-1 & -1 & 0 & 0 & 0 & 2 \\
-1 & 0 & 1 & 0 & -1 & 1
\end{pmatrix}
\]
C-x * e
禁用 Calc 嵌入模式并让我们恢复正常编辑。现在唯一的问题是我们有一个pmatrix
而不是原始的bmatrix
。不幸的是,这是预料之中的,并记录在 Calc 文档中……但修复它很简单!如果您使用 AucTeX,只需按下C-u C-c C-e
矩阵内部并输入bmatrix
。