1
1
include (" Sequences.jl" )
2
2
3
- function orbit (angle:: Rational )
4
- items = Rational[]
3
+ alphabet = [' *' ,' A' ,' B' ]
4
+
5
+ struct RationalAngle <: Number
6
+ value:: Rational
7
+ function RationalAngle (theta:: Rational )
8
+ if theta > 1
9
+ @warn " Creating angle from number larger than 1, only the fractional part will be kept."
10
+ new (mod (theta,1 ))
11
+ else
12
+ new (theta)
13
+ end
14
+ end
15
+ end
16
+
17
+ import Base: + , * , / , < , > , numerator, denominator
18
+
19
+ phi:: RationalAngle + theta:: RationalAngle = RationalAngle (mod (phi. value+ theta. value,1 ))
20
+ theta:: RationalAngle * s:: Number = RationalAngle (mod (theta. value* s,1 ))
21
+ s:: Number * theta:: RationalAngle = theta * s
22
+ theta:: RationalAngle / s:: Number = RationalAngle (theta. value/ s)
23
+ phi:: RationalAngle > theta:: RationalAngle = phi. value > theta. value
24
+ phi:: RationalAngle < theta:: RationalAngle = phi. value < theta. value
25
+
26
+ denominator (theta:: RationalAngle ) = denominator (theta. value)
27
+ numerator (theta:: RationalAngle ) = numerator (theta. value)
28
+
29
+ function orbit (angle:: RationalAngle )
30
+ items = RationalAngle[]
5
31
6
32
while isempty (findall (x-> x== angle,items))
7
33
push! (items,angle)
8
34
angle = angle* 2
9
- angle = angle% 1 // 1
10
35
end
11
36
12
37
preperiod = findall (x-> x== angle,items)[1 ] - 1
13
38
14
- return Sequence {Rational } (items,preperiod)
39
+ return Sequence {RationalAngle } (items,preperiod)
15
40
16
41
end
17
42
18
- abstract type KneadingSymbol end
43
+ struct KneadingSymbol <: Integer
44
+ value:: Int
45
+ function KneadingSymbol (value:: Int )
46
+ 0 <= value <= 2 || error (" Value must be in range [0, 2]" )
47
+ new (value)
48
+ end
49
+ end
19
50
20
- struct A <: KneadingSymbol end
21
- struct B <: KneadingSymbol end
22
- struct star <: KneadingSymbol end
51
+ # necessary for using kneading sequences as dictionary keys
52
+ Base. hash (d:: KneadingSymbol ,h:: UInt64 ) = hash (d. value,h)
23
53
24
- Base. show (io:: IO , symb:: A ) = print (io,' A' )
25
- Base. show (io:: IO , symb:: B ) = print (io,' B' )
26
- Base. show (io:: IO , symb:: star ) = print (io,' *' )
54
+ function KneadingSymbol (c:: Char )
55
+ return KneadingSymbol (first (findall (x-> x== c,alphabet))- 1 )
56
+ end
57
+
58
+ function Base. show (io:: IO , symb:: KneadingSymbol )
59
+ print (io,alphabet[symb. value+ 1 ])
60
+ end
27
61
28
62
const KneadingSequence = Sequence{KneadingSymbol}
29
63
30
- function KneadingSequence (angle:: Rational )
64
+ function KneadingSequence (angle:: RationalAngle )
31
65
orb = orbit (angle)
32
66
return thetaitinerary (angle,orb)
33
67
end
34
68
35
- function thetaitinerary (theta:: Rational ,angle:: Rational )
69
+ function thetaitinerary (theta:: RationalAngle ,angle:: RationalAngle )
36
70
return thetaitinerary (theta,orbit (angle))
37
71
end
38
72
39
- function thetaitinerary (theta:: Rational ,orb:: Sequence )
73
+ function thetaitinerary (theta:: RationalAngle ,orb:: Sequence )
40
74
a = theta/ 2
41
- b = ( theta+ 1 ) / 2
75
+ b = theta/ 2 + RationalAngle ( 1 // 2 )
42
76
itinerary = KneadingSymbol[]
43
77
44
78
for angle in orb. items
45
79
if angle == a
46
- push! (itinerary,star ( ))
80
+ push! (itinerary,KneadingSymbol ( ' * ' ))
47
81
elseif angle == b
48
- push! (itinerary,star ( ))
82
+ push! (itinerary,KneadingSymbol ( ' * ' ))
49
83
elseif angle > a && angle < b
50
- push! (itinerary,A ( ))
84
+ push! (itinerary,KneadingSymbol ( ' A ' ))
51
85
else
52
- push! (itinerary,B ( ))
86
+ push! (itinerary,KneadingSymbol ( ' B ' ))
53
87
end
54
88
end
55
89
@@ -115,15 +149,15 @@ end
115
149
function KneadingSequence (intadd:: InternalAddress )
116
150
address = copy (intadd. addr)
117
151
if address == [1 ]
118
- return Sequence {KneadingSymbol} (KneadingSymbol[A ( )],0 )
152
+ return Sequence {KneadingSymbol} (KneadingSymbol[KneadingSymbol ( ' A ' )],0 )
119
153
else
120
154
s = pop! (address)
121
155
K = KneadingSequence (InternalAddress (address))
122
156
R = K. items[mod1 .(1 : s- 1 ,end )]
123
- if K. items[mod1 (s,end )] == A ( )
124
- push! (R,B ( ))
157
+ if K. items[mod1 (s,end )] == KneadingSymbol ( ' A ' )
158
+ push! (R,KneadingSymbol ( ' B ' ))
125
159
else
126
- push! (R,A ( ))
160
+ push! (R,KneadingSymbol ( ' A ' ))
127
161
end
128
162
return Sequence {KneadingSymbol} (R,0 )
129
163
end
@@ -166,19 +200,19 @@ end
166
200
167
201
struct AngledInternalAddress
168
202
addr:: Vector{Int}
169
- angles:: Vector{Rational }
203
+ angles:: Vector{RationalAngle }
170
204
end
171
205
172
206
# Lemma 11.14 TreesBook page 146
173
- function AngledInternalAddress (theta:: Rational )
207
+ function AngledInternalAddress (theta:: RationalAngle )
174
208
intadd = InternalAddress (KneadingSequence (theta))
175
209
denoms = denominators (intadd)
176
210
angles = Rational[]
177
211
178
212
for ii in 1 : length (intadd)- 1
179
213
n = 0
180
214
for jj in 1 : (denoms[ii] - 1 )
181
- if ((2 // 1 )^ ((jj- 1 )* intadd[ii])* theta)% 1 <= theta
215
+ if ((2 // 1 )^ ((jj- 1 )* intadd[ii])* theta) <= theta
182
216
n += 1
183
217
end
184
218
end
@@ -323,7 +357,7 @@ Base.Int(d::Digit) = d.value
323
357
324
358
const BinaryExpansion = Sequence{Digit{2 }}
325
359
326
- function BinaryExpansion (theta:: Rational )
360
+ function BinaryExpansion (theta:: RationalAngle )
327
361
orb = orbit (theta)
328
362
itinerary = Digit{2 }[]
329
363
zero = Digit {2} (0 )
@@ -338,7 +372,7 @@ function BinaryExpansion(theta::Rational)
338
372
return Sequence {Digit{2}} (collect (itinerary),orb. preperiod)
339
373
end
340
374
341
- function Rational (bits:: BinaryExpansion )
375
+ function RationalAngle (bits:: BinaryExpansion )
342
376
theta = 0 // 1
343
377
k = bits. period
344
378
r = 1 // (1 // 1 - (2 // 1 )^- k)
@@ -351,5 +385,5 @@ function Rational(bits::BinaryExpansion)
351
385
end
352
386
end
353
387
end
354
- return theta
388
+ return RationalAngle ( theta)
355
389
end
0 commit comments