Skip to content

Commit df6823a

Browse files
committed
Through the refactor valley. The fancy sequence structs are implemented, hubbard trees are still dict wrappers
1 parent 74e28a8 commit df6823a

File tree

10 files changed

+128
-117
lines changed

10 files changed

+128
-117
lines changed

src/Spiders.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
module Spiders
2-
export treeplot
3-
export EmbeddedHubbardTree
42
include("trees/ShowTree.jl")
5-
# Write your package code here.
3+
4+
export KneadingSequence
5+
6+
export InternalAddress
7+
export HubbardTree
8+
9+
export AngledInternalAddress
10+
export OrientedHubbardTree
11+
12+
export HyperbolicComponent
13+
14+
export treeplot
615

716
end

src/parameters/DynamicRays.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ include("../sequences/AngleDoubling.jl")
22
include("../spidermap/SpiderFuncs.jl")
33

44
struct ExternalRays
5-
orb::Sequence{Rational}
6-
rays::Dict{Rational,Vector{ComplexF64}}
5+
orb::Sequence{BinaryExpansion}
6+
rays::Dict{BinaryExpansion,Vector{ComplexF64}}
77
parameter::Complex
88
end
99

1010
## Conjecture: if the collection of rays is a sequence of rays, we will not need this function.
1111
## Question: Is it possible to update the rays in a mutating and not problematic way?
1212
function goesto(seq::Sequence)
1313
l = seq.preperiod
14-
k = period(seq)
14+
k = seq.period
1515
idx = append!(collect(1:l).+1,circshift(l+1:l+k,-1))
1616
return [(seq.items[x],seq.items[y]) for (x,y) in enumerate(idx)]
1717
end
@@ -44,12 +44,12 @@ function extend!(Ext::ExternalRays)
4444
end
4545

4646

47-
function dynamicrays(c::Complex,angle::Rational,R::Real,res::Int,depth::Int)
47+
function dynamicrays(c::Complex,angle::BinaryExpansion,R::Real,res::Int,depth::Int)
4848
orb = orbit(angle)
4949
radii = collect(LinRange(R,sqrt(R),res))
5050

5151
#similar to standard spider but is outer
52-
rays = Sequence{Vector{ComplexF64}}([exp(2im*pi*theta).*radii for theta in orb.items],orb.preperiod)
52+
rays = Sequence{Vector{ComplexF64}}([exp(2im*pi*Rational(theta)).*radii for theta in orb.items],orb.preperiod)
5353

5454
for jj in 1:depth
5555
for (target,source) in goesto(rays)

src/sequences/AngleDoubling.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,10 @@ struct Digit{N} <: Integer
316316
end
317317
end
318318

319+
Base.hash(d::Digit,h::UInt64) = hash(d.value,h)
320+
319321
Base.show(io::IO, d::Digit{N}) where {N} = print(io, d.value)
320-
Base.Int(d::Digit{N}) where {N} = d.value
322+
Base.Int(d::Digit) = d.value
321323

322324
const BinaryExpansion = Sequence{Digit{2}}
323325

src/sequences/Sequences.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ struct Sequence{T}
3636
end
3737
end
3838

39+
function Base.getproperty(S::Sequence,sym::Symbol)
40+
if sym === :period
41+
return length(S.items) - S.preperiod
42+
else
43+
return getfield(S,sym)
44+
end
45+
end
46+
3947
function Sequence(str::String,preperiod::Int)
4048
return Sequence{Char}(Vector{Char}(str),preperiod)
4149
end
@@ -73,14 +81,6 @@ function Base.show(io::IO, s::Sequence{Char})
7381
end
7482
end
7583

76-
function Base.getproperty(S::Sequence,sym::Symbol)
77-
if sym === :period
78-
return length(S.items) - S.preperiod
79-
else
80-
return getfield(S,sym)
81-
end
82-
end
83-
8484
function shift(seq::Sequence{T}) where T
8585
if seq.preperiod == 0
8686
#then seq is periodic

src/spidermap/SpiderMap.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ include("../sequences/AngleDoubling.jl")
55
struct Spider
66
angle::Rational
77
orbit::Sequence{Rational}
8-
kneading_sequence::Sequence{Char}
8+
kneading_sequence::KneadingSequence
99
legs::Vector{Vector{ComplexF64}}
1010
end
1111

@@ -65,7 +65,7 @@ function mapspider!(S::Spider)
6565
λ = S.legs[2][end] #the parameter of our polynomial map z -> λ(1+z/2)^2
6666
a = (angle(S.legs[1][1]/λ)/(2*pi)+1)%1 #the angle whose halves will define the boundary between regions A and B at infinity. in full turns
6767

68-
n = length(S.orbit)
68+
n = length(S.orbit.items)
6969

7070
newLegs = Vector{Vector{ComplexF64}}(undef,n)
7171

@@ -76,11 +76,11 @@ function mapspider!(S::Spider)
7676
#this angle lays in region A by definition.
7777

7878
if a/2 < theta1 && theta1 < (a+1)/2
79-
cregion = 'A'
80-
dregion = 'B'
79+
cregion = A()
80+
dregion = B()
8181
else
82-
cregion = 'B'
83-
dregion = 'A'
82+
cregion = B()
83+
dregion = A()
8484
end
8585

8686
for ii in 2:n-1
@@ -103,13 +103,14 @@ function mapspider!(S::Spider)
103103
end
104104
end
105105

106+
#TODO what is going on with the periodic case? kneading sequences never have 1s and 2s now
106107
#we will break into periodic and preperiodic cases for the last leg
107108
if S.orbit.preperiod == 0 #periodic
108109
u = sqrt(S.legs[1][1]./λ)
109110
thetau = (angle(u)/(2*pi)+1)%1
110111

111112
if abs2(thetau - a/2) < abs2(thetau - (a+1)/2)
112-
if cregion == 'A'
113+
if cregion == A()
113114
if S.kneading_sequence.items[end] == '2'
114115
newLegs[end] = path_sqrt(S.legs[1]./λ)
115116
else
@@ -123,7 +124,7 @@ function mapspider!(S::Spider)
123124
end
124125
end
125126
else
126-
if cregion == 'A'
127+
if cregion == A()
127128
if S.kneading_sequence.items[end] == '1'
128129
newLegs[end] = path_sqrt(S.legs[1]./λ)
129130
else

src/trees/EmbedTrees.jl

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,47 @@ include("OrientTrees.jl")
22
include("../spidermap/SpiderMap.jl")
33
include("../parameters/DynamicRays.jl")
44

5-
struct EmbeddedHubbardTree
6-
zero::Sequence
7-
adj::Dict{Sequence,Vector{Sequence}}
8-
boundary::Vector{Sequence}
9-
onezero::Dict{Sequence{Char}, Char}
5+
struct HyperbolicComponent
6+
criticalpoint::Sequence
7+
adj::Dict{KneadingSequence,Vector{KneadingSequence}}
8+
boundary::Vector{KneadingSequence}
9+
onezero::Dict{KneadingSequence, Union{Nothing,Digit{2}}}
1010
angle::Rational
11-
rays::Dict{Rational,Vector{ComplexF64}}
11+
rays::Dict{BinaryExpansion,Vector{ComplexF64}}
1212
parameter::ComplexF64
13-
vertices::Dict{Sequence, ComplexF64} #maps each vertex in the tree to a point in the plane
14-
edges::Dict{Set{Sequence{Char}}, Tuple{Sequence{Char}, Vector{ComplexF64}}} #maps each edge to an oriented polyline
13+
vertices::Dict{KneadingSequence, ComplexF64} #maps each vertex in the tree to a point in the plane
14+
edges::Dict{Set{KneadingSequence}, Tuple{KneadingSequence, Vector{ComplexF64}}} #maps each edge to an oriented polyline
1515
end
1616

17-
function EmbeddedHubbardTree(OHT::OrientedHubbardTree)
17+
function HyperbolicComponent(OHT::OrientedHubbardTree)
1818

1919
OZ = labelonezero(OHT)
2020
anglelist = allanglesof(OZ,OHT)
2121

22-
criticalorbit = orbit(OHT.zero) #This is a sequence orbit
22+
criticalorbit = orbit(OHT.criticalpoint) #This is a sequence orbit
2323

24-
theta = angleof(first(criticalanglesof(OZ,OHT)))
24+
theta = Rational(first(criticalanglesof(OZ,OHT)))
2525
c = parameter(standardspider(theta),250)
26-
println(c)
2726

2827
#critical orbit
2928
rays = Dict()
3029
#periodic branch points
3130
characteristicpoints = characteristicset(OHT)
3231
for point in characteristicpoints
33-
merge!(rays,dynamicrays(c,angleof(first(anglelist[point])),100,10,20))
32+
merge!(rays,dynamicrays(c,first(anglelist[point]),100,10,20))
3433
end
35-
34+
3635
#preperiod branch points. This is slow!
3736
for node in keys(OHT.adj)
3837
for angle in anglelist[node]
3938
if !(angle in keys(rays))
40-
phi = angleof(angle)
41-
push!(rays,Pair(phi,dynamicrays(c,phi,100,10,20)[phi]))
39+
push!(rays,Pair(angle,dynamicrays(c,angle,100,10,20)[angle]))
4240
end
4341
end
4442
end
4543

46-
merge!(rays,dynamicrays(c,1//2,100,10,40))
47-
merge!(rays,dynamicrays(c,0//1,100,10,40))
44+
merge!(rays,dynamicrays(c,BinaryExpansion(1//2),100,10,40))
45+
merge!(rays,dynamicrays(c,BinaryExpansion(0//1),100,10,40))
4846

4947
paramorbit = [0.0+0.0im]
5048
n = period(theta)
@@ -56,19 +54,19 @@ function EmbeddedHubbardTree(OHT::OrientedHubbardTree)
5654

5755
zvalues = Dict{Sequence,ComplexF64}()
5856
for node in keys(OHT.adj)
59-
if '*' in node.items #then it is in the critical orbit
60-
idx = findone(x->x=='*',node.items)
57+
if star() in node.items #then it is in the critical orbit
58+
idx = findone(x->x==star(),node.items)
6159
push!(zvalues,Pair(node,paramorbit[mod1(n-idx+2,n)]))
6260
else
63-
list = [rays[angleof(angle)][end] for angle in anglelist[node]]
61+
list = [rays[angle][end] for angle in anglelist[node]]
6462
push!(zvalues,Pair(node,sum(list)/length(list)))
6563
end
6664
end
67-
E = standardedges(OHT.adj,OHT.zero,zvalues)
68-
return EmbeddedHubbardTree(OHT.zero,OHT.adj,OHT.boundary,OZ,theta,rays,c,zvalues,E)
65+
E = standardedges(OHT.adj,OHT.criticalpoint,zvalues)
66+
return HyperbolicComponent(OHT.criticalpoint,OHT.adj,OHT.boundary,OZ,theta,rays,c,zvalues,E)
6967
end
7068

71-
function Base.show(io::IO,H::EmbeddedHubbardTree)
69+
function Base.show(io::IO,H::HyperbolicComponent)
7270
return println(io,"Embedded Hubbard tree of "*repr(H.angle)*" with "*repr(length(keys(H.adj)))*" vertices")
7371
end
7472

@@ -120,15 +118,15 @@ function edgepath(graph,start, finish)
120118
end
121119

122120
function refinedtree(OHT,zvalues,steps)
123-
c = zvalues[shift(OHT.zero)]
121+
c = zvalues[shift(OHT.criticalpoint)]
124122
E = standardedges(OHT,zvalues)
125123
for ii in 1:steps
126124
E = refinetree(OHT,c,E)
127125
end
128126
return E
129127
end
130128

131-
function refinetree!(EHT::EmbeddedHubbardTree)
129+
function refinetree!(EHT)
132130

133131
newedges = []
134132
for edge in keys(EHT.edges)

src/trees/Graphs.jl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1+
#implement adj and you should be able to use all these functions?
12
abstract type Graph end
23

3-
struct SetGraph{T} <: Graph
4-
adj::Dict{T,Set{T}}
5-
end
6-
7-
struct OrientedGraph{T} <: Graph
8-
adj::Dict{T,Vector{T}}
9-
end
10-
114
function Base.getindex(G::Graph,idx)
125
return G.adj[idx]
136
end
147

8+
function vertices(G::Graph)
9+
return Set(keys(G.adj))
10+
end
11+
1512
Base.show(io::IO,G::Graph) = display(G.adj)
1613

17-
function adjlist(graph::Graph)
14+
function adjlist(graph)
1815
#first, assign an index to each point
19-
nodes = collect(graph.vertices)
16+
nodes = collect(keys(graph))
2017
E = Vector{Int}[]
2118
for node in nodes
2219
g = []

src/trees/HubbardTrees.jl

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@
55
include("../sequences/AngleDoubling.jl")
66
include("Graphs.jl")
77

8-
const HubbardTree = SetGraph{KneadingSequence}
8+
abstract type AbstractHubbardTree <: Graph end
9+
10+
function criticalpoint(H::AbstractHubbardTree)
11+
return first(filter(x->x[1]==star(),vertices(H)))
12+
end
13+
14+
struct HubbardTree <: AbstractHubbardTree
15+
adj::Dict{KneadingSequence,Set{KneadingSequence}}
16+
criticalpoint::KneadingSequence
17+
end
918

1019
function HubbardTree(K::KneadingSequence)
1120
starK = prepend(K,star())
@@ -21,7 +30,7 @@ function HubbardTree(K::KneadingSequence)
2130
#println("result is $H")
2231
end
2332
end
24-
return SetGraph{KneadingSequence}(H)
33+
return HubbardTree(H,starK)
2534
end
2635

2736
function HubbardTree(intadd::InternalAddress)
@@ -31,16 +40,6 @@ function HubbardTree(intadd::InternalAddress)
3140
return HubbardTree(Sequence{KneadingSymbol}(seq,0))
3241
end
3342

34-
function Base.getproperty(H::HubbardTree,sym::Symbol)
35-
if sym === :zero
36-
return first(filter(x->x[1]==star(),H.vertices))
37-
elseif sym === :vertices
38-
return Set(keys(H.adj))
39-
else
40-
return getfield(H,sym)
41-
end
42-
end
43-
4443
function addsequence(Htree,Kseq,(A,Bset),newpoint)
4544
if newpoint in collect(keys(Htree))
4645
print("warning: point already in tree")
@@ -74,9 +73,9 @@ function addsequence(Htree,Kseq,(A,Bset),newpoint)
7473
end
7574

7675
function extend(H::HubbardTree,new::Sequence)
77-
Z = H.zero
76+
Z = criticalpoint(H)
7877
K = shift(Z)
79-
return HubbardTree(addsequence(H.adj,K,(Z,deepcopy(H.adj[Z])),new))
78+
return HubbardTree(addsequence(H.adj,K,(Z,deepcopy(H.adj[Z])),new),Z)
8079
end
8180

8281
function iteratetriod(K::Sequence,triod::Tuple{Sequence,Sequence,Sequence})
@@ -159,8 +158,8 @@ function findone(f,A)
159158
end
160159
end
161160

162-
function isbetween(htree::Dict,a,b,c)
163-
zero = first(filter(x->x.items[1]==star(),keys(htree)))
161+
function isbetween(htree::AbstractHubbardTree,a,b,c)
162+
zero = htree.criticalpoint
164163
K = shift(zero)
165164
(type,vertex) = iteratetriod(K,(a,b,c))
166165
if type == "flat" && vertex == a

0 commit comments

Comments
 (0)