-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmobius_transform.html
More file actions
executable file
·232 lines (224 loc) · 18.9 KB
/
mobius_transform.html
File metadata and controls
executable file
·232 lines (224 loc) · 18.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0">
<title>Möbius Transform · Ptolemy MathLex</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Cinzel:wght@400;600&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,300;1,400&display=swap');
:root {
--bg:#080d1a;--panel:#0d1525;--border:#1a2540;--border2:#243050;
--white:#e8eef8;--cyan:#00d4ff;--gold:#f0c040;--red:#ff4455;--blue:#4488ff;
--green:#00ff88;--violet:#bb88ff;--orange:#ff8833;--grey:#6a7a8a;
--i-color:#00ffcc;--j-color:#ff66aa;--k-color:#aa66ff;
--e1:#ff4444;--e2:#ff8800;--e3:#ffdd00;--e4:#44ff44;--e5:#00ddff;--e6:#4466ff;--e7:#cc44ff;
--nav-h:52px;
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent;}
body{background:var(--bg);color:var(--white);font-family:'Source Serif 4',serif;font-size:16px;line-height:1.7;padding-bottom:80px;}
nav{position:sticky;top:0;z-index:200;background:#060b14;border-bottom:1px solid var(--cyan);height:var(--nav-h);display:flex;align-items:center;padding:0 14px;gap:10px;box-shadow:0 2px 20px rgba(0,212,255,0.12);}
.nav-home{font-family:'Share Tech Mono',monospace;font-size:10px;color:var(--grey);text-decoration:none;letter-spacing:2px;padding:6px 10px;border:1px solid var(--border2);border-radius:4px;}
.nav-home:hover{color:var(--cyan);border-color:var(--cyan);}
.nav-title{flex:1;font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--cyan);letter-spacing:2px;text-align:center;text-transform:uppercase;}
.nav-btn{font-family:'Share Tech Mono',monospace;font-size:12px;color:var(--grey);text-decoration:none;padding:6px 12px;border:1px solid var(--border2);border-radius:4px;transition:all 0.15s;}
.nav-btn:hover{color:var(--cyan);border-color:var(--cyan);}
.hero{background:linear-gradient(160deg,#0a1228 0%,#0d1830 50%,#0a0f20 100%);border-bottom:1px solid var(--border);padding:32px 20px 24px;position:relative;overflow:hidden;}
.hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at 70% 50%,rgba(0,212,255,0.06) 0%,transparent 60%);pointer-events:none;}
.category-tag{font-family:'Share Tech Mono',monospace;font-size:10px;color:var(--violet);letter-spacing:3px;text-transform:uppercase;margin-bottom:8px;}
.hero h1{font-family:'Cinzel',serif;font-size:clamp(22px,5vw,34px);font-weight:600;color:var(--white);line-height:1.2;margin-bottom:10px;}
.hero h1 span{color:var(--cyan);}
.hero-sub{font-size:14px;color:var(--grey);font-family:'Share Tech Mono',monospace;letter-spacing:1px;}
.anim-panel{background:#060c18;border-bottom:1px solid var(--border);height:180px;overflow:hidden;position:relative;display:flex;align-items:center;justify-content:center;}
.anim-label{position:absolute;bottom:8px;left:12px;font-family:'Share Tech Mono',monospace;font-size:9px;color:var(--grey);letter-spacing:2px;}
canvas.geo{width:100%;height:100%;display:block;}
.palette-strip{display:flex;flex-wrap:wrap;gap:6px;padding:10px 16px;background:#060b14;border-top:1px solid var(--border);border-bottom:1px solid var(--border);}
.pal-item{font-family:'Share Tech Mono',monospace;font-size:9px;letter-spacing:1px;padding:3px 8px;border-radius:3px;border:1px solid rgba(255,255,255,0.08);}
main{max-width:860px;margin:0 auto;padding:0 16px;}
.section{margin:28px 0;border-left:2px solid var(--border2);padding-left:16px;}
.section-hdr{font-family:'Share Tech Mono',monospace;font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--grey);margin-bottom:12px;display:flex;align-items:center;gap:8px;}
.section-hdr::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--cyan);flex-shrink:0;}
.w{color:var(--white);}.cy{color:var(--cyan);}.go{color:var(--gold);}.re{color:var(--red);}.bl{color:var(--blue);}.gr{color:var(--green);}.vi{color:var(--violet);}.or{color:var(--orange);}.gy{color:var(--grey);}
.ri{color:var(--i-color);font-style:italic;}.rj{color:var(--j-color);font-style:italic;}.rk{color:var(--k-color);font-style:italic;}
.math-block{background:#060c18;border:1px solid var(--border2);border-radius:6px;padding:16px 18px;font-family:'Share Tech Mono',monospace;font-size:13px;line-height:2;margin:12px 0;overflow-x:auto;}
.proof-line{display:block;padding:2px 0;border-left:2px solid transparent;padding-left:8px;margin:2px 0;}
.proof-line.step{border-left-color:var(--green);}
.proof-line.note{border-left-color:var(--grey);color:var(--grey);font-size:11px;}
.proof-line.warn{border-left-color:var(--orange);}
.levels{margin:16px 0;}
.level-block{border:1px solid var(--border);border-radius:8px;margin-bottom:8px;overflow:hidden;}
.level-hdr{background:#0a1220;padding:12px 16px;cursor:pointer;display:flex;align-items:center;justify-content:space-between;user-select:none;-webkit-user-select:none;transition:background 0.15s;}
.level-hdr:active{background:#0d1830;}
.level-hdr-left{display:flex;align-items:center;gap:10px;}
.level-badge{font-family:'Share Tech Mono',monospace;font-size:9px;letter-spacing:2px;padding:3px 8px;border-radius:3px;font-weight:700;}
.badge-novice{background:rgba(0,255,136,0.15);color:var(--green);border:1px solid rgba(0,255,136,0.3);}
.badge-journeyman{background:rgba(240,192,64,0.15);color:var(--gold);border:1px solid rgba(240,192,64,0.3);}
.badge-master{background:rgba(187,136,255,0.15);color:var(--violet);border:1px solid rgba(187,136,255,0.3);}
.level-title{font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--grey);letter-spacing:1px;}
.chevron{font-family:'Share Tech Mono',monospace;font-size:12px;color:var(--grey);transition:transform 0.2s;}
.level-body{padding:16px;border-top:1px solid var(--border);display:none;font-size:15px;line-height:1.75;}
.level-body.open{display:block;}
.chevron.open{transform:rotate(90deg);}
.code-block{background:#04080f;border:1px solid var(--border2);border-radius:6px;padding:14px 16px;font-family:'Share Tech Mono',monospace;font-size:12px;line-height:1.9;overflow-x:auto;margin:12px 0;counter-reset:line;}
.code-line{display:block;color:var(--white);}
.code-line::before{counter-increment:line;content:counter(line);color:var(--border2);display:inline-block;width:24px;margin-right:12px;text-align:right;font-size:10px;user-select:none;}
.c-kw{color:var(--violet);}.c-fn{color:var(--cyan);}.c-str{color:var(--gold);}.c-cm{color:var(--grey);font-style:italic;}.c-num{color:var(--orange);}.c-op{color:var(--green);}
.jupyter-cell{border:1px solid #2a3a5a;border-radius:6px;margin:16px 0;overflow:hidden;}
.cell-in-label{background:#0d1830;padding:4px 12px;font-family:'Share Tech Mono',monospace;font-size:9px;color:#3a5a8a;letter-spacing:2px;border-bottom:1px solid var(--border);}
.cell-in-label span{color:var(--blue);}
.cell-out-label{background:#100a14;padding:4px 12px;font-family:'Share Tech Mono',monospace;font-size:9px;color:#5a3a6a;letter-spacing:2px;border-top:1px solid var(--border);border-bottom:1px solid var(--border);}
.cell-out-label span{color:var(--red);}
.cell-out-body{background:#0c0810;padding:10px 16px;font-family:'Share Tech Mono',monospace;font-size:12px;color:var(--green);line-height:1.8;}
.ptolemy-box{background:linear-gradient(135deg,#0d1525 0%,#0a1020 100%);border:1px solid var(--violet);border-radius:8px;padding:16px;margin:12px 0;}
.ptolemy-box .face-tag{font-family:'Share Tech Mono',monospace;font-size:9px;letter-spacing:3px;color:var(--violet);text-transform:uppercase;margin-bottom:8px;}
.ptolemy-box p{font-size:14px;color:var(--grey);}
.ptolemy-box p strong{color:var(--white);}
.mistake{background:rgba(255,68,85,0.06);border-left:3px solid var(--red);border-radius:0 6px 6px 0;padding:10px 14px;margin:8px 0;font-size:14px;}
.mistake .m-label{font-family:'Share Tech Mono',monospace;font-size:9px;color:var(--red);letter-spacing:2px;margin-bottom:4px;}
.crosslinks{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0;}
.crosslink{font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--cyan);text-decoration:none;padding:6px 12px;border:1px solid rgba(0,212,255,0.3);border-radius:4px;transition:all 0.15s;}
.crosslink:hover{background:rgba(0,212,255,0.08);}
.divider{border:none;border-top:1px solid var(--border);margin:28px 0;}
</style>
</head>
<body>
<nav>
<a class="nav-home" href="index.html">⬡ INDEX</a>
<div class="nav-title">MÖBIUS TRANSFORM</div>
<div style="display:flex;gap:6px;">
<a class="nav-btn" href="mellin_transform.html">←</a>
<a class="nav-btn" href="hodge_decomposition.html">→</a>
</div>
</nav>
<div class="hero">
<div class="category-tag">⬡ Transforms · 04 of 23</div>
<h1>Möbius Transform</h1>
<div class="hero-sub">fractional linear map · Riemann sphere</div>
</div>
<div class="anim-panel">
<canvas class="geo" id="geo"></canvas>
<div class="anim-label">CONFORMAL MAP ON THE RIEMANN SPHERE</div>
</div>
<div class="palette-strip">
<span class="pal-item w" style="border-color:rgba(232,238,248,0.2)">WHITE · statement</span>
<span class="pal-item cy" style="border-color:rgba(0,212,255,0.3)">CYAN · result</span>
<span class="pal-item go" style="border-color:rgba(240,192,64,0.3)">GOLD · constant</span>
<span class="pal-item re" style="border-color:rgba(255,68,85,0.3)">RED · var A</span>
<span class="pal-item bl" style="border-color:rgba(68,136,255,0.3)">BLUE · var B</span>
<span class="pal-item gr" style="border-color:rgba(0,255,136,0.3)">GREEN · proof step</span>
<span class="pal-item vi" style="border-color:rgba(187,136,255,0.3)">VIOLET · structure</span>
<span class="pal-item or" style="border-color:rgba(255,136,51,0.3)">ORANGE · singularity</span>
</div>
<main>
<div class="section"><div class="section-hdr">Definition</div><p>A <span class="vi">Möbius transform</span> (linear fractional transformation) on ℂ∪{∞} is:</p>
<div class="math-block">
<span class="proof-line step"><span class="cy">w</span> <span class="gr">=</span> (<span class="re">a</span><span class="bl">z</span> + <span class="re">b</span>) / (<span class="re">c</span><span class="bl">z</span> + <span class="re">d</span>) <span class="gy">with ad − bc ≠ 0</span></span>
<span class="proof-line note">// a,b,c,d ∈ ℂ; the condition ad−bc≠0 ensures invertibility</span>
<span class="proof-line warn">pole at <span class="or">z = −d/c</span>: maps to ∞</span>
</div></div>
<div class="section"><div class="section-hdr">Geometric Intuition — What It Does</div><p>Every Möbius transform is a composition of four primitive moves: translation (z+b), scaling (az), inversion (1/z), and rotation (e^(iθ)z). Together they generate all <span class="go">conformal maps</span> — angle-preserving transformations of the sphere.</p>
<p style="margin-top:10px">Circles and lines on ℂ map to circles and lines. That's the key: the family is closed. Inversion turns a circle through 0 into a line — density at origin becomes density at infinity.</p></div>
<div class="section"><div class="section-hdr">Relational Analysis — Density · Pull · Attraction</div><p><span class="go">Pull</span>: fixed points of a Möbius transform are where the map "attracts" or "repels". Every non-identity Möbius transform has exactly 2 fixed points (counting ∞). The transform is conjugate to z→λz — a scaling centered on the fixed points. λ encodes the strength of pull.</p></div>
<div class="section"><div class="section-hdr">Three Levels of Understanding</div>
<div class="levels">
<div class="level-block">
<div class="level-hdr" onclick="toggleLevel(this)">
<div class="level-hdr-left">
<span class="level-badge badge-novice">NOVICE</span>
<span class="level-title">High School · Circles to Circles</span>
</div>
<span class="chevron open">▶</span>
</div>
<div class="level-body open"><p>Draw a circle on a sheet of glass. Apply a Möbius transform — it's like a special stretch-and-fold. Every circle becomes another circle (or a straight line, which is a circle through infinity). The transform is conformal: angles between crossing circles are preserved.</p></div>
</div>
<div class="level-block">
<div class="level-hdr" onclick="toggleLevel(this)">
<div class="level-hdr-left">
<span class="level-badge badge-journeyman">JOURNEYMAN</span>
<span class="level-title">Collegiate · PSL(2,ℂ)</span>
</div>
<span class="chevron">▶</span>
</div>
<div class="level-body"><p>Möbius transforms form the group <span class='vi'>PSL(2,ℂ) = SL(2,ℂ)/{±I}</span>. The matrix [[a,b],[c,d]] acts on ℙ¹(ℂ). Classification by trace²: elliptic (|trace|<2, rotation-like), parabolic (trace=±2, one fixed point), hyperbolic (|trace|>2, two fixed points), loxodromic (trace ∈ ℂ∖ℝ, spiral).</p></div>
</div>
<div class="level-block">
<div class="level-hdr" onclick="toggleLevel(this)">
<div class="level-hdr-left">
<span class="level-badge badge-master">MASTER</span>
<span class="level-title">Graduate / PhD · Uniformization</span>
</div>
<span class="chevron">▶</span>
</div>
<div class="level-body"><p>By the uniformization theorem, every simply connected Riemann surface is conformally equivalent to ℂ, ℂ̂, or ℍ (upper half-plane). The automorphism groups are all Möbius transforms: Aut(ℂ̂) = PSL(2,ℂ), Aut(ℍ) = PSL(2,ℝ). Discrete subgroups Γ ⊂ PSL(2,ℝ) give modular curves — the bridge to modular forms and the Langlands program.</p></div>
</div>
</div></div>
<div class="section"><div class="section-hdr">Derivation</div><div class="math-block">
<span class="proof-line note">// Derive inverse and composition</span>
<span class="proof-line step gr">If w = (az+b)/(cz+d), solve for z:</span>
<span class="proof-line"> <span class="re">z</span> <span class="gr">=</span> (<span class="go">d</span><span class="bl">w</span> − <span class="re">b</span>) / (−<span class="re">c</span><span class="bl">w</span> + <span class="re">a</span>) <span class="gy">// matrix inverse [[d,-b],[-c,a]]</span></span>
<span class="proof-line step gr">Composition = matrix multiplication:</span>
<span class="proof-line"> [[<span class="re">a₁</span>,<span class="re">b₁</span>],[<span class="re">c₁</span>,<span class="re">d₁</span>]] · [[<span class="bl">a₂</span>,<span class="bl">b₂</span>],[<span class="bl">c₂</span>,<span class="bl">d₂</span>]] <span class="gr">→</span> <span class="cy">new Möbius transform</span></span>
</div></div>
<div class="section"><div class="section-hdr">Hello World — Simplest Instantiation</div><div class="math-block">
<span class="proof-line">w <span class="gr">=</span> <span class="go">1/z</span> <span class="gy">(a=0,b=1,c=1,d=0)</span> <span class="cy">inversion</span></span>
<span class="proof-line">w <span class="gr">=</span> (<span class="re">z</span>−<span class="re">i</span>)/(<span class="re">z</span>+<span class="re">i</span>) <span class="gy">maps upper half-plane to unit disk</span></span>
</div></div>
<div class="section"><div class="section-hdr">Jupyter Build — Step by Step</div>
<div class="jupyter-cell">
<div class="cell-in-label">In [<span>1</span>]:</div>
<div class="code-block"><span class="code-line"><span class="c-kw">import</span> numpy <span class="c-kw">as</span> np</span>
<span class="code-line"><span class="c-kw">def</span> <span class="c-fn">mobius</span>(z,a,b,c,d): <span class="c-kw">return</span> (a*z+b)/(c*z+d)</span>
<span class="code-line"><span class="c-cm"># Map upper half plane to unit disk</span></span>
<span class="code-line">pts = np.array([<span class="c-num">0</span>+<span class="c-num">1</span>j, <span class="c-num">1</span>+<span class="c-num">1</span>j, <span class="c-num">0</span>+<span class="c-num">2</span>j])</span>
<span class="code-line"><span class="c-kw">for</span> z <span class="c-kw">in</span> pts:</span>
<span class="code-line"> w=mobius(z,<span class="c-num">1</span>,<span class="c-op">-</span><span class="c-num">1</span>j,<span class="c-num">1</span>,<span class="c-num">1</span>j)</span>
<span class="code-line"> <span class="c-fn">print</span>(<span class="c-str">f"z={z} → |w|={abs(w):.3f}"</span>)</span></div>
<div class="cell-out-label">Out [<span>1</span>]:</div>
<div class="cell-out-body">z=1j → |w|=0.000
z=(1+1j) → |w|=0.707
z=2j → |w|=0.333 (all inside unit disk ✓)</div>
</div></div>
<div class="section"><div class="section-hdr">Ptolemy Connection</div><div class="ptolemy-box"><div class="face-tag">⬡ Ptolemy Architecture</div><p><strong>Face:</strong> Archimedes + Alexandria (OpenGL)</p><p style="margin-top:6px"><strong>Use:</strong> Conformal visualization. Möbius transforms are used in Alexandria to map hyperbolic graph layouts (the Cayley graph index) onto the rendering surface without distorting angular relationships between nodes.</p></div></div>
<div class="section"><div class="section-hdr">Common Mistakes</div><div class="mistake"><div class="m-label">MISTAKE 01</div>Forgetting ad−bc=0 makes it degenerate — the output is constant, not a bijection.</div><div class="mistake"><div class="m-label">MISTAKE 02</div>Treating the pole z=−d/c as an error. It maps to ∞ — a valid point on the Riemann sphere.</div><div class="mistake"><div class="m-label">MISTAKE 03</div>Assuming all conformal maps are Möbius. On ℂ̂ yes, but on subdomains there are many more (Riemann mapping theorem).</div></div>
<div class="section"><div class="section-hdr">Cross-Links</div><div class="crosslinks"><a class="crosslink" href="cauchy_riemann_equation.html">Cauchy-Riemann Equation →</a><a class="crosslink" href="wirtinger_derivative.html">Wirtinger Derivative →</a><a class="crosslink" href="jacobian_form.html">Jacobian Form →</a><a class="crosslink" href="cayley_graph.html">Cayley Graph →</a></div></div>
</main>
<script>
function toggleLevel(hdr){
const body=hdr.nextElementSibling;
const chev=hdr.querySelector('.chevron');
const isOpen=body.classList.contains('open');
body.classList.toggle('open',!isOpen);
chev.classList.toggle('open',!isOpen);
}
</script>
<script>
const canvas=document.getElementById('geo');
const ctx=canvas.getContext('2d');
function resize(){canvas.width=canvas.offsetWidth;canvas.height=canvas.offsetHeight;}
resize();window.addEventListener('resize',resize);
let t=0;
function draw(){
const W=canvas.width,H=canvas.height,cx=W/2,cy=H/2,r=Math.min(W,H)*0.3;
ctx.clearRect(0,0,W,H);
const a=Math.cos(t),b=Math.sin(t),c=-Math.sin(t),d=Math.cos(t);
for(let k=-3;k<=3;k++){
ctx.beginPath();
for(let th=0;th<=Math.PI*2;th+=0.05){
const zr=k*0.6,zi=Math.cos(th)*0.8;
const denom=(c*zr+d)*(c*zr+d)+(c*zi)*(c*zi)||0.001;
const wr=((a*zr+b)*(c*zr+d)+(a*zi)*(c*zi))/denom;
const wi=((a*zi)*(c*zr+d)-(a*zr+b)*(c*zi))/denom;
const px=cx+wr*r*0.5,py=cy-wi*r*0.5;
th===0?ctx.moveTo(px,py):ctx.lineTo(px,py);
}
const cols=['#ff4455','#4488ff','#00ff88','#f0c040','#bb88ff','#00ffcc','#ff8833'];
ctx.strokeStyle=cols[(k+3)%7];ctx.lineWidth=1.2;ctx.globalAlpha=0.7;ctx.stroke();
}
ctx.globalAlpha=1;
ctx.font='9px Share Tech Mono,monospace';ctx.fillStyle='#4a5a6a';
ctx.fillText('w = (az+b)/(cz+d)',10,15);
t+=0.01;requestAnimationFrame(draw);
}
draw();
</script>
</body>
</html>