动态生成矩阵中的值并使用它们进行计算

动态生成矩阵中的值并使用它们进行计算

我正在使用以下代码生成一个填充随机值的矩阵。我想用这个矩阵来解释如何将卷积应用于图像(特别是平均值),所以我试图用它填充输出矩阵。我无法重复使用列表中的值来用于 pgfmath 计算,这是此方法不起作用的主要原因。任何帮助都非常感谢!

谢谢大家。

% tikzpic.tex
\documentclass[crop,tikz]{standalone}% 'crop' is the default for v1.0, before it was 'preview'
\usetikzlibrary{calc,matrix,positioning,backgrounds,fit}
\usepackage{listofitems}
\setsepchar{;/,}
\begin{document}
\begin{tikzpicture}[
            DA/.style={
                    fill,
                    opacity=0.2,
                    %rounded corners,
                    inner sep=-1pt,
                    line width=1pt,
                },
        ]

        \readlist\image{%
            \pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
            \pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
            \pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
            \pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
            \pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
            \pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
            \pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
        }
        
        \matrix [matrix of math nodes,left delimiter={[},right delimiter={]}] (im) {
                \image[1,1]  &\image[1,2] &\image[1,3] &\image[1,4] &\image[1,5] &\image[1,6] &\image[1,7]\\
                \image[2,1]  &\image[2,2] &\image[2,3] &\image[2,4] &\image[2,5] &\image[2,6] &\image[2,7]\\
                \image[3,1]  &\image[3,2] &\image[3,3] &\image[3,4] &\image[3,5] &\image[3,6] &\image[3,7]\\
                \image[4,1]  &\image[4,2] &\image[4,3] &\image[4,4] &\image[4,5] &\image[4,6] &\image[4,7]\\
                \image[5,1]  &\image[5,2] &\image[5,3] &\image[5,4] &\image[5,5] &\image[5,6] &\image[5,7]\\
                \image[6,1]  &\image[6,2] &\image[6,3] &\image[6,4] &\image[6,5] &\image[6,6] &\image[6,7]\\
                \image[7,1]  &\image[7,2] &\image[7,3] &\image[7,4] &\image[7,5] &\image[7,6] &\image[7,7]\\
            };


        \node[right=.2em of im] (str) {\(\ast\)};

        \matrix (k) [matrix of math nodes,left delimiter={[},right delimiter={]}, right=.2em of str] {
                \frac{1}{9}&\frac{1}{9}&\frac{1}{9} \\
                \frac{1}{9}&\frac{1}{9}&\frac{1}{9} \\
                \frac{1}{9}&\frac{1}{9}&\frac{1}{9} \\
            };
        \node[right=.2em of k] (eq) {\(=\)};

        \matrix (imp) [matrix of math nodes,left delimiter={[},right delimiter={]}, right=.2em of eq] {
                1 & 4 & 3 & 4 & 1\\
                1 & 2 & 4 & 3 & 3\\
                1 & 2 & 3 & 4 & 1\\
                1 & 3 & 3 & 1 & 1\\
                3 & 3 & 1 & 1 & 0\\
            };
        \node[below=0.2em of im] (imlabel) {\(i_{mn}\)};

        \node (klabel) at (k|-imlabel) {\(k_{pq}\)};

        \node (conv) at (str|-imlabel) {\(\ast\)};
        \node (eqlabel) at (eq|-imlabel) {\(=\)};
        \node (implabel) at (imp|-imlabel) {\({im'}_{mn}\)};

        \begin{scope}[on background layer]
            \node[DA,blue,fit=(im-1-4)(im-3-6)](im_sub){};
            \node[DA,purple,fit=(imp-1-4)(imp-1-4)](imp_sub){};
            \node[DA,red,fit=(k-1-1)(k-3-3)](k_sub){};
        \end{scope}

        \draw[dashed, teal] (im_sub.north east) -- (k_sub.north west);
        \draw[dashed, teal] (im_sub.south east) -- (k_sub.south west);

        \draw[dashed, blue!80!black] (k_sub.north east) -- (imp_sub.north west);
        \draw[dashed, blue!80!black] (k_sub.south east) -- (imp_sub.south west);
    \end{tikzpicture}
\end{document}

随机填充的矩阵,带有内核和(错误地)填充的输出

答案1

这是一个使用 PGFMath 数组的 PGFmath 和\fpeval解决方案(仅用于将九个数字相加并除以 9)。

但是,由于我让 PGFmath 评估了该数组一次(因为我们想要固定数字),因此它不再以逗号分隔列表(逗号分隔列表)的形式存储,而是以其内部格式(使用括号对项目进行分组)存储。\pgfmatharray@不幸的是,要再次访问它,我们需要使用。

这是通过\pgfmathtwoarray以下方式完成的:不是可扩展但返回结果\pgfmathresult。这可用于打印或在内部使用\fpeval


我已经调整了矩阵的一些设置,以便分隔符能够更漂亮地放置在矩阵周围。

anchor=base east可以通过使用矩阵内的节点并用填充小数位0(通过 PGFmath 或siunitx或...)来实现数字的水平对齐。


为了更容易访问这 49 个值,我只需将它们存储在宏/值键中,就可以直接通过它们的索引访问它们,但这是一种完全不同的方法。

虽然\fpeval支持元组,但我在手册中没有看到有关访问其值的任何信息。这可能需要l3fparray/l3intarray来提供对其数组值的可扩展访问。

代码

\documentclass[tikz]{standalone}
% \usepackage{xfp}% possibly necessary for older distributions
\usetikzlibrary{calc,matrix,positioning,backgrounds,fit}
\makeatletter
\newcommand*\repeatMe[2]{%
  \ifnum#1=0 \expandafter\@gobble\else\expandafter\@firstofone\fi
    {#2\expandafter\repeatMe\expandafter{\the\numexpr#1-1\relax}{#2}}}
\newcommand*\pgfmathtwoarray[3]{
  \pgfmatharray@{#1}{\pgfinteval{#2-1}}%
  \pgfmatharray@{\pgfmathresult}{\pgfinteval{#3-1}}}
\newcommand*\tikzbuildmatrix[3]{%
  \repeatMe{#1}{%
    \repeatMe{#2}{%
      \node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]{#3};
      \unless\ifnum\pgfmatrixcurrentcolumn=#1 \expandafter\pgfmatrixnextcell\fi}
   \unless\ifnum\pgfmatrixcurrentrow=#2 \expandafter\pgfmatrixendrow\fi}
\pgfmatrixendrow}
\makeatother
\begin{document}
\begin{tikzpicture}[
    DA/.style={
        fill,
        opacity=0.2,
        %rounded corners,
        inner sep=-1pt,
        line width=1pt,
    },
    every left delimiter/.append style={xshift=.3333em},
    every right delimiter/.append style={xshift=-.3333em},
    every outer matrix/.append style={inner sep=+0pt},
]

\pgfmathsetmacro\image{{% this % is important here
    {random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
    {random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
    {random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
    {random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
    {random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
    {random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
    {random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)}}}
\matrix [left delimiter={[},right delimiter={]},nodes={anchor=base}] (im) {
  \tikzbuildmatrix{7}{7}
    {\pgfmathtwoarray{\image}{\pgfmatrixcurrentrow}{\pgfmatrixcurrentcolumn}\pgfmathresult}
};

\node[right=.2em of im] (str) {\(\ast\)};

\matrix (k) [left delimiter={[},right delimiter={]}, right=.2em of str] {
  \tikzbuildmatrix{3}{3}{$\frac{1}{9}$}};
\node[right=.2em of k] (eq) {\(=\)};

\matrix (imp) [matrix of math nodes,left delimiter={[},right delimiter={]}, right=.2em of eq,
  row 1 column 4/.style={nodes={fill=purple!20, alias=imp_sub}}] {
    \tikzbuildmatrix{5}{5}{
      \gdef\solution{0}%
      \foreach[expand list] \ROW in {\pgfmatrixcurrentrow,...,\inteval{\pgfmatrixcurrentrow+2}}{
        \foreach[expand list] \COL in {\pgfmatrixcurrentcolumn,...,\inteval{\pgfmatrixcurrentcolumn+2}}{
          \pgfmathtwoarray{\image}{\ROW}{\COL}%
          \xdef\solution{\fpeval{\solution+\pgfmathresult}}
        }
      }
      \fpeval{round(\solution/9,2)}
  }};
\node[below=0.2em of im] (imlabel) {\(i_{mn}\)};

\node (klabel) at (k|-imlabel) {\(k_{pq}\)};

\node (conv) at (str|-imlabel) {\(\ast\)};
\node (eqlabel) at (eq|-imlabel) {\(=\)};
\node (implabel) at (imp|-imlabel) {\({im'}_{mn}\)};

\begin{scope}[on background layer]
    \node[DA,blue,fit=(im-1-4)(im-1-5)(im-1-6)(im-1-6)(im-2-6)(im-3-6)](im_sub){};
    \node[DA,red,fit=(k-1-1)(k-3-3)](k_sub){};
\end{scope}

\draw[dashed, teal] (im_sub.north east) -- (k_sub.north west);
\draw[dashed, teal] (im_sub.south east) -- (k_sub.south west);

\draw[dashed, blue!80!black] (k_sub.north east) -- (imp_sub.north west);
\draw[dashed, blue!80!black] (k_sub.south east) -- (imp_sub.south west);
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容