CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download
Project: Dynamics 2019
Views: 76
Visibility: Unlisted (only visible to those who know the link)
Image: ubuntu2004
Kernel: SageMath (stable)

Topological Conjugacy for homeomorphisms of R\mathbb R.

Let f:I→If:I \to I and g:J→Jg: J \to J be continuous maps. We say they are topologically conjugate if there is a homeomorphism h:I→Jh:I \to J so that g∘h(x)=h∘f(x)g \circ h(x)=h \circ f(x) for all x∈Ix \in I.

We will demonstrate the idea behind the following result:

Theorem. Suppose I=(a,b)I=(a,b) and J=(c,d)J=(c,d) are intervals in R\mathbb R. Suppose f:I→If:I \to I and g:J→Jg:J \to J are orientation-preserving homeomorphisms so that

  • f(x)>xf(x)>x for each x∈Ix \in I, and

  • g(y)>yg(y)>y for each y∈Jy \in J. Then ff and gg are topologically conjugate.

To demonstrate this, we will consider two such maps.

f(x) = sqrt(2*x-x^2) # Consider over the interval (0,pi) plot(f, 0, 1, aspect_ratio=1) + plot(x,(x, 0, 1), color="red")
Image in a Jupyter notebook
# Here we work out the inverse map x=var("x") y=var("y") assume(y>0) # Used to help Sage find the solution we want below. assume(y<1) show((f(x)==y).solve(x))

Note that the inverse must be the first one since the second takes values greater than one.

# Here we define the inverse map finv(y) = -sqrt(-y^2 + 1) + 1

Lets plot f−1f^{-1} with ff to be sure.

plot(finv, 0, 1, color="green", aspect_ratio=1) + plot(f,(x,0,1), color="blue")
Image in a Jupyter notebook
g(x) = 1/2*(x*(3-x)) # Consider over the interval (0,pi) plot(g, 0, 1, aspect_ratio=1) + plot(x,(x,0,1), color="red")
Image in a Jupyter notebook
# Here we work out the inverse map x=var("x") y=var("y") assume(y>0) # Used to help Sage find the solution we want below. assume(y<1) (g(x)==y).solve(x)
[x == -1/2*sqrt(-8*y + 9) + 3/2, x == 1/2*sqrt(-8*y + 9) + 3/2]
ginv(y) = -1/2*sqrt(-8*y + 9) + 3/2
plot(ginv, 0, 1, color="green", aspect_ratio=1) + plot(g,(x,0,1), color="blue")
Image in a Jupyter notebook

Defining the topological conjugacy:

First we pick a points afa_f and aga_g in the domains of ff and gg:

a_f = 1/2 a_g = 1/2

We define bf=f(af)b_f = f(a_f) and bg=g(ag)b_g = g (a_g):

b_f = f(a_f) print("b_f = %s"%b_f) b_g = g(a_g) print("b_g = %s"%b_g)
b_f = 1/2*sqrt(3) b_g = 5/8

The intervals [af,bf)[a_f, b_f) is a fundamental domains for ff. This means for each x∈(0,1)x \in (0,1), there is a unique n∈Zn \in \mathbb Z so that fn(x)∈[af,bf)f^n(x) \in [a_f, b_f). Similarly, [ag,bg)[a_g, b_g) is a fundamental domain for gg.

We define a homeomorphism h0:[af,bf)→[ag,bg).h_0:[a_f,b_f) \to [a_g, b_g).

h_0(x) = (b_g - a_g)/(b_f - a_f)*(x - a_f) + a_g show(h_0(x)) assert h_0(a_f)==a_g # Prints errors if false. assert h_0(b_f)==b_g

Note that this function is more complex, so we define it using a Python type function. This allows us to use any Python or Sage type expression we want, including if statements and loops.

def h(x): assert 0 < x < 1 # Cause an error if not in the domain of f. if a_f <= x < b_f: # Use h_0: return h_0(x) if x >= b_f: count = 0 while x >= b_f: # Apply f^-1 until we land in the fundamental x = finv(x) # domain and count the number of times count = count + 1 # we apply f^-1. assert a_f <= x < b_f y = h_0(x) # Move to the domain of g using h_0. for i in range(count): # Now apply g to y, the same number of times. y = g(y) return y if x < a_f: count = 0 while x < a_f: x = f(x) count = count + 1 assert a_f <= x < b_f y = h_0(x) for i in range(count): y = ginv(y) return y
# Plot h. # Note that h is not defined at zero or at one, so # we have shrunk the interval we are plotting slightly. # Calling plot(h, 0, 1) will give rise to errors. plot(h, 0.001, 0.999)
Image in a Jupyter notebook
# Check one value larger than b_f: show( h(9/10) ) # Check the conjugacy equation: assert( h(f(9/10)) == g(h(9/10)) )
# Check one value larger than b_f: show( h(1/4) ) # Check the conjugacy equation: assert( h(f(1/4)) == g(h(1/4)) )

We can graphically check the conjugacy. For plot1 we will plot h∘fh \circ f and for plot2 we will plot g∘hg \circ h.

plot1 = plot(lambda x: h(f(x)), 0.001, 0.999) show(plot1) plot2 = plot(lambda x: g(h(x)), 0.001, 0.999, color="red") show(plot2)
Image in a Jupyter notebookImage in a Jupyter notebook
# Plot them on top of each other plot1 + plot2
Image in a Jupyter notebook
# Note that h is continuous but not differentiable: def approximate_derivative_of_h(x, epsilon=0.0001): return (h(x+epsilon)-h(x)) / epsilon
plot(approximate_derivative_of_h,0.1,0.9)
Image in a Jupyter notebook

By fiddling appropriately with our function h0(x)h_0(x) we could get hh to be smooth. The main issue is derivatives at afa_f. At other points, hh is defined to be h0h_0 or compositions of h0h_0 with powers of ff and gg. Note that for values slightly bigger than afa_f, hh is given by h0h_0. While for values slightly to the left of afa_f, hh is given by g−1∘h0∘fg^{-1} \circ h_0 \circ f. Thus if we want the derivative to match at afa_f, we would have to have h0′(af)=(g−1)′(h∘f(af))⋅h0′(f(af))⋅f′(af)=(g−1)′(bg)h0′(bf)f′(af)=f′(af)g′(ag)h0′(bf).h_0'(a_f)= (g^{-1})'\big(h \circ f(a_f)\big) \cdot h_0'\big(f(a_f)\big) \cdot f'(a_f)= (g^{-1})'(b_g) h_0'(b_f) f'(a_f)= \frac{f'(a_f)}{g'(a_g)} h_0'(b_f). So we would have to choose h0h_0 to satisfy g′(ag)h0′(af)=f′(af)h0′(bf)g'(a_g) h_0'(a_f) = f'(a_f) h_0'(b_f).