2

I am trying to draw the dynamics of a discrete dynamical system using Tikz. I'd like to use a loop to do so, but for some reason it does not perform the \tkzmath operations inside the loop. Here's the code with a minimal example. The first figure shows what I'd like to get, while the second one what I'd like to get without having to copy paste the same code 3 times.

\documentclass{article}%
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}

\begin{tikzpicture}[scale=1.5, line width=1.5]
    \draw[->, line width=1] (0,0) -- (6,0) node[right] {$L_t$};
    \draw[->, line width=1] (0,0) -- (0,4.2) node[above] {$L_{t+1}$};
    \draw[dashed, line width=1] (0,0) -- (4.2, 4.2)node[right] {$L_{t+1}=L_t$};
    \draw[scale=1,domain=0:5,smooth,variable=\x,blue]  plot ({\x},{1.25*\x^0.5})  node[right] {$L_{t+1}=\phi (L_{t};A)$};

    % Initialize location and do 1 iteration
    \tikzmath{\xt=4.8; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt,0) -- (\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);

    % Iterate 3 times to show path
    % 1
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    % 2
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    % 3
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
\end{tikzpicture}

\begin{tikzpicture}[scale=1.5, line width=1.5]
    \draw[->, line width=1] (0,0) -- (6,0) node[right] {$L_t$};
    \draw[->, line width=1] (0,0) -- (0,4.2) node[above] {$L_{t+1}$};
    \draw[dashed, line width=1] (0,0) -- (4.2, 4.2)node[right] {$L_{t+1}=L_t$};
    \draw[scale=1,domain=0:5,smooth,variable=\x,blue]  plot ({\x},{1.25*\x^0.5})  node[right] {$L_{t+1}=\phi (L_{t};A)$};

    % Initialize location and do 1 iteration
    \tikzmath{\xt=4.8; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt,0) -- (\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);

    % Iterate 3 times to show path
    \foreach \x in {0,1,2}{
        \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
        \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
        \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    }
\end{tikzpicture}


\end{document}

Any help would be appreciated.

0

1 Answer 1

1

The problem you are seeing stems from the fact that the argument of \foreach is a group, and hence \xt and \yt only get locally updated, and the local update gets "forgotten". One rather blunt way of overcoming this is to make \xt and \yt global using \xdef.

\documentclass{article}%
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}

\begin{tikzpicture}[scale=1.5, line width=1.5]
    \draw[->, line width=1] (0,0) -- (6,0) node[right] {$L_t$};
    \draw[->, line width=1] (0,0) -- (0,4.2) node[above] {$L_{t+1}$};
    \draw[dashed, line width=1] (0,0) -- (4.2, 4.2)node[right] {$L_{t+1}=L_t$};
    \draw[scale=1,domain=0:5,smooth,variable=\x,blue]  plot ({\x},{1.25*\x^0.5})  node[right] {$L_{t+1}=\phi (L_{t};A)$};

    % Initialize location and do 1 iteration
    \tikzmath{\xt=4.8; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt,0) -- (\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);

    % Iterate 3 times to show path
    % 1
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    % 2
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    % 3
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
\end{tikzpicture}

\begin{tikzpicture}[scale=1.5, line width=1.5]
    \draw[->, line width=1] (0,0) -- (6,0) node[right] {$L_t$};
    \draw[->, line width=1] (0,0) -- (0,4.2) node[above] {$L_{t+1}$};
    \draw[dashed, line width=1] (0,0) -- (4.2, 4.2)node[right] {$L_{t+1}=L_t$};
    \draw[scale=1,domain=0:5,smooth,variable=\x,blue]  plot ({\x},{1.25*\x^0.5})  node[right] {$L_{t+1}=\phi (L_{t};A)$};

    % Initialize location and do 1 iteration
    \tikzmath{\xt=4.8; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt,0) -- (\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);

    % Iterate 3 times to show path
    \foreach \x in {0,1,2}{
        \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
        \xdef\xt{\xt}\xdef\yt{\yt}
        \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
        \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    }
\end{tikzpicture}
\end{document}

enter image description here

An arguably less blunt way to go is to (ab?)use the remember key that is available for \foreach.

\documentclass{article}%
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}

\begin{tikzpicture}[scale=1.5, line width=1.5]
    \draw[->, line width=1] (0,0) -- (6,0) node[right] {$L_t$};
    \draw[->, line width=1] (0,0) -- (0,4.2) node[above] {$L_{t+1}$};
    \draw[dashed, line width=1] (0,0) -- (4.2, 4.2)node[right] {$L_{t+1}=L_t$};
    \draw[scale=1,domain=0:5,smooth,variable=\x,blue]  plot ({\x},{1.25*\x^0.5})  node[right] {$L_{t+1}=\phi (L_{t};A)$};

    % Initialize location and do 1 iteration
    \tikzmath{\xt=4.8; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt,0) -- (\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);

    % Iterate 3 times to show path
    % 1
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    % 2
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    % 3
    \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
\end{tikzpicture}

\begin{tikzpicture}[scale=1.5, line width=1.5]
    \draw[->, line width=1] (0,0) -- (6,0) node[right] {$L_t$};
    \draw[->, line width=1] (0,0) -- (0,4.2) node[above] {$L_{t+1}$};
    \draw[dashed, line width=1] (0,0) -- (4.2, 4.2)node[right] {$L_{t+1}=L_t$};
    \draw[scale=1,domain=0:5,smooth,variable=\x,blue]  plot ({\x},{1.25*\x^0.5})  node[right] {$L_{t+1}=\phi (L_{t};A)$};

    % Initialize location and do 1 iteration
    \tikzmath{\xt=4.8; \yt=1.25*\xt^0.5;}
    \draw[->, dotted, line width=1] (\xt,0) -- (\xt, \yt);
    \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);

    % Iterate 3 times to show path
    \foreach \x [remember=\yt as \yt] in {0,1,2}{
        \tikzmath{\xt=\yt; \yt=1.25*\xt^0.5;}
        \draw[->, dotted, line width=1] (\xt, \xt) --(\xt, \yt);
        \draw[->, dotted, line width=1] (\xt, \yt) --(\yt, \yt);
    }
\end{tikzpicture}
\end{document}

(Same output as above.)

1
  • Works perfectly! Thanks!
    – ozak
    Sep 19, 2019 at 23:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .