自己回帰関数 / 線形差分方程式のプロット

自己回帰関数 / 線形差分方程式のプロット

何らかの関数 があると仮定します。 から始まり、ステップを実行して$k_{t+1} = f(k_t)$パスをプロットするよりスマートな方法はありますか? よろしくお願いします。$k_0$$n$

\documentclass[
paper=A4,               
fontsize=12pt,          
parskip=half+,          
numbers=ddot,           
]
{scrbook}  

\usepackage{tkz-euclide}
\usepackage{tikz}
\usetikzlibrary{shapes, arrows, shapes.geometric,positioning,intersections,shapes,decorations, arrows.meta, calc, plotmarks}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{arrows.meta}
\usepackage[T1]{fontenc}
\usetikzlibrary{hobby}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.10}
\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=newest}
\usetkzobj{all}
\usepackage{amsmath}
\usepackage{amssymb}

% 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] 
\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]{x + 0.1*x*(x-4)*(x-8)}; 

% (k_0,0) -> (k_0, f(k_0))
\draw[->, color=red] (axis cs: \start, 0) -- (axis cs: \start, {\start + 0.1*\start*(\start-4)*(\start-8)});
% (k_0, f(k_0)) -> (f(k_0), f(k_0))
\draw[->, color=red] (axis cs: \start, {\start + 0.1*\start*(\start-4)*(\start-8)}) -- (axis cs: {\start + 0.1*\start*(\start-4)*(\start-8)}, {\start + 0.1*\start*(\start-4)*(\start-8)});
% (f(k_0), f(k_0) -> (f(k_0), f(f(k_0)))
\draw[->, color=red] (axis cs: {\start + 0.1*\start*(\start-4)*(\start-8)}, {\start + 0.1*\start*(\start-4)*(\start-8)}) -- (axis cs: {\start + 0.1*\start*(\start-4)*(\start-8)}, {(\start + 0.1*\start*(\start-4)*(\start-8)) + 0.1*(\start + 0.1*\start*(\start-4)*(\start-8))*((\start + 0.1*\start*(\start-4)*(\start-8))-4)*((\start + 0.1*\start*(\start-4)*(\start-8))-8)});
% ...

\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}

次のプロットが生成されます。

プロット

より正確に言うと、次のように置き換えます。

% (k_0,0) -> (k_0, f(k_0)) 
...
% (k_0, f(k_0)) -> (f(k_0), f(k_0))
...
% (f(k_0), f(k_0) -> (f(k_0), f(f(k_0)))

次のような内容です:

k_0 = \start;
for(i = 1; i<n; i++){
\draw[->, color=red] (k_i-1, f(k_i-1)) -- (f(k_i-1), f(k_i-1));
\draw[->, color=red] (f(k_i-1), f(k_i-1)) -- (f(k_i-1), f(f(k_i-1)));
k_i = f(k_i);
}

答え1

pgfplotsはい、展開を注意深く見れば、ループを組み込むことは可能です。

\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}

ここに画像の説明を入力してください

答え2

declare functionここでは、 を使用して を定義しf、 を使用して\edefを描画し(pgfplots\foreachマニュアルaxis cs:の 548 ページを参照)、rememberと を使用してとevaluateの値を計算して記憶する解法を示します。kf(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}

ここに画像の説明を入力してください

答え3

楽しみまたは比較の目的のみの PSTricks ソリューション。

\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}

ここに画像の説明を入力してください

欠けている部分は、練習用に意図的に残してあります。

関連情報