Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
186 views
ubuntu2404
1
## -*- encoding: utf-8 -*-
2
## This file (main.sagetex.sage) was *autogenerated* from main.tex with sagetex.sty version 2021/10/16 v3.6.
3
import sagetex
4
_st_ = sagetex.SageTeXProcessor('main', version='2021/10/16 v3.6', version_check=True)
5
_st_.current_tex_line = 226
6
_st_.blockbegin()
7
try:
8
# Compute cyclotomic polynomials for n = 1 to 20
9
cyclotomic_data = {}
10
for n in range(1, 21):
11
phi_n = cyclotomic_polynomial(n)
12
degree = phi_n.degree()
13
coeffs = phi_n.coefficients(sparse=False)
14
15
cyclotomic_data[n] = {
16
'polynomial': phi_n,
17
'degree': degree,
18
'coefficients': coeffs,
19
'euler_phi': euler_phi(n)
20
}
21
22
# Display cyclotomic polynomials for small n
23
print("Cyclotomic Polynomials Φ_n(x) for n = 1 to 12:")
24
for n in range(1, 13):
25
phi_n = cyclotomic_data[n]['polynomial']
26
degree = cyclotomic_data[n]['degree']
27
print(f"Φ_{n}(x) = {phi_n}, degree = {degree}")
28
29
# Verify that degree equals Euler's totient function
30
print("\nVerification: deg(Φ_n) = φ(n)")
31
for n in range(1, 13):
32
degree = cyclotomic_data[n]['degree']
33
euler_val = cyclotomic_data[n]['euler_phi']
34
print(f"n = {n}: deg(Φ_{n}) = {degree}, φ({n}) = {euler_val}, Equal: {degree == euler_val}")
35
except:
36
_st_.goboom(254)
37
_st_.blockend()
38
_st_.current_tex_line = 277
39
_st_.blockbegin()
40
try:
41
# Verify the fundamental identity for several values of n
42
print(r"Verification of $x^n - 1 = \prod_{d \mid n} \Phi_d(x)$:")
43
44
for n in [6, 8, 12, 15]:
45
# Left side: x^n - 1
46
left_side = x^n - 1
47
48
# Right side: product of \Phi_d(x) for all d dividing n
49
divisors = [d for d in range(1, n+1) if n % d == 0]
50
right_side = 1
51
for d in divisors:
52
right_side *= cyclotomic_polynomial(d)
53
54
# Verify equality (no need to expand - SageMath polynomials are already expanded)
55
equality = (left_side == right_side)
56
57
print(f"n = {n}: divisors = {divisors}")
58
print(f" x^{n} - 1 = {left_side}")
59
print(f" Product = {right_side}")
60
print(f" Equal: {equality}")
61
62
# Analyze coefficient patterns in cyclotomic polynomials
63
print("\nCoefficient analysis:")
64
for n in [105, 210, 420]: # Cases where coefficients exceed ±1
65
if n <= 20: # Only for computed cases
66
continue
67
phi_n = cyclotomic_polynomial(n)
68
coeffs = phi_n.coefficients(sparse=False)
69
max_coeff = max(abs(c) for c in coeffs)
70
print(f"\\Phi_{n}(x): max |coefficient| = {max_coeff}")
71
except:
72
_st_.goboom(308)
73
_st_.blockend()
74
_st_.current_tex_line = 314
75
_st_.blockbegin()
76
try:
77
# Analysis of roots structure for visualization
78
print("Roots of Unity Analysis:")
79
for n in [6, 8, 12, 16]:
80
all_roots = n
81
primitive_roots = euler_phi(n)
82
print(f"n = {n}: Total {n}-th roots of unity: {all_roots}")
83
print(f" Primitive {n}-th roots of unity: {primitive_roots}")
84
print(f" Cyclotomic polynomial Φ_{n}(x) has degree {primitive_roots}")
85
except:
86
_st_.goboom(323)
87
_st_.blockend()
88
_st_.current_tex_line = 348
89
_st_.blockbegin()
90
try:
91
# Analyze Galois groups for cyclotomic fields
92
print("Galois Groups of Cyclotomic Fields Q(ζ_n)/Q:")
93
94
galois_data = {}
95
for n in range(1, 17):
96
# Units group (Z/nZ)*
97
units_group = Integers(n).unit_group()
98
group_order = units_group.order()
99
group_structure = units_group.invariants()
100
101
# Field degree [Q(ζ_n) : Q] = φ(n)
102
field_degree = euler_phi(n)
103
104
galois_data[n] = {
105
'field_degree': field_degree,
106
'group_order': group_order,
107
'group_structure': group_structure,
108
'units_group': units_group
109
}
110
111
print(f"n = {n:2d}: [Q(ζ_{n}) : Q] = {field_degree:2d}, "
112
f"|Gal| = {group_order:2d}, structure = {group_structure}")
113
114
# Detailed analysis for specific cases
115
print("\nDetailed Galois group analysis:")
116
117
interesting_cases = [8, 12, 15, 16, 20]
118
for n in interesting_cases:
119
if n >= len(galois_data):
120
continue
121
122
units = Integers(n).unit_group()
123
elements = [a for a in range(1, n) if gcd(a, n) == 1]
124
125
print(f"\nn = {n}: Q(ζ_{n})/Q")
126
print(f" Units (Z/{n}Z)* = {{{', '.join(map(str, elements))}}}")
127
print(f" Group structure: {units.invariants()}")
128
print(f" Cyclic: {units.is_cyclic()}")
129
130
# Generator information for cyclic groups
131
if units.is_cyclic():
132
# Find a generator
133
for a in elements:
134
order = Integers(n)(a).multiplicative_order()
135
if order == len(elements):
136
print(f" Generator: {a} (order {order})")
137
break
138
except:
139
_st_.goboom(396)
140
_st_.blockend()
141
_st_.current_tex_line = 408
142
_st_.blockbegin()
143
try:
144
# Analyze ramification patterns
145
print("Ramification Analysis in Cyclotomic Fields:")
146
147
def analyze_ramification(n):
148
"""Analyze ramification of primes in Q(ζ_n)"""
149
print(f"\nQ(ζ_{n})/Q ramification:")
150
151
# Get prime divisors of n
152
n_factorization = factor(n)
153
ramified_primes = [p for p, e in n_factorization]
154
155
print(f" n = {n} = {n_factorization}")
156
print(f" Ramified primes: {ramified_primes}")
157
158
# Analyze each small prime
159
for p in [2, 3, 5, 7, 11]:
160
if p > n:
161
break
162
163
if p not in ramified_primes:
164
# Unramified case - compute splitting behavior
165
if gcd(p, n) == 1:
166
f = Integers(n)(p).multiplicative_order()
167
else:
168
f = "undefined"
169
print(f" p = {p}: unramified, inertia degree f = {f}")
170
else:
171
# Ramified case - find the exponent of p in the factorization
172
ramification_index = 0
173
for prime, exp in n_factorization:
174
if prime == p:
175
ramification_index = exp
176
break
177
totally_ramified = ramification_index == 1
178
print(f" p = {p}: ramified (e = {ramification_index}), "
179
f"totally ramified: {totally_ramified}")
180
181
# Analyze several cyclotomic fields
182
for n in [8, 12, 15, 20, 24]:
183
analyze_ramification(n)
184
except:
185
_st_.goboom(449)
186
_st_.blockend()
187
_st_.current_tex_line = 468
188
_st_.blockbegin()
189
try:
190
import os
191
if not os.path.exists('figures'):
192
os.makedirs('figures')
193
194
# Demonstrate quadratic reciprocity computations
195
print("Quadratic Reciprocity Examples:")
196
197
def legendre_symbol(a, p):
198
"""Compute Legendre symbol (a/p)"""
199
return kronecker_symbol(a, p)
200
201
def verify_reciprocity(p, q):
202
"""Verify quadratic reciprocity for primes p, q"""
203
left_side = legendre_symbol(p, q) * legendre_symbol(q, p)
204
right_side = (-1)**((p-1)//2 * (q-1)//2)
205
return left_side == right_side
206
207
# Test quadratic reciprocity for several prime pairs
208
prime_pairs = [(3, 5), (3, 7), (5, 7), (7, 11), (11, 13), (13, 17)]
209
210
for p, q in prime_pairs:
211
leg_p_q = legendre_symbol(p, q)
212
leg_q_p = legendre_symbol(q, p)
213
product = leg_p_q * leg_q_p
214
expected = (-1)**((p-1)//2 * (q-1)//2)
215
verified = verify_reciprocity(p, q)
216
217
print(f"p = {p}, q = {q}: ({p}/{q}) = {leg_p_q:2d}, ({q}/{p}) = {leg_q_p:2d}")
218
print(f" Product = {product:2d}, Expected = {expected:2d}, Verified: {verified}")
219
220
# Analysis summary for the visualization
221
print("\nQuadratic reciprocity visualization generated showing Legendre symbols.")
222
print("The reciprocity pattern demonstrates the fundamental law:")
223
print("For distinct odd primes p, q: (p/q)(q/p) = (-1)^((p-1)/2 * (q-1)/2)")
224
225
# Additional analysis of specific cases
226
print("\nDetailed reciprocity analysis:")
227
small_primes = [3, 5, 7, 11, 13]
228
for i, p in enumerate(small_primes):
229
for j, q in enumerate(small_primes):
230
if i < j: # Only examine pairs once
231
symbol_pq = legendre_symbol(p, q)
232
symbol_qp = legendre_symbol(q, p)
233
print(f"({p}/{q}) = {symbol_pq:2d}, ({q}/{p}) = {symbol_qp:2d}, Product = {symbol_pq * symbol_qp:2d}")
234
except:
235
_st_.goboom(513)
236
_st_.blockend()
237
_st_.current_tex_line = 524
238
_st_.blockbegin()
239
try:
240
# Investigate cyclotomic class numbers
241
print("Class Numbers of Cyclotomic Fields:")
242
243
def compute_cyclotomic_info(n):
244
"""Compute information about the n-th cyclotomic field"""
245
# For computational feasibility, we focus on small n
246
if n > 20:
247
return None
248
249
field_degree = euler_phi(n)
250
discriminant_factor_count = len([p for p, e in factor(n)])
251
252
return {
253
'n': n,
254
'degree': field_degree,
255
'conductor': n,
256
'discriminant_complexity': discriminant_factor_count
257
}
258
259
# Analyze cyclotomic fields
260
cyclotomic_info = []
261
for n in range(1, 21):
262
info = compute_cyclotomic_info(n)
263
if info:
264
cyclotomic_info.append(info)
265
266
print("Cyclotomic Field Data:")
267
print("n degree conductor discriminant_complexity")
268
print("-" * 45)
269
for info in cyclotomic_info:
270
print(f"{info['n']:2d} {info['degree']:3d} {info['conductor']:3d} {info['discriminant_complexity']:3d}")
271
272
# Focus on specific interesting cases
273
interesting_fields = [7, 8, 9, 12, 15, 16, 20]
274
print(f"\nDetailed analysis for selected cyclotomic fields:")
275
276
for n in interesting_fields:
277
if n <= 20:
278
phi_n = euler_phi(n)
279
units_structure = Integers(n).unit_group().invariants()
280
print(f"Q(ζ_{n}): degree {phi_n}, Gal ≅ {units_structure}")
281
except:
282
_st_.goboom(566)
283
_st_.blockend()
284
_st_.current_tex_line = 576
285
_st_.blockbegin()
286
try:
287
# Analyze computational complexity of cyclotomic polynomial operations
288
print("Computational Complexity Analysis:")
289
290
def time_cyclotomic_computation(n_max):
291
"""Analyze timing for cyclotomic polynomial computations"""
292
import time
293
294
timing_data = []
295
296
for n in range(1, min(n_max + 1, 101)): # Limit for computational feasibility
297
start_time = time.time()
298
299
# Compute cyclotomic polynomial
300
phi_n = cyclotomic_polynomial(n)
301
degree = phi_n.degree()
302
height = max(abs(c) for c in phi_n.coefficients(sparse=False))
303
304
end_time = time.time()
305
computation_time = end_time - start_time
306
307
timing_data.append({
308
'n': int(n),
309
'degree': int(degree),
310
'height': int(height),
311
'time': float(computation_time)
312
})
313
314
if n <= 30 or n % 10 == 0:
315
print(f"n = {n:3d}: degree = {degree:3d}, "
316
f"height = {height:4d}, time = {computation_time:.4f}s")
317
318
return timing_data
319
320
# Perform timing analysis for moderate values
321
print("Timing analysis for cyclotomic polynomial computation:")
322
timing_results = time_cyclotomic_computation(50)
323
324
# Summary analysis of complexity results
325
print("\nComplexity Analysis Summary:")
326
print(f"Analyzed cyclotomic polynomials for n = 1 to {len(timing_results)}")
327
328
n_values = [data['n'] for data in timing_results]
329
degrees = [data['degree'] for data in timing_results]
330
heights = [data['height'] for data in timing_results]
331
times = [data['time'] for data in timing_results]
332
333
print(f"Maximum degree observed: {max(degrees)} (for n = {n_values[degrees.index(max(degrees))]})")
334
print(f"Maximum coefficient height: {max(heights)} (for n = {n_values[heights.index(max(heights))]})")
335
print(f"Total computation time: {sum(times):.4f} seconds")
336
337
# Highlight some interesting cases
338
interesting_n = [12, 15, 20, 24, 30, 40]
339
print("\nComplexity for selected values:")
340
for n in interesting_n:
341
if n <= len(timing_results):
342
idx = n - 1
343
print(f"n = {n:2d}: degree = {degrees[idx]:2d}, height = {heights[idx]:3d}, time = {times[idx]:.4f}s")
344
except:
345
_st_.goboom(634)
346
_st_.blockend()
347
_st_.endofdoc()
348
349