Plotting Autoregressive Functions / Linear Difference Equations
Yes, one can do loops in pgfplots
as long as one carefully looks at the expansions.
\documentclass[
paper=A4,
fontsize=12pt,
parskip=half+,
numbers=ddot,
]
{scrbook}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.16}
% see: https://tex.stackexchange.com/questions/256883/telling-tikz-to-continue-the-previously-drawn-path-with-a-line-to-operation
\tikzset{%
from end of path/.style={
insert path={
\pgfextra{%
\expandafter\pgfprocesspathextractpoints%
\csname tikz@intersect@path@name@#1\endcsname%
\pgfpointlastonpath%
\pgfgetlastxy\lastx\lasty
}
(\lastx,\lasty)
}}}
\begin{document}
\begin{minipage}[t]{\pdfpagewidth}
%%Tikzpicture
\begin{tikzpicture}[>=latex,x=1pt, y=1pt,declare function={
f(\x)=\x+0.1*\x*(\x-4)*(\x-8);}]
\begin{axis}[
axis lines=center,
xtick=\empty,
ytick=\empty,
xlabel={$k_t$},
ylabel={$k_{t+1}$},
xlabel style={below},
ylabel style={left},
xmin=0,
xmax=10,
ymin=0,
ymax=10,
axis equal image
]
\xdef\start{1};
\coordinate[] (kzero) at (axis cs: \start,0);
%% Functions
\addplot[color=black,mark=none, domain=0:8.5, name path global=linear]{x};
\addplot[color=red,mark=none, domain=0:8.5, samples=500, name path global=red]{f(x)};
\xdef\tmpX{1}
\xdef\tmpY{0}
\pgfplotsinvokeforeach{0,...,3}{ %
\edef\temp{
\noexpand\draw[->, color=red] (axis cs:\tmpX,\tmpY) -- (axis cs:\tmpX,{f(\tmpX)});
\noexpand\draw[->, color=red] (axis cs:\tmpX,{f(\tmpX)}) -- (axis cs:{f(\tmpX)},{f(\tmpX)});
}
\temp
\pgfmathparse{f(\tmpX)}
\xdef\tmpX{\pgfmathresult}
\xdef\tmpY{\pgfmathresult}
}
\end{axis}
\node[color=red, below right, from end of path=red] {$k_{t+1} = f(k_t)$};
\node[color=red, below] at (kzero) {$k_0$};
\end{tikzpicture}
\end{minipage}
\end{document}
Here is a solution using declare function
to define f
, using \edef
to draw in a \foreach
via axis cs:
(cf. p.548, pgfplots manual) and using remember
and evaluate
to calculate and memorize the values of k
and f(k)
.
\documentclass{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=newest}
% see: https://tex.stackexchange.com/questions/256883/telling-tikz-to-continue-the-previously-drawn-path-with-a-line-to-operation
\tikzset{%
from end of path/.style={
insert path={
\pgfextra{%
\expandafter\pgfprocesspathextractpoints%
\csname tikz@intersect@path@name@#1\endcsname%
\pgfpointlastonpath%
\pgfgetlastxy\lastx\lasty
}
(\lastx,\lasty)
}}}
\begin{document}
\begin{tikzpicture}[>=latex,x=1pt, y=1pt]
\begin{axis}[
axis lines=center,
xtick=\empty,
ytick=\empty,
xlabel={$k_t$},
ylabel={$k_{t+1}$},
xlabel style={below},
ylabel style={left},
xmin=0,
xmax=10,
ymin=0,
ymax=10,
axis equal image,
declare function={
f(\x) = \x + .1*\x*(\x-4)*(\x-8);
},
]
\xdef\start{.15};
\coordinate[] (kzero) at (axis cs: \start,0);
\draw[->,color=blue] (kzero) -- (\start,{f(\start)});
%% Functions
\addplot[color=black,mark=none, domain=0:8.5]{x};
\addplot[color=red,mark=none, domain=0:8.5, samples=500, name path global=red]{f(x)};
\foreach \c[remember={\f as \k (initially \start)},{evaluate=\f using f(\k)}] in {1,...,5}{
\typeout{c:\c, k:\k, f:\f}
% (cf. p.548, pgfplots manual)
\edef\temp{
\noexpand\draw[->,color=blue] (axis cs: \k, \f) -- (axis cs:\f, \f);
\noexpand\draw[->,color=blue] (axis cs: \f, \f) -- (axis cs:\f, {f(\f)});
}
\temp
}
\end{axis}
\node[color=red, below right, from end of path=red] {$k_{t+1} = f(k_t)$};
\node[color=red, below] at (kzero) {$k_0$};
\end{tikzpicture}
\end{document}
A PSTricks solution only for either fun or comparison purposes.
\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{pst-plot}
\def\f{x+x*(x-4)*(x-8)/10}
\begin{document}
\begin{pspicture}[algebraic](-.75,-.5)(10,11)
\psaxes[ticks=none,labels=none]{->}(0,0)(-.5,-.5)(10,11)[$k_t$,-90][$k_{t+1}$,180]
\psplot[linecolor=red,linewidth=2pt]{0}{8.5}{\f}
\psline(10,10)
\psFixpoint[linecolor=blue]{1}{\f}{20}
\rput[br](*8.5 {\f+.1}){$k_{t+1}=f(k_t)$}
\end{pspicture}
\end{document}
The missing parts are intentionally left for your exercises.