阅读其他主题后,这是我目前得到的结果:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows}
\begin{document}
\begin{figure}[htbp]
\centering
\newcounter{j}
\begin{tikzpicture}[>=latex',scale=10,
declare function={%
p(\t)= greater(\t,0.5) ? 1 : 2* \t ;}]
\draw[color=blue,domain=-0:1.05] plot (\x,{\x^3});
\draw[color=green](0,0)--(1.1,1.1);
\draw[->](0,0)--(0,1) node[above]{$y$};
\draw[->](0,0)--(1,0) node[right]{$x$};
\newcommand{\x}{.1}
\foreach \i in {1,...,4}{%
\pgfmathparse{(p(\x)}
\let\y\pgfmathresult
\draw[color=magenta](\x,\x)--(\x,\y)--(\y,\y);
\draw[color=orange,dotted,line width=0.8pt]%
(\x,\x)--(\x,0) node[below=8pt]{$u_\i$};
\pgfmathsetcounter{j}{\i+1}
\draw[color=blue,dotted,line width=0.8pt]%
(\x,\y)--(0,\y) node[left=8pt] {$u_\thej$};
\global\let\x\y}
\end{tikzpicture}
\end{figure}
\end{document}
答案1
以下是入门大纲。思路是定义(声明)一个函数f(\x)
。绘制函数和线后,我们使用\foreach
执行一定次数的迭代。\evaluate
在 for 循环中使用计算\newv
函数在起始值处的值\startv
。然后使用垂直于函数并水平于线绘制\draw (\startv,\startv)|-(\newv,\newv);
。最后将的值重置\startv
为计算值\newv
并循环。
代码如下
\documentclass{article}
\usepackage{tikz}
\newcommand{\startv}{.8}
\begin{document}
\begin{tikzpicture}[scale=3,declare function={f(\x)=\x*\x*\x;}]
\draw[<->](0,1.1)|-(1.1,0);
\draw[green!70!black] (0,0)--(1,1);
\draw[blue, domain=0:1, smooth] plot (\x,{f(\x)});
\foreach \t[evaluate=\t as \newv using f(\startv)] in {1,...,4}{
\draw[red] (\startv,\startv)|-(\newv,\newv);
\xdef\startv{\newv}}
\end{tikzpicture}
\end{document}
您可以轻松更改函数、起始值和迭代次数。
例如:设置f(\x)=3.2*\x*(1-\x);
。更改\newcommand{\startv}{.25}
,并使用 循环 100 次以{1,...,100}
生成图像
f(\x)=3.8*\x*(1-\x);
类似地,
您可以将整个内容放入一个\cobweb
使用三个参数(一个可选)调用的宏中:
\cobweb[<start value>]{<function>}{<iterations>}
<start value>
是可选的(默认值=.5),<function>
必须用于\x
变量。示例用法:
\cobweb[.8]{\x*\x*\x}{4}\qquad
\cobweb[.25]{3.2*\x*(1-\x)}{100}\qquad
\cobweb{3.8*\x*(1-\x)}{100}
生产
以下是带有宏的代码:
\documentclass{article}
\usepackage{tikz}
\newcommand{\cobweb}[3][.5]{% \cobweb[<start value>]{<function>}{<iterations>}
\begin{tikzpicture}[scale=3,declare function={f(\x)=#2;}]
\xdef\startv{#1}
\draw[<->](0,1.1)|-(1.1,0);
\draw[green!70!black] (0,0)--(1,1);
\draw[blue, domain=0:1, smooth] plot (\x,{f(\x)});
\foreach \t[evaluate=\t as \newv using f(\startv)] in {1,...,#3}{
\draw[red] (\startv,\startv)|-(\newv,\newv);
\xdef\startv{\newv}}
\end{tikzpicture}}
\begin{document}
\cobweb[.8]{\x*\x*\x}{4}\qquad
\cobweb[.25]{3.2*\x*(1-\x)}{100}\qquad
\cobweb{3.8*\x*(1-\x)}{100}
\end{document}
更新:
我决定继续研究这个问题,通过迭代函数族 f(x)=4λx(1-x) 来检查分叉和混沌行为。该函数现在内置于一个宏中,\bifur
该宏接受 4 个参数,其中一个是可选的:
\bifur[<skip>]{<start value>}{<lambda>}{<iterations>}
可选参数<skip>
不会绘制<skip>
函数的第一次迭代以查看长期行为。如果省略,则不会跳过任何迭代。例如,要跳过前 50 次迭代并绘制接下来的 100 次(并与 skip=0 进行比较):
\bifur{.1}{.8}{100}\qquad
\bifur[50]{.1}{.8}{100}
\bifur{.1}{.88}{100}\qquad
\bifur[50]{.1}{.88}{100}
\bifur{.1}{.96}{100}\qquad
\bifur[50]{.1}{.96}{100}
\bifur{.1}{.97}{100}\qquad
\bifur[50]{.1}{.97}{100}
以下是带有宏的代码\bifur
:
\documentclass{article}
\usepackage{tikz,ifthen}
\tikzset{tick/.style={draw, minimum width=0pt, minimum height=2pt, inner sep=0pt, label=below:$\scriptstyle#1$},
tick/.default={}}
\newcommand{\bifur}[4][0]{% \bifur[<skip>]{<start value>}{<lambda>}{<iterations>}
\begin{tikzpicture}[scale=3,declare function={f(\x)=#3*4*\x*(1-\x);}]
\draw[<->](0,1.1)|-(1.1,0);
\node[tick=1] at (1,0){}; \node[tick=#3,rotate=-90] at (0,#3){};
\xdef\startv{#2}
\draw[green!70!black] (0,0)--(1,1);
\draw[blue, domain=0:1, smooth] plot (\x,{f(\x)});
\ifthenelse{#1=0}{}{
\foreach \t[evaluate=\t as \newv using f(\startv)] in {1,...,#1}{
\xdef\startv{\newv}}}
\foreach \t[evaluate=\t as \newv using f(\startv)] in {1,...,#4}{
\draw[red, very thin, line cap=round, line join=round] (\startv,\startv)|-(\newv,\newv);
\xdef\startv{\newv}}
\end{tikzpicture}}
\begin{document}
\bifur{.1}{.8}{100}\qquad
\bifur[50]{.1}{.8}{100}
\end{document}
以下是转换成 gif 后的样子:
答案2
// COBWEB
// Run on http://asymptote.ualberta.ca/
// Asymptote translation from Sandy G at
// https://tex.stackexchange.com/a/640044/140722
unitsize(5cm);
import graph;
real f(real x){return 3.8*x*(1-x);}
path gf=graph(f,0,1);
draw((1.1,0)--(0,0)--(0,1.1),Arrows(TeXHead));
draw((0,0)--(1,1),.7green);
draw(gf,blue);
real startv=.5;
int n=50;
for(int i=1; i<n; ++i){
real newv=f(startv);
draw((startv,startv)--(startv,newv)--(newv,newv),red);
startv=newv;
}
shipout(bbox(5mm,invisible));