自动生成矩阵上三角

自动生成矩阵上三角

我想自动创建这样的结构: 在此处输入图片描述

上面的图片是通过以下方式生成的NiceTabular

\begin{NiceTabular}{cccc}[hvlines,corners=SW]
\NotEmpty &  &  &   \\
& \NotEmpty   &  &  \\
&   & \NotEmpty   &  \\
&   &   & \NotEmpty   \\
&   &   &   \\
\end{NiceTabular}

我希望有一个命令可以自动生成遵循模式的内容,而不是逐个写入单元格。例如,使用如下块:

\begin{uppertriangle}{4}
\end{uppertriangle}

这样它就会生成上面的图。数字{4}将是第一行的长度,并且每个后续行的长度必须以 1 为单位递减。我还希望能够像我所做的那样写入内容并操作生成的数组的内容NiceTabular(顺便说一句,请注意,第一个单元格的大小不正确;这不是我):

在此处输入图片描述

由此生成:

\begin{NiceTabular}{cccc}[hvlines,corners=SW]
\CodeBefore
\cellcolor[HTML]{FFFF88}{1-2,1-3,2-3,2-4,4-4}
\Body
\NotEmpty & 1 & 1 &   \\
& \NotEmpty   & 1 & 1 \\
&   & \NotEmpty   & 1 \\
&   &   & \NotEmpty   \\
&   &   &   \\
\end{NiceTabular}

答案1

这是一个 TikZ 解决方案,它创建了一个tikzpicture,但不是一个矩阵。

在此处输入图片描述

命令是\uppertriangle[<contents>]{<rows>}

<rows>是必需的,并且应为正整数(行数)。<contents>是一个可选的逗号分隔列表,其条目具有以下格式

<row>-<column>/<entry>/<fill color>

例如,中间的图形是使用命令创建的

\uppertriangle[1-3/A/yellow,3-2/B/red,2-1/C/none]{4}

请注意,列是从右到左编入索引的。单元格大小由 全局控制\cellsize(当前设置为.75cm)。

\documentclass{article}

\usepackage{tikz}
\tikzset{cell/.style={draw, minimum size=\cellsize, fill=#1},
    cell/.default={none}}

\newcommand{\cellsize}{.75cm}
\newcommand{\uppertriangle}[2][]{\tikz[]{
\foreach \n[count=\j] in {#2,...,1}
    \foreach \m[count=\k] in {1,...,\n}
    {\node[cell](A\k-\j) at (\cellsize*\n,-\cellsize*\m){};}
\foreach \c/\d/\s in {#1}{\node[cell=\s]at(A\c){\d};}
}}

\begin{document}

\uppertriangle{4}\qquad
\uppertriangle[1-3/A/yellow,3-2/B/red,2-1/C/none]{4}\qquad
\uppertriangle[1-2/1/yellow,2-4/1/orange,3-1/1/cyan]{5}

\end{document}

答案2

这些结构通常称为年轻画面您可以使用ytableauyoungtab包来绘制它们。

\documentclass{article}
\usepackage{ytableau}

\colorlet{yty}{yellow!60} % Young Tableau Yellow

\begin{document}

\[
\ydiagram{4,1+3,2+2,3+1}
\]

\[
\begin{ytableau}
{} & *(yty) 1 & *(yty) 1 & {} \\
\none & & *(yty) 1 & *(yty) 1 \\
\none & \none & {} & 1 \\
\none & \none & \none & *(yty) {}
\end{ytableau}
\]


\end{document}

在第一种情况下,我们在第一行指定四个单元格,在第二行指定三个单元格,偏移量为一,依此类推。第二个表有明确的条目;但未\none绘制框架。

在此处输入图片描述

答案3

我用单个参数实现了宏\utriangle,它给出了第一行的单元格数量。

\utrinagle 4

打印问题中所示的三角形。\utrianhle 7打印更大的三角形等。

在使用 之前\utriangle,可以使用\utriangledecl\utrianglecolors来声明单元格的内容。问题中显示的示例可以通过以下方式打印:

\utriangledecl {
  . 1 1 .
    . 1 1
      . 1
        .  
}
\colorlet{y}{yellow!60}
\utrianglecolors {
   . y y .
     . y y
       . .
         y
}
\utriangle 4

\utrianglecell和使用的单元格参数以\utrianglecolors空格分隔。点表示空参数。您可以将它们排列成三角形以保持可读性。例如:

\utriangledecl {
   .  x_1     x_2     .
      x_{12}  x_{13}  .
              .       .
                      x_7
}
\utriangle 4

请注意,参数是以数学模式打印的。

结果的大小取决于\cellw表示单个单元格宽度和高度的寄存器。默认值为\cellw=17pt

该实现不依赖于 LaTeX 宏,但它也可以在 LaTeX 中使用。颜色宏只有一个例外,它们依赖于使用的格式。

\documentclass{article}
\usepackage{xcolor}

\newcount\cellnum \newcount\tmpnum
\newdimen\cellw \cellw=17pt

\def\utriangle#1 {%
   \vbox{\chardef\uwidth=#1 \offinterlineskip
      \tmpnum=#1 \cellnum=0
      \hrule
      \printrow
   }
}
\def\printrow{\hbox to\the\uwidth\cellw{\hss \printcell}
   \advance\tmpnum by-1
   \ifnum\tmpnum>0 \expandafter \printrow \fi
}
\def\printcell{\global\advance\cellnum by1 \singlecell
   \advance\tmpnum by-1
   \ifnum\tmpnum>0 \expandafter \printcell \else \vrule \fi
}
\def\singlecell{\vbox{\hbox to\cellw{%
   \ifcsname cellcolor:\the\cellnum \endcsname
      \rlap{\color{\csname cellcolor:\the\cellnum\endcsname}% <-- format dependent part
            \vrule height.7\cellw depth.3\cellw width\cellw}%
   \fi
   \vrule height.7\cellw depth.3\cellw 
   \hss $\csname cell:\the\cellnum\endcsname$\hss}\kern-.4pt\hrule}%
   \global \expandafter\let \csname cell:\the\cellnum\endcsname \undefined
   \global \expandafter\let \csname cellcolor:\the\cellnum\endcsname \undefined
}

\def\utriangledecl #1{\cellnum=0 \def\prefix{cell}\declcell #1 {\end} }
\def\utrianglecolors #1{\cellnum=0 \def\prefix{cellcolor}\declcell #1 {\end} }
\def\declcell#1 {%
   \advance\cellnum by1
   \ifx\end#1\relax \else
      \ifx &#1&\advance\cellnum by-1 \else
         \ifx .#1\relax \else 
         \expandafter\def\csname\prefix:\the\cellnum\endcsname{#1}\fi\fi
      \expandafter\declcell 
   \fi
}

\begin{document}

%%% tests:
\utriangledecl {
  . 1 2 .
    . 1 1
      . 1
        .  
}
\colorlet{y}{yellow!60}
\utrianglecolors {
   . y y .
     . y y
       . .
         y
}
\utriangle 4

\utriangle 14

\utriangledecl {
   .  x_1    x_2   .
      x_{12} x_{13}  .
             .     .
                   x_7
}
\utriangle 4

\end{document}

答案4

此解决方案允许您使用其强制参数指定列数和行数。

环境为uppertrianglelowertriangle。它们的可选参数将被转发到内部\matrix

宏实际上将以一种无需在行首或行末添加空单元格的方式进行修补。空单元格将自动插入两端\\\pgfmatrixendrow

矩阵的设置方式为execute at empty cellexecute at begin cell并且execute at end cell只有实际单元格中可能存在空节点。这些使用宏,matrix of nodes因此您应该能够|[<options]|像往常一样在节点中使用。

但不要使用matrix of math nodes,因为这将与 发生冲突triangle matrix/triangle setup。只需使用

math nodes/.style={
  nodes={
    execute at begin node=$,%
    execute at end node=$%
  }
}

我的ext.node-families图书馆有助于使同一列中的所有节点具有相同的宽度。更简单的方法如果你事先知道单元格内容的话。(当然,我们也可以不画任何节点,然后循环遍历它们,然后找出在哪里画线。)

该样式matrix like tabular设置节点的方式与设置tabular或单元格的方式类似。不同之处在于,节点的高度和深度设置为 的尺寸,但如果内容更高或更深,它们不会扩展。array\strut\strut

这在很大程度上取决于矩阵的内容。如果你无法预测,而且它可能更复杂,你可能需要设置系列node family/text heightnode family/text depth(就像我在这个答案的先前版本中所做的那样)。


设置cell color = {<list of cells>}{<color>}其第一个参数中的所有单元格以用作<color>填充。

此密钥是提供的解决方案的专门版本我的另一个答案


请记住,在 PGF/TikZ 矩阵中, 被&激活,并且不是通常的对齐字符。如果您将其用作宏参数的一部分,则需要使用ampersand replacement

抢先看

输出是

\begin{uppertriangle}[cell color={1-2, 1-3, 2-3, 2-4, 4-4}{yellow!60}]{4}
 & 1 & 1     \\
     & 1 & 1 \\
         & 1
\end{uppertriangle}
\begin{lowertriangle}{10}
\end{lowertriangle}

输出

在此处输入图片描述

代码

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix,ext.node-families}
\makeatletter
\def\pgfutil@addto@macro#1#2{%
  \expandafter\def\expandafter#1\expandafter{#1#2}}
\tikzset{
  execute before new row/.style={% \preto
    /utils/tempa/.initial/.expand once=\pgfmatrixendrow,
    /utils/tempa/.prefix={#1}, /utils/tempa/.get=\pgfmatrixendrow},
  execute after new row/.code={% \appto
    \pgfutil@addto@macro\pgf@matrix@no@eom@found{#1}},
  triangle matrix/triangle setup/.style={
    execute before new row={
      \let\tikz@temp\pgfutil@empty \c@pgf@counta=\pgfmatrixcurrentcolumn
      \pgfutil@loop\ifnum\c@pgf@counta<\tikzmatrixrows\relax
        \pgfutil@addto@macro\tikz@temp\pgfmatrixnextcell
      \advance\c@pgf@counta1 \pgfutil@repeat\tikz@temp},
    nodes in empty cells,
    execute at empty cell={%
      \ifnum\pgfmatrixcurrentrow#1\pgfmatrixcurrentcolumn\else
        \expandafter\tikz@lib@matrix@empty@cell\fi},
    execute at begin cell={%
      \ifnum\pgfmatrixcurrentrow#1\pgfmatrixcurrentcolumn\else
        \expandafter\tikz@lib@matrix@start@cell\fi},
    execute at end cell={%
      \ifnum\pgfmatrixcurrentrow#1\pgfmatrixcurrentcolumn\else
        \expandafter\tikz@lib@matrix@end@cell\fi}},
  triangle matrix/upper triangle/.style={
    triangle matrix/triangle setup={>},
    execute after new row={%
      \let\tikz@temp\pgfutil@empty \c@pgf@counta=\pgfmatrixcurrentrow 
        \pgfutil@loop\ifnum\c@pgf@counta>1
          \pgfutil@addto@macro\tikz@temp\pgfmatrixnextcell
          \advance\c@pgf@counta-1 \pgfutil@repeat\tikz@temp}},
  triangle matrix/lower triangle/.style={triangle matrix/triangle setup={<}},
  triangle matrix/remaining rows/.initial={%
    \let\tikz@temp\pgfutil@empty
    \c@pgf@counta=\pgfmatrixcurrentrow\relax
    \pgfutil@loop
      \ifnum\c@pgf@counta<\tikzmatrixrows\relax
      \pgfutil@addto@macro\tikz@temp\pgfmatrixendrow
      \advance\c@pgf@counta1
    \pgfutil@repeat
    \tikz@temp}}
\makeatother
\tikzset{
  matrix like tabular/.style={
    /pgf/inner xsep=+\tabcolsep, /pgf/inner ysep=+0pt,
    /tikz/text height=+.7\baselineskip,% .7 and .3 → basically \strutbox
    /tikz/text depth=+.3\baselineskip},% or font=\strut
  %
  % specialized version of https://tex.stackexchange.com/a/660100
  cell color/.style 2 args={
    /utils/tempa/.style args={##1-##2}{row ##1 column ##2/.append style={nodes={fill=#2}}},
    /utils/tempa/.list={#1}},
  %
  triangle matrix/picture/.style={
    baseline=(current bounding box.center),% triangle matrix-1-1.base
    /utils/exec=\pgfmathtruncatemacro\tikzmatrixrows{#1},
    matrix like tabular},
  triangle matrix/matrix/.style={
    name=triangle matrix, every outer matrix/.append style={/pgf/inner sep=+0pt},
    column sep=+-\pgflinewidth, row sep=+-\pgflinewidth,
    nodes={draw, node family={
        prefix/.append=\tikzmatrixname,
        width=col\the\pgfmatrixcurrentcolumn}}}}

\newenvironment*{uppertriangle}[2][]{%
  \tikzpicture[triangle matrix/picture/.evaluated={int(#2)}, triangle matrix/upper triangle]
  \matrix[triangle matrix/matrix,#1]\bgroup
}{%
  \pgfkeysvalueof{/tikz/triangle matrix/remaining rows}%
  \pgfmatrixendrow\egroup;
  \endtikzpicture}
\newenvironment*{lowertriangle}[2][]{%
  \tikzpicture[triangle matrix/picture/.evaluated={int(#2)}, triangle matrix/lower triangle]
  \matrix[triangle matrix/matrix,#1]\bgroup
}{%
  \pgfkeysvalueof{/tikz/triangle matrix/remaining rows}%
  \pgfmatrixendrow\egroup;
  \endtikzpicture}

\begin{document}
\begin{uppertriangle}[cell color={1-2, 1-3, 2-3, 2-4, 4-4}{yellow!60}]{4}
 & 1 & 1     \\
     & 1 & 1 \\
         & 1
\end{uppertriangle}
\begin{lowertriangle}{10}
\end{lowertriangle}
\end{document}

相关内容