var('x')
f = (x/2)*cos(pi*x/2)^2 + ((3*x + 1)/2)*sin(pi*x/2)^2
f_latex = r'$\frac{x}{2}\cdot\cos^2\left(\frac{\pi x}{2}\right) \,+\, \frac{3x + 1}{2}\cdot\sin^2\left(\frac{\pi x}{2}\right)$'
def cobweb(f, x, xmin, xmax, max_iter=100, f_latex=None):
p = plot(f, (xmin, xmax), ymin=xmin, ymax=xmax, aspect_ratio=1, legend_label=f_latex)
p += plot(lambda x: x, xmin=xmin, xmax=xmax, color='gray')
path = [(x, 0)]
for k in range(max_iter):
y = f(x=x)
path.append((x, y))
x = y
path.append((x, x))
if (x, x) in path[:-1]:
break
p += line(path, rgbcolor=(1, 0, 0))
return p
x0 = 10
xmin, xmax = 0, 12
p = cobweb(f, x=x0, xmin=xmin, xmax=xmax, f_latex=f_latex)
config = dict(
aspect_ratio=1, legend_font_size=13.5, legend_handlelength=1.5, legend_borderpad=0.3, legend_loc='upper left',
ticks=[[xmin..xmax], [xmin..xmax]], tick_formatter='latex', ticks_integer=True,
gridlines=True, gridlinesstyle={'linestyle': ':'}
)
show(p, **config)
p.save('Collatz_Cobweb.svg', **config)