|
1 | 1 | using Primes
|
2 | 2 | using IterTools
|
3 | 3 |
|
| 4 | +struct Digit{N} <: Integer |
| 5 | + value::Int |
| 6 | + function Digit{N}(value::Int) where N |
| 7 | + m = N-1 |
| 8 | + 0 <= value < N || error("Value must be in range [0, $m]") |
| 9 | + new{N}(value) |
| 10 | + end |
| 11 | +end |
| 12 | + |
| 13 | +Base.show(io::IO, d::Digit{N}) where {N} = print(io, d.value) |
| 14 | +Base.Int(d::Digit{N}) where {N} = d.value |
| 15 | + |
4 | 16 | struct Sequence{T}
|
5 | 17 | items::Vector{T}
|
6 | 18 | preperiod::Int
|
@@ -36,6 +48,79 @@ struct Sequence{T}
|
36 | 48 | end
|
37 | 49 | end
|
38 | 50 |
|
| 51 | +const BinaryExpansion = Sequence{Digit{2}} |
| 52 | + |
| 53 | +function BinaryExpansion(theta::Rational) |
| 54 | + orb = orbit(theta) |
| 55 | + itinerary = Digit{2}[] |
| 56 | + zero = Digit{2}(0) |
| 57 | + one = Digit{2}(1) |
| 58 | + for theta in orb.items |
| 59 | + if theta < 1//2 |
| 60 | + push!(itinerary,zero) |
| 61 | + else |
| 62 | + push!(itinerary,one) |
| 63 | + end |
| 64 | + end |
| 65 | + return Sequence{Digit{2}}(collect(itinerary),orb.preperiod) |
| 66 | +end |
| 67 | + |
| 68 | +function orbit(angle::Rational) |
| 69 | + items = Rational[] |
| 70 | + |
| 71 | + while isempty(findall(x->x==angle,items)) |
| 72 | + push!(items,angle) |
| 73 | + angle = angle*2 |
| 74 | + angle = angle%1//1 |
| 75 | + end |
| 76 | + |
| 77 | + preperiod = findall(x->x==angle,items)[1] - 1 |
| 78 | + |
| 79 | + return Sequence{Rational}(items,preperiod) |
| 80 | + |
| 81 | +end |
| 82 | + |
| 83 | +abstract type KneadingSymbol end |
| 84 | + |
| 85 | +struct A <: KneadingSymbol end |
| 86 | +struct B <: KneadingSymbol end |
| 87 | +struct star <: KneadingSymbol end |
| 88 | + |
| 89 | +Base.show(io::IO, symb::KneadingSymbol) = print(io, repr(typeof(symb))) |
| 90 | + |
| 91 | +const KneadingSequence = Sequence{KneadingSymbol} |
| 92 | + |
| 93 | +function thetaitinerary(theta::Rational,orb::Sequence) |
| 94 | + a = theta/2 |
| 95 | + b = (theta+1)/2 |
| 96 | + itinerary = KneadingSymbol[] |
| 97 | + |
| 98 | + for angle in orb.items |
| 99 | + if angle == a |
| 100 | + push!(itinerary,star()) |
| 101 | + elseif angle == b |
| 102 | + push!(itinerary,star()) |
| 103 | + elseif angle > a && angle < b |
| 104 | + push!(itinerary,A()) |
| 105 | + else |
| 106 | + push!(itinerary,B()) |
| 107 | + end |
| 108 | + end |
| 109 | + |
| 110 | + return Sequence{KneadingSymbol}(itinerary,orb.preperiod) |
| 111 | +end |
| 112 | + |
| 113 | +function thetaitinerary(theta::Rational,angle::Rational) |
| 114 | + return thetaitinerary(theta,orbit(angle)) |
| 115 | +end |
| 116 | + |
| 117 | +function KneadingSequence(angle::Rational) |
| 118 | + orb = orbit(angle) |
| 119 | + return thetaitinerary(angle,orb) |
| 120 | +end |
| 121 | + |
| 122 | + |
| 123 | + |
39 | 124 | function Sequence(str::String,preperiod::Int)
|
40 | 125 | return Sequence{Char}(Vector{Char}(str),preperiod)
|
41 | 126 | end
|
@@ -103,21 +188,6 @@ function shiftby(seq::Sequence,n::Int)
|
103 | 188 | end
|
104 | 189 | end
|
105 | 190 |
|
106 |
| -function divisors(n) |
107 |
| - d = Int64[1] |
108 |
| - for (p, e) in factor(n) |
109 |
| - r = 1 |
110 |
| - l = length(d) |
111 |
| - for i in 1:e |
112 |
| - r *= p |
113 |
| - for j in 1:l |
114 |
| - push!(d, d[j]*r) |
115 |
| - end |
116 |
| - end |
117 |
| - end |
118 |
| - return sort(d) |
119 |
| -end |
120 |
| - |
121 | 191 | function prepend(K::Sequence,thing)
|
122 | 192 | return Sequence{Char}(pushfirst!(copy(K.items),thing),K.preperiod+1)
|
123 | 193 | end
|
|
0 commit comments