通常,张量被定义为具有N
上标和M
下标的对象。每个上标和下标可以取一系列值1,2,...,n
。例如,一个张量M^[ij]_[klm]
可以具有i=1,2,3
、j=1,2,3
和k=1,2
、l=1,2
和m=1,2,3
。我可以使用以下代码表示这样的张量:
\documentclass[11pt,a4paper]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}
\begin{document}
\[
\begin{matrix} % all blocks
\begin{matrix} % empty block at top left
& & & \\
& & &
\end{matrix} % empty block at top left
&
\begin{matrix} % matrix of superscripts
\quad 1\quad & \quad 1\quad & \quad 1\quad & \quad 2\quad & \quad 2\quad & \quad 2 \quad & \quad 3\quad & \quad 3\quad & \quad 3\quad \\
\quad 1\quad & \quad 2\quad & \quad 3\quad & \quad 1\quad & \quad 2\quad & \quad 3\quad & \quad 1\quad & \quad 2\quad & \quad 3\quad
\end{matrix} % matrix of superscripts
\\ %end of top group of block matrices
\begin{matrix} % matrix of subscripts
1 & 1 & 1 \\
1 & 1 & 2 \\
1 & 1 & 3 \\
1 & 2 & 1 \\
1 & 2 & 2 \\
1 & 2 & 3 \\
2 & 1 & 1 \\
2 & 1 & 2 \\
2 & 1 & 3 \\
2 & 2 & 1 \\
2 & 2 & 2 \\
2 & 2 & 3
\end{matrix} % matrix of subscripts
&
\begin{bmatrix} % tensor
\begin{bmatrix}
\begin{bmatrix}
M^{11}_{111} & M^{12}_{111} & M^{13}_{111} \\
M^{11}_{112} & M^{12}_{112} & M^{13}_{112} \\
M^{11}_{113} & M^{12}_{113} & M^{13}_{113}
\end{bmatrix}
&
\begin{bmatrix}
M^{21}_{111} & M^{22}_{111} & M^{23}_{111} \\
M^{21}_{112} & M^{22}_{112} & M^{23}_{112} \\
M^{21}_{113} & M^{22}_{113} & M^{23}_{113}
\end{bmatrix}
&
\begin{bmatrix}
M^{31}_{111} & M^{32}_{111} & M^{33}_{111} \\
M^{31}_{112} & M^{32}_{112} & M^{33}_{112} \\
M^{31}_{113} & M^{32}_{113} & M^{33}_{113}
\end{bmatrix}
\\
\begin{bmatrix}
M^{11}_{121} & M^{12}_{121} & M^{13}_{121} \\
M^{11}_{122} & M^{12}_{122} & M^{13}_{122} \\
M^{11}_{123} & M^{12}_{123} & M^{13}_{123}
\end{bmatrix}
&
\begin{bmatrix}
M^{21}_{121} & M^{22}_{121} & M^{23}_{121} \\
M^{21}_{122} & M^{22}_{122} & M^{23}_{122} \\
M^{21}_{123} & M^{22}_{123} & M^{23}_{123}
\end{bmatrix}
&
\begin{bmatrix}
M^{31}_{121} & M^{32}_{121} & M^{33}_{121} \\
M^{31}_{122} & M^{32}_{122} & M^{33}_{122} \\
M^{31}_{123} & M^{32}_{123} & M^{33}_{123}
\end{bmatrix}
\end{bmatrix}
\\
\begin{bmatrix}
\begin{bmatrix}
M^{11}_{211} & M^{12}_{211} & M^{13}_{211} \\
M^{11}_{212} & M^{12}_{212} & M^{13}_{212} \\
M^{11}_{213} & M^{12}_{213} & M^{13}_{213}
\end{bmatrix}
&
\begin{bmatrix}
M^{21}_{211} & M^{22}_{211} & M^{23}_{211} \\
M^{21}_{212} & M^{22}_{212} & M^{23}_{212} \\
M^{21}_{213} & M^{22}_{213} & M^{23}_{213}
\end{bmatrix}
&
\begin{bmatrix}
M^{31}_{211} & M^{32}_{211} & M^{33}_{211} \\
M^{31}_{212} & M^{32}_{212} & M^{33}_{212} \\
M^{31}_{213} & M^{32}_{213} & M^{33}_{213}
\end{bmatrix}
\\
\begin{bmatrix}
M^{11}_{221} & M^{12}_{221} & M^{13}_{221} \\
M^{11}_{222} & M^{12}_{222} & M^{13}_{222} \\
M^{11}_{223} & M^{12}_{223} & M^{13}_{223}
\end{bmatrix}
&
\begin{bmatrix}
M^{21}_{221} & M^{22}_{221} & M^{23}_{221} \\
M^{21}_{222} & M^{22}_{222} & M^{23}_{222} \\
M^{21}_{223} & M^{22}_{223} & M^{23}_{223}
\end{bmatrix}
&
\begin{bmatrix}
M^{31}_{221} & M^{32}_{221} & M^{33}_{221} \\
M^{31}_{222} & M^{32}_{222} & M^{33}_{222} \\
M^{31}_{223} & M^{32}_{223} & M^{33}_{223}
\end{bmatrix}
\end{bmatrix}
\end{bmatrix} % tensor
\end{matrix} % all blocks
\]
\end{document}
其结果如下:
这个对象的二维结构是一系列嵌套矩阵。本例中的基本块是 3x3 矩阵。使用这个基本块,我们可以构建一个由 3x3 矩阵组成的 2x3 矩阵。最后一步是构建一个由 3x3 矩阵组成的 2x3 矩阵的 2x1 矩阵。因此,通常使用分块矩阵作为构建块来构建张量是一个递归过程。首先从一个sup[]={3,3}
长度等于上标数量的数组开始,每个条目是每个上标的范围,还有一个类似的下标数组。然后从和sub[]={2,2,3}
开始构建对,这定义了基本构建块。下一级使用和等等;如果那么某些对必须是或,具体取决于哪个索引已经用完。sup[sup.length]
sub[sub.length]
sup[sup.length-1]
sub[sub.length-1]
sup.length \neq sub.length
(1,sup[i])
(sub[j],1)
问题是:“怎样才能实现自动化呢?”我找不到任何可以处理此类任务的tikz
东西asymptote
。理想情况下,应该能够编写类似以下内容的内容:
\begin{equation}
\tmatrix{M}{^3^3_2_2_3}
\end{equation}
而不是上面显示的手动密集型代码。我意识到这是一个大项目,所以我正在寻找指导而不是解决方案。也许最好的方法是编写一个全新的包...
答案1
递归的多维方面看起来令人望而生畏。
这是一个非递归版本,它构建了一个具有 2×2×3 行和 3×3 列的 TikZ 矩阵。首先计算这些乘积(→ mul list
)并将其存储在\ROWSprod
和中\COLSprod
。密钥还计算条目数(此处为 3 和 2),但它们未被使用。
关键tmatrix'
是计算上标和下标。我曾尝试使用 PGFmath 来计算,但出了点问题,所以我使用了基于计数的计算\pgfint…
。
在构建矩阵并知道其边界框之后,左侧和上方的标签可能放置得更好,但是原始标签已经使其变得非常简单。
不幸的是,我找不到一种数学方法来评估应该使用哪些分隔符 - 对于我的大脑来说仍然太多了 - 这就是为什么我让用户给出所需的矩阵:
LR delims={l2 6x9 1-1, 7-1}
意味着矩阵应该在第二级获得分隔符(级别仅用作更改分隔符的外观和位置的选项),围绕 6×9 子矩阵块,其右上角位于 1-1 和 7-1。
我意识到这并不像它应该的那样自动化 - 并且它甚至不会成为递归嵌套bmatrix
解决方案的问题 - 但是用键指定所需的分隔符也不需要那么多工作LR delims
。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{matrix,ext.misc}
\newcommand*\tmatrixSTOP{\tmatrixSTOP}
\pgfqkeys{/handlers}{
.add/.code=\pgfkeyssetevalue{\pgfkeyscurrentpath}%
{\the\numexpr\pgfkeysvalueof{\pgfkeyscurrentpath}+#1},
.mul/.code=\pgfkeyssetevalue{\pgfkeyscurrentpath}%
{\the\numexpr\pgfkeysvalueof{\pgfkeyscurrentpath}*#1},
.++/.style={\pgfkeyscurrentpath/.add=1}}
\pgfqkeys{/tmatrix}{
mul list/.style n args={3}{
/tmatrix/tempa/.initial=0, /tmatrix/tempb/.initial=1,
/tmatrix/temp/.style={/tmatrix/tempa/.++,/tmatrix/tempb/.mul={##1}},
/tmatrix/temp/.list={#1}, /tmatrix/tempa/.get=#2, /tmatrix/tempb/.get=#3},
tmatrix'/.style n args={4}{
/return #4/.initial=, /utils/tempa/.initial=1,
/utils/temp/.style={
/return #4 list/.initial={##1},
/utils/temp/.style={/return #4 list/.prefix={####1,}}},
/tmatrix/tmatrix do/.style={
/utils/tempa/.mul={##1},
/return #4/.append/.expanded=%
\pgfinteval{\pgfintmod{\pgfintdivtruncate
{#1}{#3/\pgfkeysvalueof{/utils/tempa}}}{##1}+1},
/utils/temp/.expanded=%
\pgfinteval{\pgfintmod{\pgfintdivtruncate
{#1}{#3/\pgfkeysvalueof{/utils/tempa}}}{##1}+1}},
/tmatrix/tmatrix do/.list={#2}}}
\tikzset{
add label above/.style={@add label above={#1,\tmatrixSTOP}},
add label left/.style={@add label left={#1,\tmatrixSTOP}},
@add label above/.style args={#1,#2}{%
/utils/TeX/ifx={\tmatrixSTOP}{#2}{label={above:#1}}{
label={[@add label above={#2}]above:#1}}},
@add label left/.style args={#1,#2}{%
/utils/TeX/ifx={\tmatrixSTOP}{#2}{label={[xshift=-1em]left:#1}}{
label={[xshift=-1em,@@add label left={#2}]left:#1}}},
@@add label left/.style args={#1,#2}{%
/utils/TeX/ifx={\tmatrixSTOP}{#2}{label={left:#1}}{
label={[@@add label left={#2}]left:#1}}},
add lr delim/.style n args={3}{append after command={
[local bounding box=@] (\tikzlastnode-#1.north west)
(\tikzlastnode-#2.south east)\bgroup (@) [
every left delimiter/.append style={lr #3 left/.try},
every right delimiter/.append style={lr #3 right/.try},
late options={left delimiter={[},right delimiter={]}}]\egroup}},
LR delims/.style args={l#1 #2x#3 #4}{
% #1 = level, #2=width, #3 = height, #4 = top right corners
/utils/temp/.style args={##1-##2}{
add lr delim=
{##1-##2}{\the\numexpr##1+#2-1\relax-\the\numexpr##2+#3-1\relax}{#1}},
/utils/temp/.list={#4}}}
\makeatletter
\let\gappto\pgfutil@g@addto@macro
\newcommand*\repeatMe[2]{%
\ifnum#1=0 \expandafter\@gobble\else\expandafter\@firstofone\fi
{#2\expandafter\repeatMe\expandafter{\the\numexpr#1-1\relax}{#2}}}
\makeatother
\newcommand*\tmatrix[4][]{%
\begin{tikzpicture}[
/tmatrix/mul list={#3}\ROWScnt\ROWSprod,
/tmatrix/mul list={#4}\COLScnt\COLSprod,
M/.style={every matrix/.append style={##1}},#1]
\matrix[
name=M, column sep=\the\arraycolsep,
column 1/.append style={
tmatrix node/.append style={
add label left/.expanded=\pgfkeysvalueof{/return row list}}},
row 1/.append style={
tmatrix node/.append style={
add label above/.expanded=\pgfkeysvalueof{/return col list}}},
every cell/.append style={
/tmatrix/tmatrix'/.expanded=% construct the subscript
{\the\numexpr\pgfmatrixcurrentrow-1\relax}{#3}{\ROWSprod}{row},
/tmatrix/tmatrix'/.expanded=% construct the superscript
{\the\numexpr\pgfmatrixcurrentcolumn-1\relax}{#4}{\COLSprod}{col}}
] {
\repeatMe{\ROWSprod}{
\repeatMe{\COLSprod}{
\node[tmatrix node/.try]
(\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn)
{${#2}_{\pgfkeysvalueof{/return row}}^{\pgfkeysvalueof{/return col}}$};
\unless\ifnum\pgfmatrixcurrentcolumn=\COLSprod\relax % no & after last col
\expandafter\pgfmatrixnextcell\fi}
\unless\ifnum\pgfmatrixcurrentrow=\ROWSprod\relax % no \\ after last row
\expandafter\pgfmatrixendrow\fi
}\pgfmatrixendrow};
\end{tikzpicture}}
\tikzset{
lr delim shift/.style 2 args={
lr #1 left/.append style={xshift={#2}},
lr #1 right/.append style={xshift={-(#2)}}}}
\begin{document}
\tmatrix[
% these two need to be set outside of the matrix
lr delim shift={3}{.35em},
lr delim shift={1}{-.35em},
M={% this gets forwarded to the matrix
LR delims={l1 12x9 1-1},
LR delims={l2 6x9 1-1, 7-1},
LR delims={l3 3x3 1-1, 1-4, 1-7,
4-1, 4-4, 4-7,
7-1, 7-4, 7-7,
10-1, 10-4, 10-7}}%
]{M}{2,2,3}{3,3}
\end{document}