Created
January 25, 2019 17:57
-
-
Save marshareb/9e3e2196bcf4c0847429b49b4365b953 to your computer and use it in GitHub Desktop.
Devils Staircase
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from matplotlib import pyplot as plt | |
from matplotlib import animation | |
fig = plt.figure() | |
ax = plt.axes(xlim=(0, 1), ylim=(0, 1)) | |
line, = ax.plot([], [], lw=2) | |
def init(): | |
line.set_data([], []) | |
return line, | |
# C_n in the Cantor set definition | |
def c(n): | |
if n == 0: | |
return [(0,1)] | |
else: | |
h = c(n-1) | |
k = [] | |
for i in h: | |
k.append((i[0]/3, i[1]/3)) | |
k.append((i[0]/3 + 2/3, i[1]/3 + 2/3)) | |
return k | |
def complement(n): | |
h = c(n) | |
h = sorted(h, key = lambda x: x[1]) | |
k = [] | |
for i in range(len(h) - 1): | |
k.append((h[i][1], h[i+1][0])) | |
return k | |
def k(n): | |
h = [] | |
for i in range(0,n+1): | |
for l in complement(i): | |
if (l,i-1) not in h: | |
h.append(l) | |
return sorted(set(h), key = lambda x : x[0]) | |
def line_between(x1, x2, y1, y2, x): | |
m = (y2-y1)/(x2-x1) | |
b = (x1*y1-x2*y1)/(x2-x1) | |
return ((y2-y1)/(x2-x1))*x + (x1*y2-x2*y1)/(x1-x2) | |
def f(x, n): | |
intervals = k(n) | |
if x >= 0 and x < intervals[0][0]: | |
return line_between(0, intervals[0][0], 0, 1/2**(n), x) | |
if x <= 1 and x > intervals[-1][1]: | |
return line_between(intervals[-1][1], 1, (len(intervals))/(2**(n)), 1, x) | |
for i in range(len(intervals)): | |
if x >= intervals[i][0] and x <= intervals[i][1]: | |
return (i+1)/2**(n) | |
elif x < intervals[i][0]: | |
if intervals[i-1][1] < x: | |
return min(1,line_between(round(intervals[i-1][1],5), round(intervals[i][0],5), ((i)/2**(n)), ((i+1)/(2**(n))), x)) | |
def connectpoints(x,y,p1,p2): | |
x1, x2 = x[p1], x[p2] | |
y1, y2 = y[p1], y[p2] | |
plt.plot([x1,x2],[y1,y2],'k-') | |
def animate(n): | |
print(n) | |
x = np.linspace(0, 1, 100) | |
h = k(n) | |
y = [f(i, n+1) for i in x] | |
line.set_data(x, y) | |
return line, | |
anim = animation.FuncAnimation(fig, animate, init_func=init, | |
frames=10, interval=200, blit=True) | |
''' | |
# In case you just want to plot the function itself. | |
x = np.linspace(0, 1, 100) | |
y = [f(i,4) for i in x] | |
plt.plot(x,y) | |
plt.show() | |
''' | |
# Saves the animation as a .gif. Used imagemagick since I'm on a linux distribution. | |
anim.save('cantor.gif', fps=1, writer='imagemagick') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment