LECTURE NOTES

Math 263x
计算数论与代数几何计算技术

统一术语表

中英术语对照与简释。

类别中文术语英文术语说明
基础与算法位复杂度bit complexity以输入比特数衡量算法成本。
基础与算法多项式时间polynomial time相对于输入长度为多项式的运行时间。
基础与算法有限域finite field元素个数有限的域,常记为 𝐅q\mathbf F_q
基础与算法二次剩余quadratic residue模素数可写成平方的非零剩余类。
基础与算法二次非剩余quadratic nonresidueLegendre 符号为 1-1 的剩余类。
基础与算法lattice欧氏空间中的离散满秩加法子群。
基础与算法格约化lattice reduction寻找较短且较正交的格基;LLL 是核心算法。
基础与算法有理数重构rational reconstruction从模整数或高精度近似恢复小分子、分母。
基础与算法整数关系integer relation寻找 c1x1++cnxn=0c_1x_1+\cdots+c_nx_n=0 的整数系数。
基础与算法代数数识别algebraic number recognition由近似值恢复最小多项式或数域坐标。
基础与算法中国剩余重构Chinese remainder reconstruction由多个模素数结果恢复整数或多项式。
基础与算法中途相遇meet-in-the-middle把双重枚举改写为两个值表的碰撞搜索。
基础与算法批量求逆batch inversion用一次求逆和线性次乘法求多个逆元。
p进方法pp-进数p-adic numberpp-进绝对值完备化得到的数。
p进方法赋值valuation测量元素被素元整除次数的函数。
p进方法Hensel 提升Hensel lifting把模 pp 解提升到模 pkp^k𝐙p\mathbf Z_p 解。
p进方法多元Newton 法multivariate Newton method用 Jacobian 线性化同时修正多个变量。
p进方法Jacobian 矩阵Jacobian matrix偏导数组成的矩阵;与 Jacobian 簇区分。
p进方法简单根simple root导数或 Jacobian 行列式在剩余域中非零的根。
曲线与覆盖代数曲线algebraic curve一维代数簇;本讲义通常默认光滑、射影、几何连通。
曲线与覆盖亏格genus曲线全纯微分空间维数。
曲线与覆盖覆盖cover曲线之间的有限态射;拓扑语境下指覆盖空间。
曲线与覆盖分歧点ramification point源曲线上局部分歧指数大于 1 的点。
曲线与覆盖分支点branch point分歧点在目标曲线上的像。
曲线与覆盖分支集branch locus所有分支点组成的有限集合。
曲线与覆盖非分歧覆盖unramified cover所有分歧指数均为 1 的覆盖。
曲线与覆盖平展覆盖étale cover代数几何中的 étale 覆盖;光滑曲线上与非分歧有限覆盖相应。
曲线与覆盖单值群monodromy group纤维沿环路解析延拓得到的置换群;亦见“单值化群”。
曲线与覆盖置换三元组permutation triple满足乘积为 1 的三个分支置换。
曲线与覆盖循环型cycle type置换循环长度给出的整数分拆。
曲线与覆盖Riemann–Hurwitz公式Riemann–Hurwitz formula连接覆盖次数、亏格与分歧的公式。
曲线与覆盖Riemann 存在定理Riemann existence theorem把拓扑覆盖数据与复代数曲线覆盖对应起来。
Belyi理论Belyi 映射Belyi map只在 0,1,0,1,\infty 上分支的有限映射。
Belyi理论Belyi 定理Belyi theorem曲线可定义在 𝐐¯\overline{\mathbf Q} 上当且仅当存在 Belyi 映射。
Belyi理论Grothendieck dessin d’enfant(童画)dessin d’enfantBelyi 映射对区间 [0,1][0,1] 的逆像;亦见“儿童画”。
Belyi理论Hurwitz 空间Hurwitz space参数化固定分歧数据的覆盖的模空间。
Belyi理论传递置换群transitive permutation group对应连通覆盖的单值群。
Belyi理论本原群primitive group没有非平凡块系统的传递置换群。
Belyi理论Chebyshev 多项式Chebyshev polynomial二面体型三点分支多项式的标准模型。
交换代数结式resultant检测两个多项式公共根的系数多项式。
交换代数Sylvester 矩阵Sylvester matrix其行列式等于两个一元多项式的结式。
交换代数子结式subresultant控制 gcd 次数和参数特殊化的行列式序列。
交换代数消元理论elimination theory从多元方程中消去变量的理论与算法。
交换代数消元理想elimination ideal原理想与较小变量多项式环的交。
交换代数Gröbner 基Gröbner basis多元理想的标准生成系统。
交换代数理想饱和ideal saturation排除指定退化分量的理想运算。
交换代数判别式discriminant检测重根、奇异纤维或分歧的多项式。
交换代数平方自由squarefree没有非单位平方因子的多项式。
交换代数首一多项式monic polynomial最高次项系数为 1 的多项式。
曲线模型除子divisor曲线上点的有限整数线性组合。
曲线模型线性等价linear equivalence两个除子之差是某个有理函数的主除子。
曲线模型典范除子canonical divisor非零有理微分的除子类。
曲线模型典范映射canonical map由全纯微分线性系给出的映射。
曲线模型Riemann–Roch 定理Riemann–Roch theorem计算除子线性系维数的基本定理。
曲线模型超椭圆曲线hyperelliptic curve存在到 𝐏1\mathbf P^1 的 2 次映射的曲线。
曲线模型三角曲线trigonal curve存在到 𝐏1\mathbf P^1 的 3 次映射的曲线。
曲线模型有理正规滚动面rational normal scroll典范三角曲线所在的标准有理曲面。
曲线模型Jacobian 簇Jacobian variety曲线的零次 Picard 簇。
椭圆曲线椭圆曲线elliptic curve带指定基点的光滑亏格 1 曲线。
椭圆曲线挠点torsion point在群律下具有有限阶的点。
椭圆曲线截面section椭圆曲面到基曲线映射的右逆。
椭圆曲线挠截面torsion section在一般纤维的 Mordell–Weil 群中为挠元的截面。
椭圆曲线同源isogeny椭圆曲线之间保持原点的有限态射。
椭圆曲线循环同源cyclic isogeny核为循环群的同源。
椭圆曲线对偶同源dual isogeny与原同源复合为乘法映射的同源。
椭圆曲线Weil 函数Weil function除子为 n(T)n(O)n(T)-n(O) 的函数。
椭圆曲线Tate 标准形Tate normal form带指定非低阶点的归一化 Weierstrass 方程。
椭圆曲线复乘complex multiplication (CM)椭圆曲线具有大于 𝐙\mathbf Z 的自同态环。
椭圆曲线奇异模singular modulusCM 椭圆曲线的 jj-不变量。
反射群复反射群complex reflection group由固定超平面的有限阶线性变换生成的群。
反射群伪反射pseudoreflection复反射的另一常用名称。
反射群不变量环invariant ring群作用下固定的多项式组成的环。
反射群相对不变量relative invariant群作用后只乘一个一维特征的多项式。
反射群协变式covariant等变的多项式映射;经典不变量论常用译名。
反射群Reynolds 算子Reynolds operator对有限群取平均得到的不变量投影。
反射群Hilbert 级数Hilbert series记录分次维数的生成函数。
反射群Molien 公式Molien formula由群元素行列式平均计算不变量 Hilbert 级数。
反射群HessianHessian二阶偏导矩阵的行列式。
反射群Jacobian 行列式Jacobian determinant一组多项式偏导矩阵的行列式。
反射群二元多面体群binary polyhedral group多面体旋转群在 SL2\mathrm{SL}_2 中的逆像。
反射群根系root system满足反射封闭和整性条件的向量集合。
反射群根格root lattice由根系整数生成的格。
反射群权格weight lattice与所有余根整数配对的向量格。
反射群Weyl 群Weyl group由根反射生成的有限反射群。
反射群Coxeter 数Coxeter number不可约根系的基本数值不变量。
反射群triality(三重性)trialityD4D_4 Dynkin 图的 S3S_3 外自同构。
反射群Hurwitz 四元数Hurwitz quaternionHurwitz 整数环中的四元数。
椭圆曲面椭圆曲面elliptic surface一般纤维为亏格 1 曲线并带截面的曲面纤维化。
椭圆曲面有理椭圆曲面rational elliptic surface底层曲面有理的椭圆曲面。
椭圆曲面Kodaira 纤维Kodaira fiber椭圆曲面奇异纤维的分类类型。
椭圆曲面加性纤维additive fiberKodaira 类型 II、III、IV、I* 等的奇异纤维。
椭圆曲面Mordell–Weil 群Mordell–Weil group椭圆曲面截面组成的有限生成群。
椭圆曲面Mordell–Weil 格Mordell–Weil lattice自由部分配备典范高度配对所得的格。
椭圆曲面高度配对height pairing截面之间的正定双线性配对。
椭圆曲面Néron–Severi 群Néron–Severi group除子模代数等价组成的群。
椭圆曲面Shioda–Tate 公式Shioda–Tate formula连接 Picard 数、纤维根格与 Mordell–Weil 秩。
椭圆曲面Shioda excellent familyexcellent familyShioda 专名;保留英文以避免把一般形容词误作固定术语。
椭圆曲面酉反射群unitary reflection group复 Hermitian 空间中的有限复反射群。
模曲线模曲线modular curve参数化带级结构椭圆曲线的代数曲线。
模曲线级结构level structure挠点基、指定挠点或循环子群等附加数据。
模曲线尖点cusp模曲线紧化时加入的退化椭圆曲线点。
模曲线椭圆点elliptic point上半平面中具有非平凡稳定子的点。
模曲线模形式modular form满足模变换律并在尖点全纯的函数。
模曲线尖点形式cusp form在所有尖点消失的模形式。
模曲线qq-展开q-expansionq=e2πiτq=e^{2\pi i\tau} 为变量的 Fourier 展开。
模曲线Dedekind η\eta 函数Dedekind eta functionq1/24n1(1qn)q^{1/24}\prod_{n\ge1}(1-q^n)
模曲线Hauptmodul(主模函数)Hauptmodul亏格 0 模曲线的归一化有理参数。
模曲线Fricke 对合Fricke involutionτ1/(Nτ)\tau\mapsto-1/(N\tau) 对应对偶同源。
模曲线Atkin–Lehner 对合Atkin–Lehner involution由级数的整除因子定义的模曲线对合。
模曲线正规化子normalizer满足 A1GA=GA^{-1}GA=G 的元素组成的群。
模曲线Sturm 界Sturm bound由有限个 Fourier 系数判定模形式恒等的界。
模曲线模方程modular equation联系同源椭圆曲线模参数的代数方程。

正文

讲次按课程次序排列;可由左侧目录直接跳转。

Lecture 1 / 第 1 讲

计算数论的方法论:两平方定理与复杂度

从Fermat 两平方定理出发,说明存在性证明、格约化、位复杂度和最终精确验证之间的关系。

两平方定理复杂度格约化

1. 计算问题的尺度

本课程不是把“理论”与“计算”对立起来,而是研究怎样把一个存在性证明改造成可执行、可验证并具有复杂度控制的算法。输入一个整数 pp 时,输入长度是 logp\log p,所以遍历到 p\sqrt p 的算法对输入长度而言是指数时间。

定理Fermat 两平方定理

pp 为奇素数。则 p=x2+y2p=x^2+y^2 有整数解,当且仅当 p1(mod4)p\equiv1\pmod4。解在交换 x,yx,y 以及改变符号的意义下唯一。

证明Gaussian 整数证明

在Euclidean 整环 𝐙[i]\mathbf Z[i] 中,范数为 N(a+bi)=a2+b2N(a+bi)=a^2+b^2。若 p=x2+y2p=x^2+y^2,则 1(xy1)2(modp)-1\equiv (xy^{-1})^2\pmod p,故 1-1 是模 pp 的平方,即 p1(mod4)p\equiv1\pmod4。反之,若 p1(mod4)p\equiv1\pmod4,存在 r21(modp)r^2\equiv-1\pmod p,于是 p(r+i)(ri)p\mid(r+i)(r-i),但 pp𝐙[i]\mathbf Z[i] 中不再是素元。唯一分解给出 p=(x+iy)(xiy)=x2+y2p=(x+iy)(x-iy)=x^2+y^2。唯一性来自 𝐙[i]\mathbf Z[i] 的唯一分解,单位只有 {±1,±i}\{\pm1,\pm i\}

2. 从证明到算法

证明真正给出的计算接口是:先求一个模 pp1-1 的平方根,再把同余关系转化为二维格中的短向量。二维格约化等价于Euclidean 算法,因此整体成本只需要多项式数量级的位运算。

课程中的大素数

原讲义取 p=1037πp=\lfloor10^{37}\pi\rfloor,计算得到

p=42235624485179944052+36847587138599206042.p=4223562448517994405^2+3684758713859920604^2.

这个例子强调:先选 x,yx,y 再构造 pp 会掩盖算法困难;先给定素数再恢复表示才是实际问题。

3. 线性时间与二次时间

对部分和 sn=k=1naks_n=\sum_{k=1}^n a_k,若每次重新求和,工作量为 1+2++N=Θ(N2)1+2+\cdots+N=\Theta(N^2);维护累加器只需 Θ(N)\Theta(N)。在数论计算中,同样的差别常出现在重复求 gcd、重复展开级数以及没有缓存的模运算中。

算法部分和的正确实现
s = 0
for n in range(1, N+1):
    s += a[n]
    plot(n, s)
补充复杂度记号与可验证计算

本讲义统一使用位复杂度而非“算术操作次数”。当整数有 BB 位时,一次乘法的成本记为 M(B)M(B)。任何数值猜测都必须在最后回到精确算术:代入恒等式、检查最小多项式、验证分歧型或核对群作用。

从存在性到可执行算法

课程首先说明其总体目标与精神:所关心的并不只是某个数学对象“存在”,而是如何把存在性证明改写成能够实际执行、能够估计复杂度、并且最终能够用精确算术核验的计算过程。为了在不依赖后续大量背景知识的情形下展示这种思想,原讲义选择了Fermat著名的两平方定理作为第一个例子。

两平方定理断言:素数 pp 能写成两个不同整数平方之和,当且仅当 p1(mod4)p\equiv1\pmod4;这种表示除交换两个平方项以及改变符号外是唯一的。原讲义取

p=1037π=31415926535897932384626433832795028841,p=\lfloor10^{37}\pi\rfloor =31415926535897932384626433832795028841,

于是定理保证丢番图方程 p=x2+y2p=x^2+y^2 有本质唯一的解。真正的计算问题是:怎样把这组 x,yx,y 找出来?逐一试验所有 x<px<\sqrt p 的做法虽然在形式上会在有限时间内终止,但这个“有限”远远不够小;即使计算机速度提高,也可以随时把输入的位数加倍,使这种穷举继续失效。

一个经典证明几乎直接产生高效算法。Cornacchia 在 1908 年提出的思想是:若 p=x2+y2p=x^2+y^2,则 x/yx/y 在模 pp 意义下是 1-1 的平方根;反过来,给定 r21(modp)r^2\equiv-1\pmod p,可以借助二维格约化恢复 x,yx,y。二维格约化本质上就是Euclidean 算法,因此所需时间可控制在 logcp\ll\log^c p。这里“多项式时间”的变量不是 pp 本身,而是描述 pp 所需的位数,约为 logp\log p

原讲义指出,PARI/GP 等软件已经实现了所需的模平方根与 LLL 约化。Victor Miller 在 1992 年给出的一行程序,经改写为较新的 GP 语法后可写成:

代码PARI/GP 实现
fermat(p)=qflll([lift(sqrt(Mod(-1,p))),p;1,0])[1,]

对上述大素数调用该程序,几乎瞬间返回

(x,y)=(4223562448517994405,3684758713859920604).(x,y)=(4223562448517994405,\,-3684758713859920604).

直接平方并相加即可精确验证结果。原讲义特别解释,选择 π\pi 的前若干位并没有数论上的特殊意义;这样选只是为了避免先挑好 x,yx,y 再反向构造 pp 的“作弊”。这个规模的素数足够密集,找到例子并不困难。至于如何知道该整数确实是素数,原讲义说明:对这种位数,整数分解与素性证明早已成为常规工具;有限域或数域上的多项式分解也同样非平凡但已经标准化。尤其值得注意的是,LLL 算法最初的重要应用之一,正是证明 𝐐[X]\mathbf Q[X] 中多项式分解可在多项式时间内完成。

“几乎”高效的原因:模平方根

上面的论证为何只说“几乎”得到高效算法?因为还必须求出模 pp1-1 的平方根。计算Legendre 符号很容易,它能判断一个非零元素是否为平方;然而在不作额外假设时,一般并不知道如何确定性地在多项式时间内从“它是平方”构造平方根。若假设与模 pp Legendre特征相关的广义 Riemann 假设,则可得到确定性多项式时间算法;无条件情形下则有随机多项式时间算法。寻找一个二次非剩余已经足够,而且“找二次非剩余”与“求平方根”在多项式时间归约意义下彼此等价。

原讲义随后给出一个看似迂回但理论上重要的事实:对固定的小整数,模 pp 平方根可借助椭圆曲线算术在确定性多项式时间内求出,尽管这种方法并不实用。Schoof 在 1985 年关于有限域椭圆曲线点数计算的论文中,把这一点作为算法的应用之一。对本例,考虑具有复乘的椭圆曲线

E:Y2=X3X.E:\;Y^2=X^3-X.

它的复乘环含有 1\sqrt{-1}。当 p=x2+y2p=x^2+y^2 时,点数具有 p+1±2xp+1\pm2xp+1±2yp+1\pm2y 的形式;因此确定性地计算 #E(𝐅p)\#E(\mathbf F_p) 后,便能恢复两平方表示。

一个基础但关键的复杂度插曲

原讲义提醒:即便极为常规的计算也可能隐藏不必要的低效率。设要画出实数列 a1,,aNa_1,\ldots,a_N 的部分和

sn=k=1naks_n=\sum_{k=1}^{n}a_k

对应的 NN 个点 (n,sn)(n,s_n)。若在每个 nn 处重新计算一次 k=1nak\sum_{k=1}^n a_k,总工作量约为 N2/2N^2/2;维护一个累加变量只需约 NN 次操作。低于线性时间通常不可能,因为仅仅读取或生成全部 aka_k 就需要 Θ(N)\Theta(N) 时间。原讲义说,这个错误虽看似不应出现在研究生课程中,却确实来自一位知名计算数论学者的伪代码;因此任何人都可能在“显而易见”的地方犯复杂度错误。

课程的第一个主任务:显式曲线覆盖

接下来若干周的推动问题,是计算具有给定分歧的曲线覆盖。设 f:XXf:X'\to X 是紧Riemann 曲面之间次数 n>1n>1 的映射,BXB\subset X 是有限的分支点集。给定 (X,B,n)(X,B,n),可能的 (X,f)(X',f) 只有有限多个;拓扑上它们对应于 π1(XB)\pi_1(X-B) 的指数 nn 子群。紧Riemann 曲面又等价于复数域上的光滑射影代数曲线,所以问题可以改述为:给定曲线 XX、有限点集 BB 与整数 nn,构造全部曲线 XX' 及其到 XX 的映射。

(X,B)(X,B) 定义在 F𝐂F\subset\mathbf C 上,则每个覆盖在某个有限扩张 F/FF'/F 上定义。许多数论和代数几何中的计算问题,都能编码成从 X,BX,B 以及可能的组合数据——例如 Gal(X/X)\operatorname{Gal}(X'/X)——恢复 (X,f)(X',f) 的问题。即使 X=𝐏1X=\mathbf P^1、分支点数与次数都不大,这也已经相当困难。由基本群子群得到覆盖的拓扑构造,本质上依赖Riemann 存在定理,因而具有“超越性”:它能给出例如定义域次数的上界,却不会自动给出代数方程。把这种拓扑存在性转化为显式方程,正是课程最初的一系列目标。

补充:两平方定理的多种证明与算法化差异

两平方定理有多种证明,而它们提供的算法信息并不相同。Wilson 定理与二项式系数证明可以说明 1-1 是模 pp 的平方,却不会直接给出较小的整数 x,yx,y。几何数论证明考察格 L=(p,0),(r,1)L=\langle(p,0),(r,1)\rangle,用 Minkowski 定理保证存在非零向量 (x,y)(x,y) 满足 x2+y2<2px^2+y^2<2p;同余条件使 px2+y2p\mid x^2+y^2,因而只能等于 pp。这条证明已经非常接近算法,因为“找短向量”可由约化实现。

Gaussian 整数证明则揭示唯一性。若 p1(mod4)p\equiv1\pmod4,多项式 X2+1X^2+1𝐅p\mathbf F_p 中分裂,故理想 (p,r+i)𝐙[i](p,r+i)\subset\mathbf Z[i] 的范数为 pp。在Euclidean 整环中求其生成元 π=x+iy\pi=x+iy,得到 p=ππp=\pi\bar\pi。若还有 p=u2+v2p=u^2+v^2,则 u+ivu+ivπ\pi 只差单位与共轭,从而表示唯一。实现时可直接在 𝐙[i]\mathbf Z[i] 做 gcd;Cornacchia 只是把同一运算压缩到普通整数Euclidean 算法。

输入长度与位复杂度

ppB=log2pB=\lceil\log_2p\rceil 位。试除所有 xpx\le\sqrt p 需要约 2B/22^{B/2} 次循环,是指数时间。Euclidean 算法只需 O(B)O(B) 次除法;若 M(B)M(B)BB 位整数乘法成本,则快速 gcd 可在 O(M(B)logB)O(M(B)\log B) 位操作内完成。Tonelli–Shanks 的主要成本是 O(logp)O(\log p) 次模乘与幂运算。因而整个两平方恢复在随机多项式时间内完成。

复杂度分析还应区分“算出一个答案”与“证明输入条件”。若 pp 未知是否为素数,先运行确定性 AKS 在理论上可行,但实践中通常用 Baillie–PSW 筛查加 ECPP 或 APR-CL 生成可验证素性证书。若输入是合数且仍满足 p1(mod4)p\equiv1\pmod4,模平方根和格约化可能产生候选,但两平方表示的存在与唯一性不再由素数定理保证。

可复现实验

复现实验时应输出:输入整数、素性证书摘要、所用平方根 rr、Euclidean 余数序列、首次低于 p\sqrt p 的余数、最终整数平方检验,以及 x2+y2px^2+y^2-p 的精确值。这样结果不依赖软件黑箱。对巨大整数,可另外给出十六进制或哈希,避免复制过程中的数字错误。

存在性证明的算法设计原则

本例体现四条贯穿全课程的原则。第一,找出证明中真正需要构造的中间对象,这里是模平方根。第二,把代数条件编码成一个具有几何意义的格或簇。第三,选择适合维数和系数规模的约化或提升算法。第四,数值阶段结束后回到精确恒等式。后续的 Belyi 映射、代数数恢复与模曲线公式都遵循同一模板。

进一步:表示数、素数分解与算法边界

两平方恒等式不仅证明可表示数对乘法封闭,还给出组合表示的算法。若已知 n=piein=\prod p_i^{e_i} 的素因子分解,则Fermat 两平方定理断言:nn 可写为两平方和,当且仅当每个 p3(mod4)p\equiv3\pmod4 的指数为偶数。对 p1(mod4)p\equiv1\pmod4 的素因子先求一组表示,再用 Brahmagupta–Fibonacci 恒等式合成;p3(mod4)p\equiv3\pmod4 的偶次幂只贡献实整数因子。

表示数的精确个数满足

r2(n)=4dnχ4(d)=4(d1(n)d3(n)),r_2(n)=4\sum_{d\mid n}\chi_4(d)=4(d_1(n)-d_3(n)),

其中按有序、有符号整数对计数,d1,d3d_1,d_3 分别统计模 4 同余于 1、3 的约数。这个公式来自 𝐙[i]\mathbf Z[i] 中的唯一分解,也可由 theta 级数比较证明。它提醒我们:“找出一个表示”和“枚举全部表示”是不同复杂度问题。

Fermat 大数的例子中,首先观察指数结构和已知因子远比盲目试除重要。若目标只是证明合数,一个非平凡因子即可;若要写成两平方和,则还需掌握所有模 3 素因子的奇偶性。现代整数分解通常分阶段使用试除、Pollard rho、ECM、二次筛和数域筛。算法选择由待找因子大小而非整数总位数单独决定。

复杂度陈述应明确输入模型。整数 NN 的输入长度是 logN\log N,所以 O(N)O(\sqrt N) 的试除对数输入是指数时间;而多项式于 logN\log N 的算法才是位复杂度意义下的多项式时间。算术操作次数还要乘上大整数乘法成本 M(n)M(n)。忽略位长会把许多表面上“线性”的循环误判为高效算法。

完成计算后可独立验证:检查 a2+b2=Na^2+b^2=N 的精确整数等式;对每个宣称的素因子做确定性或有证书的素性证明;核对因子乘积;若表示由Gaussian 整数相乘得到,检查共轭选择仅改变符号与次序而不改变范数。

练习与解答两平方与位复杂度

练习 1。证明若 n=a2+b2n=a^2+b^2 且素数 q3(mod4)q\equiv3\pmod4 整除 nn,则 qa,bq\mid a,b

解。qbq\nmid b,则 (ab1)21(modq)(ab^{-1})^2\equiv-1\pmod q,与 (1/q)=1(-1/q)=-1 矛盾;故 qbq\mid b,同理 qaq\mid a。因此这类素数在范数中只能出现偶指数。

练习 2。由Gaussian 整数唯一分解推导素数 p1(mod4)p\equiv1\pmod4 的表示在符号与交换外唯一。

解。𝐙[i]\mathbf Z[i]p=ππp=\pi\bar\pi。任何 p=a2+b2p=a^2+b^2 给出因子 a+bia+bi,只能与 π\piπ\bar\pi 相伴;单位 {±1,±i}\{\pm1,\pm i\} 正对应符号与交换。

练习 3。若试除到 N\sqrt N,以输入位数 L=log2NL=\lceil\log_2N\rceil 表示操作次数。

解。候选约为 2L/22^{L/2},故对位长是指数复杂度。每次余数运算还需要大整数成本,所以不能称为多项式时间。

深入补充:一般整数的两平方表示数与完整算法

Fermat定理只回答素数何时可写成两个平方;对合数,分解型同时控制存在性、表示数与算法结构。记 r2(n)r_2(n) 为有序带符号解 (x,y)𝐙2(x,y)\in\mathbf Z^2 满足 x2+y2=nx^2+y^2=n 的个数,并令 d1(n),d3(n)d_1(n),d_3(n) 分别表示 nn 的正因子中模 44 同余于 1,31,3 的个数。

定理 两平方表示数公式

对任意正整数 nn,有

r2(n)=4(d1(n)d3(n)).r_2(n)=4\bigl(d_1(n)-d_3(n)\bigr).

等价地,若

n=2aipiαijqjβj,pi1(mod4),qj3(mod4),n=2^a\prod_i p_i^{\alpha_i}\prod_j q_j^{\beta_j},\qquad p_i\equiv1\pmod4,\quad q_j\equiv3\pmod4,

则当且仅当所有 βj\beta_j 都为偶数时 nn 可表示为两个平方;在此情形

r2(n)=4i(αi+1).r_2(n)=4\prod_i(\alpha_i+1).

证明可直接在Gaussian 整数环中完成。素数 p1(mod4)p\equiv1\pmod4 分裂为 p=ππp=\pi\bar\pi,每个指数 α\alpha 可在 π\piπ\bar\pi 之间以 α+1\alpha+1 种方式分配;素数 q3(mod4)q\equiv3\pmod4𝐙[i]\mathbf Z[i] 中仍不可约,若其指数为奇数便不可能成为范数。单位 {±1,±i}\{\pm1,\pm i\} 给出最后的因子 44。这个论证不仅给出存在性,还给出枚举全部表示的乘法结构。

计算 325325 的全部表示数

325=5213325=5^2\cdot13,故

r2(325)=4(2+1)(1+1)=24.r_2(325)=4(2+1)(1+1)=24.

除去交换与符号,正整数表示恰有三组:

325=12+182=62+172=102+152.325=1^2+18^2=6^2+17^2=10^2+15^2.

三组各自产生八个有序带符号解,合计 2424 个;这里不存在坐标为零或两坐标相等所造成的轨道缩短。

算法 由素因数分解构造全部表示

先检查每个 q3(mod4)q\equiv3\pmod4 的指数是否为偶数。对每个 p1(mod4)p\equiv1\pmod4,用模平方根加 Cornacchia 算法求一个Gauss素因子 π=x+iy\pi=x+iy。随后在

n=2ai(πiπi)αijqj2γjn=2^a\prod_i(\pi_i\bar\pi_i)^{\alpha_i}\prod_jq_j^{2\gamma_j}

中枚举每个 πi\pi_i 的指数分配,乘出Gaussian 整数 zz,再取 (z,z)(\Re z,\Im z)。为避免重复,可规定第一非零坐标为正且 0yx0\le y\le x,最后按需要恢复完整轨道。

这个算法揭示了一个重要的复杂度边界:给定素因数分解后,判定与构造都可在输入长度和输出规模的多项式时间内完成;若只给出一般整数 nn,最困难的步骤通常不是 Cornacchia,而是分解 nn。因此“两平方问题是容易的”必须说明输入模型:对素数输入可直接做模平方根,对已分解整数也容易,而对未分解合数,算法成本与整数分解紧密相连。

还可用 theta 级数把公式编码为生成函数。Jacobi 恒等式给出

(m𝐙qm2)2=1+4n1(dnχ4(d))qn,\left(\sum_{m\in\mathbf Z}q^{m^2}\right)^2 =1+4\sum_{n\ge1}\left(\sum_{d\mid n}\chi_4(d)\right)q^n,

其中 χ4(d)=0,1,1\chi_4(d)=0,1,-1 分别对应 dd 为偶数、d1(mod4)d\equiv1\pmod4d3(mod4)d\equiv3\pmod4。比较 qnq^n 系数便再次得到 r2(n)=4dnχ4(d)r_2(n)=4\sum_{d\mid n}\chi_4(d)。这说明格点计数、模形式与Gaussian 整数分解在同一公式中汇合。

补充计算:Jacobi 表示数公式、Gaussian 乘法与全整数证书

定理 两平方表示数的乘法公式

设 \(r_2(n)=\#\{(x,y)\in\mathbf Z^2:x^2+y^2=n\}\),其中次序与符号均计入。记 \(χ_4\) 为模 4 的非主特征,则 r2(n)=4dnχ4(d)=4(d1(n)d3(n)). r_2(n)=4\sum_{d\mid n}\chi_4(d)=4(d_1(n)-d_3(n)). 等价地,若 \(n=2^a∏p_i^{α_i}∏q_j^{β_j}\),其中 \(p_i≡1 (mod 4)\),\(q_j≡3 (mod 4)\),则某个 \(β_j\) 为奇数时 \(r_2(n)=0\);否则 r2(n)=4i(αi+1). r_2(n)=4\prod_i(α_i+1).

证明 由Gaussian 整数的单位与共轭分解计数

在 \(Z[i]\) 中,2 与 1+i 伴随;每个 \(p≡1 (mod 4)\) 分裂为 \(π\bar π\);每个 \(q≡3 (mod 4)\) 仍为Gaussian 素数。若 q 在 n 中的指数为奇数,则任一范数为 n 的Gaussian 整数都要求 q 的指数在元素与共轭中各占一半,矛盾。故可表示性等价于所有 \(β_j\) 偶。

设所有 \(β_j\) 偶。范数为 n 的元素可写成单位 u、固定实因子 \(∏q_j^{β_j/2}\)、\((1+i)^a\),以及对每个 \(p_i\) 在 \(π_i\) 与 \(\bar π_i\) 之间分配 \(α_i\) 个指数的乘积。第 i 个分裂素数有 \(α_i+1\) 种分配,四个单位给出四倍;共轭与交换坐标已包含在单位和指数分配中。因此得到 \(4∏(α_i+1)\)。

另一方面,Dirichlet 卷积恒等式 \(1*χ_4\) 的素数幂值分别为 1、k+1、以及 k 为偶数时 1、奇数时 0,与上式逐素数一致,故 \(r_2=4(1*χ_4)\)。

Python 分解、构造、枚举与计数的统一核验程序
from collections import Counter
from math import isqrt

def factorint(n: int) -> Counter:
    """Trial division with wheel 2,3,6k±1; sufficient for certificates."""
    if n < 1:
        raise ValueError("n must be positive")
    factors = Counter()
    for p in (2, 3):
        while n % p == 0:
            factors[p] += 1
            n //= p
    f, step = 5, 2
    while f * f <= n:
        while n % f == 0:
            factors[f] += 1
            n //= f
        f += step
        step = 6 - step
    if n > 1:
        factors[n] += 1
    return factors

def divisors_from_factorization(factors: Counter) -> list[int]:
    divisors = [1]
    for p, e in sorted(factors.items()):
        old = divisors[:]
        divisors = []
        power = 1
        for _ in range(e + 1):
            divisors.extend(d * power for d in old)
            power *= p
    return sorted(divisors)

def r2_formula(n: int) -> int:
    """Number of ordered signed representations n=x^2+y^2."""
    d1 = d3 = 0
    for d in divisors_from_factorization(factorint(n)):
        if d % 4 == 1:
            d1 += 1
        elif d % 4 == 3:
            d3 += 1
    return 4 * (d1 - d3)

def gaussian_mul(z: tuple[int, int],
                 w: tuple[int, int]) -> tuple[int, int]:
    a, b = z
    c, d = w
    return a*c - b*d, a*d + b*c

def gaussian_pow(z: tuple[int, int], e: int) -> tuple[int, int]:
    out = (1, 0)
    while e:
        if e & 1:
            out = gaussian_mul(out, z)
        z = gaussian_mul(z, z)
        e >>= 1
    return out

def prime_sum_two_squares_brutal(p: int) -> tuple[int, int]:
    """Small-prime base case used only to build exact certificates."""
    for x in range(isqrt(p), -1, -1):
        y2 = p - x*x
        y = isqrt(y2)
        if y*y == y2:
            return x, y
    raise ValueError(f"{p} has no representation")

def one_representation(n: int) -> tuple[int, int] | None:
    """
    Construct one representation using Gaussian multiplication.
    A prime q≡3 mod 4 must occur to even exponent.
    """
    factors = factorint(n)
    z = (1, 0)
    scalar = 1
    for p, e in sorted(factors.items()):
        if p == 2:
            z = gaussian_mul(z, gaussian_pow((1, 1), e))
        elif p % 4 == 1:
            base = prime_sum_two_squares_brutal(p)
            z = gaussian_mul(z, gaussian_pow(base, e))
        else:
            if e & 1:
                return None
            scalar *= p ** (e // 2)
    return abs(z[0] * scalar), abs(z[1] * scalar)

def enumerate_representations(n: int) -> set[tuple[int, int]]:
    result = set()
    bound = isqrt(n)
    for x in range(-bound, bound + 1):
        y2 = n - x*x
        if y2 < 0:
            continue
        y = isqrt(y2)
        if y*y == y2:
            result.add((x, y))
            result.add((x, -y))
    return result

def certificate(n: int) -> dict:
    factors = factorint(n)
    candidate = one_representation(n)
    enum = enumerate_representations(n)
    return {
        "n": n,
        "factorization": dict(factors),
        "formula": r2_formula(n),
        "enumerated": len(enum),
        "candidate": candidate,
        "candidate_ok": candidate is None or
                        candidate[0]**2 + candidate[1]**2 == n,
        "count_ok": r2_formula(n) == len(enum),
    }

samples = [5, 13, 25, 65, 85, 125, 221, 325, 1105, 1885]
for n in samples:
    c = certificate(n)
    print(
        f"n={n:4d} factors={str(c['factorization']):18s} "
        f"r2={c['formula']:2d} rep={str(c['candidate']):10s} "
        f"count_ok={c['count_ok']}"
    )

print("\nfirst failures of representability below 80:")
bad = [n for n in range(1, 80) if one_representation(n) is None]
print(bad)

print("\nidentity checks:")
for a, b in [(5, 13), (13, 17), (25, 29), (65, 73)]:
    z = one_representation(a)
    w = one_representation(b)
    zw = gaussian_mul(z, w)
    print(f"{a}*{b}={a*b}: {z}·{w}={zw}, norm={zw[0]**2+zw[1]**2}")

print("\nJacobi-count and constructive-certificate table, 1 <= n <= 30:")
for n in range(1,31):
    fac=factorint(n)
    rep=one_representation(n)
    r2=r2_formula(n)
    enum_count=len(enumerate_representations(n))
    fac_text="*".join(f"{p}^{e}" if e>1 else str(p)
                      for p,e in sorted(fac.items()))
    if rep is None:
        rep_text="--"
        check=(r2==0 and enum_count==0)
    else:
        rep_text=f"{rep[0]}^2+{rep[1]}^2"
        check=(rep[0]**2+rep[1]**2==n and r2==enum_count)
    print(f"  n={n:3d} factor={fac_text:17s} r2={r2:3d} "
          f"enumerated={enum_count:3d} certificate={rep_text:13s} exact={check}")
运行结果 样本分解、表示数与范数恒等式
n=   5 factors={5: 1}             r2= 8 rep=(2, 1)     count_ok=True
n=  13 factors={13: 1}            r2= 8 rep=(3, 2)     count_ok=True
n=  25 factors={5: 2}             r2=12 rep=(3, 4)     count_ok=True
n=  65 factors={5: 1, 13: 1}      r2=16 rep=(4, 7)     count_ok=True
n=  85 factors={5: 1, 17: 1}      r2=16 rep=(7, 6)     count_ok=True
n= 125 factors={5: 3}             r2=16 rep=(2, 11)    count_ok=True
n= 221 factors={13: 1, 17: 1}     r2=16 rep=(10, 11)   count_ok=True
n= 325 factors={5: 2, 13: 1}      r2=24 rep=(1, 18)    count_ok=True
n=1105 factors={5: 1, 13: 1, 17: 1} r2=32 rep=(9, 32)    count_ok=True
n=1885 factors={5: 1, 13: 1, 29: 1} r2=32 rep=(6, 43)    count_ok=True

first failures of representability below 80:
[3, 6, 7, 11, 12, 14, 15, 19, 21, 22, 23, 24, 27, 28, 30, 31, 33, 35, 38, 39, 42, 43, 44, 46, 47, 48, 51, 54, 55, 56, 57, 59, 60, 62, 63, 66, 67, 69, 70, 71, 75, 76, 77, 78, 79]

identity checks:
5*13=65: (2, 1)·(3, 2)=(4, 7), norm=65
13*17=221: (3, 2)·(4, 1)=(10, 11), norm=221
25*29=725: (3, 4)·(5, 2)=(7, 26), norm=725
65*73=4745: (4, 7)·(8, 3)=(11, 68), norm=4745

Jacobi-count and constructive-certificate table, 1 <= n <= 30:
  n=  1 factor=                  r2=  4 enumerated=  4 certificate=1^2+0^2       exact=True
  n=  2 factor=2                 r2=  4 enumerated=  4 certificate=1^2+1^2       exact=True
  n=  3 factor=3                 r2=  0 enumerated=  0 certificate=--            exact=True
  n=  4 factor=2^2               r2=  4 enumerated=  4 certificate=0^2+2^2       exact=True
  n=  5 factor=5                 r2=  8 enumerated=  8 certificate=2^2+1^2       exact=True
  n=  6 factor=2*3               r2=  0 enumerated=  0 certificate=--            exact=True
  n=  7 factor=7                 r2=  0 enumerated=  0 certificate=--            exact=True
  n=  8 factor=2^3               r2=  4 enumerated=  4 certificate=2^2+2^2       exact=True
  n=  9 factor=3^2               r2=  4 enumerated=  4 certificate=3^2+0^2       exact=True
  n= 10 factor=2*5               r2=  8 enumerated=  8 certificate=1^2+3^2       exact=True
  n= 11 factor=11                r2=  0 enumerated=  0 certificate=--            exact=True
  n= 12 factor=2^2*3             r2=  0 enumerated=  0 certificate=--            exact=True
  n= 13 factor=13                r2=  8 enumerated=  8 certificate=3^2+2^2       exact=True
  n= 14 factor=2*7               r2=  0 enumerated=  0 certificate=--            exact=True
  n= 15 factor=3*5               r2=  0 enumerated=  0 certificate=--            exact=True
  n= 16 factor=2^4               r2=  4 enumerated=  4 certificate=4^2+0^2       exact=True
  n= 17 factor=17                r2=  8 enumerated=  8 certificate=4^2+1^2       exact=True
  n= 18 factor=2*3^2             r2=  4 enumerated=  4 certificate=3^2+3^2       exact=True
  n= 19 factor=19                r2=  0 enumerated=  0 certificate=--            exact=True
  n= 20 factor=2^2*5             r2=  8 enumerated=  8 certificate=2^2+4^2       exact=True
  n= 21 factor=3*7               r2=  0 enumerated=  0 certificate=--            exact=True
  n= 22 factor=2*11              r2=  0 enumerated=  0 certificate=--            exact=True
  n= 23 factor=23                r2=  0 enumerated=  0 certificate=--            exact=True
  n= 24 factor=2^3*3             r2=  0 enumerated=  0 certificate=--            exact=True
  n= 25 factor=5^2               r2= 12 enumerated= 12 certificate=3^2+4^2       exact=True
  n= 26 factor=2*13              r2=  8 enumerated=  8 certificate=1^2+5^2       exact=True
  n= 27 factor=3^3               r2=  0 enumerated=  0 certificate=--            exact=True
  n= 28 factor=2^2*7             r2=  0 enumerated=  0 certificate=--            exact=True
  n= 29 factor=29                r2=  8 enumerated=  8 certificate=5^2+2^2       exact=True
  n= 30 factor=2*3*5             r2=  0 enumerated=  0 certificate=--            exact=True
计算 局部因子与 Dirichlet 级数

对 Re(s)>1, n1r2(n)ns=4ζ(s)L(s,χ4). \sum_{n\ge1}\frac{r_2(n)}{n^s}=4\zeta(s)L(s,\chi_4). 素数 p≡1 (mod 4) 的 Euler 因子为 4 的全局常数之外的 (1-p^{-s})^{-2};素数 q≡3 (mod 4) 的因子为 (1-q^{-2s})^{-1};素数 2 的因子为 (1-2^{-s})^{-1}。对 n=1105=5·13·17,有 r_2(n)=4·2^3=32;程序枚举得到 32 个有序带符号解。

Lecture 2 / 第 2 讲

有限域平方根、Cornacchia 算法与二维格约化

把模平方根、Euclidean 算法和二维格统一起来,并说明随机算法与确定性算法的差异。

CornacchiaTonelli–Shanks有限域

1. Cornacchia 算法

算法r21(modp)r^2\equiv-1\pmod p 恢复 p=x2+y2p=x^2+y^2
  1. 任选一个根 r(0,p)r\in(0,p),令 r0=p,r1=rr_0=p,r_1=r
  2. 执行Euclidean 算法 rk1=qkrk+rk+1r_{k-1}=q_kr_k+r_{k+1},直到首次出现 rk<pr_k<\sqrt p
  3. x=rkx=r_k,计算 y2=px2y^2=p-x^2。若它是平方,输出 (x,y)(x,y);否则换用另一个平方根 prp-r
定理Cornacchia 正确性(两平方情形)

p1(mod4)p\equiv1\pmod4r21(modp)r^2\equiv-1\pmod p,则上述算法能恢复唯一的两平方表示。

证明格解释

考虑格 Λ=(p,0),(r,1)𝐙2\Lambda=\langle(p,0),(r,1)\rangle\subset\mathbf Z^2。因为 r2+10(modp)r^2+1\equiv0\pmod p,真实向量 (x,±y)(x,\pm y) 属于 Λ\Lambda,且长度为 p\sqrt p。二维 Gauss 约化(等价于Euclidean 算法)会找到长度不超过 p\sqrt p 的约化向量;两平方表示的唯一性排除了错误候选。

2. 模平方根

对奇素数 pp,Euler 判据为 a(p1)/2(ap)(modp)a^{(p-1)/2}\equiv\left(\frac ap\right)\pmod p。当 p3(mod4)p\equiv3\pmod4 时,平方根可直接写成 a(p+1)/4a^{(p+1)/4}。一般情形可用 Tonelli–Shanks 算法;它需要找到一个二次非剩余。随机抽样很快,但在不附加假设时,确定性多项式时间寻找非剩余是微妙的问题。

算法Tonelli–Shanks 的结构

p1=2sqp-1=2^s qqq 为奇数),用二次非剩余 zz 构造 22-Sylow 部分中的修正因子。循环把当前误差 tt 的阶减半,最终得到 x2a(modp)x^2\equiv a\pmod p。实现时应显式检查 a=0a=0、Legendre 符号以及乘法溢出。

3. 有限域与椭圆曲线的反向应用

Schoof 算法能在确定性多项式时间内计算 #E(𝐅p)\#E(\mathbf F_p)。对具有复乘的曲线 E:y2=x3xE:y^2=x^3-x,点数与 p=x2+y2p=x^2+y^2 中的 x,yx,y 直接相关,因此“数点”也能反向恢复模平方根或两平方表示。这个例子说明,引入更丰富的结构有时会使算法形式更复杂,却能得到更好的复杂度界。

模平方根与 Cornacchia 算法的完整计算链

给定奇素数 p1(mod4)p\equiv1\pmod4,第一步是求一个 rr 使 r21(modp)r^2\equiv-1\pmod p。若写 p1=2sqp-1=2^s qqq 为奇数,Tonelli–Shanks 算法从一个二次非剩余 zz 出发,通过反复修正 r,t,cr,t,c 等量求出平方根。它的随机性通常只体现在寻找 zz;一旦得到二次非剩余,后续步骤是确定的。对 p3(mod4)p\equiv3\pmod4,平方根可由 a(p+1)/4a^{(p+1)/4} 直接给出;对 p5(mod8)p\equiv5\pmod8 也有更短公式。两平方问题的素数满足 p1(mod4)p\equiv1\pmod4,所以一般需要完整算法。

Cornacchia 算法可解释为在格

L={(u,v)𝐙2:urv0(modp)}=(p,0),(r,1)L=\{(u,v)\in\mathbf Z^2:u-rv\equiv0\pmod p\} =\langle(p,0),(r,1)\rangle

中寻找范数平方为 pp 的短向量。若 p=x2+y2p=x^2+y^2rxy1(modp)r\equiv xy^{-1}\pmod p,则 (x,y)L(x,y)\in L。二维格的 Gauss 约化与Euclidean 算法等价:对 p,rp,r 做带余除法,当余数首次小于 p\sqrt p 时,检验 px2p-x^2 是否为平方。若所选根给出的余数不合适,换成另一个根 prp-r

算法的正确性来自最短向量与连续分数逼近。由 xry(modp)x\equiv ry\pmod p 可知 x/yx/yr/pr/p 的特别好的有理逼近;Legendre 型判据保证这种逼近出现在连分数的收敛分数中。Euclidean 算法正是在枚举这些收敛分数,因此会遇到所需的 xx。二维情形的特殊性在于,约化过程完全可控;高维格则需要 LLL 等近似约化算法。

随机与确定性之间的区别

Legendre 符号 a(p1)/2(modp)a^{(p-1)/2}\pmod p 能在多项式时间内判断 aa 是平方、非平方还是零,但它不直接给出平方根。随机选择元素直到找到二次非剩余,期望尝试次数约为 2,因此实践中非常快;理论上却无法保证在确定的多项式步数内找到。广义 Riemann 假设能给出很小的二次非剩余上界,从而把随机步骤确定化。课程借此强调:实际运行极快与无条件确定性复杂度是两个不同的问题。

椭圆曲线点数如何返回两平方表示

曲线 E:y2=x3xE:y^2=x^3-x 在复数上有自同态 (x,y)(x,iy)(x,y)\mapsto(-x,iy),因此其自同态环含 𝐙[i]\mathbf Z[i]。当 p1(mod4)p\equiv1\pmod4 时,pp 在Gaussian 整数中分裂为 ππ\pi\bar\pi,Frobenius 对应于范数为 pp 的Gaussian 整数 π=x+iy\pi=x+iy。于是迹

ap=p+1#E(𝐅p)a_p=p+1-\#E(\mathbf F_p)

等于 ±2x\pm2x±2y\pm2y,具体取决于对 π\pi 的单位选择。Schoof 算法通过计算 Frobenius 在各个小素数 \ell 的挠点群上的作用,逐步确定 apmoda_p\bmod\ell,再用中国剩余定理恢复满足 Hasse 界 |ap|2p|a_p|\le2\sqrt p 的唯一整数。由 apa_p 得到一个坐标后,另一个坐标由 px2p-x^2 开平方得到。

实现时的精确检查

在程序中应分别检查:输入是否为素数;是否满足 p1(mod4)p\equiv1\pmod4;模平方根是否确实满足同余;Euclidean停止条件是否正确;候选 px2p-x^2 是否为整数平方;最终是否精确满足 x2+y2=px^2+y^2=p。任何浮点平方根都只应用于估计停止界,判定“是否为平方”必须使用整数平方根函数。

补充:Tonelli–Shanks 的推导

aa 是模奇素数 pp 的二次剩余,写 p1=2sqp-1=2^sq,其中 qq 为奇数。选二次非剩余 zz,令

c=zq,t=aq,r=a(q+1)/2.c=z^q,\qquad t=a^q,\qquad r=a^{(q+1)/2}.

tt 位于 𝐅p×\mathbf F_p^\times22-Sylow 子群中,且 r2=atr^2=at。目标是通过乘 cc 的适当幂逐步把 tt 变成 1。若 t1t\ne1,找最小 ii 使 t2i=1t^{2^i}=1,令 b=c2mi1b=c^{2^{m-i-1}},更新

rrb,ttb2,cb2,mi.r\leftarrow rb,\qquad t\leftarrow tb^2,\qquad c\leftarrow b^2,\qquad m\leftarrow i.

每次严格降低 tt 的 2-幂阶,因此至多 s1s-1 轮。证明只用循环群结构。实现中应预先检查 a=0a=0 与Legendre 符号;指数运算使用二进制快速幂。

Cornacchia 的停止准则

r0=p,r1=rr_0=p,r_1=r 开始执行 ri1=qiri+ri+1r_{i-1}=q_ir_i+r_{i+1}。当 ri2pr_i^2\le pri12>pr_{i-1}^2>p 时停止,令 x=rix=r_i。若 px2p-x^2 是平方,得到解。为何不用继续枚举所有更小余数?因为真正的解对应一个最佳逼近,若越过该收敛分数,余数与分母的组合不再可能同时满足范数 pp。严格证明可用连分数相邻收敛分数的行列式为 ±1\pm1 与 Legendre 逼近定理。

对一般方程 x2+dy2=mx^2+dy^2=m,若已知 r2d(modm)r^2\equiv-d\pmod m,Cornacchia 方法同样适用,但停止界和可解性检验略有变化。若 mm 合数,必须处理 rrmm 不互素、多个素因子上的局部条件和可能的非唯一表示。

Schoof 算法的结构

对每个小素数 p\ell\ne p,Frobenius π\piE[]E[\ell] 上满足

π2apπ+p=0.\pi^2-a_p\pi+p=0.

在除法多项式定义的坐标环中,测试各个候选 apmoda_p\bmod\ell,直到找到满足该关系者。选择足够多 \ell 使乘积超过 4p4\sqrt p,由中国剩余定理与 Hasse 界唯一恢复 apa_p。原始 Schoof 算法是确定性多项式时间,但常数很大;Schoof–Elkies–Atkin 通过利用模多项式与 Frobenius 特征线大幅加速,成为实际点数算法。

复乘曲线的更快专用方法

j=1728j=1728 曲线 y2=x3xy^2=x^3-x,可使用 CM 理论直接由 pp𝐙[i]\mathbf Z[i] 中的分解确定 apa_p。但这看似循环,因为分解本身就是两平方问题。Schoof 的意义在于提供不先知道分解的确定性途径。实践中仍以模平方根加 Cornacchia 最快;Schoof 说明的是复杂度理论上的“可确定化”。

常见实现错误

平方根 rrprp-r 可能分别对应交换或符号变化后的解;不要只尝试一个根后就宣布失败。整数平方判定应使用 y=px2y=\lfloor\sqrt{p-x^2}\rfloor 并检查 y2=px2y^2=p-x^2。当使用 LLL 库时,应确认返回的是行向量还是列向量、基向量排列方式以及约化后的第一向量是否确为最短;二维专用Euclidean实现更透明。

进一步:模平方根到 Cornacchia 的完整证明链

对奇素数 p1(mod4)p\equiv1\pmod4,Euler 判据给出 (1)(p1)/2=1(-1)^{(p-1)/2}=1,故 1-1 是模 pp 二次剩余。Tonelli–Shanks 算法把 p1=2sqp-1=2^sqqq 奇)分解,利用一个二次非剩余逐步降低 2-幂阶,得到 r21(modp)r^2\equiv-1\pmod p。若 p5(mod8)p\equiv5\pmod8,可用更短公式;但统一实现仍应处理所有奇素数并先验证输入素性。

Cornacchia 算法从 (p,r)(p,r) 执行 Euclidean 余数序列,直到余数 a<pa<\sqrt p。若 p=a2+b2p=a^2+b^2,则对应Gaussian 整数 a+bia+bippr+ir+i𝐙[i]\mathbf Z[i] 中的 gcd;Euclidean 算法投影到整数余数后恰找到其一个坐标。最后计算 pa2p-a^2 是否为完全平方。该最后检验不可省略,因为任意模平方根都能产生余数序列,但中间余数不必对应表示。

广义 Cornacchia 求 x2+dy2=mx^2+dy^2=m 时先求 r2d(modm)r^2\equiv-d\pmod m,再 Euclidean 降到 r<mr<\sqrt m,检查 (mr2)/d(m-r^2)/d 是否为平方。正确性需要 gcd(d,m)=1\gcd(d,m)=1 等条件,并要处理合数模数、多个平方根和非本原表示。对二次型的一般表示问题,则需理想类群而不只是单次 Euclidean 算法。

实现中完全平方测试应使用整数平方根:令 b=nb=\lfloor\sqrt n\rfloor,检查 b2=nb^2=n,避免浮点舍入。对千位整数,先按小模数筛掉不可能平方的剩余类可减少大整数开方次数。Euclidean 步数为 O(logp)O(\log p),主要成本通常在模平方根和大整数运算。

若输入是 CM 判别式相关的素数表示,p=x2+dy2p=x^2+dy^2 的符号与单位选择可能影响后续 Frobenius 迹。此时不能只返回无序绝对值;还需结合模条件、嵌入或 Hecke 特征固定“主”生成元。

练习与解答Cornacchia 算法

练习 1。p=29p=29,取 r=12r=12,验证 r21(mod29)r^2\equiv-1\pmod{29},执行余数序列并求表示。

解。29=212+529=2\cdot12+512=25+212=2\cdot5+2。首个小于 29\sqrt{29} 的余数可取 5,且 2925=429-25=4,所以 29=52+2229=5^2+2^2

练习 2。解释为何两个模平方根 r,prr,p-r 不需都运行。

解。它们对应共轭Gaussian 因子,Euclidean 序列给出的表示只差符号/交换;实现中仍可在边界情况下尝试两根作为防错。

练习 3。把算法推广到 x2+2y2=px^2+2y^2=p 时第一步是什么?

解。先求 r22(modp)r^2\equiv-2\pmod p,再降余数并检查 (pa2)/2(p-a^2)/2 为完全平方;同时需确认局部可解和整除条件。

深入补充:Tonelli–Shanks 的不变量与 Cornacchia 的连分数证书

pp 为奇素数,aa 是模 pp 的二次剩余。写

p1=2sq,q 为奇数.p-1=2^s q,\qquad q\text{ 为奇数}.

Tonelli–Shanks 算法的本质是在 𝐅p×\mathbf F_p^\times 的 Sylow 22-子群中逐步消去误差。取二次非剩余 zz,令

c=zq,x=a(q+1)/2,t=aq,m=s.c=z^q, \qquad x=a^{(q+1)/2}, \qquad t=a^q, \qquad m=s.

始终保持

x2at(modp),t2m1=1.x^2\equiv at\pmod p, \qquad t^{2^{m-1}}=1.

t1t\ne1,寻找最小的 i<mi<m 使 t2i=1t^{2^i}=1,令

b=c2mi1,xxb,ttb2,cb2,mi.b=c^{2^{m-i-1}}, \quad x\leftarrow xb, \quad t\leftarrow tb^2, \quad c\leftarrow b^2, \quad m\leftarrow i.

新的 tt22-幂阶严格下降,故至多循环 s1s-1 次,终止时 x2ax^2\equiv a

定理 Cornacchia 的连分数位置

r21(modp)r^2\equiv-1\pmod p,对 (p,r)(p,r) 运行 Euclidean 算法,得到余数链

r1=p,r0=r,rk1=qkrk+rk+1.r_{-1}=p, \quad r_0=r, \quad r_{k-1}=q_kr_k+r_{k+1}.

p=x2+y2p=x^2+y^20<xy0<x\le y,则余数链中第一次满足 rk<pr_k<\sqrt p 的正余数必为 xxyy 中较小者;检查 prk2p-r_k^2 是否为平方即可恢复表示。

证明可用连分数最佳逼近。由 r21(modp)r^2\equiv-1\pmod pp=x2+y2p=x^2+y^2,在模 pp 下有 r±xy1r\equiv\pm x y^{-1}。于是存在整数 mm 使

rymp=±x.ry-mp=\pm x.

因为 |x|<p|x|<\sqrt p|y|<p|y|<\sqrt p,分数 m/ym/yr/pr/p 的逼近满足 Legendre 型阈值,故它必须是一个连分数收敛分数;相应 Euclidean 余数就是 |x||x|。这也解释停止阈值为何恰是 p\sqrt p,而不是任意经验界。

计算 73=82+3273=8^2+3^2

272=7291(mod73)27^2=729\equiv-1\pmod{73}。Euclidean 余数链为

73=227+19,27=119+8.73=2\cdot27+19, \qquad27=1\cdot19+8.

因为 8<73<98<\sqrt{73}<9,停止并计算

7382=9=32.73-8^2=9=3^2.

所以得到 73=82+3273=8^2+3^2。证书只包含同余式 272+1027^2+1\equiv0、两步整数除法和最终平方等式,完全可独立核验。

算法 可认证的两阶段实现

第一阶段用 Euler 判据确认 a(p1)/21a^{(p-1)/2}\equiv1,再运行 Tonelli–Shanks;输出平方根 rr 后立即验证 r2ar^2\equiv a。第二阶段运行 Euclidean 算法,保存商与余数;首次低于 p\sqrt p 时做整数平方判定。若失败,另一平方根 prp-r 给出同一余数结构,无需重算。

随机寻找非剩余的期望尝试次数为 22,因为恰有一半非零元素是非剩余。模幂可用重复平方在 O(logp)O(\log p) 次模乘法内完成;若整数乘法成本记为 M(logp)M(\log p),整体位复杂度近似为 O(M(logp)logp)O(M(\log p)\log p),外加 O(logp)O(\log p) 次 Euclidean 除法。对固定 s=v2(p1)s=v_2(p-1) 的素数族,Tonelli–Shanks 的群论部分成本很小;当 ss 很大时,可预先保存 c,c2,c4,c,c^2,c^4,\ldots,避免每轮重复幂运算。

若目标是同时求许多 aia_i 的平方根,可先按 Legendre 符号过滤,再共享模幂窗口表和 Montgomery 表示。每个输出仍需单独平方验证;批量优化只能降低发现成本,不能替代逐项证书。

补充计算:模平方根不变量、连分数停止点与格证书

定理 Cornacchia 停止点的唯一候选性

设 p 为奇素数,\(d>0\),且 \(r^2≡-d (mod p)\)。对Euclidean 余数列 \(r_{-1}=p\),\(r_0=r\),\(r_{k+1}=r_{k-1} mod r_k\),令 m 为满足 \(r_m^2≤p<r_{m-1}^2\) 的首个指标。若 \(x^2+dy^2=p\) 有解且 \(x≡±ry (mod p)\),则 \(|x|=r_m\);因此只需检查 \((p-r_m^2)/d\) 是否为平方。

证明 由最小余数与连分数最佳逼近推出停止准则

由 \(x≡ry (mod p)\) 可写 \(x-ry=kp\)。若 \(0<|x|≤√p\),则分数 k/y 逼近 r/p,并满足 \(|r/p-k/y|=|x|/(p|y|)\)。由 \(x^2+dy^2=p\) 得 \(|x|·|y|<p/√d\),故该逼近落入连分数最佳逼近的范围。Euclidean 算法的连续余数与 r/p 的连分数收敛分母、分子互为伴随;所有绝对值不超过 \(√p\) 的非零格向量中,首个穿过 \(√p\) 的余数给出唯一可能的 x。

若在 \(r_m\) 处检查失败,则不存在同一同余类中的解。对另一个平方根 p-r 重复同样过程即可覆盖符号选择。检查 \(x^2+dy^2=p\) 同时排除伪候选;检查 \(x±ry≡0 (mod p)\) 给出所属格 \(Λ=⟨(p,0),(r,1)⟩\) 的证书。\(det Λ=p\),而候选向量范数恰为 p,因此二维 Minkowski 界与连续最小值的估计在此达到精确尺度。

Python Tonelli–Shanks、Cornacchia 与二维格同余证书
from dataclasses import dataclass
from math import isqrt

@dataclass(frozen=True)
class RootCertificate:
    a: int
    p: int
    root: int
    legendre: int
    two_adic_exponent: int
    odd_part: int

def legendre_symbol(a: int, p: int) -> int:
    a %= p
    if a == 0:
        return 0
    value = pow(a, (p - 1) // 2, p)
    return -1 if value == p - 1 else value

def split_two_part(n: int) -> tuple[int, int]:
    s = 0
    while n % 2 == 0:
        s += 1
        n //= 2
    return s, n

def tonelli_shanks(a: int, p: int) -> RootCertificate:
    if p == 2:
        return RootCertificate(a, p, a & 1, 1, 0, 1)
    a %= p
    ls = legendre_symbol(a, p)
    if ls != 1:
        raise ValueError("a is not a nonzero quadratic residue")
    s, q = split_two_part(p - 1)
    if s == 1:
        r = pow(a, (p + 1) // 4, p)
        return RootCertificate(a, p, min(r, p-r), ls, s, q)

    z = 2
    while legendre_symbol(z, p) != -1:
        z += 1
    c = pow(z, q, p)
    r = pow(a, (q + 1) // 2, p)
    t = pow(a, q, p)
    m = s

    while t != 1:
        i = 1
        t2i = t * t % p
        while i < m and t2i != 1:
            t2i = t2i * t2i % p
            i += 1
        if i == m:
            raise ArithmeticError("Tonelli-Shanks invariant failed")
        b = pow(c, 1 << (m - i - 1), p)
        r = r * b % p
        t = t * b * b % p
        c = b * b % p
        m = i

    r = min(r, p-r)
    assert r*r % p == a
    return RootCertificate(a, p, r, ls, s, q)

@dataclass(frozen=True)
class CornacchiaCertificate:
    p: int
    d: int
    modular_root: int
    remainders: tuple[int, ...]
    x: int
    y: int
    verified: bool

def cornacchia_prime(p: int, d: int = 1) -> CornacchiaCertificate:
    """
    Solve x^2+d*y^2=p for odd prime p.
    Requires a square root of -d modulo p.
    """
    root_cert = tonelli_shanks((-d) % p, p)
    roots = (root_cert.root, p - root_cert.root)
    best = None

    for r in roots:
        a, b = p, r
        chain = [a, b]
        while b*b > p:
            a, b = b, a % b
            chain.append(b)
        x = b
        remainder = p - x*x
        if remainder < 0 or remainder % d:
            continue
        y2 = remainder // d
        y = isqrt(y2)
        if y*y == y2:
            cert = CornacchiaCertificate(
                p=p,
                d=d,
                modular_root=r,
                remainders=tuple(chain),
                x=x,
                y=y,
                verified=x*x + d*y*y == p
            )
            if best is None or (x, y) < (best.x, best.y):
                best = cert

    if best is None:
        raise ValueError("no representation found")
    return best

def determinant_certificate(p: int, r: int,
                            x: int, y: int) -> tuple[int, int, int]:
    """
    (p,0) and (r,1) span a determinant-p lattice.
    A solution x^2+y^2=p satisfies x-r*y ≡0 mod p.
    """
    congruence = (x - r*y) % p
    determinant = p
    norm = x*x + y*y
    return determinant, congruence, norm

def batch(primes: list[int]) -> None:
    for p in primes:
        cert = cornacchia_prime(p)
        det, cong1, norm = determinant_certificate(
            p, cert.modular_root, cert.x, cert.y
        )
        # Depending on the chosen root/sign, x+r*y may vanish instead.
        cong2 = (cert.x + cert.modular_root*cert.y) % p
        lattice_ok = min(cong1, cong2) == 0
        chain = " > ".join(map(str, cert.remainders))
        print(
            f"p={p:5d} root={cert.modular_root:5d} "
            f"(x,y)=({cert.x:3d},{cert.y:3d}) "
            f"steps={len(cert.remainders)-2:2d} "
            f"lattice={lattice_ok} norm={norm}"
        )
        print(f"  Euclid: {chain}")

primes = [5, 13, 17, 29, 37, 41, 73, 97, 193, 257, 401, 577, 1009]
batch(primes)

print("\nquadratic-residue audit modulo 97:")
for a in [2, 3, 4, 6, 8, 12, 16, 18, 25, 32, 47, 75]:
    ls = legendre_symbol(a, 97)
    if ls == 1:
        c = tonelli_shanks(a, 97)
        print(f"a={a:2d} χ={ls:+d} root={c.root:2d} check={c.root*c.root%97:2d}")
    else:
        print(f"a={a:2d} χ={ls:+d} root=--")

def is_prime_trial(n):
    if n<2:return False
    if n%2==0:return n==2
    d=3
    while d*d<=n:
        if n%d==0:return False
        d+=2
    return True

print("\nCornacchia certificate ledger for primes p <= 100 with p congruent 1 mod 4:")
for p in range(5,101,4):
    if not is_prime_trial(p):
        continue
    cert=cornacchia_prime(p,1)
    chain=">".join(map(str,cert.remainders))
    descent=all(cert.remainders[i]>cert.remainders[i+1]
                for i in range(len(cert.remainders)-1))
    print(f"  p={p:4d} root={cert.modular_root:4d} "
          f"chain={chain:42s} x={cert.x:3d} y={cert.y:3d} "
          f"norm={cert.x*cert.x+cert.y*cert.y:4d} "
          f"descent={descent} verified={cert.verified}")

print("\nTonelli-Shanks complete residue audit for selected primes:")
for p in [97]:
    residues=sorted({x*x%p for x in range(1,p)})
    checked=0
    for a in residues[:8]:
        cert=tonelli_shanks(a,p)
        print(f"  p={p:3d} a={a:3d} root={cert.root:3d} "
              f"s={cert.two_adic_exponent:2d} q={cert.odd_part:3d} "
              f"root^2 mod p={cert.root*cert.root%p:3d}")
        checked+=1
    print(f"  subtotal p={p}: checked={checked}")
运行结果 Euclidean链与模平方根批量核验
p=    5 root=    2 (x,y)=(  2,  1) steps= 0 lattice=True norm=5
  Euclid: 5 > 2
p=   13 root=    5 (x,y)=(  3,  2) steps= 1 lattice=True norm=13
  Euclid: 13 > 5 > 3
p=   17 root=    4 (x,y)=(  4,  1) steps= 0 lattice=True norm=17
  Euclid: 17 > 4
p=   29 root=   12 (x,y)=(  5,  2) steps= 1 lattice=True norm=29
  Euclid: 29 > 12 > 5
p=   37 root=    6 (x,y)=(  6,  1) steps= 0 lattice=True norm=37
  Euclid: 37 > 6
p=   41 root=    9 (x,y)=(  5,  4) steps= 1 lattice=True norm=41
  Euclid: 41 > 9 > 5
p=   73 root=   27 (x,y)=(  8,  3) steps= 2 lattice=True norm=73
  Euclid: 73 > 27 > 19 > 8
p=   97 root=   22 (x,y)=(  9,  4) steps= 1 lattice=True norm=97
  Euclid: 97 > 22 > 9
p=  193 root=   81 (x,y)=( 12,  7) steps= 3 lattice=True norm=193
  Euclid: 193 > 81 > 31 > 19 > 12
p=  257 root=   16 (x,y)=( 16,  1) steps= 0 lattice=True norm=257
  Euclid: 257 > 16
p=  401 root=   20 (x,y)=( 20,  1) steps= 0 lattice=True norm=401
  Euclid: 401 > 20
p=  577 root=   24 (x,y)=( 24,  1) steps= 0 lattice=True norm=577
  Euclid: 577 > 24
p= 1009 root=  469 (x,y)=( 28, 15) steps= 3 lattice=True norm=1009
  Euclid: 1009 > 469 > 71 > 43 > 28

quadratic-residue audit modulo 97:
a= 2 χ=+1 root=14 check= 2
a= 3 χ=+1 root=10 check= 3
a= 4 χ=+1 root= 2 check= 4
a= 6 χ=+1 root=43 check= 6
a= 8 χ=+1 root=28 check= 8
a=12 χ=+1 root=20 check=12
a=16 χ=+1 root= 4 check=16
a=18 χ=+1 root=42 check=18
a=25 χ=+1 root= 5 check=25
a=32 χ=+1 root=41 check=32
a=47 χ=+1 root=12 check=47
a=75 χ=+1 root=47 check=75

Cornacchia certificate ledger for primes p <= 100 with p congruent 1 mod 4:
  p=   5 root=   2 chain=5>2                                        x=  2 y=  1 norm=   5 descent=True verified=True
  p=  13 root=   5 chain=13>5>3                                     x=  3 y=  2 norm=  13 descent=True verified=True
  p=  17 root=   4 chain=17>4                                       x=  4 y=  1 norm=  17 descent=True verified=True
  p=  29 root=  12 chain=29>12>5                                    x=  5 y=  2 norm=  29 descent=True verified=True
  p=  37 root=   6 chain=37>6                                       x=  6 y=  1 norm=  37 descent=True verified=True
  p=  41 root=   9 chain=41>9>5                                     x=  5 y=  4 norm=  41 descent=True verified=True
  p=  53 root=  23 chain=53>23>7                                    x=  7 y=  2 norm=  53 descent=True verified=True
  p=  61 root=  11 chain=61>11>6                                    x=  6 y=  5 norm=  61 descent=True verified=True
  p=  73 root=  27 chain=73>27>19>8                                 x=  8 y=  3 norm=  73 descent=True verified=True
  p=  89 root=  34 chain=89>34>21>13>8                              x=  8 y=  5 norm=  89 descent=True verified=True
  p=  97 root=  22 chain=97>22>9                                    x=  9 y=  4 norm=  97 descent=True verified=True

Tonelli-Shanks complete residue audit for selected primes:
  p= 97 a=  1 root=  1 s= 5 q=  3 root^2 mod p=  1
  p= 97 a=  2 root= 14 s= 5 q=  3 root^2 mod p=  2
  p= 97 a=  3 root= 10 s= 5 q=  3 root^2 mod p=  3
  p= 97 a=  4 root=  2 s= 5 q=  3 root^2 mod p=  4
  p= 97 a=  6 root= 43 s= 5 q=  3 root^2 mod p=  6
  p= 97 a=  8 root= 28 s= 5 q=  3 root^2 mod p=  8
  p= 97 a=  9 root=  3 s= 5 q=  3 root^2 mod p=  9
  p= 97 a= 11 root= 37 s= 5 q=  3 root^2 mod p= 11
  subtotal p=97: checked=8
计算 Tonelli–Shanks 循环不变量

写 p-1=2^s q,q 为奇数。循环中保持 r^2≡a t (mod p),t^{2^{m-1}}=1,c 的阶整除 2^m。取最小 i 使 t^{2^i}=1,并令 b=c^{2^{m-i-1}},则新变量满足 t' = t b^2、c'=b^2、m'=i;于是 t'^{2^{i-1}}=1 且 m 严格下降。循环至 t=1 时得到 r^2≡a。每轮至多进行 O(m) 次模平方,m≤log_2 p。

Lecture 3 / 第 3 讲

曲线覆盖、分歧、Riemann–Hurwitz公式与单值群

建立后续 Belyi 映射计算所需的拓扑与代数语言。

覆盖分歧单值群

1. 覆盖与分歧

定义有限覆盖与分支点

f:XYf:X\to Y 是光滑射影曲线之间的非常值态射。局部参数满足 f*u=czeP+f^*u=c z^{e_P}+\cdots,整数 eP1e_P\ge1 称为点 PP 的分歧指数。若 eP>1e_P>1,则 PP 是分歧点;其像 f(P)f(P) 是分支点。

定理Riemann–Hurwitz公式
2gX2=n(2gY2)+PX(eP1),2g_X-2=n(2g_Y-2)+\sum_{P\in X}(e_P-1),

其中 n=degfn=\deg f

证明微分除子证明

典范除子满足 KX=f*KY+RK_X=f^*K_Y+R,其中分歧除子 R=P(eP1)PR=\sum_P(e_P-1)P。取次数即得公式。解析上,这是局部关系 du=ePzeP1dz+du=e_P z^{e_P-1}dz+\cdots 对零点阶数的贡献。

2. 拓扑分类与单值群

去掉分支集 BYB\subset Y 后,f:Xf1(B)YBf:X-f^{-1}(B)\to Y-B 是非分歧覆盖。选择基点并编号纤维后,解析延拓给出

ρ:π1(YB)Sn.\rho:\pi_1(Y-B)\longrightarrow S_n.

像称为单值群(monodromy group)。覆盖连通当且仅当该群在 {1,,n}\{1,\dots,n\} 上传递。不同编号只会同时共轭所有置换。

定义置换三元组

Y=𝐏1Y=\mathbf P^1B={0,1,}B=\{0,1,\infty\} 时,可取环路 γ0γ1γ=1\gamma_0\gamma_1\gamma_\infty=1。相应置换 (g0,g1,g)(g_0,g_1,g_\infty) 满足 g0g1g=1g_0g_1g_\infty=1,并生成传递子群。循环长度正是各分支点上方的分歧指数。

两个分支点

B={0,}B=\{0,\infty\},则 π1(𝐂*)𝐙\pi_1(\mathbf C^*)\cong\mathbf Z。每个指数 nn 的连通覆盖都等价于 zznz\mapsto z^n。第三个分支点出现后,自由群 F2F_2 的有限指数子群带来丰富得多的组合数据。

补充从拓扑数据到方程的困难

Riemann 存在定理保证传递置换数据产生复代数曲线,但这个证明本身不输出方程。课程的主线正是:把循环型、群、定义域等离散信息转化为多项式方程,再通过消元、pp-进提升与格约化恢复精确系数。

覆盖、分歧与基本群

若分支集 BB 为空而基曲线 XX 的亏格为 1,则连通无分歧有限覆盖 XXX'\to X 正是椭圆曲线之间的同源映射,且 XX' 仍为亏格 1。它们也可以从 𝐏1\mathbf P^1 的四点分歧覆盖中出现:椭圆曲线到 𝐏1\mathbf P^1 的次数 2 商映射,以四个 2-挠点像为分支点。

更一般地,若 XX 的亏格 g>0g>0 且覆盖是Abelian覆盖,它可由 XX 的 Jacobian 中有限子群或相应的挠点数据描述。次数 2 时,分支点数必须为偶数;选择双覆盖等价于选择次数为 #B/2\#B/2 的除子类 [D][D],使

2[D]PBP.2[D]\sim\sum_{P\in B}P.

X=𝐏1X=\mathbf P^1 时 Picard 群由次数决定,因此这种选择唯一,所得 XX' 是分支于 2g+22g+2 个点的超椭圆曲线。原讲义采用较宽的用法,把带次数 2 映射到 𝐏1\mathbf P^1 的亏格 0、1 曲线也称为超椭圆曲线;对应分支点数分别为 2、4。若 X=𝐏1X=\mathbf P^1、次数为 3 且全部分支均简单,则相关选择数为 (32g1)/2(3^{2g}-1)/2,它们对应于同一超椭圆曲线 Jacobian 中阶为 3 的循环子群。

经典模曲线 X0(N),X1(N),X(N)X_0(N),X_1(N),X(N)jj-直线的覆盖,除 j=,0,1728j=\infty,0,1728 外无分歧。更一般地,若 ΓΓ\Gamma'\subset\Gamma 且指数为 nn,则相应模曲线覆盖仅可能在 Γ\Gamma 的椭圆点与尖点处分歧,即在上半平面或边界上具有非平凡稳定子的点处分歧。课程的一个应用目标正是为若干模曲线求显式方程。

为什么重点转向 𝐏1\mathbf P^1

基曲线通常取为 𝐏1\mathbf P^1,因为它最简单,也是唯一没有连续模参数的紧Riemann 曲面。若 #B=0\#B=0,球面本身单连通;若 #B=1\#B=1,去掉一点得到复平面,仍单连通,所以不存在次数大于 1 的连通无分歧覆盖。若 #B=2\#B=2,可用射影线性变换把分支点送到 0,0,\infty,此时

π1(𝐏1{0,})=π1(𝐂×)𝐙.\pi_1(\mathbf P^1-\{0,\infty\})=\pi_1(\mathbf C^\times)\cong\mathbf Z.

每个 nn 只有唯一的指数 nn 子群 n𝐙n\mathbf Z,对应于 zznz\mapsto z^n。这里用到 PGL2(𝐂)\operatorname{PGL}_2(\mathbf C)𝐏1\mathbf P^1 上的2-传递性。

事实上该作用是锐 3-传递的:给定两组各由三个互异点组成的有序三元组,存在唯一 Möbius 变换逐点把前者送到后者。因此当 #B=3\#B=3 时,也可唯一规范化为 {0,1,}\{0,1,\infty\},仍没有连续模参数;但基本群现在是两个生成元的自由群,指数 nn 子群的种类极为丰富。等价地,覆盖由 SnS_n 中两个生成元的传递置换表示描述。

置换三元组与Riemann 存在定理

取绕 0,1,0,1,\infty 的正向小环路 γ0,γ1,γ\gamma_0,\gamma_1,\gamma_\infty,满足 γ0γ1γ=1\gamma_0\gamma_1\gamma_\infty=1。沿这些环路解析延拓 nn 个局部分支,得到置换 g0,g1,gSng_0,g_1,g_\infty\in S_n,它们满足

g0g1g=1,g0,g1,g{1,,n}上传递.g_0g_1g_\infty=1, \qquad \langle g_0,g_1,g_\infty\rangle\ \text{在 }\{1,\ldots,n\}\text{上传递}.

传递性等价于覆盖连通。每个 gig_i 的循环长度就是位于相应分支值上各点的分歧指数。反过来,满足上述条件的传递置换三元组通过Riemann 存在定理唯一决定一个复代数曲线覆盖,唯一性取同时共轭意义。

生成的置换群 GG 是函数域扩张 𝐂(X)/𝐂(t)\mathbf C(X')/\mathbf C(t) 的 Galois 闭包之群。若覆盖只定义在非代数闭域 FF 上,几何单值群与算术 Galois 群可能不同;例如 t=znt=z^n𝐐\mathbf Q 上若不含全部 nn 次单位根,便需扩张常数域才能出现预期的循环 Galois 群。置换三元组还只在 SnS_nGG 的正规化子作用下定义;不同拓扑生成元的选择也可能把看似不同的三元组联系起来。

Riemann–Hurwitz公式的置换形式

c(g)c(g) 表示置换 gg 的循环数,则在三点覆盖中,分歧贡献为 nc(gi)n-c(g_i),故

2g(X)2=2n+i{0,1,}(nc(gi))=nc(g0)c(g1)c(g).2g(X')-2=-2n+\sum_{i\in\{0,1,\infty\}}\bigl(n-c(g_i)\bigr) =n-c(g_0)-c(g_1)-c(g_\infty).

因此只从循环型就能计算源曲线亏格,也能在建立方程前排除不可能的三元组。显式计算时,置换数据是离散的“拓扑输入”,多项式或代数曲线方程则是待恢复的“代数输出”。

补充:覆盖的局部标准形

在复曲线的点 PXP\in X'Q=f(P)XQ=f(P)\in X 附近,可选局部参数 u,tu,t 使

t=ueP.t=u^{e_P}.

整数 eP1e_P\ge1 是分歧指数;eP>1e_P>1PP 为分歧点,QQ 为分支点。不同点的剩余域在复数上都相同;在数域上还要记录剩余次数。函数域语言中,ePe_P 是离散赋值在扩张中的指数。

Riemann–Hurwitz公式的证明框架

典范除子满足

KXf*KX+R,R=PX(eP1)P.K_{X'}\sim f^\ast K_X+R,\qquad R=\sum_{P\in X'}(e_P-1)P.

取次数得

2g(X)2=n(2g(X)2)+degR.2g(X')-2=n(2g(X)-2)+\deg R.

局部证明来自 dt=ePueP1dudt=e_Pu^{e_P-1}du,故微分拉回多出 eP1e_P-1 阶零。这个公式不仅计算亏格,也约束可能的分歧分拆。例如球面三点覆盖若三置换的指标和不等于 2n2+2g2n-2+2g,则不可能存在。

基本群与置换表示

选基点 x0XBx_0\in X-B,覆盖纤维 f1(x0)f^{-1}(x_0)nn 点。每条环路沿覆盖提升,置换纤维,得到单值表示

ρ:π1(XB,x0)Sn.\rho:\pi_1(X-B,x_0)\to S_n.

覆盖连通当且仅当像传递。固定一个纤维点,其稳定子的原像是指数 nn 子群;改变纤维标号对应同时共轭。若覆盖是 Galois,稳定子正规,单值群在纤维上正则作用。

非紧曲面基本群的表示

亏格 γ\gamma、删去 kk 点的曲面基本群有表示

a1,b1,,aγ,bγ,c1,,ck|i=1γ[ai,bi]j=1kcj=1.\left\langle a_1,b_1,\ldots,a_\gamma,b_\gamma,c_1,\ldots,c_k \;\middle|\; \prod_{i=1}^{\gamma}[a_i,b_i]\prod_{j=1}^{k}c_j=1 \right\rangle.

因此覆盖枚举化成有限群中满足一个乘积关系的元组枚举。球面 k=3k=3 时只需两个自由生成元;椭圆曲线删一点时关系为 [a,b]c=1[a,b]c=1

定义域、模域与下降障碍

置换三元组的 Galois 轨道给出覆盖的模域,但模域不一定是定义域。障碍可表示为一个非Abelian上同调类,常与覆盖自同构有关。若童画无非平凡自同构,模域通常可作为定义域;有自同构时可能需要扩张。显式方程计算必须区分“系数所在域”“几何单值群定义域”和“Galois 闭包常数域”。

从拓扑数据到方程的路径

常用方法包括:直接系数比较;有限域搜索加 Hensel 提升;复解析数值 continuation;在 Hurwitz 空间中移动分支点;利用群不变量或模解释构造。无论方法为何,最终应从方程重新计算分歧除子与单值群,闭合拓扑—代数转换。

进一步:覆盖的局部模型与单值群重构

有限可分态射 f:CDf:C\to D 在点 PQP\mapsto Q 的完备局部环上可写为 utePu\mapsto t^{e_P} 乘单位,其中 ePe_P 是分歧指数。特征 0 时不同指数贡献 eP1e_P-1;正特征若 pePp\mid e_P,还会出现野分歧,Riemann–Hurwitz 中应使用不同指数而非简单的 eP1e_P-1。本课程大多在复数或数域上,因此属于温和情形。

选择目标分支值的基点和到各分支值的小环路,解析延拓覆盖纤维得到置换 σi\sigma_i。它们满足 σ1σr=1\sigma_1\cdots\sigma_r=1,生成传递群当且仅当源曲线连通。改变纤维标号同时共轭全部置换;改变环路系统则施加 Hurwitz 辫群作用。因此覆盖的组合数据是同时共轭类与辫群轨道,而不是某个固定书写的元组。

给定置换元组,源亏格由

2g(C)2=2n+i(nc(σi))2g(C)-2=-2n+\sum_i\bigl(n-c(\sigma_i)\bigr)

计算,其中 c(σ)c(\sigma) 是循环数。每个长度 ee 的循环对应分支纤维中的一点,贡献 e1e-1。这是从 dessin 或单值数据快速检查模型的首要公式。

若群作用不本原,覆盖可分解为非平凡中间覆盖;块系统对应函数域中间域。计算中先用置换群算法寻找块,常能把一个高次数方程分解为两个低次数问题。若群本原但非 2-传递,点稳定子轨道仍可提示低次数辅助对应。

从代数模型恢复单值群可用数值路径提升,也可在好素数上因式分解特化多项式,利用 Frobenius 循环型推断 Galois 群。最终证明通常结合判别式、已知生成循环型、传递性和群分类;仅看到几个素数的因式分解模式只提供下界证据。

练习与解答Riemann–Hurwitz 与置换

练习 1。次数 7 覆盖的三个置换循环型为 773,2,1,13,2,1,14,2,14,2,1。求源亏格。

解。三个贡献为 66(31)+(21)=3(3-1)+(2-1)=3(41)+(21)=4(4-1)+(2-1)=4,总 13。于是 2g2=14+13=12g-2=-14+13=-1,不可能。故这种数据不存在;Riemann–Hurwitz 还提供奇偶一致性筛选。

练习 2。为何置换元组乘积必须为 1?

解。目标去掉分支点后的基本群中,依次绕所有小环路的乘积可缩为常值环路;单值表示把该关系送到置换乘积 1。

练习 3。若生成群不传递意味着什么?

解。纤维分成多个轨道,解析延拓不能互达,源覆盖分裂为相应多个连通分量。

深入补充:分支循环、亏格与覆盖自同构的统一计算

f:X𝐏1f:X\to\mathbf P^1 是次数 dd 的连通覆盖,分支值取为 b1,,brb_1,\ldots,b_r。选择基点与纤维编号后得到分支循环 σ1,,σrSd\sigma_1,\ldots,\sigma_r\in S_d,满足 σ1σr=1\sigma_1\cdots\sigma_r=1 且生成传递子群。若 c(σ)c(\sigma) 表示置换的循环个数,则每个分支点的总分歧贡献为 dc(σ)d-c(\sigma)

定理 置换形式的Riemann–Hurwitz公式

对上述覆盖,

2g(X)2=2d+i=1r(dc(σi)),2g(X)-2=-2d+\sum_{i=1}^r\bigl(d-c(\sigma_i)\bigr),

因而

g(X)=1d+12i=1r(dc(σi)).g(X)=1-d+\frac12\sum_{i=1}^r\bigl(d-c(\sigma_i)\bigr).

在三分支点情形,这可改写为

g(X)=1+dc(σ0)c(σ1)c(σ)2.g(X)=1+\frac{d-c(\sigma_0)-c(\sigma_1)-c(\sigma_\infty)}2.

这个公式在枚举置换三元组时应当最先使用:它只依赖循环型,可在任何方程求解之前排除亏格错误的候选。比如取

σ0=(1234567),σ1=(12)(34)(56).\sigma_0=(1\ 2\ 3\ 4\ 5\ 6\ 7),\qquad \sigma_1=(1\ 2)(3\ 4)(5\ 6).

σ=(σ0σ1)1\sigma_\infty=(\sigma_0\sigma_1)^{-1},其循环型为 (4)(1)(1)(1)(4)(1)(1)(1)。于是三个循环数为 1,4,41,4,4,得到 g=0g=0。这个计算无需知道覆盖方程,却已经确定源曲线是有理曲线。

定理 覆盖自同构等于单值群的中心化子

固定纤维编号后,基底上恒等的覆盖自同构群满足

Aut𝐏1(X)CSd(G),\operatorname{Aut}_{\mathbf P^1}(X)\cong C_{S_d}(G),

其中 G=σ1,,σrG=\langle\sigma_1,\ldots,\sigma_r\rangle 是单值群,CSd(G)C_{S_d}(G) 是其在 SdS_d 中的中心化子。

证明的核心是路径提升。覆盖自同构在未分支纤维上给出一个置换 τ\tau;它必须与沿每条闭路的解析延拓交换,所以 τσi=σiτ\tau\sigma_i=\sigma_i\tau。反过来,与单值群交换的纤维置换与所有路径提升相容,因而延拓为覆盖自同构。由此立即得到一个实用判据:若中心化子平凡,则覆盖没有非平凡的基底上自同构;若 GG 在纤维上正则作用,则中心化子是相反的正则表示,阶为 dd

分支循环还给出局部微分的精确阶数。若 PXP\in X 位于 bib_i 上方且对应循环长度 ee,可取局部参数使

tbi=ue,dt=eue1du.t-b_i=u^e,\qquad dt=e u^{e-1}du.

因此 ordP(dt)=e1\operatorname{ord}_P(dt)=e-1。把所有点的这些局部贡献相加,再加入基底典范除子的拉回,便得到

KX=f*K𝐏1+R,K_X=f^*K_{\mathbf P^1}+R,

其中 R=P(eP1)PR=\sum_P(e_P-1)P。这不仅证明亏格公式,也可用于构造微分:若希望写出 H0(X,KX)H^0(X,K_X) 的显式基,必须让候选微分在每个分支点满足由 ePe_P 决定的零极点约束。

算法 覆盖数据的零方程预检

给定循环型,依次执行:计算亏格;检查生成群传递性;计算中心化子以预测自同构;计算块系统以判断覆盖是否可分解;最后才建立系数方程。若存在非平凡块系统,则覆盖分解为 XY𝐏1X\to Y\to\mathbf P^1,直接求次数 dd 的方程往往会引入大量冗余变量,而分层求两个较低次数的映射更稳定。

补充计算:分支循环证书、亏格账本与覆盖自同构

定理 分支循环形式的 Riemann–Hurwitz 公式

设 \(σ_1,…,σ_r∈S_n\) 满足 \(σ_1···σ_r=1\),且生成传递子群。记 c(σ) 为包含不动点的循环个数,\(ind(σ)=n-c(σ)\)。对应连通次数 n 覆盖 \(X→P^1\) 的亏格满足 2g(X)2=2n+j=1rind(σj), 2g(X)-2=-2n+\sum_{j=1}^r\operatorname{ind}(σ_j), 并且覆盖的甲板变换群同构于 \(C_{S_n}(⟨σ_1,…,σ_r⟩)\)。

证明 由局部分歧指数与纤维标号作用逐项求和

\(σ_j\) 的每个长度 e 的循环对应分支值上方一点,其局部分歧指数为 e。该循环对分歧除子的贡献 e-1;对全部循环求和为 \(n-c(σ_j)=ind(σ_j)\)。将所有分支值的贡献代入 Riemann–Hurwitz 公式 \(K_X=f^*K_{P^1}+R\),并取次数,即得第一式。

固定非分支基点及其纤维标号。甲板变换保持覆盖,故在纤维上给出一个与每条路径提升作用交换的置换,因此落在全部 \(σ_j\) 的共同中心化子中。反之,共同中心化子的置换与路径提升相容,可由解析延拓在整个非分支覆盖上定义自同构;有限覆盖的正规性使其唯一延拓过分支点。两种构造互逆。

Python 置换运算、传递性、单值群与中心化子核验
from dataclasses import dataclass
from itertools import permutations, product
from math import gcd

Permutation = tuple[int, ...]

def identity(n: int) -> Permutation:
    return tuple(range(n))

def compose(a: Permutation, b: Permutation) -> Permutation:
    """a∘b: first b, then a."""
    return tuple(a[b[i]] for i in range(len(a)))

def inverse(a: Permutation) -> Permutation:
    out = [0] * len(a)
    for i, j in enumerate(a):
        out[j] = i
    return tuple(out)

def power(a: Permutation, k: int) -> Permutation:
    if k < 0:
        return power(inverse(a), -k)
    out = identity(len(a))
    base = a
    while k:
        if k & 1:
            out = compose(out, base)
        base = compose(base, base)
        k >>= 1
    return out

def cycles(a: Permutation, include_fixed: bool = True) -> list[tuple[int, ...]]:
    seen = [False] * len(a)
    result = []
    for i in range(len(a)):
        if seen[i]:
            continue
        c = []
        j = i
        while not seen[j]:
            seen[j] = True
            c.append(j)
            j = a[j]
        if include_fixed or len(c) > 1:
            result.append(tuple(c))
    return result

def cycle_type(a: Permutation) -> tuple[int, ...]:
    return tuple(sorted((len(c) for c in cycles(a)), reverse=True))

def support(a: Permutation) -> frozenset[int]:
    return frozenset(i for i, j in enumerate(a) if i != j)

def orbit(generators: list[Permutation], start: int) -> frozenset[int]:
    q = [start]
    seen = {start}
    while q:
        x = q.pop()
        for g in generators:
            y = g[x]
            if y not in seen:
                seen.add(y)
                q.append(y)
    return frozenset(seen)

def generated_group(generators: list[Permutation]) -> set[Permutation]:
    n = len(generators[0])
    gens = generators + [inverse(g) for g in generators]
    group = {identity(n)}
    frontier = [identity(n)]
    while frontier:
        h = frontier.pop()
        for g in gens:
            gh = compose(g, h)
            if gh not in group:
                group.add(gh)
                frontier.append(gh)
    return group

def centralizer_in_symmetric(generators: list[Permutation]) -> set[Permutation]:
    n = len(generators[0])
    result = set()
    for h in permutations(range(n)):
        h = tuple(h)
        if all(compose(h, g) == compose(g, h) for g in generators):
            result.add(h)
    return result

def index_defect(a: Permutation) -> int:
    return len(a) - len(cycles(a))

def genus_from_branch_cycles(branch: list[Permutation]) -> int:
    n = len(branch[0])
    defect = sum(index_defect(g) for g in branch)
    numerator = 2 - 2*n + defect
    if numerator % 2:
        raise ValueError("Riemann-Hurwitz parity failure")
    return numerator // 2

def check_branch_tuple(branch: list[Permutation]) -> dict:
    n = len(branch[0])
    prod_perm = identity(n)
    for g in branch:
        prod_perm = compose(prod_perm, g)
    transitive = len(orbit(branch, 0)) == n
    group = generated_group(branch)
    deck = centralizer_in_symmetric(branch)
    return {
        "degree": n,
        "product_is_one": prod_perm == identity(n),
        "transitive": transitive,
        "types": [cycle_type(g) for g in branch],
        "genus": genus_from_branch_cycles(branch),
        "monodromy_order": len(group),
        "deck_order": len(deck),
    }

def perm_from_cycles(n: int, *cycs: tuple[int, ...]) -> Permutation:
    a = list(range(n))
    for cyc in cycs:
        for x, y in zip(cyc, cyc[1:] + cyc[:1]):
            a[x] = y
    return tuple(a)

examples = {
    "degree-3 polynomial": [
        perm_from_cycles(3, (0,1)),
        perm_from_cycles(3, (1,2)),
    ],
    "tetrahedral dessin": [
        perm_from_cycles(4, (0,1,2)),
        perm_from_cycles(4, (0,3,2)),
    ],
    "degree-5 dihedral": [
        perm_from_cycles(5, (0,1,2,3,4)),
        perm_from_cycles(5, (1,4), (2,3)),
    ],
    "degree-6 genus-one": [
        perm_from_cycles(6, (0,1,2), (3,4,5)),
        perm_from_cycles(6, (0,3), (1,4), (2,5)),
    ],
}

for name, first_two in examples.items():
    sigma0, sigma1 = first_two
    sigma_inf = inverse(compose(sigma0, sigma1))
    cert = check_branch_tuple([sigma0, sigma1, sigma_inf])
    print(name)
    for k, v in cert.items():
        print(f"  {k:18s}: {v}")

print("\nlocal ramification ledger for the genus-one example:")
branch = examples["degree-6 genus-one"]
branch.append(inverse(compose(*branch)))
for label, sigma in zip(("0", "1", "∞"), branch):
    cyc = cycles(sigma)
    defects = [len(c)-1 for c in cyc]
    print(f"  over {label}: cycles={cyc}, defects={defects}, total={sum(defects)}")
运行结果 四组分支数据的亏格与群阶
degree-3 polynomial
  degree            : 3
  product_is_one    : True
  transitive        : True
  types             : [(2, 1), (2, 1), (3,)]
  genus             : 0
  monodromy_order   : 6
  deck_order        : 1
tetrahedral dessin
  degree            : 4
  product_is_one    : True
  transitive        : True
  types             : [(3, 1), (3, 1), (2, 2)]
  genus             : 0
  monodromy_order   : 12
  deck_order        : 1
degree-5 dihedral
  degree            : 5
  product_is_one    : True
  transitive        : True
  types             : [(5,), (2, 2, 1), (2, 2, 1)]
  genus             : 0
  monodromy_order   : 10
  deck_order        : 1
degree-6 genus-one
  degree            : 6
  product_is_one    : True
  transitive        : True
  types             : [(3, 3), (2, 2, 2), (6,)]
  genus             : 1
  monodromy_order   : 6
  deck_order        : 6

local ramification ledger for the genus-one example:
  over 0: cycles=[(0, 1, 2), (3, 4, 5)], defects=[2, 2], total=4
  over 1: cycles=[(0, 3), (1, 4), (2, 5)], defects=[1, 1, 1], total=3
  over ∞: cycles=[(0, 5, 1, 3, 2, 4)], defects=[5], total=5
计算 亏格一六次例的分歧总和

循环型为 (3,3)、(2,2,2)、(6)。三处亏损分别为 (3-1)+(3-1)=4、3·(2-1)=3、6-1=5,总亏损为 12。因此 2g-2=-12+12=0,故 g=1。共同中心化子的阶为 6,等于正则 S_3 覆盖的甲板群阶。

Lecture 4 / 第 4 讲

Belyi 映射、童画与算术曲线

说明三点分支覆盖为何同时连接拓扑、组合、Galois 作用和显式方程。

Belyi映射童画Galois

1. Belyi 映射

定义Belyi 映射

Belyi 映射是有限态射 β:X𝐏1\beta:X\to\mathbf P^1,其分支值包含在 {0,1,}\{0,1,\infty\} 中。允许其中某个值实际上不分支。

定理Belyi 定理

复光滑射影曲线 XX 可定义在 𝐐¯\overline{\mathbf Q} 上,当且仅当 XX 存在 Belyi 映射。

证明证明思路

“存在 Belyi 映射 \Rightarrow 可定义在 𝐐¯\overline{\mathbf Q}”来自固定次数和分歧型的覆盖只有有限多个同构类,Galois 作用因而给出有限轨道。“可定义在 𝐐¯\overline{\mathbf Q} \Rightarrow 存在 Belyi 映射”先取一个到 𝐏1\mathbf P^1 的函数,再用定义在数域上的有理函数反复把有限分支集压到三个点。完整证明需要控制分支集在每次复合中的变化。

2. 童画与组合编码

D=β1([0,1])D=\beta^{-1}([0,1])。把 00 的原像染成黑点、11 的原像染成白点,边是区间 (0,1)(0,1) 的提升,就得到嵌入曲面的二分图,称为 Grothendieck dessin d’enfant(童画)。黑点、白点和面的度数分别给出 g0,g1,gg_0,g_1,g_\infty 的循环长度。

定理童画—置换三元组对应

连通的、带编号边的童画与满足 g0g1g=1g_0g_1g_\infty=1 且生成传递群的置换三元组一一对应;忘掉编号对应于同时共轭。

3. 模曲线作为 Belyi 覆盖

经典模曲线 X(N),X1(N),X0(N)X(N),X_1(N),X_0(N)X(1)𝐏j1X(1)\cong\mathbf P^1_j 的映射只在 j=0,1728,j=0,1728,\infty 分支。归一化 j/1728j/1728 后,分支值正是 0,1,0,1,\infty。这解释了课程后半部分为何能把模曲线公式视为 Belyi 方程。

练习由循环型求亏格

给定次数 nn 与三个分拆 λ0,λ1,λ\lambda_0,\lambda_1,\lambda_\infty,证明

2g2=2n+t{0,1,}(n(λt)).2g-2=-2n+\sum_{t\in\{0,1,\infty\}}\bigl(n-\ell(\lambda_t)\bigr).

用它快速排除不可能的分歧数据。

Belyi 定理及其应用的完整展开

当分支点恰为三个时,把它们规范化为 0,1,0,1,\infty。给定次数 nn,可能的置换三元组只有有限多个,所以相应曲线与映射组成零维集合,并定义在某个数域上。Belyi 的定理给出令人惊讶的逆命题:一条复代数曲线可在 𝐐¯\overline{\mathbf Q} 上定义,当且仅当它承认一个只在 0,1,0,1,\infty 上分歧的非常值有理函数。更强地,对曲线上任意有限个代数点,可选择 Belyi 函数把它们全部送入 {0,1,}\{0,1,\infty\}

这说明三点分歧覆盖并非偶然的小类,而是编码全部数域上代数曲线的媒介。课程把这种函数作为第一个主要计算对象。原讲义建议参阅 Serre 的《Topics in Galois Theory》,其中讨论了 Belyi 映射在逆 Galois 问题中的应用。若一条亏格 g>1g>1 的曲线达到 Hurwitz 上界 84(g1)84(g-1),或者更一般地有超过 12(g1)12(g-1) 个自同构,则商映射 CC/Aut(C)C\to C/\operatorname{Aut}(C) 是 Belyi 映射;这解释了它们为何在高度对称曲线中频繁出现。

童画的组合编码

取区间 [0,1][0,1] 的逆像 f1([0,1])f^{-1}([0,1])。在 00 的原像处放黑顶点,在 11 的原像处放白顶点,每条边映到 [0,1][0,1]。所得嵌入定向曲面的二分图称为 Grothendieck dessin d’enfant(童画)。黑顶点度数给出 g0g_0 的循环长度,白顶点度数给出 g1g_1 的循环长度,面度的一半给出 gg_\infty 的循环长度。曲面的定向记录每个顶点周围半边的循环次序,从而恢复置换三元组。

因此,置换三元组、童画、三点分歧覆盖和函数域扩张是同一对象的四种语言。置换适合枚举和群论;童画适合可视化与判断原始性;函数域适合精确代数计算;几何覆盖适合使用除子、微分与模空间。

逆 Galois 问题中的作用

若三元组生成群 GG,则 Belyi 覆盖的 Galois 闭包给出一个以 GG 为几何单值群的正则扩张。结合定义域理论与 Hilbert 特化定理,可以把参数特化成 𝐐\mathbf Q 上的数域扩张。原讲义提到,借助大量实例与更深入理论,除可能的 M23M_{23} 外,每个散在单群都已知是无穷多个 𝐐\mathbf Q 扩张的 Galois 群。某些构造次数巨大,几乎不可能写出完整数域;对 M11M_{11} 等较小群以及许多非散在群,则确实能够计算 Belyi 覆盖并得到显式多项式。

原讲义列举的出现领域

Belyi 映射还出现在以下工作中:由 abcabc 猜想推出 Mordell 型结论;Klein 四次曲线 x3y+y3z+z3x=0x^3y+y^3z+z^3x=0 的数论;分歧覆盖的其他算术表现;与算术三角群可公度的 Shimura 曲线计算;利用格约化研究靠近曲线的有理点以及小的非零 |x3y2||x^3-y^2|;具有阶 16816881688\cdot168 Galois 群的七次、八次三项式;以及关于数论中 abcabc 的综述。原讲义的观点是:Belyi 函数在许多表面上互不相干的问题中反复出现,其普遍性本身值得系统研究。

有理重构插曲

计算 Belyi 映射时,经常先得到一个高精度实数、复数或 pp-进数近似,并预期它是有理数 r=a/br=a/b。若已知 |a|,|b|H|a|,|b|\le H,候选数约有 H2H^2 个,所以实近似至少要精确到约 1/H21/H^2;若分子分母各有 dd 位,通常至少需要 2d2d 位精度,并应留出安全余量,以便区分真正的小关系与随机巧合。连续分数或Euclidean 算法能在关于 d=logHd=\log H 的多项式时间内恢复 a,ba,b

同一思想在非阿基米德情形中完全类似。若知道 rmodpdr\bmod p^d,只要 pd>H2p^d>H^2,便能唯一恢复受界的 a,ba,b。更一般地,知道 rmodNr\bmod NNH2N\gg H^2 时,寻找格

{(a,b)𝐙2:arb(modN)}\{(a,b)\in\mathbf Z^2:a\equiv rb\pmod N\}

中的最短非零向量即可。对实近似,可给 𝐙2\mathbf Z^2 配二次型

Q(a,b)=(arb)2+ε(a2+b2),Q(a,b)=(a-rb)^2+\varepsilon(a^2+b^2),

短向量同时控制逼近误差与分子分母高度。这一二维图景既回到 Cornacchia 算法,也预示了后续的同时逼近、整数关系和 LLL 恢复。

关于 X0(5782)X_0(5782) 的更正与说明

原讲义曾即兴说,显式写出 X0(5782)X_0(5782) 几乎没有希望,随后作了更正。因为

5782=24959,5782=2\cdot49\cdot59,

且这些因子两两互素,所以 X0(5782)X_0(5782) 可看成 X0(2),X0(49),X0(59)X_0(2),X_0(49),X_0(59) 关于 jj-直线 X(1)X(1) 的纤维积。相应映射次数分别为 3,56,603,56,60,方程可写为

j2(x2)=j49(x49,y49)=j59(x59,y59).j_2(x_2)=j_{49}(x_{49},y_{49})=j_{59}(x_{59},y_{59}).

其中 X0(2)X_0(2) 是有理曲线,X0(49)X_0(49) 是具有复乘的椭圆曲线,X0(59)X_0(59) 是亏格 5 的超椭圆曲线。虽然 j49j_{49}j59j_{59} 的显式表达式并不漂亮,这些曲线和映射仍在可计算范围内。

补充:Belyi 定理构造的核心步骤

从“有 Belyi 映射”推出曲线定义在 𝐐¯\overline{\mathbf Q} 较直接:固定次数与分歧型的三点覆盖只有有限多个,方程系统系数在 𝐐\mathbf Q 中,因此其孤立解坐标为代数数。反向更深。对定义在数域上的曲线 CC,先取一个非恒定函数 g:C𝐏1g:C\to\mathbf P^1,其分支值均为代数数。接着构造 𝐏1\mathbf P^1 上的有理函数,把有限个代数分支值逐步送到 𝐐\mathbf Q,再送到 {0,1,}\{0,1,\infty\},且不产生新的非代数分支值。与 gg 复合即得 Belyi 映射。

把任意指定有限代数点集一并送到三点集,可先把这些点像加入待处理分支值集合。构造中次数通常极大,所以定理本身不提供实际最小 Belyi 映射;显式计算是独立且困难的问题。

童画中的 Euler 特征

若童画有 BB 个黑点、WW 个白点、E=nE=n 条边、FF 个面,则

22g=B+WE+F.2-2g=B+W-E+F.

这里 B=c(g0)B=c(g_0)W=c(g1)W=c(g_1)F=c(g)F=c(g_\infty),立即恢复置换形式的Riemann–Hurwitz公式。面边界长度等于 2e2e,其中 ee\infty 上对应点的分歧指数,因为每条边在边界遍历中出现两次。

绝对与内在 Galois 作用

Gal(𝐐¯/𝐐)\operatorname{Gal}(\overline{\mathbf Q}/\mathbf Q) 作用在 Belyi 映射系数上,因而忠实作用在童画集合上。它保持次数、亏格、三种度数分拆和自同构群,却可能改变嵌入的细致组合结构。童画理论的魅力之一,是把绝对 Galois 群这个极复杂对象表示为有限组合对象上的置换群。

Hurwitz 上界的推导

CC 亏格 g>1g>1,令 G=Aut(C)G=\operatorname{Aut}(C),商曲线亏格为 g0g_0,分歧指数为 e1,,ere_1,\ldots,e_r。Riemann–Hurwitz 给出

2g2=|G|(2g02+i=1r(11ei)).2g-2=|G| \left(2g_0-2+\sum_{i=1}^{r}\left(1-\frac1{e_i}\right)\right).

括号内最小正值为 1/421/42,在 g0=0g_0=0(e1,e2,e3)=(2,3,7)(e_1,e_2,e_3)=(2,3,7) 时取得。因此 |G|84(g1)|G|\le84(g-1)。若 |G|>12(g1)|G|>12(g-1),括号小于 1/61/6,迫使商为球面且分支点不超过三个,所以商映射是 Belyi 映射。

正则童画与三角群

当 Belyi 覆盖本身 Galois 时,童画称为正则童画。它来自三角群

Δ(a,b,c)=x,y,z:xa=yb=zc=xyz=1\Delta(a,b,c)= \langle x,y,z:x^a=y^b=z^c=xyz=1\rangle

的有限商。Hurwitz 曲线对应 (2,3,7)(2,3,7)。Klein 四次曲线是最小例子,群 PSL2(𝐅7)\operatorname{PSL}_2(\mathbf F_7) 阶 168,恰等于 84(31)84(3-1)

计算中的规范选择

目标三点可在六种方式中排列,分别对应 f,1f,1/f,f/(f1)f,1-f,1/f,f/(f-1) 等 anharmonic 变换。源曲线也可能有自同构。数据库与比较算法必须先固定规范,否则同一映射会出现多种方程。常用不变量包括 passport、单值群、定义域、童画自同构群与分支循环的有序共轭类。

进一步:Belyi 定理、dessin 与定义域

Belyi 定理断言:光滑射影复曲线可定义在 𝐐¯\overline{\mathbf Q} 上,当且仅当它存在只在三个点分歧的非恒定映射到 𝐏1\mathbf P^1。把三个分支值经 Möbius 变换规范为 0,1,0,1,\infty,得到 Belyi 映射。定理的“存在”并不提供低次数或低高度模型,显式构造仍是困难的计算问题。

dessin 是 f1([0,1])f^{-1}([0,1]) 在定向曲面上的二分图:黑顶点在 f1(0)f^{-1}(0),白顶点在 f1(1)f^{-1}(1),面对应 f1()f^{-1}(\infty)。顶点度与面边界长度给出三个置换的循环长度。曲面定向编码循环次序,因此单纯的抽象二分图不足以确定覆盖,还需旋转系统。

dessin 的自同构群等于与三个置换都交换的置换中心化子,也等于覆盖在目标固定时的 deck 变换群。若自同构群非平凡,模数域到定义域之间可能有下降障碍。模数域由 Galois 稳定的同构类确定;实际方程可能需扩张,这通常由非平凡自同构群产生的 2-上同调类控制。

计算 Belyi 映射时,先从循环型写因子化模板,例如 f=Ae/Cf=A^e/Cf1=Bd/Cf-1=B^d/C,把分歧条件转为多项式恒等式。随后消除源、目标的 PGL2\operatorname{PGL}_2 自由度。规范化过弱会留下正维伪族,过强则可能排除所有解,尤其当所选分支纤维没有足够多个有理点时。

精确验证需检查源曲线光滑、函数非恒定、次数、三个特殊纤维的完整因式分解以及导数没有额外零点。对有理函数 f=P/Qf=P/Q,临界点由 PQPQP'Q-PQ' 给出;要同时处理无穷远和 P,QP,Q 的公共因子。通过结果式消元可证明所有临界值属于 {0,1,}\{0,1,\infty\}

练习与解答Belyi 映射认证

练习 1。说明 f(x)=4x(1x)f(x)=4x(1-x) 是次数 2 的 Belyi 多项式并写循环型。

解。f1(0)={0,1}f^{-1}(0)=\{0,1\} 均简单,f1=(2x1)2f-1=-(2x-1)^21/21/2 二重,\infty 完全二重。循环型为 (1,1),(2),(2)(1,1),(2),(2)

练习 2。若把目标三个分支值从 a,b,ca,b,c 变为 0,1,0,1,\infty,写出一种 Möbius 变换。

解。可取 z((za)(bc))/((zc)(ba))z\mapsto ((z-a)(b-c))/((z-c)(b-a)),它依次送 a,b,ca,b,c0,1,0,1,\infty

练习 3。为什么只检查 fff1f-1 的因式分解仍需检查导数?

解。模板可能未约去公共因子、在无穷远产生额外临界点,或遗漏不在三个指定纤维中的导数零点;导数/结果式提供全局排除。

深入补充:童画的 Euler 公式、清洁化与算术不变量

对 Belyi 映射 β:X𝐏1\beta:X\to\mathbf P^1,童画定义为 β1([0,1])\beta^{-1}([0,1])。把 00 上方点画成黑点,11 上方点画成白点,每个映射到开区间 (0,1)(0,1) 的分支给一条边。若映射次数为 dd,边数恰为 dd;黑、白顶点度数分别是 σ0,σ1\sigma_0,\sigma_1 的循环长度,面度数由 σ\sigma_\infty 的循环长度决定。

定理 童画的 Euler–置换公式

V0=c(σ0),V1=c(σ1),F=c(σ),E=d.V_0=c(\sigma_0), \qquad V_1=c(\sigma_1), \qquad F=c(\sigma_\infty), \qquad E=d.

V0+V1E+F=22g(X).V_0+V_1-E+F=2-2g(X).

等价地,

g(X)=1+dc(σ0)c(σ1)c(σ)2.g(X)=1+\frac{d-c(\sigma_0)-c(\sigma_1)-c(\sigma_\infty)}2.

这给出一个纯组合的亏格算法:只需沿每个置换数循环,无需构造曲面或方程。童画连通当且仅当 σ0,σ1\langle\sigma_0,\sigma_1\rangle 在边集上传递;童画的定向自同构群是同时中心化 σ0,σ1\sigma_0, \sigma_1 的置换群。

若源曲线为 𝐏1\mathbf P^1β\beta 是多项式,\infty 上方只有一个点,所以童画只有一个面;嵌入球面的连通二分图满足 VE+1=2V-E+1=2,即 E=V1E=V-1,故必为树。反之,每棵带循环次序的平面二分树都对应一个 Shabat 多项式,唯一性只差源、目标的仿射归一化。

构造 任意童画的清洁化

给定 Belyi 映射 β\beta,复合

β̃=4β(1β)\widetilde\beta=4\beta(1-\beta)

仍是 Belyi 映射,并且 β̃1(1)\widetilde\beta^{-1}(1) 上的分歧指数全部为 22;相应童画称为清洁童画。组合上,这相当于在原童画每条边中插入一个二价白点,并重新编码黑白颜色。

清洁化把一般童画化为“白点全为二价”的情形,常用于把童画编码为带旋转系统的普通图。但次数加倍,单值群也嵌入更大的置换群,因此显式方程求解不一定更容易;它主要是分类与理论归约工具。

Galois 作用保持许多离散量:次数、亏格、passport、单值群的同构类型、覆盖自同构群阶以及童画是否正则。然而 passport 通常不是完整不变量:同一循环型可有多个辫群轨道,甚至分属不同 Galois 轨道。更细的不变量包括单值群中的 Nielsen 类、子覆盖格、点稳定子的轨道长度、以及由童画邻接算子得到的谱。

算法 从置换三元组重建嵌入图

把边标为 1,,d1, \ldots,dσ0\sigma_0 每个循环给一个黑点,并按循环顺序规定其周围半边的逆时针次序;σ1\sigma_1 同理给白点。沿 σ=(σ0σ1)1\sigma_\infty=(\sigma_0\sigma_1)^{-1} 的循环追踪面边界。由此可生成旋转系统、计算 Euler 特征,并在不作数值绘图的情况下判定两个带标号童画是否同构。

若要比较无标号童画,可先用顶点度、多重边与面度做分层哈希,再求同时共轭的置换。最终认证应输出显式共轭置换;仅凭两幅平面图“看起来一样”不够,因为不同的局部循环次序可能给出不同的定向曲面嵌入。

补充计算:童画的置换模型、清洁化与组合不变量

定理 童画的 Euler 公式与清洁化保持亏格

设 \((σ_0,σ_1,σ_∞)\) 为次数 n 的传递置换三元组,\(σ_0σ_1σ_∞=1\)。若 B、W、F 分别为三置换的循环数,则 22g=B+W+Fn. 2-2g=B+W+F-n. 在每条边中插入一个二价白点得到清洁童画时,边数由 n 变为 2n,新增 n 个白点,而黑点与面数按带状图细分不变,因此 Euler 特征与亏格不变。

证明 由带状图胞腔分解与边细分计算

\(σ_0\) 的循环给出黑顶点,\(σ_1\) 的循环给出白顶点,\(σ_∞\) 的循环给出面;每个标号对应一条边。连通性等价于 \(⟨σ_0,σ_1⟩\) 的传递性。于是该定向曲面具有 B+W 个零胞腔、n 个一胞腔、F 个二胞腔,故 \(χ=B+W-n+F=2-2g\)。

清洁化把每条旧边分为两条新边:V 增加 n,E 增加 n,F 不变,所以 \(χ'=(V+n)-(E+n)+F=χ\)。置换模型中,新白置换恰为 n 个换位,故所有白顶点度数为 2;新黑置换在两类半边上分别承载原黑、原白旋转,从而完整保留原带状邻接数据。

Python passport、关联矩阵、自同构与边细分程序
from dataclasses import dataclass
from itertools import permutations
from collections import Counter, deque

Perm = tuple[int, ...]

def compose(a: Perm, b: Perm) -> Perm:
    return tuple(a[b[i]] for i in range(len(a)))

def inverse(a: Perm) -> Perm:
    out = [0]*len(a)
    for i,j in enumerate(a):
        out[j] = i
    return tuple(out)

def cycles(a: Perm) -> list[tuple[int, ...]]:
    seen = set()
    result = []
    for i in range(len(a)):
        if i in seen:
            continue
        cyc = []
        j = i
        while j not in seen:
            seen.add(j)
            cyc.append(j)
            j = a[j]
        result.append(tuple(cyc))
    return result

def cycle_type(a: Perm) -> tuple[int, ...]:
    return tuple(sorted((len(c) for c in cycles(a)), reverse=True))

def perm_from_cycles(n: int, data: list[tuple[int,...]]) -> Perm:
    out = list(range(n))
    for cyc in data:
        for x,y in zip(cyc, cyc[1:]+cyc[:1]):
            out[x] = y
    return tuple(out)

@dataclass(frozen=True)
class Dessin:
    sigma_black: Perm
    sigma_white: Perm

    def __post_init__(self):
        if len(self.sigma_black) != len(self.sigma_white):
            raise ValueError("degree mismatch")

    @property
    def degree(self) -> int:
        return len(self.sigma_black)

    @property
    def sigma_face(self) -> Perm:
        return inverse(compose(self.sigma_black, self.sigma_white))

    @property
    def passport(self):
        return (
            cycle_type(self.sigma_black),
            cycle_type(self.sigma_white),
            cycle_type(self.sigma_face),
        )

    @property
    def euler_characteristic(self) -> int:
        return (
            len(cycles(self.sigma_black))
            + len(cycles(self.sigma_white))
            + len(cycles(self.sigma_face))
            - self.degree
        )

    @property
    def genus(self) -> int:
        chi = self.euler_characteristic
        if (2-chi) % 2:
            raise ArithmeticError("nonorientable or invalid permutation data")
        return (2-chi)//2

    def connected_components(self) -> list[frozenset[int]]:
        gens = (self.sigma_black, self.sigma_white,
                inverse(self.sigma_black), inverse(self.sigma_white))
        unseen = set(range(self.degree))
        parts = []
        while unseen:
            start = min(unseen)
            q = deque([start])
            comp = {start}
            unseen.remove(start)
            while q:
                x = q.popleft()
                for g in gens:
                    y = g[x]
                    if y not in comp:
                        comp.add(y)
                        unseen.discard(y)
                        q.append(y)
            parts.append(frozenset(comp))
        return parts

    def automorphisms(self) -> list[Perm]:
        result = []
        for tau0 in permutations(range(self.degree)):
            tau = tuple(tau0)
            if (compose(tau, self.sigma_black)
                    == compose(self.sigma_black, tau)
                and compose(tau, self.sigma_white)
                    == compose(self.sigma_white, tau)):
                result.append(tau)
        return result

    def incidence_matrix(self) -> list[list[int]]:
        black = cycles(self.sigma_black)
        white = cycles(self.sigma_white)
        b_index = {dart:i for i,c in enumerate(black) for dart in c}
        w_index = {dart:j for j,c in enumerate(white) for dart in c}
        matrix = [[0]*len(white) for _ in black]
        for dart in range(self.degree):
            matrix[b_index[dart]][w_index[dart]] += 1
        return matrix

    def invariant_record(self) -> dict:
        return {
            "degree": self.degree,
            "passport": self.passport,
            "components": len(self.connected_components()),
            "chi": self.euler_characteristic,
            "genus": self.genus,
            "aut_order": len(self.automorphisms()),
            "black_valencies": Counter(map(len, cycles(self.sigma_black))),
            "white_valencies": Counter(map(len, cycles(self.sigma_white))),
            "face_valencies": Counter(map(len, cycles(self.sigma_face))),
        }

def subdivide_edges(dessin: Dessin) -> Dessin:
    """
    Insert a white bivalent vertex in every edge.
    New darts are 0,...,2n-1; pair 2e,2e+1 belongs to the new white vertex.
    The black rotation acts on even darts as the old black rotation and
    fixes the odd copy; face data is induced by the ribbon structure.
    """
    n = dessin.degree
    sb = list(range(2*n))
    sw = list(range(2*n))
    for e in range(n):
        sb[2*e] = 2*dessin.sigma_black[e]
        sw[2*e] = 2*e+1
        sw[2*e+1] = 2*e
    # Old white rotations are transferred to the odd darts.
    for e in range(n):
        sb[2*e+1] = 2*dessin.sigma_white[e]+1
    return Dessin(tuple(sb), tuple(sw))

examples = {
    "segment": Dessin(
        perm_from_cycles(1, [(0,)]),
        perm_from_cycles(1, [(0,)])
    ),
    "degree-3 tree": Dessin(
        perm_from_cycles(3, [(0,1,2)]),
        perm_from_cycles(3, [(0,1),(2,)])
    ),
    "tetrahedral": Dessin(
        perm_from_cycles(4, [(0,1,2),(3,)]),
        perm_from_cycles(4, [(0,3,2),(1,)])
    ),
    "torus hexagon": Dessin(
        perm_from_cycles(6, [(0,1,2),(3,4,5)]),
        perm_from_cycles(6, [(0,3),(1,4),(2,5)])
    ),
}

for name, dessin in examples.items():
    record = dessin.invariant_record()
    print(name)
    for k,v in record.items():
        print(f"  {k:17s}: {v}")
    print("  incidence:")
    for row in dessin.incidence_matrix():
        print("   ", row)

print("\nedge subdivision:")
for name in ("degree-3 tree", "tetrahedral"):
    old = examples[name]
    new = subdivide_edges(old)
    print(
        f"{name:15s}: degree {old.degree}->{new.degree}, "
        f"genus {old.genus}->{new.genus}, "
        f"white type {cycle_type(new.sigma_white)}"
    )
运行结果 树、四面体童画与亏格一童画的组合记录
segment
  degree           : 1
  passport         : ((1,), (1,), (1,))
  components       : 1
  chi              : 2
  genus            : 0
  aut_order        : 1
  black_valencies  : Counter({1: 1})
  white_valencies  : Counter({1: 1})
  face_valencies   : Counter({1: 1})
  incidence:
    [1]
degree-3 tree
  degree           : 3
  passport         : ((3,), (2, 1), (2, 1))
  components       : 1
  chi              : 2
  genus            : 0
  aut_order        : 1
  black_valencies  : Counter({3: 1})
  white_valencies  : Counter({2: 1, 1: 1})
  face_valencies   : Counter({2: 1, 1: 1})
  incidence:
    [2, 1]
tetrahedral
  degree           : 4
  passport         : ((3, 1), (3, 1), (2, 2))
  components       : 1
  chi              : 2
  genus            : 0
  aut_order        : 1
  black_valencies  : Counter({3: 1, 1: 1})
  white_valencies  : Counter({3: 1, 1: 1})
  face_valencies   : Counter({2: 2})
  incidence:
    [2, 1]
    [1, 0]
torus hexagon
  degree           : 6
  passport         : ((3, 3), (2, 2, 2), (6,))
  components       : 1
  chi              : 0
  genus            : 1
  aut_order        : 6
  black_valencies  : Counter({3: 2})
  white_valencies  : Counter({2: 3})
  face_valencies   : Counter({6: 1})
  incidence:
    [1, 1, 1]
    [1, 1, 1]

edge subdivision:
degree-3 tree  : degree 3->6, genus 0->0, white type (2, 2, 2)
tetrahedral    : degree 4->8, genus 0->0, white type (2, 2, 2, 2)
计算 Galois 作用下的离散不变量

passport、连通分支数、亏格、童画自同构群阶、黑白顶点度数多重集及面度数多重集均由有限置换运算定义,因而在绝对 Galois 作用下保持不变。它们通常不能区分同一 passport 内的全部轨道;进一步可加入单值群同构类型、点稳定子、子轨道长度、甲板群及笛卡儿幂上的轨道数。

Lecture 5 / 第 5 讲

显式 Belyi 多项式:由循环型建立方程

把置换循环型变成根重数、对数导数与齐次方程。

Belyi多项式循环型完全交

1. 多项式情形的归一化

gg_\infty 是一个 nn-循环,可把唯一的极点放在 x=x=\infty,于是 Belyi 函数成为次数 nn 的多项式 P(x)P(x)。通过仿射变换 xax+bx\mapsto ax+b 与目标端缩放,可固定两个根的位置和首项系数,减少未知数并消除伪自由度。

定义循环型记号

记号 n/331/22111n/331/22111 表示 gg_\infty 为一个 nn-循环,g0g_0 的循环长度为 3,3,13,3,1g1g_1 的循环长度为 2,2,1,1,12,2,1,1,1。分拆中所有部分之和必须等于 nn

2. 从根的重数写方程

00 上方的重数为 a1,,ara_1,\ldots,a_r,先写

P(x)=ci=1r(xui)ai.P(x)=c\prod_{i=1}^r(x-u_i)^{a_i}.

11 上方的重数为 b1,,bsb_1,\ldots,b_s,则要求 P(x)1P(x)-1 具有相应因子。直接比较系数通常方程很多;更有效的是利用对数导数

P(x)P(x)=i=1raixui.\frac{P'(x)}{P(x)}=\sum_{i=1}^r\frac{a_i}{x-u_i}.
定理高重根的导数判据

vvP(x)1P(x)-1mm 重根,当且仅当 P(v)=1P(v)=1P(v)==P(m1)(v)=0P'(v)=\cdots=P^{(m-1)}(v)=0。因此可以先让对数导数的分子具有指定重根,再用一个标量条件确定 cc

三个根与一个三重临界点

P=xa1(x1)a2(xw)a3P=x^{a_1}(x-1)^{a_2}(x-w)^{a_3}。若 P1P-1 要在某点有三重根,则 P/PP'/P 的分子(一个二次多项式)必须是完全平方。比较判别式为零即可得到关于 ww 的代数方程。

3. 完全交与 Bézout 计数

一般地,若 PPm+1m+1 个根,而另一个分支值对应一个 (m+1)(m+1)-循环,则对数导数分子需为 mm 次幂。消去该幂的根后,会得到次数 2,3,,m2,3,\dots,mm1m-1 个齐次方程,位于 𝐏m1\mathbf P^{m-1} 中。若交是横截的,Bézout 数为 23m=m!2\cdot3\cdots m=m!,恰好匹配根的循环排列数。

补充必须检查的退化分量

Bézout 计数只给带重数的射影交数。计算中必须饱和掉 ui=uju_i=u_jui=u_i=\infty、首项消失等退化分量,并检查得到的函数次数、分歧型与传递性。

从循环型到 Belyi 多项式方程

\infty 上只有一个点且分歧指数等于覆盖次数 nn,则 Belyi 映射可以规范化成次数 nn 的多项式 P(x)P(x)。其余两个分支值可取为 0,10,1。设 g0,g1,gg_0,g_1,g_\infty 的循环型分别为指定分拆;那么 PP 的零点重数由 g0g_0 决定,P1P-1 的零点重数由 g1g_1 决定,而 gg_\inftynn-循环。

显式求解的基本做法是把重数结构写成因子分解。例如若 00 上循环型为 (e1,,er)(e_1,\ldots,e_r),可设

P(x)=ci=1r(xai)ei;P(x)=c\prod_{i=1}^{r}(x-a_i)^{e_i};

11 上循环型为 (f1,,fs)(f_1,\ldots,f_s),则设

P(x)1=dj=1s(xbj)fj.P(x)-1=d\prod_{j=1}^{s}(x-b_j)^{f_j}.

比较系数得到非线性方程组。必须先除去仿射变换 xux+vx\mapsto ux+v 与目标上的规范自由度,否则方程组会出现无意义的一维或二维解族,Jacobian 也必然奇异。常用规范是把两个指定原像放到 0,10,1,并令首项系数或一个剩余参数为 1。

三循环分析与树

gg_\infty 为全循环时,童画只有一个面,因此是平面树。给定黑、白顶点度数,寻找置换三元组等价于枚举具有相应二分度数序列的嵌入树。原讲义通过“边”“双边”以及循环相邻关系,分析低次数例子,并指出同一循环型可能对应多个非共轭树,也可能生成不同的单值群。

置换三元组应满足乘积为恒等且生成传递群。仅知道各自循环型并不能唯一确定覆盖。枚举时可先固定一个全循环 g=(12n)g_\infty=(1\,2\,\cdots\,n),再在中央化子作用下枚举 g0g_0,由 g1=(g0g)1g_1=(g_0g_\infty)^{-1} 计算第三个置换,筛选循环型与传递性。最后还需按同时共轭和可能的正规化子作用去重。

次数 6 的两种几何与群

原讲义详细讨论了循环型中含两个“双边”的次数 6 情形。若两个双边相邻,所得单值群是

PGL2(𝐅5)S5,\operatorname{PGL}_2(\mathbf F_5)\cong S_5,

以其在六个射影点上的3-传递作用嵌入 S6S_6。这也是 S6S_6 外自同构把一个点稳定子送出的非标准 S5S_5。若两个双边相对,则得到阶 48 的非本原子群,它同构于八面体对称群在六个顶点上的作用,并保持三对对顶点组成的分块系统;它也可由 S6S_6 的外自同构从二元子集稳定子 S2×S4S_2\times S_4 得到。

代数计算中,设某个二次因子

Q(x)=6x2+5ax+4b.Q(x)=6x^2+5ax+4b.

PPQ2Q^2 化简,x3x^3 项为 144ab100a3144ab-100a^3,从而

a=036b=25a2.a=0\quad\text{或}\quad36b=25a^2.

a=0a=0PPx2x^2 的多项式,对应保持分块的非本原解;另一支对应 PGL2(𝐅5)\operatorname{PGL}_2(\mathbf F_5) 解。取方便的缩放 (a,b)=(6,25)(a,b)=(6,25),得到恒等式

27x4(x2+6x+25)=(3x212x+20)(3x2+15x+50)250000.27x^4(x^2+6x+25) =(3x^2-12x+20)(3x^2+15x+50)^2-50000.

把两边除以适当常数并作 Möbius 规范化,即得到三点分歧的 Belyi 多项式。

低次数计算的工作准则

  1. 先用循环型与Riemann–Hurwitz公式检查亏格。
  2. 用平面树或置换枚举确定几何解的数量与可能的单值群。
  3. 根据重数写出因子化 ansatz,而不是展开一般多项式。
  4. 固定仿射坐标自由度,减少未知数。
  5. 比较系数、使用 Gröbner 基或结式消元。
  6. 对每个代数解计算判别式、分歧型和生成群,排除退化解。
  7. 在最终方程中精确验证 PPP1P-1 的因子重数,并检查无额外临界值。

原讲义还提出两个练习:由一个次数 6、Galois 闭包群为 S5S_5 的覆盖,寻找具有同一 Galois 闭包的次数 5 Belyi 映射,其循环型为 32/41/22132/41/221;以及研究次数 7、g1g_1 为双换位、g0g_0 型为 331331421421 的 Belyi 多项式。后续讲次继续完成这些计算。

补充:系数比较系统的规模控制

若直接令 P(x)=cnxn++c0P(x)=c_nx^n+\cdots+c_0,再要求导数具有指定重根,未知数和方程迅速膨胀。因子化 ansatz 已把重数条件内置,只需解根位置与少量常数。例如分拆 λ=(e1,,er)\lambda=(e_1,\ldots,e_r) 只引入 rr 个根,而不是 nn 个一般系数。对根有重复次数的同类点,还可使用初等对称函数代替逐根坐标,自动对称化 Galois 作用。

对数导数技巧

P=ci(xai)ei,P=c\prod_i(x-a_i)^{e_i},

PP=ieixai.\frac{P'}P=\sum_i\frac{e_i}{x-a_i}.

P1P-1 的重根必为 PP' 的根,且不与 PP 的根重合。因此可先从对数导数分子构造重根多项式 QQ,再要求 P1(modQm)P\equiv1\pmod{Q^m}。这比同时引入 P1P-1 的全部根更小。若 QQ 次数低,可用多项式除法余数直接产生方程。

加权齐次结构

坐标缩放 xλxx\mapsto\lambda x 使根位置权为 1,系数按次数赋权。方程通常是加权齐次的。选择权零比值可把求解降到普通射影坐标;消元多项式的次数往往恰等于预计的 Hurwitz 数。若 Bézout 次数乘积与置换枚举数一致,并且无无穷远或退化解,就能证明方程组已找全。

本原性判定

若单值群保持非平凡分块系统,覆盖分解为较低次数覆盖的复合。多项式上常表现为 P(x)=R(S(x))P(x)=R(S(x)) 或在平移后成为 xmx^m 的多项式。检测方法包括:置换群的 block 系统;函数域中间域;多项式分解算法;分支循环型是否与复合相容。Čebyšev 例子就是二面体非本原结构的典型。

数值求解与认证

复杂方程可先用 homotopy continuation 得到全部复近似解,再用 alpha-theory 认证每个近似附近有唯一精确解。随后用 LLL 识别代数数。与 pp-进路线相比,复方法易于跟踪全部解,但高精度与近重根可能不稳定;pp-进方法精确且适合代数恢复,但需找到好素数与模解。两者交叉验证最可靠。

从方程恢复置换群

可选一个不穿过分支点的基点,数值求出 P(x)=t0P(x)=t_0 的全部根,沿绕 0,1,0,1,\infty 的路径连续跟踪根,得到单值置换。纯代数方法则在多个好素数下考察 P(x)tP(x)-t 的分解与判别式,结合候选传递群数据库筛选。最终若群很小,可给出明确置换生成元并验证其阶;若群为 An,SnA_n,S_n,判别式与一个适当 Frobenius 循环型常已足够。

进一步:多项式 Belyi 映射的树结构

若 Belyi 映射是多项式,则 \infty 上只有一个点且完全分歧,dessin 因而是一棵平面二分树。反过来,每棵带平面嵌入的二分树对应一个多项式 Belyi 映射,唯一到源目标仿射变换。顶点度序列分别给出 fff1f-1 的根重数。

设黑度分拆为 α=(αi)\alpha=(\alpha_i),白度分拆为 β=(βj)\beta=(\beta_j),总次数 nn。可写

f(x)=ci(xai)αi,f(x)1=cj(xbj)βj.f(x)=c\prod_i(x-a_i)^{\alpha_i},\qquad f(x)-1=c\prod_j(x-b_j)^{\beta_j}.

比较系数得到方程。更高效的方法是对数微分:

ff=iαixai,ff1=jβjxbj,\frac{f'}f=\sum_i\frac{\alpha_i}{x-a_i},\qquad \frac{f'}{f-1}=\sum_j\frac{\beta_j}{x-b_j},

它暴露所有临界点并减少高次展开。

树的嵌入数可由置换三元组枚举,先确定有多少等价解。若 Hurwitz 数为 1,系数方程出现多个数值解通常只是不同规范化或 Galois 共轭;若 Hurwitz 数更大,必须按 dessin 不变量区分各分支。

有理重构的常见策略是在多个良素数上求解,再用中国剩余定理和有理重构恢复整数/有理系数。模素数解应满足 Jacobian 非奇异,以便 Hensel 提升。坏素数可能使不同复解合并或树退化,不能用于计数。

模型化简可利用树的对称性:若存在对合,可把坐标选到对合为 xxx\mapsto-xx1/xx\mapsto1/x,使多项式只含特定奇偶项。最终应将模型的 dessin 数值绘制或路径提升与原树旋转系统比较,避免只匹配度序列却选错平面嵌入。

练习与解答平面树与多项式

练习 1。一棵二分树有 nn 条边,黑白顶点数为 b,wb,w。证明 b+w=n+1b+w=n+1

解。树的 Euler 关系 VE=1V-E=1,而 V=b+w,E=nV=b+w,E=n。这也等价于多项式 Belyi 的 Riemann–Hurwitz 条件。

练习 2。若所有黑顶点度为 2,说明 nn 必为偶数并给黑顶点数。

解。黑度和等于边数 nn,故 2b=n2b=n

练习 3。因子化模板中为何可以固定一个黑点为 0、一个白点为 1?

解。𝐏1\mathbf P^1 的仿射变换有两个自由参数;在多项式情形无穷远已固定,剩余可把两个不同有限点规范为 0、1。若所选点不在定义域,规范化会扩大系数域。

深入补充:对数导数、Newton 和与系数方程的降维

设次数为 nn 的多项式 Belyi 映射已经归一化为

β(x)=ci=1r(xai)ei,β(x)1=cj=1s(xbj)fj,\beta(x)=c\prod_{i=1}^r(x-a_i)^{e_i},\qquad \beta(x)-1=c\prod_{j=1}^s(x-b_j)^{f_j},

其中 ei=fj=n\sum e_i=\sum f_j=n。直接比较两边全部系数会产生高次数、强耦合的方程;对数导数把重数条件转化为低次数有理恒等式:

ββ=i=1reixai,ββ1=j=1sfjxbj.\frac{\beta'}{\beta}=\sum_{i=1}^r\frac{e_i}{x-a_i},\qquad \frac{\beta'}{\beta-1}=\sum_{j=1}^s\frac{f_j}{x-b_j}.
推论 临界点多项式的强制因子

A=i(xai)A=\prod_i(x-a_i)B=j(xbj)B=\prod_j(x-b_j) 为平方自由根多项式,则

Aei1Bfj1A^{e_i-1}\text{ 与 }B^{f_j-1}

所代表的重数因子必整除 β\beta'。更精确地,

gcd(β,β)=i(xai)ei1,gcd(β1,β)=j(xbj)fj1.\gcd(\beta,\beta')=\prod_i(x-a_i)^{e_i-1},\qquad \gcd(\beta-1,\beta')=\prod_j(x-b_j)^{f_j-1}.

因此在特征零中,只要这两个 gcd 的次数正确且剩余临界点不存在,就已认证全部分歧。

在计算上,可先写

β=CU0U1,\beta'=C\,U_0U_1,

其中 U0=i(xai)ei1U_0=\prod_i(x-a_i)^{e_i-1}U1=j(xbj)fj1U_1=\prod_j(x-b_j)^{f_j-1},常数 CC 由首项决定。对三分支点亏格零的多项式覆盖,循环数满足

r+s+1=n+2,r+s+1=n+2,

于是

degU0+degU1=(nr)+(ns)=n1=degβ.\deg U_0+\deg U_1=(n-r)+(n-s)=n-1=\deg\beta'.

故不存在额外临界因子,实际上有精确恒等式

β=ncU0U1.\beta'=nc\,U_0U_1.

这条次数等式把原来的“比较两个次数 nn 多项式”改写成一个次数 n1n-1 的乘积分解问题,通常显著减少方程次数。

算法 用 Newton 和替代根变量的对称消元

若同一纤维中根很多,不直接保存 aia_i,而保存根多项式

A(x)=xr+A1xr1++ArA(x)=x^r+A_1x^{r-1}+\cdots+A_r

及幂和 pk=iaikp_k=\sum_i a_i^k。Newton 恒等式

pk+A1pk1++Ak1p1+kAk=0(kr)p_k+A_1p_{k-1}+\cdots+A_{k-1}p_1+kA_k=0\quad(k\le r)

把根的对称表达转成系数的递推。展开 β/β\beta'/\beta 在无穷远处的 Laurent 级数,得到

ββ=nx+ieiaix2+ieiai2x3+.\frac{\beta'}{\beta}=\frac n x+\frac{\sum_i e_i a_i}{x^2} +\frac{\sum_i e_i a_i^2}{x^3}+\cdots.

与另一纤维的展开比较,可逐阶得到加权幂和方程。低阶方程常为线性或三角形,先解它们再处理剩余非线性方程,比一次性 Gröbner 消元稳定得多。

射影线自同构还提供三个规范自由度。多项式情形已经把无穷远送到无穷远,剩下仿射变换 xux+vx\mapsto ux+v;可固定两个有限根,例如令 a1=0a_1=0a2=1a_2=1。若某个纤维只有一个有限根,也可用“首一”和“次首项为零”固定缩放与平移。规范必须在建立方程前完成,否则 Jacobian 会出现由坐标变换造成的零方向,Newton 法会把这种几何自由度误判为正维解族。

最后的认证不应只检查系数恒等式。还需验证:A,BA,B 平方自由;二者互素;常数 c0c\ne0;映射次数确为 nnβ\betaβ1\beta-1 的因子重数完全等于给定 passport;以及生成的置换群具有预期传递性。这样可同时排除根碰撞、次数下降和非本原分量。

补充计算:系数方程、临界值结式与分歧认证

定理 多项式 Belyi 映射的导数因子判据

设 \(β∈K[x]\) 为次数 n 的非常数多项式。β 的有限临界值均属于 {0,1},当且仅当 rad(β)rad(β(β1)), \operatorname{rad}(\beta' )\mid \operatorname{rad}(\beta(\beta-1)), 其中根按代数闭包计算。若 \(β=A∏(x-a_i)^{e_i}\) 且 \(β-1=A∏(x-b_j)^{f_j}\),则 β=A(i(xai)ei1)(j(xbj)fj1)H(x), \beta'=A\left(\prod_i(x-a_i)^{e_i-1}\right) \left(\prod_j(x-b_j)^{f_j-1}\right)H(x), 而 Belyi 条件等价于剩余因子 H 为非零常数。

证明 由临界点纤维与次数计数完成充要性

若有限临界值只含 0、1,则 \(β'(c)=0\) 的每个根 c 必满足 \(β(c)β(c)-β(c)=0\),即 c 是 β 或 β-1 的根,故根式整除成立。反之,若 β' 的每个根都落在 β(β-1) 的零点上,则每个有限临界点像为 0 或 1;无穷远为多项式的唯一极点,故分支值包含于 {0,1,∞}。

对零纤维中重数 \(e_i\) 的点,β' 至少含 \((x-a_i)^{e_i-1}\);对一纤维同理。两组根不交。其总次数为 \(∑(e_i-1)+∑(f_j-1)\)。Riemann–Hurwitz 对多项式情形要求再加无穷远贡献 n-1 后总分歧为 2n-2,故有限贡献恰为 \(n-1=deg β'\)。因此不存在额外因子,H 为常数。反向亦立即成立。

Python 归一化求解、passport 提取与临界值结式
import sympy as sp
from dataclasses import dataclass
from collections import Counter

x = sp.Symbol("x")

def multiplicity_partition(poly: sp.Poly) -> tuple[int, ...]:
    coeff, factors = sp.factor_list(poly.as_expr())
    parts = []
    for factor, exponent in factors:
        degree = sp.Poly(factor, x).degree()
        parts.extend([exponent] * degree)
    return tuple(sorted(parts, reverse=True))

def polynomial_passport(beta: sp.Expr) -> tuple[tuple[int,...], ...]:
    p = sp.Poly(sp.expand(beta), x, domain=sp.QQ)
    p0 = sp.Poly(p.as_expr(), x, domain=sp.QQ)
    p1 = sp.Poly(p.as_expr() - 1, x, domain=sp.QQ)
    return (
        multiplicity_partition(p0),
        multiplicity_partition(p1),
        (p.degree(),)
    )

def critical_values(beta: sp.Expr) -> list[sp.Expr]:
    deriv = sp.diff(beta, x)
    roots = sp.roots(deriv, x)
    values = []
    for root in roots:
        values.append(sp.simplify(beta.subs(x, root)))
    return sorted(set(values), key=sp.default_sort_key)

def ramification_certificate(beta: sp.Expr) -> dict:
    p = sp.Poly(sp.expand(beta), x, domain=sp.QQ)
    derivative = sp.Poly(sp.diff(p.as_expr(), x), x, domain=sp.QQ)
    resultant_y = sp.Symbol("y")
    crit_poly = sp.resultant(
        p.as_expr() - resultant_y,
        derivative.as_expr(),
        x
    )
    crit_poly = sp.factor(crit_poly)
    passport = polynomial_passport(beta)
    total_defect = sum(sum(e-1 for e in part) for part in passport)
    return {
        "degree": p.degree(),
        "beta": sp.factor(p.as_expr()),
        "beta_minus_one": sp.factor(p.as_expr()-1),
        "derivative": sp.factor(derivative.as_expr()),
        "passport": passport,
        "critical_values": critical_values(beta),
        "critical_value_resultant": crit_poly,
        "defect": total_defect,
        "riemann_hurwitz_ok": total_defect == 2*p.degree()-2,
    }

def cubic_from_multiplicity_conditions() -> sp.Expr:
    """
    β has a double zero at 0, a double 1-point at 1, and degree 3.
    β=a*x^2+b*x^3; impose β(1)=1 and β'(1)=0.
    """
    a, b = sp.symbols("a b")
    beta = a*x**2 + b*x**3
    equations = [
        sp.Eq(beta.subs(x, 1), 1),
        sp.Eq(sp.diff(beta, x).subs(x, 1), 0),
    ]
    solution = sp.solve(equations, (a,b), dict=True)
    if len(solution) != 1:
        raise ArithmeticError("normalization should give a unique map")
    return sp.expand(beta.subs(solution[0]))

def quartic_even_solution() -> list[sp.Expr]:
    """
    Seek β=a*x^4+b*x^2+c with critical values contained in {0,1}.
    The derivative has critical points 0 and ±sqrt(-b/(2a)).
    Force β(0)=0 and the two nonzero critical points to map to 1.
    """
    a, b, c, u = sp.symbols("a b c u")
    beta = a*x**4+b*x**2+c
    equations = [
        sp.Eq(c, 0),
        sp.Eq(2*a*u+b, 0),
        sp.Eq(a*u**2+b*u+c, 1),
    ]
    raw = sp.solve(equations, (b,c,u), dict=True)
    family = [sp.factor(beta.subs(sol)) for sol in raw]
    # Scale x so that a=1 after solving one representative.
    return family

def coefficient_equations_from_fibers(
    zeros: list[tuple[sp.Expr,int]],
    ones: list[tuple[sp.Expr,int]],
    leading: sp.Symbol,
) -> tuple[sp.Expr, list[sp.Expr]]:
    left = leading
    for root, multiplicity in zeros:
        left *= (x-root)**multiplicity
    right = leading
    for root, multiplicity in ones:
        right *= (x-root)**multiplicity
    difference = sp.Poly(sp.expand(left-right-1), x)
    equations = [sp.expand(c) for c in difference.all_coeffs()]
    return sp.expand(left), equations

beta3 = cubic_from_multiplicity_conditions()
print("normalized cubic:", beta3)
for k,v in ramification_certificate(beta3).items():
    print(f"  {k:26s}: {v}")

print("\neven quartic family:")
for f in quartic_even_solution():
    print(" ", f)

a, u, v = sp.symbols("a u v")
candidate, equations = coefficient_equations_from_fibers(
    zeros=[(0,2),(u,1)],
    ones=[(1,2),(v,1)],
    leading=a,
)
print("\ncoefficient equations for passport ((2,1),(2,1),(3)):")
print("  beta =", candidate)
for eq in equations:
    print(" ", eq, "= 0")

solution = sp.solve(equations, (a,u,v), dict=True)
print("\nsolutions:")
for sol in solution:
    print(" ", sol)
    f = sp.factor(candidate.subs(sol))
    print("   passport =", polynomial_passport(f))
    print("   beta-1 =", sp.factor(f-1))
运行结果 三次映射的唯一归一化解与精确认证
normalized cubic: -2*x**3 + 3*x**2
  degree                    : 3
  beta                      : -x**2*(2*x - 3)
  beta_minus_one            : -(x - 1)**2*(2*x + 1)
  derivative                : -6*x*(x - 1)
  passport                  : ((2, 1), (2, 1), (3,))
  critical_values           : [0, 1]
  critical_value_resultant  : -216*y*(y - 1)
  defect                    : 4
  riemann_hurwitz_ok        : True

even quartic family:
  a*x**2*(x**2 - 2*sqrt(-1/a))
  a*x**2*(x**2 + 2*sqrt(-1/a))

coefficient equations for passport ((2,1),(2,1),(3)):
  beta = -a*u*x**2 + a*x**3
  -a*u + a*v + 2*a = 0
  -2*a*v - a = 0
  a*v - 1 = 0

solutions:
  {a: -2, u: 3/2, v: -1/2}
   passport = ((2, 1), (2, 1), (3,))
   beta-1 = -(x - 1)**2*(2*x + 1)
计算 三次例的系数消元

设 β=a x^2(x-u),β-1=a(x-1)^2(x-v)。比较 x^2、x、常数项得到 -a u+a v+2a=0,-2av-a=0,av-1=0。 由后两式得 a=-2、v=-1/2,再得 u=3/2。因此 β=-2x^3+3x^2,且 β-1=-(x-1)^2(2x+1)。临界值结式为 -216y(y-1),直接排除第三个有限临界值。

Lecture 6 / 第 6 讲

置换三元组、Hurwitz 计数与定义域

系统处理组合候选、Galois 轨道与单值群识别。

Hurwitz空间置换群定义域

1. Hurwitz 等价与计数

对固定共轭类 C0,C1,CSnC_0,C_1,C_\infty\subset S_n,候选是满足 g0g1g=1g_0g_1g_\infty=1gtCtg_t\in C_t 且生成传递群的三元组,再模去同时共轭。计算时可以固定 gg_\infty 为标准循环,只枚举其中心化子的轨道,从而大幅减少搜索。

算法置换三元组枚举
  1. 固定一个代表 gg_\infty
  2. 枚举 g0C0g_0\in C_0,令 g1=g01g1g_1=g_0^{-1}g_\infty^{-1}
  3. 检查 g1C1g_1\in C_1 与生成群的传递性。
  4. ZSn(g)Z_{S_n}(g_\infty) 的共轭作用合并。
  5. 必要时计算生成群的阶、块系统和置换特征。

2. 定义域与 Galois 轨道

组合上不同的三元组可能对应同一个数域上的共轭方程。系数的 Galois 共轭保持分歧型,却可能改变童画。候选解分成若干 Galois 轨道;轨道大小通常给出定义域次数的上界,但域的自同构和下降障碍需要另行检查。

小次数中的不同群

课程材料记录了次数 771111 的例子:同一组循环型可能产生 AnA_nPSL2(𝐅11)\mathrm{PSL}_2(\mathbf F_{11}) 或 Mathieu 群 M11M_{11} 等不同单值群。因此只核对循环型不足以识别覆盖。

3. 群的实用判别

  • 传递但有非平凡块系统:覆盖是非本原的,常可分解为低次覆盖复合。
  • 若生成元均为偶置换,则群包含在 AnA_n
  • 利用循环型和 Jordan 型定理常可证明群含 AnA_n
  • 小次数时可由群阶、点稳定子、轨道长度和特征标识别。
证明为什么两个对合常给出二面体群

a2=b2=1a^2=b^2=1,则群 a,b\langle a,b\rangler=abr=abaa 生成,并满足 ara=r1ara=r^{-1}。因此它是某个二面体群的商;在传递的多项式覆盖情形常得到 Chebyshev 型函数。

练习同时共轭不变量

证明 g0g1g=1g_0g_1g_\infty=1、循环型、生成群同构类型以及亏格在同时共轭下不变。解释为什么“边编号”不是几何数据。

低次数例子的完整分类信息

g1g_1 为双换位的 Belyi 多项式中,次数 4 的唯一可能循环型是 4/211/224/211/22;交换 g0,g1g_0,g_1 等价于把 PP 换成 1P1-P。次数 5 有 5/311/2215/311/2215/221/2215/221/221 两类。后一类中 g0,g1g_0,g_1 都是对合,因此生成群必为二面体群,覆盖等价于 Čebyšev 多项式。原讲义给出恒等式

x(x2+5x+5)2+4=(x+4)(x2+3x+1)2.x(x^2+5x+5)^2+4=(x+4)(x^2+3x+1)^2.

平移 xx2x\mapsto x-2 可化为对称形式

(x2)(x2+x1)2+4=(x+2)(x2x1)2,(x-2)(x^2+x-1)^2+4=(x+2)(x^2-x-1)^2,

再作 x2xx\mapsto2x 与目标缩放,得到第五 Čebyšev 多项式

T5(x)=16x520x3+5x,T_5(x)=16x^5-20x^3+5x,

它只在 ±1\pm1 上分歧,每个分支值各有一个单原像与两个二重原像。

次数 6 除 6/411/22116/411/2211 外,还有 6/222/22116/222/22116/321/22116/321/2211。前者仍为二面体、且因次数合成而非本原。后者有三个解,均生成 A6A_6。写

P(x)=cx3(x+1)2(x+w),P(x)=c\,x^3(x+1)^2(x+w),

可得 ww 满足不可约三次方程

25w312w224w16=0.25w^3-12w^2-24w-16=0.

该三次数域的判别式为 108-108,可识别为 𝐐(23)\mathbf Q(\sqrt[3]{2});原讲义给出一种显式表达 w=24/3/(321/3)w=2^{4/3}/(3-2^{1/3})。对于任意三次扩张 K/FK/F,任取两个不在 FF 中的本原元,它们由唯一的分式线性 FF-变换相联系,这可直接用线性代数求得。

循环型 7/331/221117/331/22111 的群必为阶 168168 的简单群 PSL2(𝐅7)\operatorname{PSL}_2(\mathbf F_7)。多项式定义在 𝐐(7)\mathbf Q(\sqrt{-7}) 上;Galois 闭包是 Klein 四次曲线。坐标 xx 是该曲线按两类指数 7 的 S4S_4 子群之一取商得到的有理参数;两类子群由群的外自同构交换。Klein 四次曲线本身可在 𝐐\mathbf Q 上定义,但其全自同构群不能全部在 𝐐\mathbf Q 上定义。

循环型 7/421/221117/421/22111 可写

P(x)=cx4(x+1)2(x+w).P(x)=c\,x^4(x+1)^2(x+w).

共有四个 ww:其中两个是 2w2+w+12w^2+w+1 的根,生成 𝐐(7)\mathbf Q(\sqrt{-7});另两个是 27w218w2527w^2-18w-25 的根,生成 𝐐(21)\mathbf Q(\sqrt{21})。相应单值群一类为阶 168168 群,另一类为 A7A_7。这些例子显示,“解的代数共轭轨道”“定义域”“生成群”三者需要分别计算,不能由循环型直接读出。

有限群中乘积为单位元的计数公式

定理Frobenius–Serre 特征标计数公式

C1,,CkC_1,\ldots,C_k 是有限群 GG 的共轭类。满足 giCig_i\in C_ig1gk=1g_1\cdots g_k=1 的有序 kk-元组数为

1|G|i=1k|Ci|χIrr(G)χ(C1)χ(Ck)χ(1)k2.\frac{1}{|G|}\prod_{i=1}^{k}|C_i| \sum_{\chi\in\operatorname{Irr}(G)} \frac{\chi(C_1)\cdots\chi(C_k)}{\chi(1)^{k-2}}.

证明在群代数 A=𝐂[G]A=\mathbf C[G] 中进行。令 ci=gCigc_i=\sum_{g\in C_i}g。所求数是乘积 c1ckc_1\cdots c_k 中单位元的系数,也就是该中央元素在正则表示上的迹除以 |G||G|。正则表示分解为

𝐂[G]χVχχ(1)χEnd(Vχ).\mathbf C[G]\cong\bigoplus_{\chi}V_\chi^{\oplus\chi(1)} \cong\bigoplus_\chi\operatorname{End}(V_\chi).

由于 cic_i 在群代数中心中,Schur 引理说明它在 VχV_\chi 上为标量;比较迹得该标量为 |Ci|χ(Ci)/χ(1)|C_i|\chi(C_i)/\chi(1)。把各标量相乘,并计入 VχV_\chi 在正则表示中的重数 χ(1)\chi(1),再对全部不可约特征标求和,即得公式。

平凡特征标给出主项 |G|1|Ci||G|^{-1}\prod|C_i|,这正是“若所有乘积在群元素间均匀分布”时的答案。非平凡特征标给出偏离均匀性的修正。一维非平凡特征标则共同检测 C1CkC_1\cdots C_k 在Abelian化 GabG^{\mathrm{ab}} 中是否可能为单位元。

该公式计算的是全部解,不保证这些元素生成整个 GG。要数生成 GG 的三元组,可对所有真子群应用同一公式,再借助子群格和 Möbius 反演扣除落在真子群中的解。

SnS_n 中含全循环时的简化

V1V_1nn 维置换表示的迹零超平面,Vj=jV1V_j=\bigwedge^jV_1,则 VjV_j 是维数 (n1j)\binom{n-1}{j} 的不可约表示。全循环在 V1V_1 上的特征值是除 1 外的全部 nn 次单位根,于是

j=0n1(1)jχj((n))Xj=ωn=1ω1(1ωX)=1Xn1X.\sum_{j=0}^{n-1}(-1)^j\chi_j((n))X^j =\prod_{\substack{\omega^n=1\\\omega\ne1}}(1-\omega X) =\frac{1-X^n}{1-X}.

比较系数得 χj((n))=(1)j\chi_j((n))=(-1)^j。列正交关系又说明,除这些外所有不可约特征标在全循环上的值都为零。因此三元组计数只需 nn 项。

n=7n=7,双换位在 V1V_1 上的特征值 1,11,-1 的重数为 4,24,2,生成多项式为

(1X)4(1+X)2=12XX2+4X3X42X5+X6.(1-X)^4(1+X)^2=1-2X-X^2+4X^3-X^4-2X^5+X^6.

循环型 331331 给出 (1X3)2(1-X^3)^2,计数为 10080=27!10080=2\cdot7!,即模同时共轭有两个解;循环型 421421 给出 (1X2)(1X4)(1-X^2)(1-X^4),计数为 20160=47!20160=4\cdot7!,即有四个解。这与直接置换枚举完全一致。

高亏格基曲面的推广

若基曲面亏格为 γ\gamma,基本群关系为

g1gk=[a1,b1][aγ,bγ],[a,b]=a1b1ab.g_1\cdots g_k=[a_1,b_1]\cdots[a_\gamma,b_\gamma], \qquad [a,b]=a^{-1}b^{-1}ab.

相应解数为

|G|2γ1i|Ci|χχ(C1)χ(Ck)χ(1)k+2γ2.|G|^{2\gamma-1}\prod_i|C_i| \sum_\chi \frac{\chi(C_1)\cdots\chi(C_k)} {\chi(1)^{k+2\gamma-2}}.

γ=0\gamma=0 回到球面公式;当 k=0,γ=1k=0,\gamma=1 时,公式等价于“可交换有序对的数量等于 |G||G| 乘以共轭类数”。

补充:特征标公式的卷积解释

对类函数 1Ci1_{C_i},卷积 1C1**1Ck1_{C_1}\ast\cdots\ast1_{C_k} 在单位元处的值就是所求元组数。有限群 Fourier 变换把卷积化为不可约表示上的矩阵乘积;因为共轭类指示函数是中心函数,每个 Fourier 分量为标量。特征标公式正是这一非交换 Fourier 反演。它说明计数并非偶然技巧,而是群代数谱分解的直接结果。

从全部解到生成解:子群 Möbius 反演

NHN_H 是所有元组落在子群 HH 中的数量,GHG_H 是生成恰为 HH 的数量,则

NH=KHGK.N_H=\sum_{K\le H}G_K.

在子群偏序上作 Möbius 反演得到 GGG_G。实际中不需遍历全部子群,而只需可能同时包含给定共轭类的极大子群,再递归扣除。若只数到 GG-共轭,必须除以正规化子大小,而不能一律除以 |G||G|;含非平凡三元组中央化子时轨道大小会减小。

刚性判据

若给定共轭类的生成三元组在 GG-共轭下恰有一个轨道,且各类在 Gal(𝐐¯/𝐐)\operatorname{Gal}(\overline{\mathbf Q}/\mathbf Q) 作用下有合适的有理性,则称为刚性三元组。刚性方法可构造 𝐐(t)\mathbf Q(t) 上正则 Galois 扩张。特征标计数先给出轨道总数,再用极大子群排除非生成解;若结果为 1,就得到候选刚性数据。

特征标值的外幂生成函数

ggV1V_1 上特征值为 λ1,,λn1\lambda_1,\ldots,\lambda_{n-1},则

j=0n1χjV1(g)uj=i=1n1(1+λiu).\sum_{j=0}^{n-1}\chi_{\wedge^jV_1}(g)u^j =\prod_{i=1}^{n-1}(1+\lambda_i u).

原讲义采用带 (1)j(-1)^j 的版本。对循环型 rrmr\prod_r r^{m_r},置换表示特征多项式为 r(Xr1)mr\prod_r(X^r-1)^{m_r};去掉一个平凡特征值即可迅速求迹零表示的全部外幂特征标。这使大批 SnS_n passport 的计数可自动化。

曲面基本群计数与二维 Yang–Mills

高亏格公式中的 χ(1)22γk\chi(1)^{2-2\gamma-k} 与二维有限规范理论的配分函数相同。每增加一个柄,就多求和一对 a,ba,b,在表示侧贡献 (|G|/χ(1))2(|G|/\chi(1))^2。这一结构也解释了为什么交换对数量与不可约表示数相联系。

检查示例的完整流程

7/331/221117/331/22111,先计算类大小:7-循环有 6!6! 个,331331 型有 280280 个,双换位有 105105 个。代入特征标简化公式得 1008010080。每个生成三元组在同时共轭下通常有 7!7! 大小轨道,因此得到两个轨道。再检查两轨都生成阶 168 群而非 A7A_7。对 421421 同理得四个轨道,并由判别式和分解型区分两个阶 168 与两个 A7A_7 轨道。

进一步:Hurwitz 数的表示论计算

给定有限群 GG 的共轭类 C1,,CrC_1,\ldots,C_r,满足乘积为 1 的元组数可由 Frobenius 特征标公式计算:

N=|C1||Cr||G|χIrr(G)χ(C1)χ(Cr)χ(1)r2.N=\frac{|C_1|\cdots|C_r|}{|G|}\sum_{\chi\in\operatorname{Irr}(G)}\frac{\chi(C_1)\cdots\chi(C_r)}{\chi(1)^{r-2}}.

这个数包含不生成 GG 的元组。要计数生成且传递的覆盖,可用子群格上的 Möbius 反演,或先枚举再检验生成子群。

除以同时共轭后,每个轨道按中心化子大小加权。若覆盖自同构群平凡,轨道大小为 |G||G|;有自同构时不能简单用 N/|G|N/|G| 得到整数个覆盖。叠意义下的 Hurwitz 数自然带权 1/|Aut|1/|\operatorname{Aut}|,而粗模点数则需逐轨道处理。

SnS_n 中特征标值可用 Murnaghan–Nakayama 规则由 Young 图计算。全循环类尤其简单:只有钩形分拆对应的特征标可能非零。这解释了课程中某些全循环 Hurwitz 计数化成短和式。实现时可缓存分拆、共轭类大小和特征标表。

辫群轨道把组合元组组织成 Hurwitz 空间连通分支。两个元组即使具有同一生成群和相同循环型,也可能位于不同轨道,对应不同模空间分量。计算轨道时应在“同时共轭类代表”上操作以压缩状态,并记录稳定子。

高亏格源曲线只改变 Riemann–Hurwitz约束,不改变特征标公式的乘积计数。若目标也有正亏格,则单值关系加入 2gD2g_D 对生成元的交换子,计数公式相应包含表面群关系;二维拓扑量子场论给出统一的特征标和式。

练习与解答特征标公式与轨道

练习 1。在Abelian 群中简化 Frobenius 公式。

解。所有不可约特征标的次数均为 1,类为单点;特征标正交关系使和式等于 |G||G| 当给定元素乘积为 1,否则为 0,恰恢复唯一乘积条件。

练习 2。为什么同时共轭轨道稳定子等于元组生成子群的中心化子?

解。稳定一个元组的 gg 必须与每个 σi\sigma_i 交换,故与其生成群交换;反之亦然。

练习 3。辫生成元作用为何保持乘积?

解。把相邻对 (a,b)(a,b) 换成 (aba1,a)(aba^{-1},a),其乘积仍为 abab,其余项不变。

深入补充:Nielsen 类、辫群作用与 Hurwitz 空间连通分支

给定有限群 GG 的共轭类 C1,,CrC_1,\ldots,C_r,定义内 Nielsen 类

Niin(G,𝐂)={(g1,,gr):giCi,g1gr=1,gi=G}/G,\operatorname{Ni}^{\mathrm{in}}(G,\mathbf C)= \{(g_1,\ldots,g_r):g_i\in C_i,\,g_1\cdots g_r=1,\,\langle g_i\rangle=G\}/G,

其中 GG 以同时共轭作用。这个有限集合不仅枚举分支循环,还携带辫群作用;辫群轨道正是 Hurwitz 空间连通分支的组合影子。

公式 Hurwitz 辫生成元

取约定

qi:(g1,,gi,gi+1,,gr)(g1,,gigi+1gi1,gi,,gr).q_i:(g_1,\ldots,g_i,g_{i+1},\ldots,g_r) \longmapsto (g_1,\ldots,g_ig_{i+1}g_i^{-1},g_i,\ldots,g_r).

该变换保持总乘积,且满足

qiqi+1qi=qi+1qiqi+1,qiqj=qjqi(|ij|>1),q_iq_{i+1}q_i=q_{i+1}q_iq_{i+1},\qquad q_iq_j=q_jq_i\quad(|i-j|>1),

因而给出辫群 BrB_r 的作用。若只关心无序分支点,还需再除以置换共轭类标签的作用。

几何上,qiq_i 对应让第 iii+1i+1 个分支点互绕一次。沿这条参数回路解析延拓覆盖,分支循环发生上述 Hurwitz 变换。于是同一辫轨道中的三元组属于同一代数族;不同轨道通常给出 Hurwitz 空间的不同连通分支,即使它们具有完全相同的群和循环型。

计数 加权质量公式

TT 为满足 giCig_i\in C_ig1gr=1g_1\cdots g_r=1 且生成 GG 的有序元组集合。则

[𝐠]T/G1|CG(𝐠)|=|T||G|,\sum_{[\mathbf g]\in T/G}\frac1{|C_G(\mathbf g)|}=\frac{|T|}{|G|},

其中 CG(𝐠)=iCG(gi)C_G(\mathbf g)=\bigcap_iC_G(g_i)。左边是按覆盖自同构群加权的 Hurwitz 质量;若所有生成元组的共同中心化子都等于 Z(G)Z(G),则内轨道数为 |T||Z(G)|/|G||T|\,|Z(G)|/|G|

这解释了为什么特征标公式首先给出“带权计数”,而不是直接给出几何同构类个数。要从全部乘积为一的元组中抽出生成 GG 的元组,可在子群格上作 Möbius 反演,或实际枚举后用群生成测试过滤。对大群,先按最大子群类型做包含排除,通常比逐元组求生成群更快。

刚性判据 单轨道三元组的定义域信息

r=3r=3GG 无中心,三个共轭类在适当的有理性意义下对 Galois 作用稳定。若生成三元组在同时共轭下只有一个轨道,则相应三点 GG-覆盖是刚性的;其模域为有理数域,并且在通常的无下降障碍条件下可下降到 𝐐\mathbf Q

“无中心”与“生成”条件不可省略。中心会产生非平凡覆盖自同构,从而出现下降的二阶障碍;不生成 GG 的元组只描述较小群的覆盖。计算中应分别保存:全部解数、生成解数、同时共轭轨道数、辫群轨道数和每个轨道的稳定子。这五个数字回答不同问题,混用会造成 Hurwitz 数与几何族数之间的整数倍误差。

算法 从三元组枚举到 Hurwitz 分支

先用特征标公式预测全部乘积为一的元组数;再按共轭类代表元和中心化子双陪集枚举,避免遍历 |G|2|G|^2 对元素;过滤生成性并取同时共轭轨道;最后对轨道代表施加 qiq_i,用并查集求辫轨道。每个辫轨道附带 cusp 宽度、稳定子和循环型,可直接用于估计 Hurwitz 曲线的亏格及边界点。

补充计算:Nielsen 类、辫群轨道与生成性过滤

定理 内 Nielsen 类与 Hurwitz 空间连通分支

固定有限群 G 的共轭类 \(C_1,…,C_r\)。内 Nielsen 类 Niin(G,𝐂)={(g1,,gr):giCi,g1gr=1,gi=G}/G \operatorname{Ni}^{\mathrm{in}}(G,\mathbf C)= \{(g_1,\ldots,g_r):g_i\in C_i,\ g_1\cdots g_r=1,\ \langle g_i\rangle=G\}/G 承受辫群 \(B_r\) 的 Hurwitz 作用。相应 Hurwitz 空间的几何连通分支与该有限集合上的辫群轨道一一对应。

证明 由分支点运动与路径提升识别辫群作用

在分支点互异的配置空间中选择标准生成环路,覆盖给出乘积为 1 的分支循环组。改变纤维标号造成同时共轭,故模去 G 的内共轭。沿配置空间中的基本辫子交换相邻分支点时,标准环路基变换为 Hurwitz 变换 \((g_i,g_{i+1})↦(g_{i+1},g_{i+1}^{-1}g_i g_{i+1})\)。 因此同一解析连通族中的点给出同一辫群轨道。

反之,Riemann 存在定理把每个生成的乘积一元组实现为覆盖;基本辫子由连续移动分支点实现,故同一辫群轨道中的数据位于同一连通分支。生成性条件保证覆盖连通,内共轭商对应保持目标坐标而改变纤维标号。

Python 共轭类枚举、生成群阶与 Hurwitz 轨道分解
from itertools import permutations, product
from collections import deque, Counter

Perm = tuple[int, ...]

def ident(n):
    return tuple(range(n))

def compose(a,b):
    return tuple(a[b[i]] for i in range(len(a)))

def inverse(a):
    out=[0]*len(a)
    for i,j in enumerate(a):
        out[j]=i
    return tuple(out)

def conjugate(g,h):
    return compose(compose(h,g),inverse(h))

def cycles(g):
    seen=set()
    ans=[]
    for i in range(len(g)):
        if i in seen:
            continue
        c=[]
        j=i
        while j not in seen:
            seen.add(j); c.append(j); j=g[j]
        ans.append(tuple(c))
    return ans

def ctype(g):
    return tuple(sorted((len(c) for c in cycles(g)),reverse=True))

def orbit(gens,start=0):
    seen={start}; q=[start]
    while q:
        x=q.pop()
        for g in gens:
            y=g[x]
            if y not in seen:
                seen.add(y); q.append(y)
    return seen

def generated_group(gens):
    n=len(gens[0])
    allgens=gens+[inverse(g) for g in gens]
    G={ident(n)}
    q=[ident(n)]
    while q:
        h=q.pop()
        for g in allgens:
            gh=compose(g,h)
            if gh not in G:
                G.add(gh); q.append(gh)
    return G

def conjugacy_class(n, typ):
    return [g for g in permutations(range(n)) if ctype(g)==typ]

def simultaneous_conjugates(triple):
    n=len(triple[0])
    for h in permutations(range(n)):
        h=tuple(h)
        yield tuple(conjugate(g,h) for g in triple)

def canonical_conjugacy_rep(triple):
    return min(simultaneous_conjugates(triple))

def hurwitz_q1(triple):
    a,b,c=triple
    return (b, compose(compose(inverse(b),a),b), c)

def hurwitz_q1_inv(triple):
    a,b,c=triple
    return (compose(compose(a,b),inverse(a)), a, c)

def hurwitz_q2(triple):
    a,b,c=triple
    return (a,c,compose(compose(inverse(c),b),c))

def hurwitz_q2_inv(triple):
    a,b,c=triple
    return (a,compose(compose(b,c),inverse(b)),b)

def enumerate_nielsen(n, types):
    classes=[conjugacy_class(n,t) for t in types]
    reps={}
    for a in classes[0]:
        for b in classes[1]:
            c=inverse(compose(a,b))
            if ctype(c)!=types[2]:
                continue
            triple=(a,b,c)
            if len(orbit(list(triple),0))!=n:
                continue
            key=canonical_conjugacy_rep(triple)
            reps[key]=triple
    return sorted(reps)

def braid_orbit(seed, allowed_types=None):
    moves=[hurwitz_q1,hurwitz_q1_inv,hurwitz_q2,hurwitz_q2_inv]
    start=canonical_conjugacy_rep(seed)
    seen={start}
    q=deque([start])
    while q:
        cur=q.popleft()
        for move in moves:
            nxt=move(cur)
            if allowed_types is not None:
                # Pure braid applications may temporarily permute equal classes;
                # for the examples below the repeated classes make this harmless.
                if sorted(map(ctype,nxt))!=sorted(allowed_types):
                    continue
            nxt=canonical_conjugacy_rep(nxt)
            if nxt not in seen:
                seen.add(nxt); q.append(nxt)
    return seen

def character_free_count(n, types):
    """Direct class-product count, before transitivity/conjugacy quotient."""
    classes=[conjugacy_class(n,t) for t in types]
    count=0
    generated_orders=Counter()
    for a in classes[0]:
        for b in classes[1]:
            c=inverse(compose(a,b))
            if c in set(classes[2]):
                count+=1
                generated_orders[len(generated_group([a,b,c]))]+=1
    return count, generated_orders

cases=[
    (4,((3,1),(3,1),(2,2))),
    (5,((5,),(2,2,1),(2,2,1))),
    (5,((3,1,1),(3,1,1),(5,))),
]

for n,types in cases:
    reps=enumerate_nielsen(n,types)
    raw,orders=character_free_count(n,types)
    print(f"n={n}, types={types}")
    print(f"  raw product-one tuples = {raw}")
    print(f"  generated group orders = {dict(sorted(orders.items()))}")
    print(f"  inner Nielsen classes  = {len(reps)}")
    remaining=set(reps)
    sizes=[]
    while remaining:
        seed=min(remaining)
        orb=braid_orbit(seed,types)
        part=remaining.intersection(orb)
        sizes.append(len(part))
        remaining.difference_update(part)
    print(f"  braid components       = {sorted(sizes,reverse=True)}")
    for j,rep in enumerate(reps[:3],1):
        print(f"   rep {j}:")
        for g in rep:
            print(f"      {g} type={ctype(g)}")
运行结果 三个低次数 passport 的 Nielsen 类计算
n=4, types=((3, 1), (3, 1), (2, 2))
  raw product-one tuples = 24
  generated group orders = {12: 24}
  inner Nielsen classes  = 1
  braid components       = [1]
   rep 1:
      (0, 2, 3, 1) type=(3, 1)
      (1, 2, 0, 3) type=(3, 1)
      (2, 3, 0, 1) type=(2, 2)
n=5, types=((5,), (2, 2, 1), (2, 2, 1))
  raw product-one tuples = 120
  generated group orders = {10: 120}
  inner Nielsen classes  = 1
  braid components       = [1]
   rep 1:
      (1, 2, 3, 4, 0) type=(5,)
      (0, 4, 3, 2, 1) type=(2, 2, 1)
      (1, 0, 4, 3, 2) type=(2, 2, 1)
n=5, types=((3, 1, 1), (3, 1, 1), (5,))
  raw product-one tuples = 120
  generated group orders = {60: 120}
  inner Nielsen classes  = 1
  braid components       = [1]
   rep 1:
      (0, 1, 3, 4, 2) type=(3, 1, 1)
      (1, 2, 0, 3, 4) type=(3, 1, 1)
      (2, 0, 4, 1, 3) type=(5,)
计算 原始计数与内共轭商

次数 4 的 ((3,1),(3,1),(2,2)) 共有 24 个乘积为 1 的有标号三元组,全部生成 A_4。A_4 的中心平凡,单个内共轭轨道大小为 12;在 S_4 标号同时共轭下得到一个代表。次数 5 的 ((5),(2,2,1),(2,2,1)) 共有 120 个三元组,全部生成 D_5;其规范化标号商仍只有一个内 Nielsen 类。

Lecture 7 / 第 7 讲

结式、Sylvester 矩阵与消元理论

给出结式的定义、证明、消元意义与计算陷阱。

结式消元Sylvester矩阵

1. 结式

定义一元多项式的结式

P=ami=1m(xαi)P=a_m\prod_{i=1}^m(x-\alpha_i)Q=bnj=1n(xβj)Q=b_n\prod_{j=1}^n(x-\beta_j)。定义

Resx(P,Q)=amnbnmi,j(αiβj)=amniQ(αi).\operatorname{Res}_x(P,Q)=a_m^n b_n^m\prod_{i,j}(\alpha_i-\beta_j)=a_m^n\prod_i Q(\alpha_i).
定理基本判据

Resx(P,Q)=0\operatorname{Res}_x(P,Q)=0 当且仅当 P,QP,Q 在代数闭包中有公共根;等价地,gcd(P,Q)1\gcd(P,Q)\ne1

2. Sylvester 矩阵

P,QP,Q 的系数按移位排列成 (m+n)×(m+n)(m+n)\times(m+n) 的 Sylvester 矩阵 S(P,Q)S(P,Q),则

detS(P,Q)=Resx(P,Q).\det S(P,Q)=\operatorname{Res}_x(P,Q).

其行核可解释为满足 AP+BQ=0AP+BQ=0degA<n,degB<m\deg A<n,\deg B<m 的多项式对。矩阵余秩等于 deggcd(P,Q)\deg\gcd(P,Q)。重根情形需要把导数向量或局部代数的长度计入。

证明公共根判据的线性代数证明

ξ\xi 为公共根,则 (ξm+n1,,ξ,1)T(\xi^{m+n-1},\ldots,\xi,1)^T 落在 Sylvester 矩阵核中,故行列式为零。反之,核向量给出非零 A,BA,B 使 AP+BQ=0AP+BQ=0;若 P,QP,Q 互素,Bézout 恒等式迫使这样的次数受限关系不存在。

3. 消元

F(x,y)=G(x,y)=0F(x,y)=G(x,y)=0,则任何解的 yy-坐标必满足

R(y)=Resx(F,G)=0.R(y)=\operatorname{Res}_x(F,G)=0.

R(y)=0R(y)=0 可能含首项同时消失产生的伪根。应在射影闭包中检查无穷远分量,或用理想饱和、Gröbner 基与回代排除。

算法两方程消元工作流
  1. 选择使次数和系数增长较小的变量消元。
  2. 计算结式并平方自由化、因式分解。
  3. 逐因子定义候选数域并回代求另一变量。
  4. 检查原方程、非退化条件、目标分歧型。
  5. 用判别式与局部分解研究坏素数和 Galois 群。
补充子结式与 gcd

子结式序列同时给出结式、gcd 次数以及带参数多项式的特殊化行为。相比直接展开巨大的行列式,模素数计算、中国剩余重构和快速子结式算法通常更稳定。

结式的定义、结构与几何意义

当一个 Belyi 计算已经化成两个未知量满足两个非线性方程时,最自然的消元工具之一是结式。设

P(X)=amXm++a0,Q(X)=bnXn++b0.P(X)=a_mX^m+\cdots+a_0,\qquad Q(X)=b_nX^n+\cdots+b_0.

Sylvester 矩阵是从 Xn1P,,P,Xm1Q,,QX^{n-1}P,\ldots,P,X^{m-1}Q,\ldots,Q 的系数行组成的 (m+n)×(m+n)(m+n)\times(m+n) 矩阵,其行列式定义为 ResX(P,Q)\operatorname{Res}_X(P,Q)。结式为零当且仅当 P,QP,Q 在代数闭包中有公共根。

行核可识别为

{(A,B):degA<n,degB<m,AP+BQ=0}.\{(A,B):\deg A<n,\ \deg B<m,\ AP+BQ=0\}.

因此 Sylvester 矩阵的亏秩等于 deggcd(P,Q)\deg\gcd(P,Q)。若 ξ\xi 是公共根,则向量

(ξm+n1,ξm+n2,,ξ,1)𝖳(\xi^{m+n-1},\xi^{m+n-2},\ldots,\xi,1)^{\mathsf T}

位于列核中。若最大公因式的根互异,这些 Vandermonde 型向量张成整个核;若公共根有更高重数,还需要对 ξ\xi 求导得到的广义特征向量,等价地使用函数在 ξ\xi 处的 jet。一个重数 ee 的公共根贡献 ee 维核。

根的乘积公式与基本性质

P=ami(Xαi)P=a_m\prod_i(X-\alpha_i),则

Res(P,Q)=amniQ(αi)=(1)mnbnmjP(βj).\operatorname{Res}(P,Q) =a_m^n\prod_iQ(\alpha_i) =(-1)^{mn}b_n^m\prod_jP(\beta_j).

由此立即得到交换符号、乘法性以及坐标变换下的权:

Res(P,Q)=(1)mnRes(Q,P),Res(P1P2,Q)=Res(P1,Q)Res(P2,Q).\operatorname{Res}(P,Q)=(-1)^{mn}\operatorname{Res}(Q,P), \qquad \operatorname{Res}(P_1P_2,Q)=\operatorname{Res}(P_1,Q)\operatorname{Res}(P_2,Q).

判别式是结式的特例:

Disc(P)=(1)m(m1)/2am1Res(P,P).\operatorname{Disc}(P) =(-1)^{m(m-1)/2}a_m^{-1}\operatorname{Res}(P,P').

它在且仅在 PP 有重根时为零。消元时应注意首项系数为零导致的“无穷远公共根”;齐次结式能把这一点统一处理。

把两变量系统降为一变量

F(u,v)=G(u,v)=0F(u,v)=G(u,v)=0,视它们为 vv 的多项式,计算

R(u)=Resv(F,G).R(u)=\operatorname{Res}_v(F,G).

任何公共零点的 uu-坐标都满足 R(u)=0R(u)=0。但反向不一定自动成立:结式可能含有由公共首项因子、清分母、退化参数或射影无穷远点产生的伪根。实际算法应对每个 uu 根回代求 vv,并验证原方程与非退化条件。若 RR 有高次因子,应分解后按 Galois 轨道分别处理。

次数 11 的 Belyi 多项式设置

对循环型 11/3312/241311/3^3 1^2/2^4 1^3,令

P(x)=C(x3+ax+b)3(x2+cx+d).P(x)=C\,(x^3+ax+b)^3(x^2+cx+d).

通过平移已去掉三次因子的 x2x^2 项。对数导数为

PP=33x2+ax3+ax+b+2x+cx2+cx+d.\frac{P'}P= 3\frac{3x^2+a}{x^3+ax+b} +\frac{2x+c}{x^2+cx+d}.

其分子中的四次多项式 Q(x)Q(x) 的根正是 P1P-1 的四个二重零点。条件等价于 P1(modQ2)P\equiv1\pmod{Q^2}。参数 a,b,c,da,b,c,d 受加权缩放

(x,a,b,c,d)(λx,λ2a,λ3b,λc,λ2d)(x,a,b,c,d)\mapsto (\lambda x,\lambda^2a,\lambda^3b,\lambda c,\lambda^2d)

支配。第一条系数方程通常对最高权参数 dd 线性,因此先解出 dd,余下两个加权齐次方程只含 a,b,ca,b,c。对 bb 取结式后,得到关于某个权零比值的十次方程,并分成二次与八次因子。

r=c/a2r=c/a^2 表示时,二次因子为

1331r2+363r+207,1331r^2+363r+207,

其根在 𝐐(11)\mathbf Q(\sqrt{-11}) 中。八次因子对应一个判别式为 5273116-5^2\,7^3\,11^6 的八次数域;可用更简洁的生成多项式

X8+2X63X5+10X414X3+14X28X+1X^8+2X^6-3X^5+10X^4-14X^3+14X^2-8X+1

描述。十个几何解分成大小 2 与 8 的 Galois 轨道;在原讲义的一个版本中,小轨道生成 M11M_{11},另一个近似循环型则生成 PSL2(𝐅11)\operatorname{PSL}_2(\mathbf F_{11}),大轨道均生成 A11A_{11}𝐐(11)\mathbf Q(\sqrt{-11}) 的出现与 11-循环的幂共轭有关:在相关群及其 S11S_{11} 正规化子中,gg_\inftygkg_\infty^k 共轭当且仅当 kk 是模 11 的平方剩余;固定平方子群的圆分子域二次子域正是 𝐐(11)\mathbf Q(\sqrt{-11})

补充:次结式与多重公共根

Res(P,Q)=0\operatorname{Res}(P,Q)=0 时,单个行列式只说明至少有一个公共根。要恢复最大公因式次数与系数,可使用次结式序列。第 kk 个次结式是 Sylvester 矩阵某些子式的组合;若 deggcd(P,Q)=d\deg\gcd(P,Q)=d,则前 dd 个适当次结式消失,而第 dd 个非零,并能给出 gcd。计算机代数中的 subresultant PRS 避免了有理函数Euclidean 算法的系数爆炸。

结式的高度与系数增长

P,QP,Q 的次数为 m,nm,n、系数位长约 BB,Sylvester 行列式直接展开会产生巨大中间整数。更好的方法是模多个机器素数计算结式,再用中国剩余定理重构;或使用次结式伪余数序列。多变量消元时,结式系数本身是另一些变量的多项式,次数上界需预先估计,以决定插值点数。

齐次结式与射影根

P(X),Q(X)P(X),Q(X) 齐次化为 Ph(X,Z),Qh(X,Z)P_h(X,Z),Q_h(X,Z)。齐次结式在且仅在 𝐏1\mathbf P^1 上有公共根时为零,包括 Z=0Z=0 的无穷远点。仿射计算中若首项系数同时消失,会误把次数下降当成公共有限根;齐次化能正确追踪边界分量。

判别式、分歧与临界值

对有理函数 f=P/Qf=P/Q,临界点由

PQPQ=0P'Q-PQ'=0

给出。把该式与 PtQP-tQ 关于 xx 取结式,得到 tt 的分支判别式;其根是临界值。若目标是 Belyi 映射,应验证该判别式只含 t,t1t,\,t-1 与无穷远因子。这个方法比逐点因子分解更适合高次数验证。

次数 11 方程的权零坐标

原参数缩放下 wt(a,b,c,d)=(2,3,1,2)\operatorname{wt}(a,b,c,d)=(2,3,1,2)。可以选 c0c\ne0 的图令 c=1c=1,或构造权零比值如 a/c2,b/c3,d/c2a/c^2,b/c^3,d/c^2。消去得到十次方程的次数与置换计数吻合,是完整性的强证据。二次和八次因子的判别式揭示两个 Galois 轨道;进一步用模素数分解型识别数域和单值群。

Gröbner 基与结式的选择

结式适合两变量或某变量次数很低的系统。变量多时可先利用线性方程、权与对称性降维,再取结式。纯字典序 Gröbner 基能直接消元,但中间表达式可能远大于结式;F4/F5 算法和模方法可缓解。实践中常组合使用:先 Gröbner 三角化,再对最后两变量取结式或因式分解。

进一步:结式的代数性质与数值稳定性

对次数 m,nm,n 的一元多项式 f,gf,g,Sylvester 矩阵行列式定义结式,并满足

Res(f,g)=afnf(α)=0g(α)=(1)mnagmg(β)=0f(β).\operatorname{Res}(f,g)=a_f^n\prod_{f(\alpha)=0}g(\alpha)=(-1)^{mn}a_g^m\prod_{g(\beta)=0}f(\beta).

因此结式为零当且仅当两多项式在代数闭包有公共根。其对系数分别齐次次数 n,mn,m,这个双齐次性是检查展开公式的重要约束。

判别式与结式关系为

Disc(f)=(1)m(m1)/2af1Res(f,f).\operatorname{Disc}(f)=(-1)^{m(m-1)/2}a_f^{-1}\operatorname{Res}(f,f').

它检测重根。对有理函数的临界值,可消去 xxResx(P(x)tQ(x),PQPQ)\operatorname{Res}_x(P(x)-tQ(x),P'Q-PQ'),其根包含临界值;之后要去除由极点、公共因子和无穷远造成的伪因子。

多变量消元中,逐次结式可能产生“leading coefficient vanishes”带来的额外分支。正确结果是消元理想的一个元素,不一定生成整个消元理想。Gröbner 基或饱和可去掉分母与基点成分。使用结式前先对公共因子饱和,通常能显著减小次数。

大 Sylvester 行列式直接展开复杂度高且系数膨胀。可在多个素数上用子结果式序列或快速多项式算法计算,再重构整数结果。若只需 gcd 或公共根次数,子结果式 PRS 比完整结式更经济。

数值结式极不稳定:接近公共根时 Sylvester 矩阵条件数巨大。浮点行列式接近零不能证明公共根。应使用精确算术,或以奇异值只作候选检测,再回到精确多项式做 gcd 和代入验证。

练习与解答结式计算

练习 1。计算 Res(xa,xb)\operatorname{Res}(x-a,x-b)

解。代根公式给 (ab)(a-b);按另一约定次序可能为 bab-a,与 (1)mn(-1)^{mn} 对称律一致。

练习 2。证明 Res(cf,g)=cdeggRes(f,g)\operatorname{Res}(cf,g)=c^{\deg g}\operatorname{Res}(f,g)

解。Sylvester 矩阵中来自 ffdegg\deg g 行均乘 cc,或由根公式直接得到。

练习 3。为何 Res(f,f)=0\operatorname{Res}(f,f')=0 等价于 ff 有重根(假设首项非零)?

解。重根正是 ff 与导数的公共根;结式为零等价于存在公共根。

深入补充:子结式、无分数消元与模算法认证

结式判定两个多项式是否有公共根,但在实际计算中常需要知道公共因子的次数、首项系数以及参数特化后何时次数跳跃。子结式序列把这些信息统一编码,并避免直接展开巨大的 Sylvester 行列式。

定理 子结式与 gcd 次数

f,gK[x]f,g\in K[x]degf=mn=degg\deg f=m\ge n=\deg g。记 Sresk(f,g)\operatorname{Sres}_k(f,g) 为第 kk 个子结式多项式。若 d=deggcd(f,g)d=\deg\gcd(f,g),则

Sres0==Sresd1=0,Sresd0,\operatorname{Sres}_0=\cdots=\operatorname{Sres}_{d-1}=0, \qquad \operatorname{Sres}_d\ne0,

并且 Sresd\operatorname{Sres}_dgcd(f,g)\gcd(f,g) 只差一个非零常数因子。

因此,当 f,gf,g 的系数含参数时,前若干子结式系数的消失方程精确描述“公共根重数至少为 dd”的退化子簇。与只令结式为零相比,这能区分一个简单公共根、两个不同公共根和一个二重公共根。

计算 线性代入的结式

f=x2af=x^2-ag=xbg=x-b,Sylvester 行列式给出

Resx(x2a,xb)=b2a.\operatorname{Res}_x(x^2-a,x-b)=b^2-a.

这正是把公共根条件 x=bx=b 代入 x2=ax^2=a 后所得方程。进一步,

Disc(x2a)=(1)1Res(x2a,2x)=4a,\operatorname{Disc}(x^2-a)=(-1)^{1}\operatorname{Res}(x^2-a,2x)=4a,

a=0a=0 恰是两个根合并的判别式点。

对整数系数,直接做Gaussian 消元会反复产生分母。Bareiss 无分数消元在第 kk 步把更新公式写成

aij(k+1)=akk(k)aij(k)aik(k)akj(k)ak1,k1(k1), a^{(k+1)}_{ij}=\frac{a^{(k)}_{kk}a^{(k)}_{ij}-a^{(k)}_{ik}a^{(k)}_{kj}}{a^{(k-1)}_{k-1,k-1}},

在非退化情形分母整除分子,所有中间量仍为整数,其大小接近真实子式而非普通分数消元的指数膨胀。计算中小型结式时,这往往比通用行列式程序稳定。

算法 模素数计算结式并重构

选择不整除首项系数、内容和预期判别式的素数 pp;在 𝐅p[x]\mathbf F_p[x] 上用子结式 PRS 或快速多项式算法计算结式;对多个良素数应用中国剩余重构整数系数;达到高度界后停止,并在一个未参与重构的新素数上核对。最终在特征零中验证 Sylvester 行列式或 Bézout 恒等式,作为确定性证书。

坏素数可能使次数下降或原本互素的多项式出现公共因子。一个实用检测是同时记录 degfp,deggp\deg f_p,\deg g_p 和 PRS 的次数序列;若与多数素数不同,就丢弃该素数。对于含参数的结式,可先随机赋值参数估计真实次数与稀疏支撑,再做稀疏插值,避免在所有参数上暴力展开。

消元顺序也可由几何维数决定。若理想 IK[x1,,xn]I\subset K[x_1,\ldots,x_n] 为零维,逐次结式可能引入由首项消失造成的伪分量;应在每一步饱和相关首项,或用 Gröbner 基的消元序验证。反之,若只需投影的闭包方程,结式包含的这些边界分量可能正是射影闭包所需。是否饱和不是纯粹的程序选项,而取决于要计算仿射像、射影像还是带重数的消元循环。

进一步计算专题:零维理想的有理单变量表示与 FGLM 转换

结式把多元系统投影到一条坐标轴,但仅有投影多项式还不足以恢复各坐标,也可能混入首项退化产生的伪根。对零维根式理想,更完整的输出是有理单变量表示(rational univariate representation)。

IK[x1,,xn]I\subset K[x_1,\ldots,x_n]

为零维根式理想,商代数

A=K[x1,,xn]/IA=K[x_1,\ldots,x_n]/I

的维数为 DD,即几何点数。选择线性形式

t=c1x1++cnxnt=c_1x_1+\cdots+c_nx_n

使它在所有解点上取值互不相同,称为分离元。乘法算子

Mt:AA,ataM_t:A\to A, \qquad a\mapsto ta

的特征多项式

h(T)=det(TIMt)h(T)=\det(TI-M_t)

恰以这些 tt-坐标为根,并且在根式情形平方自由、次数为 DD

定理 Shape lemma 与单变量参数化

tt 是分离元,则存在次数小于 DD 的多项式 gi(T)g_i(T),使

AK[T]/(h(T)),xigi(T)(modh(T)).A\cong K[T]/(h(T)), \qquad x_i\equiv g_i(T)\pmod{h(T)}.

在相应字典序坐标中,理想具有形状

I=(h(t),x1g1(t),,xngn(t))I=(h(t),x_1-g_1(t),\ldots,x_n-g_n(t))

到线性坐标变换。

因此每个根 τ\tau 唯一恢复为

xi=gi(τ).x_i=g_i(\tau).

若坐标表达含分母,可写成

xi=hi(τ)h0(τ),x_i=\frac{h_i(\tau)}{h_0(\tau)},

并额外证明 gcd(h0,h)=1\gcd(h_0,h)=1。这种表示比一串嵌套代数数更紧凑,也便于隔离实根、匹配共轭和模素数约化。

计算 MtM_t 只需一个任意项序的 Gröbner 基与商代数标准单项式基。对每个基单项式乘以 tt,再模 Gröbner 基约化,所得坐标列组成 D×DD\times D 矩阵。坐标函数可由解线性方程

gi(Mt)1=xig_i(M_t)\cdot1=x_i

求出,或用伴随、迹配对构造。

算法 FGLM 项序转换

从适合求解的次数反字典序 Gröbner 基出发,建立各变量乘法矩阵;按目标项序枚举单项式,并检测其在商代数中的像是否线性相关。第一次相关给出新的 Gröbner 关系,独立像加入目标标准基。经典复杂度约为 O(nD3)O(nD^3) 个域运算,使用稀疏线性代数可明显降低常数。

FGLM 的优势是把“昂贵的原始 Gröbner 基计算”与“适合解根的字典序输出”分开。次数反字典序通常避免中间多项式爆炸;商代数维数确定后,项序转换只是有限维线性代数。

认证 RUR 的完备性检查

一组 (h,h0,h1,,hn)(h,h_0,h_1,\ldots,h_n) 构成原系统的完备 RUR,需验证:

gcd(h,h)=1,gcd(h,h0)=1,\gcd(h,h')=1, \qquad\gcd(h,h_0)=1,

并对每个原方程 FjF_j 检查

h0(T)degFjFj(h1h0,,hnh0)0(modh(T)).h_0(T)^{\deg F_j} F_j\left(\frac{h_1}{h_0},\ldots, \frac{h_n}{h_0}\right) \equiv0\pmod{h(T)}.

此外 degh\deg h 必须等于商代数维数 DD。这些条件同时证明所有参数根给出原方程解,且没有遗漏或重复几何点。

若理想非根式,hh 会含重根,乘法矩阵出现 Jordan 块。此时特征多项式记录带重数长度,而最小多项式记录不同投影值;局部代数的幂零结构不能由点坐标单独恢复。可先求根式用于几何解,再单独计算每个点的局部长度;也可使用三角分解保存重数信息。

模算法中,应选择使 DD、首项理想和 hh 次数不变的良素数。不同素数下的分离元可能偶然不分离;检测 gcd(h,h)\gcd(h,h') 即可拒绝。重构后在特征零执行上述余式检查,得到短而确定的求解证书。

补充计算:无分数结式、子结式序列与有理单变量表示

定理 结式、公共根与零维消元

设 R 为整环,\(f,g∈R[x]\) 的次数分别为 m,n。Sylvester 矩阵 S(f,g) 的行列式 \(Res_x(f,g)\) 满足:在 R 的分式域代数闭包中,\(Res_x(f,g)=0\) 当且仅当 f,g 有公共根。若 \(I=⟨F_1,…,F_s⟩⊂K[x_1,…,x_r]\) 为零维根理想,且线性型 \(t=u_1x_1+···+u_rx_r\) 分离全部几何点,则存在平方自由 \(h∈K[t]\) 与 \(a_i∈K[t]/(h)\),使 K[x1,,xr]/IK[t]/(h),xiai(t). K[x_1,\ldots,x_r]/I\simeq K[t]/(h),\qquad x_i\mapsto a_i(t).

证明 由乘法算子与分离元建立商代数同构

在分裂域中写 \(f=a_m∏(x-α_i)\)。对 g 的乘法算子作用于 \(K[x]/(f)\),其行列式为 \(a_m^n∏g(α_i)\),与 Sylvester 行列式相同。因此结式为零恰好有某个 \(g(α_i)=0\)。无分数 Bareiss 消元只使用精确整除,故在整系数环上保持同一行列式而避免中间分母。

对零维根理想,商代数 A 为有限维约化 K-代数。分离线性型 t 在各几何点取互异值,故其最小多项式 h 的次数等于 \(dim_K A\)。映射 \(K[t]/(h)→A\) 为单射且两边维数相同,因而为同构。每个坐标类 \(x_i\) 因此唯一表示为次数小于 deg h 的 \(a_i(t)\)。把这些表示代回 \(F_j\) 并模 h 取余为零,即给出完整精确证书。

Python Sylvester 矩阵、Bareiss 行列式、PRS 与 RUR
import sympy as sp
from dataclasses import dataclass

x, y, t = sp.symbols("x y t")

def sylvester_matrix(f: sp.Poly, g: sp.Poly) -> sp.Matrix:
    f = sp.Poly(f, x)
    g = sp.Poly(g, x)
    m, n = f.degree(), g.degree()
    fc = f.all_coeffs()
    gc = g.all_coeffs()
    rows = []
    for shift in range(n):
        rows.append([0]*shift + fc + [0]*(n-1-shift))
    for shift in range(m):
        rows.append([0]*shift + gc + [0]*(m-1-shift))
    return sp.Matrix(rows)

def bareiss_det(A: sp.Matrix):
    """Fraction-free determinant over an integral domain."""
    A = A.as_mutable()
    n = A.rows
    sign = 1
    previous = sp.Integer(1)
    for k in range(n-1):
        if A[k,k] == 0:
            pivot = next((i for i in range(k+1,n) if A[i,k] != 0), None)
            if pivot is None:
                return sp.Integer(0)
            A.row_swap(k,pivot)
            sign = -sign
        pivot = A[k,k]
        for i in range(k+1,n):
            for j in range(k+1,n):
                numerator = A[i,j]*pivot - A[i,k]*A[k,j]
                A[i,j] = sp.cancel(numerator/previous)
        for i in range(k+1,n):
            A[i,k] = 0
        previous = pivot
    return sp.expand(sign*A[n-1,n-1])

def primitive_part(p: sp.Poly) -> sp.Poly:
    cont, prim = sp.primitive(p.as_expr())
    if sp.LC(sp.Poly(prim, p.gens[0])) < 0:
        prim = -prim
    return sp.Poly(prim, p.gens[0])

def subresultant_prs(f: sp.Poly, g: sp.Poly) -> list[sp.Poly]:
    """Use exact pseudo-remainders and remove content at every step."""
    f = primitive_part(sp.Poly(f, x))
    g = primitive_part(sp.Poly(g, x))
    seq = [f,g]
    while not seq[-1].is_zero:
        r = sp.prem(seq[-2],seq[-1],x)
        if r == 0:
            break
        r = primitive_part(sp.Poly(-r,x))
        seq.append(r)
    return seq

@dataclass
class RUR:
    eliminant: sp.Poly
    x_of_t: sp.Expr
    y_of_t: sp.Expr
    separator: sp.Expr

def rational_univariate_representation(F, G):
    """
    Small zero-dimensional example.
    Add t=x+2y, eliminate x,y, then recover coordinates modulo eliminant.
    """
    ideal = [sp.expand(F), sp.expand(G), t-x-2*y]
    grob = sp.groebner(ideal, x, y, t, order="lex")
    polys = [sp.Poly(p, x,y,t) for p in grob.polys]
    univariate = [p.as_expr() for p in polys
                  if not p.as_expr().has(x) and not p.as_expr().has(y)]
    if len(univariate) != 1:
        raise ArithmeticError("separator did not yield one eliminant")
    h = sp.Poly(univariate[0], t, domain=sp.QQ)

    x_rel = next(p.as_expr() for p in polys
                 if sp.Poly(p.as_expr(),x).degree()==1
                 and not sp.diff(p.as_expr(),x).has(x))
    y_rel = next(p.as_expr() for p in polys
                 if sp.Poly(p.as_expr(),y).degree()==1
                 and not sp.diff(p.as_expr(),y).has(y))

    x_sol = sp.solve(sp.Eq(x_rel,0),x)[0]
    y_sol = sp.solve(sp.Eq(y_rel,0),y)[0]
    return RUR(h,sp.factor(x_sol),sp.factor(y_sol),x+2*y)

f = sp.Poly(x**4-3*x**2+2, x)
g = sp.Poly(x**3-x, x)
S = sylvester_matrix(f,g)
print("Sylvester matrix:")
print(S)
print("det by Bareiss =", bareiss_det(S))
print("sympy resultant =", sp.resultant(f.as_expr(),g.as_expr(),x))

print("\nprimitive pseudo-remainder sequence:")
for i,p in enumerate(subresultant_prs(f,g)):
    print(f"  R{i}: degree={p.degree()}, {p.as_expr()}")

F = x**2+y**2-1
G = x-y**2
print("\nelimination of x^2+y^2-1 and x-y^2:")
res = sp.factor(sp.resultant(F,G,x))
print("  resultant_x =",res)
print("  squarefree   =",sp.factor(sp.Poly(res,y).sqf_part().as_expr()))

rur = rational_univariate_representation(F,G)
print("\nrational univariate representation with t=x+2y:")
print("  h(t)   =",rur.eliminant.as_expr())
print("  x(t)   =",rur.x_of_t)
print("  y(t)   =",rur.y_of_t)
print("  degree =",rur.eliminant.degree())

print("\nexact substitution residues modulo h:")
for label,expr in [
    ("F", F.subs({x:rur.x_of_t,y:rur.y_of_t})),
    ("G", G.subs({x:rur.x_of_t,y:rur.y_of_t})),
]:
    num = sp.together(expr).as_numer_denom()[0]
    rem = sp.rem(sp.Poly(num,t),rur.eliminant)
    print(f"  {label}: remainder={sp.factor(rem.as_expr())}")
运行结果 公共因子检测与四点零维系统的单变量化
Sylvester matrix:
Matrix([[1, 0, -3, 0, 2, 0, 0], [0, 1, 0, -3, 0, 2, 0], [0, 0, 1, 0, -3, 0, 2], [1, 0, -1, 0, 0, 0, 0], [0, 1, 0, -1, 0, 0, 0], [0, 0, 1, 0, -1, 0, 0], [0, 0, 0, 1, 0, -1, 0]])
det by Bareiss = 0
sympy resultant = 0

primitive pseudo-remainder sequence:
  R0: degree=4, x**4 - 3*x**2 + 2
  R1: degree=3, x**3 - x
  R2: degree=2, x**2 - 1

elimination of x^2+y^2-1 and x-y^2:
  resultant_x = y**4 + y**2 - 1
  squarefree   = y**4 + y**2 - 1

rational univariate representation with t=x+2y:
  h(t)   = t**4 + 2*t**3 + 3*t**2 - 18*t - 19
  x(t)   = -(2*t**3 - t**2 - 6*t - 21)/29
  y(t)   = (2*t**3 - t**2 + 23*t - 21)/58
  degree = 4

exact substitution residues modulo h:
  F: remainder=0
  G: remainder=0
计算 示例系统的坐标恢复

系统 x^2+y^2=1、x=y^2 消去 x 得 y^4+y^2-1=0,共有四个简单几何点。取 t=x+2y 后, h(t)=t^4+2t^3+3t^2-18t-19, x=-(2t^3-t^2-6t-21)/29, y=(2t^3-t^2+23t-21)/58。 两方程代入后分子对 h 的余式均为 0。

Lecture 8 / 第 8 讲

立方减平方、Hall 型恒等式与模曲线

把低次数差、多项式 abc、椭圆判别式与 Belyi 映射联系起来。

Hall猜想多项式abc判别式

1. “立方减平方”结构

若 Belyi 数据使 00 上方大多为 3 重、11 上方大多为 2 重,方程常化为

A(x)P(x)3B(x)Q(x)2=C(x),A(x)P(x)^3-B(x)Q(x)^2=C(x),

其中 A,B,CA,B,C 次数很低。这类恒等式同时接触 Hall 猜想、椭圆曲面和模曲线。关键原因是三次多项式 X3+pX+qX^3+pX+q 的判别式

Δ=4p327q2.\Delta=-4p^3-27q^2.
X0(5)X_0(5) 的经典恒等式
(x2+10x+5)31728x=(x2+4x1)2(x2+22x+125).(x^2+10x+5)^3-1728x=(x^2+4x-1)^2(x^2+22x+125).

于是

j=(x2+10x+5)3x,j=\frac{(x^2+10x+5)^3}{x},

在适当归一化后给出 X0(5)X(1)X_0(5)\to X(1) 的 Belyi 映射。右侧的平方因子编码 j1728j-1728 上方的二重分歧。

2. Hall 型恒等式

Hall 猜想研究整数 u3v2u^3-v^2 相对于 u1/2u^{1/2} 的大小。多项式恒等式中若 deg(P3Q2)\deg(P^3-Q^2) 远低于一般值,就能通过特殊化构造异常接近的立方与平方。原材料中的 Hall 例满足 degP=8\deg P=8degQ=12\deg Q=12deg(P3Q2)=5\deg(P^3-Q^2)=5

算法从 Laurent 展开寻找 P3Q2P^3-Q^2

PP 为首一偶次数多项式。形式展开 P3/2P^{3/2} 于无穷远,并令 QQ 为其多项式部分。要求若干负次项系数消失,就得到 PP 系数的多项式方程。仿射变换 xax+bx\mapsto ax+b 提供两维规范自由度,必须先固定,否则 Jacobian 会奇异。

定理多项式 abc 次数界

对两两互素的非常值多项式 A+B=CA+B=C,Mason–Stothers 定理给出

max(degA,degB,degC)degrad(ABC)1.\max(\deg A,\deg B,\deg C)\le \deg\operatorname{rad}(ABC)-1.

接近等号的恒等式对应高度分歧的三点覆盖;这正是 Belyi 结构。

证明Mason–Stothers 的核心一步

对等式求导并消去可得 ABAB=ACACA'B-AB'=A'C-AC'。每个在 ABCABC 中出现的重根都迫使左侧具有相应低一阶的零,从而 ABC/rad(ABC)ABC/\operatorname{rad}(ABC) 整除一个次数可控的 Wronskian。比较次数即得不等式。

练习判别式与椭圆曲线

E:y2=x3+px+qE:y^2=x^3+px+q,验证奇异当且仅当 4p3+27q2=04p^3+27q^2=0。解释为什么“立方减平方”因子化会自然控制椭圆纤维的退化位置。

“立方减平方”问题的原始动机

课程转向一个重要特例:g0,g1g_0,g_1 的非平凡循环主要是 3-循环与 2-循环。代数上这产生

A+B=CA+B=C

而其中两项分别“几乎是立方”与“几乎是平方”;“几乎”意为只差低次数因子。这类恒等式一方面与 Hurwitz 曲线和其他高度对称Riemann 曲面有关,另一方面与 Hall 猜想有关。Hall 猜想预言,对整数 x,yx,y,除非 x3=y2x^3=y^2,否则对任意 ε>0\varepsilon>0

|x3y2|εx1/2ε.|x^3-y^2|\gg_\varepsilon x^{1/2-\varepsilon}.

判别式解释

去掉二次项后的三次多项式 X3+pX+qX^3+pX+q 的判别式为

Δ=4p327q2.\Delta=-4p^3-27q^2.

因此当多项式 P3Q2P^3-Q^2 有大量重因子时,常可解释为一族三次曲线的判别式具有特殊因子分解;这自然连接到椭圆曲线、模曲线与椭圆曲面。一般三次式 X3+aX2+bX+cX^3+aX^2+bX+c 可由平移 XXa/3X\mapsto X-a/3 化为短式,但在显式计算中未必总选这个平移:保留一个看似多余的二次项,有时反而让系数更小、几何结构更透明。

模曲线 X0(5)X_0(5) 的恒等式

原讲义突出展示

(x2+10x+5)31728x=(x2+4x1)2(x2+22x+125).(x^2+10x+5)^3-1728x =(x^2+4x-1)^2(x^2+22x+125).

相应的 Belyi 映射循环型为 51/33/221151/33/2211,并给出模曲线覆盖 X0(5)X(1)X_0(5)\to X(1)。若取 eta 商参数

x=125(η(5τ)η(τ))6,x=125\left(\frac{\eta(5\tau)}{\eta(\tau)}\right)^6,

j(τ)=(x2+10x+5)3x;j(\tau)=\frac{(x^2+10x+5)^3}{x};

若采用规范化 j/1728j/1728,分母相应出现 1728x1728x。其 Galois 闭包是 X(5)X(5),即二十面体群 A5A_5 的球面 Galois 覆盖

𝐏1𝐏1/A5𝐏1.\mathbf P^1\longrightarrow \mathbf P^1/A_5\cong\mathbf P^1.

同一恒等式经 Pell 型递推还导出 Danilov 在 1982 年发现的、目前经典的无穷族,其中 0<|x3y2|x1/20<|x^3-y^2|\le x^{1/2}。这说明一个 Belyi 恒等式可能同时编码模参数、有限群作用与丢番图近似。

Hall 的次数 8/128/12 恒等式

原讲义讨论 Hall 的多项式例子:degP=8,degQ=12,deg(P3Q2)=5\deg P=8,\deg Q=12,\deg(P^3-Q^2)=5。其中

P(x)=4(x82x7+7x66x5+11x4+4x3+12x+1).P(x)=4\bigl(x^8-2x^7+7x^6-6x^5+11x^4+4x^3+12x+1\bigr).

系数 4 的作用是使相应 QQ 具有整数系数。QQ 可由 P3/2P^{3/2}x=x=\infty 的 Laurent 展开截断得到;展开中 x1,,x6x^{-1},\ldots,x^{-6} 的系数恰好消失。Hall 原来使用 P(x+1)P(x+1),但其系数更大。

与其只记录巨大的 P,QP,Q,更有结构的写法是考虑含参数 xx 的三次式

X3+(x4x3+3x2+1)X22(x3x2+2x)X+(x2x+1).X^3+(x^4-x^3+3x^2+1)X^2 -2(x^3-x^2+2x)X+(x^2-x+1).

其判别式分解恢复所需的立方减平方恒等式。这反映了一条更自然的发现路线:从希望获得的奇异纤维与判别式分解出发构造三次族,而不是直接猜测高次数 P,QP,Q

多项式 abcabc 与 Wronskian 下界

A+B=CA+B=C 两两互素,Mason–Stothers 定理给出

max(degA,degB,degC)degrad(ABC)1.\max(\deg A,\deg B,\deg C) \le \deg\operatorname{rad}(ABC)-1.

P3Q2=RP^3-Q^2=R,若 P,QP,Q 互素且次数分别为 2m,3m2m,3m,则不等式迫使 degR\deg R 不能任意小。接近等号意味着 P,Q,RP,Q,R 的根高度重合成少量分歧点,正对应 Belyi 或近 Belyi 映射。证明可用 Wronskian ABABA'B-AB':每个高重根使该 Wronskian 至少多消失一阶,比较总次数得到界。

四分支点与 K3 曲面的正维族

原讲义还考虑 degx=8,degy=12\deg x=8,\deg y=12,而 x3y2x^3-y^2 为非零且次数至多 6 的多项式。通常的多项式 abcabc/Wronskian/Riemann–Hurwitz论证说明其次数至少为 5。函数

f=x3y2f=\frac{x^3}{y^2}

次数为 24,在 00 上单值型 383^8,在 \infty 上型 2122^{12},在 11 上型 16181^6\,18,另有一个由 ff' 的额外零点产生的简单分支值。因此这是一族四点分歧覆盖,而非离散的 Belyi 映射。

对应椭圆 K3 曲面

Y2=X33x(t)X+2y(t)Y^2=X^3-3x(t)X+2y(t)

t=t=\infty 有至少 I18I_{18} 型奇异纤维。平凡格贡献 22,该纤维的根格贡献 1717,故 Picard 数至少 1919,模空间维数为 20ρ=120-\rho=1,与参数计数得到的一维族一致。

补充:Mason–Stothers 定理的完整证明轮廓

A+B=CA+B=C 两两互素,令 R=rad(ABC)R=\operatorname{rad}(ABC)。考虑

W=ABAB=ACAC.W=A'B-AB'=A'C-AC'.

α\alphaAAmm 重根,则 AA' 至少有 m1m-1 重零,而 B(α),C(α)0B(\alpha),C(\alpha)\ne0,故 WWα\alpha 至少 m1m-1 重消失。对 B,CB,C 同理。因此

ABCRW.\frac{ABC}{R}\mid W.

W0W\ne0,则

degA+degB+degCdegRdegWdegA+degB1,\deg A+\deg B+\deg C-\deg R \le\deg W\le\deg A+\deg B-1,

假设 degC\deg C 最大便得 degCdegR1\deg C\le\deg R-1。若 W=0W=0,则 A/BA/B 为常数,与 A+B=CA+B=C 及非常值假设矛盾。

Hall 猜想与椭圆曲线

整数解 y2=x3+ky^2=x^3+k 是 Mordell 曲线 EkE_k 上的整点。Hall 猜想控制 kk 相对 xx 的最小可能规模;从椭圆曲线高度看,它预言非挠整点的 xx-高度不能相对判别式异常大。多项式恒等式 P(t)3Q(t)2=R(t)P(t)^3-Q(t)^2=R(t) 特化后给出无穷多个整数近似,若 degR\deg R 很小,就接近猜想极限。

从判别式到 Kodaira 纤维

椭圆曲面短方程 Y2=X3+A(t)X+B(t)Y^2=X^3+A(t)X+B(t) 的判别式

Δ=16(4A3+27B2).\Delta=-16(4A^3+27B^2).

仅知道 ordvΔ\operatorname{ord}_v\Delta 不足以确定纤维型,还需 c4=48Ac_4=-48Ac6=864Bc_6=-864B 的赋值并运行 Tate 算法。但在半稳定情形 c4(v)0c_4(v)\ne0 时,ordvΔ=n\operatorname{ord}_v\Delta=n 即给出 InI_n 纤维。高重因子化因此直接制造大乘法型纤维和高 Picard 数。

Padé 逼近解释 QQ 的截断

PP 首一且次数偶数。在无穷远形式展开 P3/2P^{3/2},选择次数 3m3m 多项式 QQ 匹配尽可能多的高次项,相当于 Padé 逼近。要求连续多个负幂系数消失,就是使 P3Q2P^3-Q^2 次数尽可能低。这个线性—非线性混合过程比直接解全部系数更高效:给定 PPQQ 由截断唯一确定,剩余条件只作用于 PP 系数。

近 Belyi 映射

四分支点覆盖中,三个分支值具有大规模规定分歧,第四个只含一个简单换位,称为近 Belyi 映射。其 Hurwitz 空间通常是一条曲线。Painlevé VI 的代数解、等单值变形和椭圆 K3 曲面常通过这种近 Belyi 映射联系起来。第四分支值可作为模参数,退化到 0,1,0,1,\infty 时得到真正 Belyi 映射作为边界点。

进一步:x3y2x^3-y^2 小值与椭圆曲线方法

寻找 |x3y2||x^3-y^2| 很小的问题与 Hall 猜想相关。对固定整数 kk,方程 y2=x3ky^2=x^3-k 是椭圆曲线;求整数解可用 Mordell–Weil 群、线性形式对数估计和约化算法。单纯扫描 xx 并取最近平方只能发现有限范围内的例子,不能证明完整性。

若要在 xXx\le X 中搜索,可计算 y=x3/2y=\lfloor x^{3/2}\rceil,比较差值。但逐个 xxO(X)O(X)。利用 y/xxy/x\approx\sqrt x 的连分数、格约化或分区 Taylor 展开,可批量寻找极接近平方的立方。需要明确衡量指标:绝对差 |x3y2||x^3-y^2|、归一化差 |x3y2|/x|x^3-y^2|/\sqrt x 或质量 x1/2/|x3y2|x^{1/2}/|x^3-y^2| 排序结果不同。

方程 aX3+bY3=cZ2aX^3+bY^3=cZ^2 等加权齐次形式可定义加权射影曲线或椭圆 K3 曲面。通过选一个变量作参数,常得到椭圆曲面;其截面产生无穷多整数或有理解族。反过来,异常小差值可能对应曲面上的低高度截面。

模筛是大规模搜索关键。对许多小素数预计算立方剩余与平方剩余,排除差值 kk 不可能的同余类;再对剩余候选做大整数平方测试。若固定 kk,可把方程模多个素数的局部可解性作为必要条件,但局部处处可解不保证全局有整数点。

报告计算纪录时应同时给出搜索边界、完整算法和验证脚本所需信息。一个漂亮例子并不意味着在范围内最优;“未发现更好”只有在搜索空间与剪枝均覆盖完整时才有数学意义。

练习与解答立方与平方

练习 1。说明固定 k0k\ne0y2=x3ky^2=x^3-k 在判别式非零时是椭圆曲线。

解。短 Weierstrass 方程的判别式为 432k2-432k^2,故特征不为 2、3 且 k0k\ne0 时光滑;加无穷远点成为亏格 1 带原点曲线。

练习 2。为什么用浮点计算 x3/2x^{3/2} 可能误判最近平方?

解。xx 很大时浮点间距超过 1,舍入值可能跨过真正最近整数。应以整数平方根计算 x3\lfloor\sqrt{x^3}\rfloor

练习 3。给出一个模 8 筛选事实。

解。平方模 8 只可能为 0、1、4,立方模 8 与底数同奇偶并可枚举;固定 kk 时可预先排除使 x3kx^3-k 不属平方剩余的类。

深入补充:Mason–Stothers 下界与 Padé 构造的线性化

P,QP,Q 互素,并希望 R=P3Q2R=P^3-Q^2 的次数远小于 3degP3\deg P2degQ2\deg Q。多项式 abcabc 定理立即给出不可突破的下界,因此任何搜索都应先做次数可行性检查。

推论 平衡次数下的余项下界

degP=2m\deg P=2mdegQ=3m\deg Q=3mP,Q,R=P3Q2P,Q,R=P^3-Q^2 两两互素,则

degRm+1.\deg R\ge m+1.

证明:对 P3+(Q2)+(R)=0P^3+(-Q^2)+(-R)=0 应用 Mason–Stothers 定理,得到

6mdegrad(PQR)12m+3m+degR1.6m\le \deg\operatorname{rad}(PQR)-1 \le 2m+3m+\deg R-1.

整理即得结论。

因而理想的 Hall 型恒等式会让 degR\deg R 接近 m+1m+1;若搜索目标低于这个界,方程除退化情形外必无解。若 P,Q,RP,Q,R 共享因子,则先除去 gcd 后再应用定理;共享因子常对应椭圆曲面模型尚未最小化。

构造小余项可看成非线性 Padé 问题。取初始多项式 P0,Q0P_0,Q_0,写

P=P0+U,Q=Q0+V.P=P_0+U, \qquad Q=Q_0+V.

一阶线性化为

P3Q2=(P03Q02)+3P02U2Q0V+O(U2,UV,V2).P^3-Q^2=(P_0^3-Q_0^2)+3P_0^2U-2Q_0V+O(U^2,UV,V^2).

若规定 U,VU,V 的次数上界,并要求最高若干项消失,则 3P02U2Q0V3P_0^2U-2Q_0V 给出一个线性方程组。解出后再作 Newton 修正,可把“直接求高次多项式方程”改成一串结构相同的线性系统。

算法 逐阶消去高次项

先把 P,QP,Q 取首一,并用平移消去 PP 的次首项。按目标次数 rr 要求 x6m,x6m1,,xr+1x^{6m},x^{6m-1},\ldots,x^{r+1} 的系数在 P3Q2P^3-Q^2 中为零。最高次方程依次决定 QQ 的高次系数,剩余方程通常呈准三角形。每解出一层,就对未定系数重新线性化;最后只需处理少量真正非线性的低阶参数。

这一过程也可在无穷远处用 Laurent 级数表述。令

S(x)=P(x)3/2=x3m(1+s1x1+s2x2+).S(x)=P(x)^{3/2}=x^{3m}\left(1+s_1x^{-1}+s_2x^{-2}+\cdots\right).

选择次数 3m3mQQ 使其等于 SS 的多项式部分,则 QS=O(x1)Q-S=O(x^{-1}),于是

Q2P3=(QS)(Q+S)Q^2-P^3=(Q-S)(Q+S)

的次数自动下降。为了使次数下降超过普通截断所能保证的范围,需要调节 PP 的低次系数,使若干后续 Laurent 系数同时消失;这正是 Padé 条件。系数递推只涉及有理运算,非常适合先模素数求解再提升。

把恒等式写成椭圆曲面

y2=x3R(t)y^2=x^3-R(t)

后,x=P(t),y=Q(t)x=P(t),y=Q(t) 给出一个截面。RR 的低次数意味着无穷远纤维有较高消失阶,而截面的高度受奇异纤维局部贡献限制。于是 Mason 下界、Padé 消去和 Shioda 高度公式从三个方向约束同一组次数数据:前者给不可逾越的组合下界,中者给构造算法,后者解释何时极端恒等式来自特殊的 Mordell–Weil 格。

补充计算:多项式 abc、Padé 消去与 Hall 小差搜索

定理 Mason–Stothers 定理

设 \(A,B,C∈K[x]\) 两两互素、非常数,特征为 0,且 \(A+B=C\)。记 \(rad(ABC)\) 为 ABC 的无重因子乘积,则 max(degA,degB,degC)degrad(ABC)1. \max(\deg A,\deg B,\deg C)\le \deg\operatorname{rad}(ABC)-1. 若 \(X^3-Y^2=Z\) 且 \(gcd(X,Y)=1\),则 max(3degX,2degY)degrad(XYZ)1, \max(3\deg X,2\deg Y)\le \deg\operatorname{rad}(XYZ)-1, 从而 Z 的次数不能在无新增零点的条件下任意小。

证明 Wronskian 的零点下界与次数上界

由 \(A+B=C\) 得 \(A'B-AB'=A'C-AC'=B'C-BC'\)。记 \(W=A'B-AB'\)。若 α 是 A 的 e 重根,则 \(gcd(A,B)=1\),B(α)≠0,故 W 在 α 至少有 e-1 重零;B、C 的根同理。因此 \(ABC/rad(ABC)\) 整除 W。

若 \(W=0\),则 \((A/B)'=0\);特征 0 下 A/B 为常数,与 \(A+B=C\) 及两两互素、非常数矛盾。故 \(deg A+deg B-deg rad(AB)≤deg W≤deg A+deg B-1\)。 同时加入 C 的根所得整除关系给出 \(deg ABC-deg rad(ABC)≤deg W\)。 选取 A、B、C 中次数最大者并使用 W 的三个等价表达,可消去另外两项,得到所述不等式。

Python 根式次数、精确 Padé 逼近与整数 Hall 搜索
import sympy as sp
from math import isqrt
from dataclasses import dataclass

x = sp.Symbol("x")

def radical(poly: sp.Expr) -> sp.Poly:
    p = sp.Poly(sp.expand(poly), x, domain=sp.QQ)
    if p.is_zero:
        return p
    return sp.Poly(sp.div(p, sp.gcd(p, p.diff()))[0], x)

def mason_record(a, b, c):
    a, b, c = map(lambda z: sp.Poly(sp.expand(z), x, domain=sp.QQ),
                  (a,b,c))
    if sp.expand(a.as_expr()+b.as_expr()-c.as_expr()) != 0:
        raise ValueError("require a+b=c")
    common = sp.gcd(sp.gcd(a,b),c)
    rad = radical(a.as_expr()*b.as_expr()*c.as_expr())
    lhs = max(a.degree(),b.degree(),c.degree())
    rhs = rad.degree()-1
    return {
        "gcd": common.as_expr(),
        "degrees": (a.degree(),b.degree(),c.degree()),
        "radical": sp.factor(rad.as_expr()),
        "radical_degree": rad.degree(),
        "lhs": lhs,
        "rhs": rhs,
        "strict": lhs <= rhs,
    }

def pade_exp(series_expr, m, n):
    """
    [m/n] Padé approximation at x=0 using exact linear equations.
    Q(0)=1; require Q*S-P=O(x^(m+n+1)).
    """
    coeffs = [sp.expand(series_expr.series(x,0,m+n+1).removeO()).coeff(x,k)
              for k in range(m+n+1)]
    q = sp.symbols(f"q1:{n+1}")
    equations=[]
    for k in range(m+1,m+n+1):
        equations.append(sp.Eq(
            coeffs[k] + sum(q[j-1]*coeffs[k-j]
                            for j in range(1,min(n,k)+1)), 0))
    sol = sp.solve(equations,q,dict=True)
    if not sol:
        raise ArithmeticError("Padé system singular")
    sol=sol[0]
    Q=1+sum(sol[q[j-1]]*x**j for j in range(1,n+1))
    P=0
    for k in range(m+1):
        ck=coeffs[k]+sum(sol[q[j-1]]*coeffs[k-j]
                         for j in range(1,min(n,k)+1))
        P += sp.simplify(ck)*x**k
    return sp.factor(P), sp.factor(Q)

@dataclass(frozen=True)
class HallHit:
    x: int
    y: int
    k: int
    normalized: float

def nearest_square(n):
    y=isqrt(n)
    candidates=[y,y+1]
    return min(candidates,key=lambda z:abs(n-z*z))

def hall_search(xmax, keep=20):
    hits=[]
    for X in range(1,xmax+1):
        cube=X**3
        Y=nearest_square(cube)
        k=cube-Y*Y
        if k != 0:
            hits.append(HallHit(X,Y,k,abs(k)/(X**0.5)))
    hits.sort(key=lambda h:(abs(h.k),h.x))
    return hits[:keep]

examples = [
    (x**3, (1-x)**2, x**3+(1-x)**2),
    ((x-1)**4, 4*x*(x**2-x+1), (x+1)**2*(x**2-2*x+1)+4*x*(x**2-x+1)),
]
for j,(a,b,c) in enumerate(examples,1):
    c=sp.expand(a+b)
    rec=mason_record(a,b,c)
    print(f"Mason record {j}:")
    for k,v in rec.items():
        print(f"  {k:16s}: {v}")

P,Q=pade_exp((1-x)**sp.Rational(3,2),6,6)
error=sp.series(Q*(1-x)**sp.Rational(3,2)-P,x,0,15)
print("\n[6/6] Pade for (1-x)^(3/2):")
print("  P =",P)
print("  Q =",Q)
print("  Q*S-P =",error)

print("\nsmall Hall hits for 1<=x<=50000:")
for h in hall_search(50000,12):
    print(f"  x={h.x:6d} y={h.y:9d} k={h.k:8d} "
          f"|k|/sqrt(x)={h.normalized:.6f}")

print("\npolynomial cube-square defects:")
pairs=[
    (x**2+1, x**3+sp.Rational(3,2)*x),
    (x**4+2*x, x**6+3*x**3),
    (x**3-3*x, x**sp.Rational(9,2) if False else x**4),
]
for A,B in pairs[:2]:
    defect=sp.factor(A**3-B**2)
    print(f"  ({A})^3 - ({B})^2 = {defect}")
运行结果 Mason 记录、[6/6] 逼近及小差样本
Mason record 1:
  gcd             : 1
  degrees         : (3, 2, 3)
  radical         : x*(x - 1)*(x**3 + x**2 - 2*x + 1)
  radical_degree  : 5
  lhs             : 3
  rhs             : 4
  strict          : True
Mason record 2:
  gcd             : 1
  degrees         : (4, 3, 4)
  radical         : 4*x*(x - 1)*(x**2 + 1)*(x**2 - x + 1)
  radical_degree  : 6
  lhs             : 4
  rhs             : 5
  strict          : True

[6/6] Pade for (1-x)^(3/2):
  P = (715*x**6 - 12012*x**5 + 68640*x**4 - 183040*x**3 + 249600*x**2 - 168960*x + 45056)/45056
  Q = -(x**6 + 84*x**5 - 3360*x**4 + 26880*x**3 - 80640*x**2 + 101376*x - 45056)/45056
  Q*S-P = 15*x**13/369098752 + 15*x**14/134217728 + O(x**15)

small Hall hits for 1<=x<=50000:
  x=     2 y=        3 k=      -1 |k|/sqrt(x)=0.707107
  x=     3 y=        5 k=       2 |k|/sqrt(x)=1.154701
  x=     5 y=       11 k=       4 |k|/sqrt(x)=1.788854
  x=    32 y=      181 k=       7 |k|/sqrt(x)=1.237437
  x=    46 y=      312 k=      -8 |k|/sqrt(x)=1.179536
  x=     6 y=       15 k=      -9 |k|/sqrt(x)=3.674235
  x=    40 y=      253 k=      -9 |k|/sqrt(x)=1.423025
  x=    15 y=       58 k=      11 |k|/sqrt(x)=2.840188
  x=    13 y=       47 k=     -12 |k|/sqrt(x)=3.328201
  x=    17 y=       70 k=      13 |k|/sqrt(x)=3.152963
  x=   109 y=     1138 k=     -15 |k|/sqrt(x)=1.436739
  x=     8 y=       23 k=     -17 |k|/sqrt(x)=6.010408

polynomial cube-square defects:
  (x**2 + 1)^3 - (x**3 + 3*x/2)^2 = (3*x**2 + 4)/4
  (x**4 + 2*x)^3 - (x**6 + 3*x**3)^2 = x**3*(3*x**3 + 8)
计算 Padé 误差阶与小差恒等式

对 S(x)=(1-x)^{3/2},程序得到的 P,Q 满足 Q(0)=1 且 Q S-P=15x^{13}/369098752+O(x^{14}),达到 [6/6] Padé 所要求的 13 阶消失。平方等式 P^2-Q^2(1-x)^3 的低阶系数因而大量抵消,形成“立方减平方”型多项式小差。整数搜索中 5234^3-378661^2=-17,归一化量 |k|/√x≈0.234981。

Lecture 9 / 第 9 讲

排序、搜索、模素数表与中途相遇法

把常见的数论枚举从二次比较改写为排序、哈希、表查找和中途相遇。

排序哈希模运算

1. 找出列表中的碰撞

给定 x1,,xNx_1,\ldots,x_N,寻找所有 xi=xjx_i=x_j。逐对比较需要 Θ(N2)\Theta(N^2) 次比较;先排序后扫描需要 O(NlogN)O(N\log N),若有可靠哈希则期望 O(N)O(N)。当对象是大整数、多项式或有限域元素时,比较与哈希本身的成本也必须计算。

算法排序扫描
  1. 保存二元组 (xi,i)(x_i,i)
  2. 按第一坐标排序。
  3. 线性扫描连续的相等块;每个块中的原下标给出全部碰撞。

若只需判断是否存在碰撞,可在发现第一块时停止。

2. 模 pp

在反复计算 f(x)modpf(x)\bmod p 时,可以预计算幂表、逆元表、平方剩余表或多项式值表。例如所有逆元可由递推

inv[i](p//i)inv[pmodi](modp)\operatorname{inv}[i]\equiv-(p\mathbin{//}i)\operatorname{inv}[p\bmod i]\pmod p

在线性时间内求出。表方法用空间换时间,但要避免把 pp 取到无法容纳内存的规模。

定理批量求逆

给定域中非零元素 a1,,aNa_1,\ldots,a_N,只需一次域求逆和 O(N)O(N) 次乘法即可得到全部 ai1a_i^{-1}

证明前缀积与后缀积

先算前缀积 Pi=a1aiP_i=a_1\cdots a_i,求一次 PN1P_N^{-1}。从后向前递推,ai1=Pi1Pi1a_i^{-1}=P_{i-1}P_i^{-1},并令 Pi11=aiPi1P_{i-1}^{-1}=a_iP_i^{-1}

3. 中途相遇

方程 F(u)=G(v)F(u)=G(v)u,vu,v 各有 NN 个候选,直接枚举有 N2N^2 对。分别生成并排序两个值表,再合并扫描,只需 O(NlogN)O(N\log N) 时间和 O(N)O(N) 空间。这在寻找多项式恒等式、短向量、子集和以及模素数初始解时都很常见。

说明外存与流式计算

当表大于内存时,应分块排序并做多路归并;不要依赖解释器对象的巨大额外开销。对于有限域元素,可使用定长二进制编码,并把验证所需的原参数一同存储。

排序搜索为何能把平方复杂度降下来

给定列表 x1,,xNx_1,\ldots,x_N,寻找全部 xi=xjx_i=x_j 的朴素方法要做 (N2N)/2(N^2-N)/2 次比较。先排序再检查相邻相等项,只需 O(NlogN)O(N\log N) 时间。比较模型中这一复杂度最优,因为要区分 N!N! 种可能次序,任何比较决策树至少需要 log2(N!)=Θ(NlogN)\log_2(N!)=\Theta(N\log N) 层。桶排序等线性算法使用了比任意两元素比较更强的模型;“意大利面排序”则是说明模型依赖性的戏谑例子。

代价是空间:通常必须同时存下全部 NN 个值。若 xix_i 可由 ii 即时计算,二重循环几乎不占存储空间,而排序法需要 O(N)O(N) 存储。因此应在时间、内存和外存带宽之间权衡。数据大于内存时,可把数据分块排序,再用多路归并;这是 Unix `sort` 等程序成熟而可靠的原因。

Unix 工具作为数论算法组件

原讲义强调,`sort`、`uniq`、`comm` 能直接完成大量碰撞与集合比较任务;`grep`、`sed` 以及文本编辑器可作前处理、插入字段和后处理。即使最终程序写在 Sage、GP、Magma 或 C 中,先用这些工具验证数据管道往往更快。示例之一是从词表中寻找两个常用英文单词,它们除首字母分别为 C 与 U 外完全相同;这种文字游戏与寻找数论值碰撞在算法结构上没有区别。

中途相遇法

方程 f(x)=g(y)f(x)=g(y)x,yx,y 各有 NN 个候选,逐对比较需 N2N^2。分别列出 (f(x),x)(f(x),x)(g(y),y)(g(y),y),排序后归并,即可在 O(NlogN)O(N\log N) 时间与 O(N)O(N) 空间内找到全部解。这是“中途相遇”范式。它还可用于四变量方程:把 F(a,b)=G(c,d)F(a,b)=G(c,d) 的两边各枚举约 M2M^2 项,比枚举 M4M^4 个四元组显著更快。

哈希表在平均意义下可把查找降到 O(N)O(N),但必须考虑碰撞攻击、元素规范化、哈希计算成本和不可预测的内存局部性。对高精度整数、数域元素或多项式,先取一个或多个机器字模数作为指纹,再对候选做精确比较,通常更高效。

有限域计算表

若大量反复计算模 pp 的逆元、平方、幂或多项式值,可预计算查找表。对 1i<p1\le i<p,逆元有递推

i1pi(pmodi)1(modp),i^{-1}\equiv-\left\lfloor\frac pi\right\rfloor (p\bmod i)^{-1}\pmod p,

因此所有逆元可在线性时间求出。也可建立平方剩余到平方根的表:遍历 x𝐅px\in\mathbf F_p,记录 x2xx^2\mapsto x。这在搜索模 pp 初始解时避免重复运行通用平方根算法。

给定非零 a1,,aNa_1,\ldots,a_N,批量求逆只需一次真正的域求逆。先算前缀积 Pi=a1aiP_i=a_1\cdots a_i,求 PN1P_N^{-1},再从后向前得到每个 ai1a_i^{-1}。在椭圆曲线点运算、Jacobian 矩阵归一化及大规模射影坐标转仿射坐标中,这个技巧非常重要。

排序键与规范形式

同一个数学对象可能有多个表示。排序前应先规范化:有理数约成互素且分母为正;有限域元素取固定代表;多项式去掉可逆标量并固定首项;置换三元组取规范标签;数域元素统一到固定幂基。否则表示不同会使真正相等的对象无法碰撞。反过来,过早只保留短哈希而丢弃原参数,会使碰撞后无法重建解,因此每条记录至少要保存足够的回溯信息。

补充:比较排序的下界

任何只通过“xi<xjx_i<x_j 吗?”提问的确定性排序算法都对应一棵二叉决策树。每个叶子代表一种输入次序,至少有 N!N! 个叶子,故树高至少

log2N!=Nlog2N(log2e)N+O(logN).\lceil\log_2N!\rceil =N\log_2N-(\log_2e)N+O(\log N).

归并排序达到最坏 O(NlogN)O(N\log N);快速排序平均 O(NlogN)O(N\log N) 但最坏 O(N2)O(N^2);堆排序最坏 O(NlogN)O(N\log N) 且原地,但缓存局部性较差。数论数据常记录很大,实际瓶颈可能是内存带宽而非比较次数。

外排序与压缩记录

NN 个记录超出内存,把每块读入、排序、写出,再对有序块作 kk 路归并。记录应采用定长或前缀压缩格式;键与回溯参数分开存储。若只需碰撞,可在归并过程中立即输出相等键,无需写出完整全局排序结果。

哈希与生日悖论

若使用 bb 位哈希,约 2b/22^{b/2} 个随机对象就有显著概率发生假碰撞。对数论认证不能把哈希相等当作数学相等;应把哈希用作过滤器,再比较完整对象。若数据量接近 2642^{64} 的平方根,单个 64 位哈希远远不够,可使用两个独立模数或 128/256 位摘要。

中途相遇的时间—空间折中

子集和的经典中途相遇把 nn 个数分成两半,枚举各 2n/22^{n/2} 个子集和,时间和空间约 2n/22^{n/2}。若内存不足,可用 Schroeppel–Shamir 技巧把空间降到约 2n/42^{n/4} 而保持相似时间。Belyi 系数搜索中也可把参数分组,分别计算部分系数贡献,再匹配总和。

批量模运算与 Montgomery 技巧

大量固定模数乘法时,Montgomery 表示避免每次做昂贵除法;Barrett reduction 也可预计算倒数近似。若在多个小素数上重复同一多项式计算,可用 remainder tree 一次性求模,随后 product tree 和 CRT tree 重构。这些“批处理”思想与排序表同样重要。

可重复的搜索日志

大规模搜索应记录参数范围、规范化规则、哈希函数、模数、排序键、软件版本和完整验证脚本。若搜索无结果,应给出覆盖范围与排除逻辑,而不是只保留最终空文件。算法性数学中的负结果只有在搜索空间被精确定义并可复查时才有意义。

进一步:排序、哈希与 meet-in-the-middle

当方程可写成 A(u)=B(v)A(u)=B(v)A(u)+B(v)=C(w)A(u)+B(v)=C(w) 时,把各侧值列表化并排序可把平方级枚举降为近线性对数复杂度。两个有序列表寻找相等值可用双指针 O(M+N)O(M+N);若要找最接近值,亦可维护相邻差。

哈希表给出期望 O(1)O(1) 查找,但内存开销和最坏情况较差;排序具有可重复顺序、易于外存和范围查询。大规模整数列表常采用 radix sort 或按高位分桶。若值超过机器字长,比较成本本身依赖位数。

三变量问题可用 meet-in-the-middle:枚举 A(u)+B(v)A(u)+B(v) 的一半组合与 C(w)C(w) 匹配。时间从朴素 O(N3)O(N^3) 降至 O(N2logN)O(N^2\log N),但内存达 O(N2)O(N^2)。分块、外部排序、Bloom filter 或模哈希可在时间和内存间折中。

对近碰撞而非精确碰撞,可按值排序后扫描窗口;若允许误差依赖变量,应存储区间并做 sweep-line。只按浮点近似排序可能把极接近的大整数错序,最好使用精确整数主键,或用高位近似分桶后精确比较。

并行化时,最容易按哈希桶或高位区间分割,确保每个潜在匹配落在同一任务;边界窗口需重叠。结果还应去除由变量置换、符号和单位产生的对称重复,并保留规范代表。

练习与解答排序搜索

练习 1。两个各含 NN 个元素的有序列表如何在线性时间找交集?

解。维护两个指针;较小值一侧前移,相等时输出并按重复策略前移。每个指针最多移动 NN 次。

练习 2。若要枚举所有 a+b=c+da+b=c+d,meet-in-the-middle 的基本结构是什么?

解。分别生成所有 a+ba+bc+dc+d,排序或哈希相等值;每个值桶做Cartesian积输出解,并按对称性去重。

练习 3。为何模哈希不能单独证明整数相等?

解。同余碰撞可能来自相差模数倍。模哈希只用于筛选,候选必须回到完整整数精确比较;多个模数也只有在乘积超过差值界时才能认证。

深入补充:四表中途相遇、模指纹与外存复杂度

标准中途相遇把

ai+bj=ck+da_i+b_j=c_k+d_\ell

改写成两个二元和表,时间和内存都约为 N2N^2。当 N2N^2 条记录装不进内存时,Schroeppel–Shamir 型堆枚举可以把内存降到线性,而保持近二次时间。

算法 有序生成全部二元和

先将 ai,bja_i,b_j 排序。对每个 ii,序列

ai+b1ai+b2ai+bNa_i+b_1\le a_i+b_2\le\cdots\le a_i+b_N

已经有序。把每行首项放入最小堆;每弹出 (i,j)(i,j),就插入 (i,j+1)(i,j+1)。堆大小始终为 NN,可按全局递增次序流式产生 N2N^2 个和。对 ck+dc_k+d_\ell 用最大堆逆序产生,双指针比较两条流即可找相等值。

堆操作引入 O(logN)O(\log N) 因子,内存却从 O(N2)O(N^2) 降为 O(N)O(N)。若值域允许桶排序或 radix heap,可进一步压低对数因子。这个技巧尤其适合四变量 Diophantine 搜索,因为无需把任一完整二元表写入磁盘。

模素数过滤可以在昂贵的大整数计算前排除绝大多数候选。选互素模数 p1,,psp_1, \ldots,p_s,先比较

ai+bjck+d(modpu).a_i+b_j\equiv c_k+d_\ell\pmod{p_ u}.

若差值在每个模数下近似均匀,经过总模量 M=puM=\prod p_ u 后存活比例约为 1/M1/M。模数应避开表达式的结构性因子;例如所有值都为偶数时用模 22 没有筛选力。

认证原则 指纹碰撞只用于候选生成

哈希值或模指纹相同不能证明原整数相等。对每个存活候选必须重新计算规范化的精确值,并验证原方程。若最终目标是多项式或代数数相等,还需在其精确系数域中比较,而不能只追加更多随机模数。

多模数仍可给出确定性等式证书:若已知整数差值 DD 满足 |D|<B|D|<B,并证明 D0(modM)D\equiv0\pmod MM>2BM>2B,则必有 D=0D=0。因此关键是高度界;没有界时,多模数一致只能作为概率证据。

外排序时,真正成本是 I/O 而非比较次数。设内存一次容纳 MM 条记录,先将每块排序写成 run,再做多路归并;读写量约为数据总量乘以归并层数。记录应只保存必要字段:排序键、恢复索引和短校验和;大对象可按索引回原始数组重算。固定字节宽度记录比文本行显著减少解析与磁盘带宽。

算法 可复现的大规模碰撞搜索

固定输入枚举次序、模数、哈希种子和规范化规则;每个分块保存范围与校验和;归并时稳定排序,使相同键按原索引排序;输出候选后单独运行精确验证器。搜索程序与验证程序分离,可让验证器保持短小,并允许在不同机器上重放证书。

生日悖论给出碰撞预期:若哈希空间大小为 HH,随机放入 MM 个值,碰撞数期望约为 M(M1)/(2H)M(M-1)/(2H)。因此 64 位指纹对十亿级记录已不再“几乎不碰撞”;可使用两个独立 64 位指纹降低误报,但最终精确比较仍不可省略。对攻击性输入则应选抗碰撞哈希或完全避免把哈希唯一性当作正确性前提。

补充计算:四表中途相遇、模指纹与外存归并证书

定理 中途相遇的时间—空间界

设需寻找 \(F(a,b)+G(c,d)=T\),四个变量各有 n 个候选。分别建立 \(n^2\) 个左表值 F(a,b) 与右表补值 T-G(c,d),排序后线性归并,则确定性时间为 \(O(n^2 log n)\),空间为 \(O(n^2)\)。若记录先取 k 个两两互素模数的指纹,再对指纹相等者做整数精确比较,则算法无假阳性;指纹只影响候选数量,不影响正确性。

证明 由排序归并与最终精确比较给出完备性

任一真解对应一个左表记录 \(L=F(a,b)\) 和一个右表记录 \(R=T-G(c,d)\),且 \(L=R\),所以它们在全序排序后的相等值区间中必被归并扫描遇到,算法完备。反之,输出前检查原整数 \(L=R\),故模碰撞不能产生假解。

生成两表各需 \(Θ(n^2)\) 次函数计算。比较排序需 \(O(n^2 log(n^2))=O(n^2 log n)\),双指针归并在线性记录数内完成。外存版本把每个内存块独立排序,再以 k 路堆归并;I/O 复杂度为外排序标准界,且每个块的校验和、总行数与首尾键可组成可重复证书。

Python 模指纹归并、精确复核与临时文件外排序
from dataclasses import dataclass
from hashlib import blake2b
from itertools import combinations
from math import ceil
import heapq
import tempfile
import os

@dataclass(order=True, frozen=True)
class Record:
    key: tuple[int, ...]
    value: int
    i: int
    j: int

def fingerprint(value: int, moduli: tuple[int, ...]) -> tuple[int, ...]:
    return tuple(value % p for p in moduli)

def pair_table(values: list[int], moduli: tuple[int, ...]) -> list[Record]:
    records = []
    for i in range(len(values)):
        for j in range(i, len(values)):
            s = values[i] + values[j]
            records.append(Record(fingerprint(s, moduli), s, i, j))
    records.sort()
    return records

def merge_join(target: int,
               left_values: list[int],
               right_values: list[int],
               moduli=(1009, 1013, 1019)):
    left = pair_table(left_values, moduli)
    # Store target - pair sums under the same fingerprint convention.
    right = []
    for i in range(len(right_values)):
        for j in range(i, len(right_values)):
            complement = target - right_values[i] - right_values[j]
            right.append(Record(
                fingerprint(complement, moduli),
                complement, i, j
            ))
    right.sort()

    i = j = 0
    matches = []
    false_fingerprints = 0
    while i < len(left) and j < len(right):
        if left[i].key < right[j].key:
            i += 1
        elif left[i].key > right[j].key:
            j += 1
        else:
            ii = i
            jj = j
            while ii < len(left) and left[ii].key == left[i].key:
                ii += 1
            while jj < len(right) and right[jj].key == right[j].key:
                jj += 1
            for a in left[i:ii]:
                for b in right[j:jj]:
                    if a.value == b.value:
                        matches.append((a.i,a.j,b.i,b.j,a.value))
                    else:
                        false_fingerprints += 1
            i, j = ii, jj
    return matches, false_fingerprints, len(left), len(right)

def chunked_external_sort(records, chunk_size=500):
    """
    Deterministic external merge sort.
    Temporary files store tab-separated integers and are deleted on exit.
    """
    paths = []
    try:
        for start in range(0, len(records), chunk_size):
            chunk = sorted(records[start:start+chunk_size])
            fd, path = tempfile.mkstemp(prefix="mitm-", suffix=".txt")
            os.close(fd)
            with open(path, "w", encoding="ascii") as f:
                for r in chunk:
                    fields = (*r.key, r.value, r.i, r.j)
                    f.write("\t".join(map(str, fields))+"\n")
            paths.append(path)

        def stream(path):
            with open(path, encoding="ascii") as f:
                for line in f:
                    z = tuple(map(int,line.split()))
                    yield Record(tuple(z[:-3]),z[-3],z[-2],z[-1])

        return list(heapq.merge(*(stream(p) for p in paths)))
    finally:
        for path in paths:
            if os.path.exists(path):
                os.remove(path)

def checksum(records) -> str:
    h = blake2b(digest_size=16)
    for r in records:
        h.update(repr(r).encode("ascii"))
    return h.hexdigest()

# Search a^4+b^4+c^4+d^4 = T with two independent lists.
A = list(range(1,61))
B = list(range(1,61))
left_values = [a**4 for a in A]
right_values = [b**4 for b in B]
target = 30**4 + 40**4 + 50**4 + 60**4

matches, false_hits, nl, nr = merge_join(
    target, left_values, right_values,
    moduli=(1009,1013,1019)
)
print(f"pair rows: left={nl}, right={nr}")
print(f"fingerprint false hits after exact comparison: {false_hits}")
print(f"exact four-term matches: {len(matches)}")
for m in matches[:20]:
    i,j,k,l,s = m
    a,b,c,d = A[i],A[j],B[k],B[l]
    print(f"  {a}^4+{b}^4+{c}^4+{d}^4={target}; left pair={s}")

records = pair_table([n**3 for n in range(1,81)], (65521,65519))
sorted_external = chunked_external_sort(records, chunk_size=700)
print("\nexternal-sort audit:")
print("  rows =",len(records))
print("  already sorted equality =",records==sorted_external)
print("  checksum =",checksum(sorted_external))
print("  first =",sorted_external[0])
print("  last  =",sorted_external[-1])

print("\ntime-space table for a four-list search:")
for n in [10**2,10**3,10**4,10**5]:
    pairs=n*n
    bytes_per_record=40
    gib=pairs*bytes_per_record/2**30
    print(f"  n={n:7d}: pairs={pairs:14d}, storage≈{gib:12.3f} GiB")
运行结果 四次幂四表匹配及外排序校验
pair rows: left=1830, right=1830
fingerprint false hits after exact comparison: 0
exact four-term matches: 6
  30^4+50^4+40^4+60^4=22580000; left pair=7060000
  30^4+60^4+40^4+50^4=22580000; left pair=13770000
  40^4+50^4+30^4+60^4=22580000; left pair=8810000
  40^4+60^4+30^4+50^4=22580000; left pair=15520000
  50^4+60^4+30^4+40^4=22580000; left pair=19210000
  30^4+40^4+50^4+60^4=22580000; left pair=3370000

external-sort audit:
  rows = 3240
  already sorted equality = True
  checksum = 6d61e0b96f1190f874e8456c907f7569
  first = Record(key=(2, 2), value=2, i=0, j=0)
  last  = Record(key=(65520, 15), value=524167, i=22, j=79)

time-space table for a four-list search:
  n=    100: pairs=         10000, storage≈       0.000 GiB
  n=   1000: pairs=       1000000, storage≈       0.037 GiB
  n=  10000: pairs=     100000000, storage≈       3.725 GiB
  n= 100000: pairs=   10000000000, storage≈     372.529 GiB
计算 记录规模

若每条记录占 40 字节,n=10^5 时单侧 n^2 条记录约占 372.529 GiB;n=10^6 时约占 36.38 TiB。把三模指纹压缩为 64 或 96 位只能降低记录常数,不能改变 Θ(n^2) 空间阶。采用分块、磁盘归并或时间—空间折中时,最终整数比较仍须保留。

Lecture 10 / 第 10 讲

多元 pp-进Newton 法与Hensel 提升

从模素数初始解出发,利用 Jacobian 可逆性把精度逐次加倍。

p进数Newton 法Hensel 提升

1. 一元 Hensel 引理

定理简单根提升

f(a)0(modp)f(a)\equiv0\pmod pf(a)0(modp)f'(a)\not\equiv0\pmod p。则存在唯一 α𝐙p\alpha\in\mathbf Z_p 满足 f(α)=0f(\alpha)=0αa(modp)\alpha\equiv a\pmod p

Newton 迭代为

ak+1=akf(ak)f(ak).a_{k+1}=a_k-\frac{f(a_k)}{f'(a_k)}.

pp-进度量中,只要初值满足简单根条件,误差估值通常翻倍:若 f(ak)0(modpm)f(a_k)\equiv0\pmod{p^m},下一步可达到模 p2mp^{2m}

2. 多元版本

F=(F1,,Fn):𝐙pn𝐙pnF=(F_1,\ldots,F_n):\mathbf Z_p^n\to\mathbf Z_p^n,Jacobian 矩阵记为 JF(x)J_F(x)。若

F(a)0(modp),detJF(a)0(modp),F(a)\equiv0\pmod p,\qquad \det J_F(a)\not\equiv0\pmod p,

则存在唯一的 pp-进解 αa(modp)\alpha\equiv a\pmod p,迭代

xk+1=xkJF(xk)1F(xk)x_{k+1}=x_k-J_F(x_k)^{-1}F(x_k)

局部二次收敛。

证明线性化与误差平方

x=α+ex=\alpha+e。Taylor 展开给出 F(x)=JF(α)e+O(e2)F(x)=J_F(\alpha)e+O(e^2)。Newton 修正消去线性项,剩余误差为 O(e2)O(e^2)。Jacobian 行列式为 pp-进单位保证线性方程可唯一求解。

3. 方程数与规范自由度

Belyi 或 P3Q2P^3-Q^2 系统常带有 xax+bx\mapsto ax+b、整体缩放、根置换等对称。若不先固定规范,Jacobian 必有核,简单根提升条件失败。常见规范包括令次高项为零、固定两个分支点原像为 0,10,1、令一个首项系数为 1。

算法实际工作流
  1. 选一个避开判别式、分母和群阶的好素数 pp
  2. 𝐅p\mathbf F_p 中枚举或消元求初始解。
  3. 检查 Jacobian 满秩;不满秩时换素数或重新规范化。
  4. 提升到足以恢复有理数或代数数的精度。
  5. 用精确代入验证。
说明不要显式求矩阵逆

实现时每一步解线性方程 Jδ=FJ\delta=-F,不要先形成 J1J^{-1}。可以复用 LU 分解或用模 pmp^m 的线性求解器;系数增长时采用分段精度。

次数 11 示例如何导向多元 pp-进 Newton 法

次数 11 的 Belyi 多项式在消元后会出现次数 10、系数巨大的方程。直接在特征零中求解并在复杂数域中操作,往往比“先模一个好素数求解,再 pp-进提升,最后恢复代数数”困难得多。多元 Newton 法正是连接有限域解与特征零精确解的核心。

一元 Hensel 提升的精确形式

f(a)0(modpm)f(a)\equiv0\pmod{p^m}f(a)f'(a)pp-进单位,令

a=af(a)f(a)1(modp2m).a'=a-f(a)f'(a)^{-1}\pmod{p^{2m}}.

Taylor 展开

f(a+δ)=f(a)+f(a)δ+δ2hf(a+\delta)=f(a)+f'(a)\delta+\delta^2h

说明线性项被消掉,而 δ\delta 已被 pmp^m 整除,所以误差提升到模 p2mp^{2m}。从模 pp 开始,精度可按 1,2,4,8,1,2,4,8,\ldots 指数增长。唯一性来自导数为单位:同一模 pp 剩余类中不能有两个不同的根。

多元 Newton 迭代

F=(F1,,Fn)F=(F_1,\ldots,F_n)nn 个变量的多项式系统,J(x)J(x) 为 Jacobian。若

F(a)0(modp),detJ(a)0(modp),F(a)\equiv0\pmod p,\qquad \det J(a)\not\equiv0\pmod p,

则存在唯一 pp-进解 αa(modp)\alpha\equiv a\pmod p。在精度 pmp^m 下解线性方程

J(a)δF(a)(modp2m),anew=a+δ.J(a)\delta\equiv-F(a)\pmod{p^{2m}}, \qquad a_{\mathrm{new}}=a+\delta.

不应显式形成 J1J^{-1},而应做 LU 分解或模素数Gaussian 消元。若 Jacobian 变化较慢,可以利用 Newton–Schulz 方式同步提升逆矩阵精度;对稀疏系统则应保留稀疏结构。

权、缩放与 Jacobian 奇异

Belyi 方程常带仿射变换和整体缩放。次数 11 示例中,参数具有权

wt(a,b,c,d)=(2,3,1,2).\operatorname{wt}(a,b,c,d)=(2,3,1,2).

若不固定一个非零参数或选取权零比值,解不是孤立点而是一条缩放轨道,Jacobian 必有一维核。应先选仿射图,例如令 a=1a=1c=1c=1,或者额外加入规范方程。选图时要避免丢掉相应坐标为零的解,必要时在多个图中分别计算。

好素数的选择

素数 pp 不应整除分母、方程系统的判别式、相关群阶或规范化参数。坏素数可能使不同特征零解在模 pp 下合并、Jacobian 降秩、分歧型发生野分歧,或者使多项式次数下降。实务上可尝试若干中等大小素数,统计模 pp 解数和 Jacobian 秩;稳定的模式通常反映特征零几何。

pp 初始解的获得

低维系统可直接枚举并利用表查找;两变量系统可取结式后分解;更大系统可用 Gröbner 基、三角分解或 homotopy 的有限域版本。得到模 pp 解后必须检查所有原方程,而不能只检查消元后方程,因为结式和清分母会引入伪解。

代数数系数的 pp-进恢复

若解定义在次数 d>1d>1 的数域中,模 pp 后可能落在 𝐅pf\mathbf F_{p^f}。可在不可约多项式定义的扩域中做 Newton 提升,或者选择完全分裂素数,使各共轭分别落在 𝐅p\mathbf F_p。提升到高精度后,用 LLL 恢复最小多项式及系数间关系。对于已知数域 K=𝐐(θ)K=\mathbf Q(\theta),则把每个系数写成 1,θ,,θd11,\theta,\ldots,\theta^{d-1} 的有理线性组合并作同时有理重构。

退化根与广义 Hensel 方法

detJ(a)0(modp)\det J(a)\equiv0\pmod p,并不一定没有提升;可能只是选到了坏素数、坐标规范不当,或解位于正维分量上。可尝试换素数、增加切片、使用 deflation 增加导数方程,或采用较一般的 Hensel 条件,例如比较 vp(F(a))v_p(F(a))2vp(detJ(a))2v_p(\det J(a))。但简单根情形最稳定,也最适合大规模自动计算。

最终证明步骤

pp-进高精度近似本身不是证明。恢复候选精确系数后,应:

  1. 在确切数域中代回全部系数方程;
  2. 验证 PPP1P-1 的因子重数;
  3. 计算导数并确认没有额外临界值;
  4. 核对置换循环型与源曲线亏格;
  5. 若声称特定单值群,使用模素数分解型、判别式或明确置换生成元证明。

补充:多元 Hensel 引理的定量版本

F:𝐙pn𝐙pnF:\mathbf Z_p^n\to\mathbf Z_p^n,记 J=JF(a)J=J_F(a)。一种常用充分条件是

vp(F(a))>2vp(detJ).v_p(F(a))>2v_p(\det J).

这里 vp(F(a))v_p(F(a)) 取各坐标最小赋值。即使 detJ\det J 不是单位,只要残差足够小,仍存在唯一邻近根,并可 Newton 收敛。这对不可避免含少量 pp 因子的系统有用。

精度管理

若当前解精确到 pmp^m,直接以模 p2mp^{2m} 计算 FF 和 Jacobian 即可倍增精度。多项式求值应使用 Horner 法并在每一步约模。若系数是 pp-进扩域元素,则用固定的无分歧或分歧整数基;必须追踪统一化元与精度损失,不能把所有扩域都当作 𝐙p[θ]\mathbf Z_p[\theta] 的自由单位基。

Jacobian 的自动微分

符号求导后表达式可能巨大。前向自动微分可在一次多项式求值的常数倍成本内同时得到值与导数;稀疏系统可用图着色压缩 Jacobian 列。高阶 deflation 需要 Hessian 或方向导数时,双数或 truncated power series 方法更可靠。

奇异解的 deflation

若孤立根的 Jacobian 秩不足,可加入新变量 λ\lambda 与方程

JF(x)λ=0,L(λ)=1J_F(x)\lambda=0,\qquad L(\lambda)=1

并选取适当导数方程,降低根的重数。反复 deflation 后常得到简单根系统,再作 Hensel 提升。需要证明新系统与原根局部等价,并排除由归一化 L(λ)=1L(\lambda)=1 引入的分支遗漏。

同伦与 pp-进提升的组合

可先在一个容易的参数值求全部解,再沿参数同伦到目标,得到复近似;然后选一个数域好素数,把识别出的近似解约化并做 pp-进认证。反过来,也可在多个素数上求解并通过 CRT 恢复有理系数,无需单个很高的 pp-进精度。多模方法特别适合系数实际为整数或小分母有理数的情形。

Smale α\alpha-理论与 pp-进唯一性

复 Newton 法的近似根可用 α\alpha-理论证明收敛到唯一精确根;pp-进简单根条件则天然给出一个剩余球中的唯一性。两种认证结合可建立不同嵌入下的根对应,帮助恢复完整 Galois 轨道。

从局部解恢复全局数域

在多个分裂型不同的素数上恢复同一候选最小多项式,并检查其模 pp 因式分解与局部解一致。计算多项式判别式与 ramification,比较原几何问题的坏素数集合。若候选数域有非平凡自同构,还应确认各系数在同一嵌入下配对,而不是把不同共轭随意混合。

进一步:Newton–Hensel 的认证与奇异情形

一元 Newton 迭代 xn+1=xnf(xn)/f(xn)x_{n+1}=x_n-f(x_n)/f'(x_n) 在简单根附近二次收敛。pp-进情形若 f(x0)0(modp)f(x_0)\equiv0\pmod pf(x0)0(modp)f'(x_0)\not\equiv0\pmod p,则存在唯一 pp-进根提升;每步可使正确位数加倍。多变量版本要求 Jacobian 行列式模 pp 非零。

为避免每步完全求逆,可迭代逆 Jacobian:若 AJ1A\approx J^{-1},更新 AA(2IJA)A\leftarrow A(2I-JA),这是矩阵 Newton 迭代。结合幂级数截断可得到准线性 Hensel 提升。稀疏系统应利用结构解线性方程而非形成稠密逆矩阵。

Jacobian 奇异时,解可能是重根、多个分支交点或正维分量。简单 Hensel 唯一性失效。可使用 deflation 添加导数方程降低重数,或先做局部维数与切空间计算。模 pp 奇异也可能只是坏素数;换一个良素数常恢复非奇异。

从模 pkp^k 解恢复有理数时,若分子分母有界,可用有理重构:从同余 a/br(modM)a/b\equiv r\pmod M 中通过扩展 Euclidean 算法寻找 |a|,|b|<M/2|a|,|b|<\sqrt{M/2}。模量必须大于高度界的平方量级,且 bbMM 互素。

代数数解可先在有限域选不可约因子,进入非分歧扩张的 Witt/未分歧 pp-进域提升,再用 LLL 识别最小多项式。不同有限域根对应不同素理想嵌入;恢复多个系数时必须保持同一嵌入一致。

最终认证可完全精确:把重构系数代回原方程;检查 Jacobian 非零;用 Bézout 数、Gröbner 基或形状引理确认解数;必要时证明目标解所在零维分量无其他点。这样 Hensel 只是高效求解工具,而非结论依据。

练习与解答Hensel 提升

练习 1。x220(mod7)x^2-2\equiv0\pmod7 并提升到模 4949

解。模 7 根为 3、4。取 3,写 x=3+7tx=3+7t,除以 7 后得 (92)/7+6t1t0(mod7)(9-2)/7+6t\equiv1-t\equiv0\pmod7,故 t=1t=1,根为 10;另一根为 39。

练习 2。f(x0)0(modp)f'(x_0)\equiv0\pmod p,为何不能直接除?

解。导数不可逆,线性校正方程可能无解或有多个解;需检查更高阶、分裂成多根或换良素数。

练习 3。多变量中 Jacobian 可逆保证什么?

解。保证每一级线性校正唯一,从而存在唯一与初始模 pp 解相容的 pp-进提升。

深入补充:定量多元 Hensel 判据与奇异纤维的提升树

F=(F1,,Fn)𝐙p[x1,,xn]nF=(F_1,\ldots,F_n)\in\mathbf Z_p[x_1,\ldots,x_n]^nJ(a)J(a) 为 Jacobian 矩阵。简单根情形中,detJ(a)\det J(a) 为单位;实际计算常遇到行列式含少量 pp 因子的近奇异起点,需要使用带赋值的定量判据。

定理 定量 Newton–Hensel 判据

h=vp(detJ(a)),s=minivp(Fi(a)).h=v_p(\det J(a)),\qquad s=\min_i v_p(F_i(a)).

s>2hs>2h,则存在唯一根 α\alpha 落在相应的 Hensel 球中,并且 Newton 迭代

ak+1=akJ(ak)1F(ak)a_{k+1}=a_k-J(a_k)^{-1}F(a_k)

𝐐pn\mathbf Q_p^n 中收敛到 α\alpha。每一步正确位数近似翻倍;线性系统只需解到当前目标精度,无须显式形成 J1J^{-1}

证明使用伴随矩阵把分母控制在 php^h,并由 Taylor 展开

F(a+u)=F(a)+J(a)u+O(up2)F(a+u)=F(a)+J(a)u+O(\|u\|_p^2)

得到误差平方。条件 s>2hs>2h 正好保证二次项比线性修正更高阶。实现时应追踪每个坐标的赋值,而非只用统一绝对精度;稀疏 Jacobian 可用 pp-进 LU 分解并在后续迭代复用主元结构。

算法 精度倍增的线性求解

已知 F(a)0(modpN)F(a)\equiv0\pmod{p^N},目标提升到 p2Np^{2N}。计算 J(a)J(a)pNp^N,解

J(a)δF(a)/pN(modpN),J(a)\,\delta\equiv-F(a)/p^N\pmod{p^N},

再令 aa+pNδa\leftarrow a+p^N\delta。用 Taylor 展开可验证新误差模 p2Np^{2N} 为零。矩阵分解和多项式求值都只做到所需精度,可避免从一开始在数千位精度上运算。

奇异模 pp 解不会自动唯一提升。若 F(a)0(modpk)F(a)\equiv0\pmod{p^k},写候选提升为 a+pkua+p^ku,则下一层条件是

J(a)uF(a)/pk(modp).J(a)u\equiv-F(a)/p^k\pmod p.

若右边不在 J(a)J(a) 的像中,该分支立即死亡;若可解,解空间维数为 nrankJ(a)n-\operatorname{rank}J(a),会产生 pnrp^{n-r} 个下一层候选。继续提升得到一棵有限或无限分支树,其结构反映特殊纤维的切空间与高阶阻碍。

推论 正维分量与孤立重根的区分

Jacobian 降秩只说明一阶切空间增大,不能单独断定存在正维解族。若某个切向量在二阶或更高阶方程中受阻,解仍可为孤立重根;只有能递归解出形式幂级数参数,才得到真实的正维分支。

计算上可用 deflation 区分两者:把核向量、乘子或选定的 Jacobian 子式加入扩展系统,使孤立重根在更高维系统中变成简单根。随后应用普通 Hensel 提升,并把扩展变量消去。另一种办法是先求局部代数的标准基,计算其长度;长度有限说明孤立,长度大于一记录重数,长度无限才表明正维。

最终恢复代数数时,应保存提升素数、起始剩余类、每步精度和 Jacobian 赋值。这样候选数域元素不仅有高精度近似,还有一个唯一 Hensel 球作为局部证书;精确代入后,局部唯一性可用于证明没有选错同一数域中的其他共轭根。

进一步计算专题:多项式因子 Hensel 提升与 Newton 多边形

Hensel 提升不仅提升根,也能整体提升因式分解。设 f𝐙p[x]f\in\mathbf Z_p[x],模 pp

fg0h0(modp),gcd(g0,h0)=1.f\equiv g_0h_0\pmod p, \qquad\gcd(g_0,h_0)=1.

互素性给 Bézout 系数 u0,v0u_0,v_0 满足

u0g0+v0h01(modp).u_0g_0+v_0h_0\equiv1\pmod p.
定理 二因子 Hensel 提升

存在唯一首项归一化因子 g,h𝐙p[x]g,h\in\mathbf Z_p[x],满足

f=gh,gg0(modp),hh0(modp).f=gh, \qquad g\equiv g_0\pmod p, \qquad h\equiv h_0\pmod p.

若已知 fgh0(modpN)f-gh\equiv0\pmod{p^N},可在一次线性修正后提升到模 p2Np^{2N}

写误差

e=(fgh)/pN.e=(f-gh)/p^N.

寻找次数受限的 Δg,Δh\Delta g, \Delta h 使

gΔh+hΔge(modpN).g\Delta h+h\Delta g\equiv e\pmod{p^N}.

利用 Bézout 逆元可先取

Δhue(modg),Δg=(egΔh)/h,\Delta h\equiv ue\pmod g, \qquad\Delta g=(e-g\Delta h)/h,

再按次数正规化。令

g+=g+pNΔg,h+=h+pNΔh,g_+=g+p^N\Delta g, \qquad h_+=h+p^N\Delta h,

二次项含 p2Np^{2N},故 fg+h+0(modp2N)f-g_+h_+\equiv0\pmod{p^{2N}}

算法 多因子乘积树提升

若模 pp 分解为多个两两互素因子,不逐个线性串联,而把因子组成平衡乘积树;每个内部节点提升两个子乘积,并同步更新 Bézout 逆元。树高为 O(logr)O(\log r),适合快速多项式乘法和并行计算。最终再把各叶因子首项、内容与排列规范化。

因子提升与根提升的关系可由有限 étale 代数解释。模 pp 的互素分解对应

𝐅p[x]/(f)𝐅p[x]/(g0)×𝐅p[x]/(h0),\mathbf F_p[x]/(f) \cong \mathbf F_p[x]/(g_0) \times \mathbf F_p[x]/(h_0),

两个幂等元可唯一提升到 𝐙p\mathbf Z_p,从而提升整个直积分解。若模 pp 因子不互素,代数不再 étale,唯一性消失,必须分析 Newton 多边形或改选素数。

f(x)=i=0naixi𝐐p[x],f(x)=\sum_{i=0}^n a_ix^i\in\mathbf Q_p[x],

Newton 多边形是点 (i,vp(ai))(i,v_p(a_i)) 的下凸包。每条斜率为 λ-\lambda、水平长度为 mm 的边预示有 mm 个根的赋值为 λ\lambda,按代数闭包中重数计。

计算 从多边形读取根赋值

f(x)=x3+px+p3,f(x)=x^3+p x+p^3,

点为 (0,3),(1,1),(3,0)(0,3),(1,1),(3,0)。下凸包有从 (0,3)(0,3)(1,1)(1,1) 的斜率 2-2,以及从 (1,1)(1,1)(3,0)(3,0) 的斜率 1/2-1/2。因此一个根赋值为 22,另外两个根赋值为 1/21/2。后者通常位于二次分歧扩张中,不会在 𝐐p\mathbf Q_p 内出现。

Newton 多边形先分离不同赋值的根簇,再对每条边构造残余多项式;残余多项式平方自由时,相应因子可用 Hensel 唯一提升。这个流程比直接在模 pp 上看 ff 的普通因式分解更精细,因为若所有系数都含 pp,简单约化可能丢失全部次数信息。

在多元系统中,可先对某个消元多项式做 Newton 多边形分簇,得到候选坐标赋值,再回代其余方程。不同斜率对应不同 pp-进分支,可显著减少盲目枚举初始剩余类。最终仍应在原多元方程上做 Jacobian 或局部代数认证,不能只凭消元因子的提升认定完整解。

补充计算:精度倍增的多元 Hensel 迭代与 Jacobian 证书

定理 正则多元 Hensel 引理的倍精度形式

设 \(F=(F_1,…,F_n)∈Z_p[x_1,…,x_n]^n\),\(a∈Z_p^n\),并设 \(J=DF(a)\)。若 \(v_p(F(a))≥m\) 且 det J 为 p-adic 单位,则存在唯一 \(b≡a (mod p^m)\) 使 \(F(b)=0\);令 δJ(a)1F(a)(modp2m),a=a+δ, \delta\equiv-J(a)^{-1}F(a)\pmod {p^{2m}},\qquad a'=a+\delta, 则 \(F(a')≡0 (mod p^{2m})\)。

证明 Taylor 展开与可逆 Jacobian 的收缩估计

多项式 Taylor 展开给出 \(F(a+δ)=F(a)+J(a)δ+Q(δ)\),其中 Q 的每项至少二次。取 \(δ≡-J(a)^{-1}F(a) (mod p^{2m})\),前两项模 \(p^{2m}\) 抵消;又 \(δ∈p^mZ_p^n\),故 \(Q(δ)∈p^{2m}Z_p^n\),因此精度从 m 倍增到 2m。

若 b、c 均为根且 \(b≡c (mod p^m)\),则 \(0=F(b)-F(c)=J(c)(b-c)+O((b-c)^2)\)。左乘 \(J(c)^{-1}\),若 \(v_p(b-c)≥m≥1\),则二次项估值严格更高,迫使 b-c 的估值无限增大,所以 \(b=c\)。Jacobian 行列式为单位也保证逆矩阵在每个模 \(p^k\) 环中唯一存在。

Python 二元系统的模解筛选、倍精度提升与逆矩阵核验
from dataclasses import dataclass
from math import prod

def egcd(a,b):
    if b==0:
        return (abs(a),1 if a>=0 else -1,0)
    g,x1,y1=egcd(b,a%b)
    return g,y1,x1-(a//b)*y1

def invmod(a,m):
    g,x,_=egcd(a,m)
    if g!=1:
        raise ZeroDivisionError(f"{a} not invertible modulo {m}")
    return x%m

def mat2_inv_mod(A,m):
    (a,b),(c,d)=A
    det=(a*d-b*c)%m
    idet=invmod(det,m)
    return (
        (( d*idet)%m, (-b*idet)%m),
        ((-c*idet)%m, ( a*idet)%m),
    )

def mat_vec(A,v,m):
    return tuple(sum(A[i][j]*v[j] for j in range(len(v)))%m
                 for i in range(len(A)))

def center(a,m):
    a%=m
    return a-m if a>m//2 else a

@dataclass
class System2:
    def F(self,z):
        x,y=z
        return (x*x+y*y-1, x-y*y)

    def J(self,z):
        x,y=z
        return ((2*x,2*y),(1,-2*y))

    def exact_substitution(self,z):
        return self.F(z)

@dataclass(frozen=True)
class LiftStep:
    old_modulus: int
    new_modulus: int
    old_point: tuple[int,int]
    correction: tuple[int,int]
    new_point: tuple[int,int]
    valuations: tuple[int,int]
    determinant: int

def valuation_p(n,p,cap=10**6):
    if n==0:
        return cap
    v=0
    while n%p==0:
        v+=1;n//=p
    return v

def newton_double(system,z,p,modulus):
    """
    z solves F(z)=0 mod modulus.
    Compute correction modulo modulus^2 using J(z)^(-1).
    """
    new_modulus=modulus*modulus
    Fz=system.F(z)
    if any(v%modulus for v in Fz):
        raise ValueError("input point is not accurate to old modulus")
    Jz=system.J(z)
    Jinv=mat2_inv_mod(Jz,new_modulus)
    rhs=tuple((-v)%new_modulus for v in Fz)
    delta=mat_vec(Jinv,rhs,new_modulus)
    newz=tuple((z[i]+delta[i])%new_modulus for i in range(2))
    check=system.F(newz)
    if any(v%new_modulus for v in check):
        raise ArithmeticError("Newton lift failed")
    det=Jz[0][0]*Jz[1][1]-Jz[0][1]*Jz[1][0]
    return LiftStep(
        modulus,new_modulus,z,
        tuple(center(d,new_modulus) for d in delta),
        newz,
        tuple(valuation_p(v,p) for v in check),
        det
    )

def lift(system,z0,p,rounds):
    if any(v%p for v in system.F(z0)):
        raise ValueError("not a solution modulo p")
    z=tuple(v%p for v in z0)
    modulus=p
    history=[]
    for _ in range(rounds):
        step=newton_double(system,z,p,modulus)
        history.append(step)
        z=step.new_point
        modulus=step.new_modulus
    return z,modulus,history

def find_regular_solutions_mod_p(system,p):
    points=[]
    for x in range(p):
        for y in range(p):
            if all(v%p==0 for v in system.F((x,y))):
                J=system.J((x,y))
                det=(J[0][0]*J[1][1]-J[0][1]*J[1][0])%p
                points.append(((x,y),det,det!=0))
    return points

S=System2()
for p in (3,5,7,11,13,17,19):
    pts=find_regular_solutions_mod_p(S,p)
    print(f"p={p:2d}: {pts}")

p=11
z0=find_regular_solutions_mod_p(S,p)[0][0]
z,M,history=lift(S,z0,p,4)
print(f"\nlift from p={p}, z0={z0}")
for j,s in enumerate(history,1):
    print(
        f"  step {j}: {s.old_modulus}->{s.new_modulus}, "
        f"delta={s.correction}, z={s.new_point}, "
        f"v_p(F)={s.valuations}, det={s.determinant}"
    )
print("  final centered point =",tuple(center(v,M) for v in z))
print("  final modulus digits =",len(str(M)))
print("  residue F =",tuple(v%M for v in S.F(z)))

print("\nJacobian inverse audit at final point:")
J=S.J(z)
Jinv=mat2_inv_mod(J,M)
print("  J =",J)
print("  J^{-1} =",Jinv)
print("  J*J^{-1} columns =",
      mat_vec(J,(Jinv[0][0],Jinv[1][0]),M),
      mat_vec(J,(Jinv[0][1],Jinv[1][1]),M))
运行结果 模 11 正则根提升至 11^16
p= 3: []
p= 5: []
p= 7: []
p=11: [((3, 5), 7, True), ((3, 6), 4, True)]
p=13: []
p=17: []
p=19: [((4, 2), 2, True), ((4, 17), 17, True)]

lift from p=11, z0=(3, 5)
  step 1: 11->121, delta=(33, -11), z=(36, 115), v_p(F)=(2, 2), det=-70
  step 2: 121->14641, delta=(3993, -4114), z=(4029, 10642), v_p(F)=(5, 4), det=-16790
  step 3: 14641->214358881, delta=(24069804, 18799044), z=(24073833, 18809686), v_p(F)=(8, 8), det=-171527756
  step 4: 214358881->45949729863572161, delta=(5994635494818377, 18662978913829294), z=(5994635518892210, 18662978932638980), v_p(F)=(16, 16), det=-1811284995805124
  final centered point = (5994635518892210, 18662978932638980)
  final modulus digits = 17
  residue F = (0, 0)

Jacobian inverse audit at final point:
  J = ((11989271037784420, 37325957865277960), (1, -37325957865277960))
  J^{-1} = ((39157638098414613, 39157638098414613), (8628498837122761, 30098713447720097))
  J*J^{-1} columns = (1, 0) (0, 1)
计算 估值增长

示例系统 F_1=x^2+y^2-1、F_2=x-y^2 的 Jacobian 为 [[2x,2y],[1,-2y]],行列式 -4xy-2y=-2y(2x+1)。模 11 点 (3,5) 处行列式为 7,故为单位。四轮模数依次为 11、11^2、11^4、11^8、11^16;最终两分量余数均严格为 0。

Lecture 11 / 第 11 讲

代数数恢复:LLL、整数关系与多共轭嵌入

把高精度实数、复数或 pp-进近似恢复成有理数、数域元素或最小多项式。

LLL整数关系代数数

1. 有理数重构

若已知 xmodMx\bmod M,希望找互素整数 a,ba,b 使 xab1(modM)x\equiv a b^{-1}\pmod M|a|A,|b|B|a|\le A,|b|\le B,当 2AB<M2AB<M 时候选至多一个。扩展Euclidean 算法或二维格约化即可恢复。

定理有理重构唯一性

a1/b1a_1/b_1a2/b2a_2/b_2 都满足界和同余,则 Ma1b2a2b1M\mid a_1b_2-a_2b_1,而其绝对值小于 MM,故只能为零。

2. 最小多项式识别

α\alpha 的次数至多 dd,寻找小整数 c0,,cdc_0,\ldots,c_d 使

c0+c1α++cdαd=0.c_0+c_1\alpha+\cdots+c_d\alpha^d=0.

这是一条整数关系。把高精度近似编码进Euclidean格,LLL 会寻找异常短向量。得到多项式后必须因式分解,并选择与数值近似匹配的根。

算法LLL 识别的验证步骤
  1. 预先估计次数上界与系数高度。
  2. 以明显高于理论最低值的精度计算近似。
  3. 运行整数关系算法,得到候选多项式。
  4. 提高精度后重复;候选应稳定。
  5. 在候选数域中精确重建全部系数并代入原方程。

3. 已知数域中的元素

若已知 K=𝐐(θ)K=\mathbf Q(\theta)[K:𝐐]=d[K:\mathbf Q]=d,恢复 cKc\in K 等价于找

c=q0+q1θ++qd1θd1,qi𝐐.c=q_0+q_1\theta+\cdots+q_{d-1}\theta^{d-1},\qquad q_i\in\mathbf Q.

同时利用多个实、复或 pp-进嵌入能显著降低误识别概率。对 CM 值,先恢复各共轭的基本对称函数通常比单独识别一个巨大根更稳定。

CM jj-不变量

原课程以判别式 232-232 的二次 CM 轨道为例:两个 jj-值一个极大、一个相对较小。单独识别大数需要很高精度,而先把和与积识别为整数,再解二次方程,会稳定得多。

补充精度不是证明

LLL 输出只是一条短关系,不自动证明它是唯一关系,也不证明近似值恰是该代数数。严格证明来自高度界、分离界,或更常见的方式:把恢复出的系数精确代回原多项式系统。

当解的系数不再是有理数

在低次数 Belyi 例子中已经出现 𝐐(7)\mathbf Q(\sqrt{-7})𝐐(11)\mathbf Q(\sqrt{-11})𝐐(23)\mathbf Q(\sqrt[3]{2}) 等定义域。若预先知道是虚二次域,可以在复数域而非实数域上计算,并分别对实部与虚部作有理逼近;若只知道它是某个虚二次数,也可先恢复实部与虚部平方,从而求出二次方程。但对实二次及更高次数扩张,这种逐坐标处理不够。

先求全部共轭,再恢复对称函数

若能数值计算代数数 cc 的全部共轭 c1,,cdc_1,\ldots,c_d,则其基本对称函数是有理数;若 cc 是代数整数,则这些对称函数是整数。恢复它们便得到最小多项式。这一方法在虚二次情形中其实已经隐含出现,因为一个复近似自动给出复共轭近似。

原讲义以具有 𝐙[58]\mathbf Z[\sqrt{-58}] 复乘的椭圆曲线 jj-不变量为例。该阶的类数为 2,所以有两个共轭 j0,j1j_0,j_1。用

j(q)=q1+744+196884q+j(q)=q^{-1}+744+196884q+\cdots

或 GP 的 `ellj` 计算,一个共轭约为

j0=604729957825300085503.9999921715,j_0=604729957825300085503.9999921715\ldots,

仅凭这一近似还不足以可靠恢复二次多项式。另一个共轭约为

j1=24591258496.0000078284.j_1=24591258496.0000078284\ldots.

二者之和立刻识别为整数

j0+j1=604729957849891344000.j_0+j_1=604729957849891344000.

知道精确和之后,可用较小的共轭提高大共轭的有效精度,再识别乘积

j0j1=14871070713157137145512000000000.j_0j_1=14871070713157137145512000000000.

于是

j0,1=432000(1399837865393267±29259943365786104).j_{0,1} =432000\left( 1399837865393267 \pm\sqrt{29}\,259943365786104 \right).

乘积具有 Gross–Zagier 理论所预言的高度可分解结构。原讲义还指出,若利用更多 CM 理论,可预知差 j0j1j_0-j_129\sqrt{29},从而进一步减少所需精度。两个 jj-值异常接近整数并非偶然:它们组成模曲线 X0(2)/w2X_0(2)/w_2 上的整 CM 点。

LLL 与整数关系

pp-进计算中,通常只容易得到一个嵌入到 𝐐p\mathbf Q_p 的共轭,无法获得全部共轭,因此需要更强工具。LLL 算法在多项式时间内把格基约化,实际用途之一是从近似中寻找整数关系。若预期 deg(c)d\deg(c)\le d,就寻找非零整数向量

(a0,,ad),a0+a1c++adcd0.(a_0,\ldots,a_d),\qquad a_0+a_1c+\cdots+a_dc^d\approx0.

把近似误差乘以一个大尺度 MM 嵌入Euclidean格,真正的关系会对应异常短向量。若已知 c𝐐(α)c\in\mathbf Q(\alpha)degα=d\deg\alpha=d,则寻找

bc(a0+a1α++ad1αd1)=0bc-(a_0+a_1\alpha+\cdots+a_{d-1}\alpha^{d-1})=0

的整数关系,直接恢复 cc 在幂基中的坐标。GP 的 `algdep`、`lindep` 对实、复和 pp-进近似都可使用,因为最终约化的仍是参数规模相近的Euclidean格。

多个共轭的联合使用

若能获得 δ\delta 个共轭,可把每个候选关系在这些嵌入下的值组成 δ\delta 维向量,联合寻找短关系。这样既减少误判,也降低每个嵌入所需的精度。次数过大时,所需数千甚至数万位精度可能使“显式恢复”失去意义;课程的实际目标通常集中在中低次数、可验证的数域。

高维 LLL 对有理点恢复的改进

设要恢复射影点

(c0:c1::ck)𝐏k(𝐐)(c_0:c_1:\cdots:c_k)\in\mathbf P^k(\mathbf Q)

且各坐标高度不超过 HH。逐个对比值 ci/c0c_i/c_0 使用连分数,需要约 H2H^{-2} 的精度;把全部坐标同时放入 k+1k+1 维格,约 H(k+1)/kH^{-(k+1)/k} 的精度即可。所需精度减半往往能使高精度运算时间减少约四倍。若已知点落在 𝐏k\mathbf P^k 的某个真子簇上,还可加入这些代数关系进一步改善恢复。

𝐐(i)\mathbf Q(i) 中的数,实部与虚部常共享近似相同的分母,因此直接搜索

a+bic+di\frac{a+bi}{c+di}

a,b,c,da,b,c,d 小,常优于分别恢复实部与虚部。

为什么有时能在 𝐐p\mathbf Q_p 中看到一个共轭

一般不能保证随机选的 pp 会使数域在 𝐐p\mathbf Q_p 中有一次因子,因此这一方法在没有高度界时只是实践中常有效,而非完全确定的多项式时间算法。朴素概率与 Čebotarev 密度定理都提示:对随机素数,落在 𝐐p\mathbf Q_p 中的共轭数的期望约为 1。换几个好素数通常能找到一个可提升的根。最终一旦恢复出精确代数解,代入恒等式即可证明正确;若还需识别单值群,则必须另作群论验证。

从近似关系到整数格

设高精度近似数为 α\alpha,希望寻找次数不超过 dd、系数绝对值不超过 HH 的整数多项式 P(X)=a0+a1X++adXdP(X)=a_0+a_1X+\cdots+a_dX^d,使 P(α)=0P(\alpha)=0。这是一个整数关系问题。取精度尺度 CC,构造由下列行向量张成的格:

(1,0,,0,Cα0),,(0,,1,Cαd).(1,0,\ldots,0,\lfloor C\alpha^0\rceil),\ldots, (0,\ldots,1,\lfloor C\alpha^d\rceil).

(a0,,ad)(a_0,\ldots,a_d) 是真正关系,则相应格向量的前 d+1d+1 个坐标为系数,最后一个坐标近似 CP(α)C P(\alpha),因而异常短。LLL 约化把“寻找小系数且函数值小”转化为短向量搜索。实作时常再附加若干坐标,分别编码实部、虚部,或同时编码多个共轭值,以免某一嵌入上的偶然消去造成伪关系。

LLL 约化的核心不变量

对格基 b1,,bnb_1,\ldots,b_n,写 Gram–Schmidt 正交化为 bi*=bij<iμijbj*b_i^*=b_i-\sum_{j<i}\mu_{ij}b_j^*。LLL 首先做大小约化,使 |μij|1/2|\mu_{ij}|\le 1/2,再要求 Lovász 条件

δbi1*2bi*+μi,i1bi1*2,14<δ<1.\delta\|b_{i-1}^*\|^2\le \|b_i^*+\mu_{i,i-1}b_{i-1}^*\|^2, \qquad \tfrac14<\delta<1.

违反条件时交换相邻基向量。势函数在每次交换时严格下降,从而算法终止。输出的首向量不保证是绝对最短向量,但满足指数型近似界;对于由高精度识别构造出的“一个特别短、其余明显较长”的格,这通常足以恢复精确关系。

精度、次数与高度必须一起预算

识别并不是“多算几位就一定正确”。候选多项式的数目约随 Hd+1H^{d+1} 增长,而两个不同候选在给定复区域内的函数值可能极接近。经验上至少需要比 (d+1)log10H(d+1)\log_{10}H 更多的十进制有效位,并为根的条件数、共轭聚集和数值求解损失留下安全余量。若候选根靠近重根,|P(α)||P'(\alpha)| 很小,根的位置对系数扰动极敏感,所需精度会显著提高。

可靠流程应逐级增加精度:先在较低精度发现候选关系;把精度加倍后重新识别;检查次数和系数是否稳定;最后再以独立方式认证。候选关系若在精度提升后不断改变,通常说明高度上界过小、次数猜测错误,或数值解本身没有足够精度。

多变量代数数与共同定义域

覆盖方程往往含多个系数 c1,,crc_1,\ldots,c_r。逐个求最小多项式还不够,因为它们可能落在同一数域的不同嵌入中。先选一个本原元 θ\theta,恢复其最小多项式 mθm_\theta,再求

ci=qi(θ),qi𝐐[X],degqi<degmθ.c_i=q_i(\theta),\qquad q_i\in\mathbf Q[X],\quad \deg q_i<\deg m_\theta.

可把 1,θ,,θd1,ci1,\theta,\ldots,\theta^{d-1},c_i 同时放入整数关系问题。若不同 cic_i 需要不同嵌入,须依据所有方程共同匹配嵌入;只按数值距离逐个匹配,常在共轭根接近时出错。

PSLQ、LLL 与代数依赖

PSLQ 专门寻找实数向量之间的整数关系,特别适合 (1,α,,αd)(1,\alpha,\ldots,\alpha^d)。LLL 更通用,可同时编码多组近似、系数权重和同余条件。多变量关系 F(α,β)=0F(\alpha,\beta)=0 可把指定次数盒中的单项式 αiβj\alpha^i\beta^j 排成向量再做关系搜索;但单项式数目很快增长,必须利用已知权、对称性、消元次数或模素数信息缩小搜索空间。

从候选到证明

数值识别只产生猜想。要证明候选系数正确,至少应完成以下闭环:把识别出的代数数置于精确数域;精确代入原方程并验证等式为零;检查分母不消失、曲线光滑、映射次数正确;计算 fff1f-1 与极点除子,核对分歧型;必要时以结果式或 Gröbner 基证明没有遗漏分支点。若只需证明近似根对应候选多项式的某个唯一根,可使用复圆盘上的 Rouché 定理、区间算术或 Newton–Kantorovich 估计作局部认证。

最小多项式之后的算术整理

恢复数域后,还应计算整数环、判别式、素理想分解与可能的较小定义域。初始本原元常给出很差的幂基,导致系数巨大。通过 `polredabs` 一类数域约化,可换成较小判别式表现;再对覆盖作 Möbius 变换和源曲线坐标变换,通常能大幅降低高度。最后要检验 Galois 共轭作用是否只改变模型,还是确实产生不同的覆盖同构类。

计算专题:高度估计、共轭匹配与数域认证

在恢复代数数前,应尽量从几何推断次数和高度。若系数来自次数 nn 覆盖,消元 Bézout 界往往极粗;更有效的是利用 Galois 轨道大小、模数域次数、参数权和良素数上的因式分解型。对多个素数观察候选最小多项式的模因式分解,可限制 Galois 群和次数,但必须排除判别式素数。

若掌握全部复共轭,可用球形积树计算基本对称函数。直接相乘 (Xαi)\prod(X-\alpha_i) 会因大根小根并存而严重损失精度,宜按绝对值相近的根配对,并用任意精度复球算术传播误差界。对实系数多项式先把共轭复根配成实二次因子,可降低虚部消去误差。

从近似系数四舍五入到整数后,应利用 Mahler 测度或根界证明误差小于 1/21/2。若无法给出全局误差界,可逐个系数使用区间/球包含唯一整数来认证。根的重新排列不影响对称函数,但若只恢复某些非对称表达式,就必须通过解析延拓或附加不变量匹配共轭。

本原元选择可从小线性组合 θ=c1+mc2\theta=c_1+mc_2 搜索。坏选择可能使不同嵌入值碰撞,导致最小多项式次数下降或系数巨大。选定 θ\theta 后,以迹矩阵检查幂基是否线性无关,并求数域判别式;若幂基不是整数基,用 Round 2 或 p-maximal 算法求整数环。

将所有覆盖系数写成 qi(θ)q_i(\theta) 后,精确代入可在商环 𝐐[T]/(mθ)\mathbf Q[T]/(m_\theta) 中完成。每个分母需证明非零,可求与 mθm_\theta 的 gcd。曲线光滑性和分歧条件可归结为若干范数非零;计算这些范数还会指出所有坏素数。

最后应区分“方程定义域”“覆盖定义域”“dessin 模数域”。对每个 σGal(K/𝐐)\sigma\in\operatorname{Gal}(K/\mathbf Q),尝试求源曲线坐标变换 uσu_\sigma 使 fσ=fuσf^\sigma=f\circ u_\sigma。若可选成 1-cocycle 并满足相容性,覆盖下降;若只逐个存在而不满足 cocycle,障碍仍可能非零。

练习与解答整数关系

练习 1。若近似 α1.41421356\alpha\approx1.41421356,关系向量应包含哪些数以识别二次方程?

解。使用 (1,α,α2)(1,\alpha,\alpha^2),寻找小整数关系;得到约 (2,0,1)(-2,0,1),即 X22X^2-2

练习 2。为什么发现 P(α)P(\alpha) 很小不等于 P(α)=0P(\alpha)=0

解。高次或大系数多项式可在普通超越数附近偶然很小;必须有次数高度界、更多精度和精确代入认证。

练习 3。全部共轭已知时如何恢复多项式?

解。计算 i(Xαi)\prod_i(X-\alpha_i),用误差界将近似对称系数识别为有理数/整数,再精确验证根关系。

深入补充:共轭对称恢复、根分离与可认证精度预算

从一个复近似 α̃\tilde\alpha 猜最小多项式时,次数上界与高度上界缺一不可。若只提高精度而不限制次数,任意实数都能被高次数小系数多项式“偶然逼近”;若只限制次数而不控制系数高度,也会出现大量近似关系。

算法 单共轭的整数关系格

给定次数界 dd 和缩放 C10PC\approx10^P,构造由标准基与最后一列近似值组成的格,使短向量编码

c0+c1α̃++cdα̃d0.c_0+c_1\tilde\alpha+\cdots+c_d\tilde\alpha^d\approx0.

LLL 返回候选系数后,先取本原部分并因式分解;选择在目标复球内有根的不可约因子。候选必须在更高精度下重新评估,且残差衰减速度应与新增位数一致。

更稳定的方法是同时使用全部共轭。若数值求得 α1,,αd\alpha_1,\ldots,\alpha_d,计算幂和

pk=i=1dαik.p_k=\sum_{i=1}^d\alpha_i^k.

当目标多项式为首一整系数时,pkp_k 应接近整数;对其作区间舍入后,由 Newton 恒等式递推基本对称函数:

kek=i=1k(1)i1ekipi,e0=1.ke_k=\sum_{i=1}^k(-1)^{i-1}e_{k-i}p_i, \qquad e_0=1.

于是

m(x)=xde1xd1+e2xd2+(1)ded.m(x)=x^d-e_1x^{d-1}+e_2x^{d-2}-\cdots+(-1)^de_d.

这把一个高维整数关系问题改成对称和的整数识别,并天然利用所有共轭之间的关联。

原则 根分离给出认证所需的有限精度

固定次数 dd 与系数高度 HH 后,不同本原整多项式的根不可能任意接近;由结果式与根分离界可得到

|αβ|HO(d)|\alpha-\beta|\ge H^{-O(d)}

的显式下界。因而只要数值球半径严格小于相应分离界的一半,并且球内恰有候选多项式的一个根,根的识别就是唯一的。

实际中不必使用最尖锐常数,但必须把“工作精度”与 dlogHd\log H 同时增长。一个保守流程是先用低精度猜测 d,Hd,H,再把精度提高到明显超过候选系数位数乘以次数;随后用球算术计算 m(α̃)m(\tilde\alpha),证明其包含零,并用导数下界或根隔离证明球内只有一个根。

多个系数属于同一数域时,逐个识别最小多项式会丢失嵌入配对。应先选原始元 θ\theta,再把每个系数写成

a=a0+a1θ++ad1θd1,ai𝐐.a=a_0+a_1\theta+\cdots+a_{d-1}\theta^{d-1},\qquad a_i\in\mathbf Q.

对所有复嵌入同时建立线性系统,可恢复 aia_i;其条件数由嵌入矩阵

V=(σj(θ)i)j,iV=(\sigma_j(\theta)^{i})_{j,i}

控制。若幂基病态,可改用整基或 LLL 约化后的基。完成恢复后,在 K=𝐐[x]/(mθ)K=\mathbf Q[x]/(m_\theta) 中精确代入原方程,并逐一核对每个复嵌入与对应数值解的匹配。

算法 防止共轭错配

对每个候选嵌入计算一组稳定指纹,例如若干系数的联合近似、迹、范数和低次多项式值;用最小权匹配把数值解与数域嵌入配对。配对完成后再恢复坐标,不能先独立舍入每个系数。最终证书由最小多项式、数域坐标、指定嵌入的隔离球和精确代入余数共同组成。

补充计算:有理重构、精确 LLL 与多共轭对称恢复

定理 有理重构的唯一性与代数数关系界

设 \(gcd(a,m)=1\)。若整数 r,s 满足 \(gcd(r,s)=1\)、\(s>0\)、\(r≡as (mod m)\),且 \(2|r|s<m\),则 r/s 由 a mod m 唯一确定。若 α 为次数 d、高度至多 H 的代数数,而近似 \(\tilde α\) 满足充分小的误差,则格 (ei,Qα̃i):0id𝐙d+2 \langle(e_i,\lfloor Q\tilde α^i\rceil):0\le i\le d\rangle\subset\mathbf Z^{d+2} 中的短向量恢复 α 的整数关系。

证明 行列式下界与短向量分离

若 r/s 与 r'/s' 均满足同余,则 m 整除 rs'-r's。若两者不同,则 \(|rs'-r's|≥m\);但由 \(2|r|s<m\) 和同样的界,经 \(|rs'|+|r's|<m\) 得矛盾。因此重构唯一。扩展Euclidean 算法的相邻余数与系数给出满足大小界的候选,最终同余检查即为证书。

设 \(P(X)=∑c_iX^i\) 为 α 的本原最小多项式。嵌入向量 \(v=(c_0,…,c_d,∑c_i⌊Q\tilde α^i⌉)\) 的末坐标由近似误差控制,而前 d+1 坐标由高度控制,故范数约为 \(O(H√d+QH d|\tilde α-α|)\)。非关系向量的末坐标通常至少为代数分离界乘 Q。Q 与精度足够大时,真关系在格中与伪关系分离;LLL 给出指数近似的短向量,再以精确因式分解与代入完成认证。

Python 扩展Euclidean重构、自写 LLL 与共轭系数恢复
import sympy as sp
from fractions import Fraction
from dataclasses import dataclass
from math import isqrt

def rational_reconstruction(a: int, m: int, bound: int | None = None):
    """
    Find r/s with |r|,|s|<=bound and r ≡ a*s (mod m).
    Uses the extended Euclidean remainder sequence.
    """
    a %= m
    if bound is None:
        bound = isqrt(m // 2)
    r0, r1 = m, a
    t0, t1 = 0, 1
    while abs(r1) > bound:
        q = r0 // r1
        r0, r1 = r1, r0-q*r1
        t0, t1 = t1, t0-q*t1
    num, den = r1, t1
    if den == 0:
        raise ValueError("zero denominator")
    if den < 0:
        num, den = -num, -den
    g = sp.gcd(num, den)
    num //= g
    den //= g
    if abs(num) > bound or den > bound or (a*den-num) % m:
        raise ValueError("no reconstruction within bound")
    return int(num), int(den)

def continued_fraction_rational(x: sp.Rational):
    a=[]
    p,q=int(x.p),int(x.q)
    while q:
        c=p//q
        a.append(c)
        p,q=q,p-c*q
    return a

@dataclass(frozen=True)
class Relation:
    coefficients: tuple[int, ...]
    residual: sp.Float
    polynomial: sp.Expr


def nearest_integer(q: Fraction) -> int:
    if q >= 0:
        return (2*q.numerator + q.denominator) // (2*q.denominator)
    return -nearest_integer(-q)

def dot(u,v):
    return sum(a*b for a,b in zip(u,v))

def gram_schmidt_rows(B):
    n=len(B)
    Bstar=[]
    mu=[[Fraction(0) for _ in range(n)] for _ in range(n)]
    norms=[]
    for i in range(n):
        v=[Fraction(x) for x in B[i]]
        for j in range(i):
            if norms[j] == 0:
                continue
            mu[i][j]=Fraction(dot(B[i],Bstar[j]),norms[j])
            v=[v[k]-mu[i][j]*Bstar[j][k] for k in range(len(v))]
        Bstar.append(v)
        norms.append(dot(v,v))
    return Bstar,mu,norms

def lll_reduce(B, delta=Fraction(3,4)):
    B=[list(map(int,row)) for row in B]
    k=1
    Bstar,mu,norms=gram_schmidt_rows(B)
    while k<len(B):
        for j in range(k-1,-1,-1):
            q=nearest_integer(mu[k][j])
            if q:
                B[k]=[a-q*b for a,b in zip(B[k],B[j])]
                Bstar,mu,norms=gram_schmidt_rows(B)
        if norms[k] >= (delta-mu[k][k-1]**2)*norms[k-1]:
            k+=1
        else:
            B[k],B[k-1]=B[k-1],B[k]
            Bstar,mu,norms=gram_schmidt_rows(B)
            k=max(k-1,1)
    return B

def integer_relation_lll(alpha, degree, digits=80, scale_power=None):
    """
    Recover c_0+...+c_d alpha^d≈0 by embedding one real coordinate.
    Rows are basis vectors (e_i, round(Q*alpha^i)).
    """
    if scale_power is None:
        scale_power = digits // 2
    Q = 10**scale_power
    vals=[sp.N(alpha**i,digits) for i in range(degree+1)]
    rows=[]
    for i,v in enumerate(vals):
        row=[0]*(degree+2)
        row[i]=1
        row[-1]=int(sp.N(Q*v,digits).round())
        rows.append(row)
    L=lll_reduce(rows)
    candidates=[]
    X=sp.Symbol("X")
    for row in L:
        coeff=tuple(map(int,row[:-1]))
        if not any(coeff):
            continue
        poly=sum(coeff[i]*X**i for i in range(len(coeff)))
        residual=abs(sp.N(poly.subs(X,alpha),30))
        candidates.append(Relation(coeff,residual,sp.factor(poly)))
    return min(candidates,key=lambda r:(r.residual,sum(c*c for c in r.coefficients)))

def conjugate_symmetric_recovery(values, digits=80):
    """
    Recover a monic polynomial from approximate conjugates through
    elementary symmetric functions and nearest-integer certification.
    """
    z=sp.Symbol("z")
    poly=sp.Integer(1)
    for value in values:
        poly=sp.expand(poly*(z-sp.N(value,digits)))
    coeffs=sp.Poly(poly,z).all_coeffs()
    rounded=[sp.Integer(sp.N(c,digits).round()) for c in coeffs]
    candidate=sp.Poly.from_list(rounded,gens=z)
    errors=[abs(sp.N(c-r,digits)) for c,r in zip(coeffs,rounded)]
    return candidate,errors

print("rational reconstruction:")
tests=[
    (Fraction(37,113),10**9+7),
    (Fraction(-211,997),2**61-1),
    (Fraction(12345,54321),10**12+39),
]
for frac,m in tests:
    residue=(frac.numerator*pow(frac.denominator,-1,m))%m
    num,den=rational_reconstruction(residue,m)
    print(f"  {frac} mod {m} -> residue={residue} -> {num}/{den}")

print("\nLLL minimal-polynomial recovery:")
targets=[
    (sp.sqrt(2)+sp.sqrt(3),4),
    (2*sp.cos(2*sp.pi/7),3),
    (sp.real_root(2,3)+sp.real_root(4,3),3),
]
for alpha,d in targets:
    rel=integer_relation_lll(sp.N(alpha,100),d,digits=100,scale_power=55)
    print("  alpha≈",sp.N(alpha,18))
    print("   coefficients =",rel.coefficients)
    print("   polynomial   =",rel.polynomial)
    print("   residual     =",rel.residual)

print("\nrecovery from all conjugates of x^4-10*x^2+1:")
x=sp.Symbol("x")
roots=sp.nroots(x**4-10*x**2+1,n=90,maxsteps=200)
candidate,errors=conjugate_symmetric_recovery(roots,90)
print("  recovered =",candidate.as_expr())
print("  coefficient errors:")
for i,e in enumerate(errors):
    print(f"   c{i}: {sp.N(e,8)}")

print("\nprecision-height budget:")
for degree in (4,8,16,32):
    for height_bits in (20,50,100):
        heuristic=degree*(height_bits+sp.log(degree,2))+20
        print(f"  d={degree:2d}, Hbits={height_bits:3d}, guard≈{float(heuristic):7.1f} bits")
运行结果 三个最小多项式与四共轭恢复记录
rational reconstruction:
  37/113 mod 1000000007 -> residue=70796461 -> 37/113
  -211/997 mod 2305843009213693951 -> residue=2007494214641410581 -> -211/997
  4115/18107 mod 1000000000039 -> residue=226707903030 -> 4115/18107

LLL minimal-polynomial recovery:
  alpha≈ 3.14626436994197234
   coefficients = (1, 0, -10, 0, 1)
   polynomial   = X**4 - 10*X**2 + 1
   residual     = 1.82877982605163997154525367729e-99
  alpha≈ 1.24697960371746706
   coefficients = (-1, -2, 1, 1)
   polynomial   = X**3 + X**2 - 2*X - 1
   residual     = 0
  alpha≈ 2.84732210186307264
   coefficients = (-6, -6, 0, 1)
   polynomial   = X**3 - 6*X - 6
   residual     = 2.28597478256454996443156709661e-100

recovery from all conjugates of x^4-10*x^2+1:
  recovered = z**4 - 10*z**2 + 1
  coefficient errors:
   c0: 0
   c1: 0
   c2: 1.9636374E-90
   c3: 4.2954568E-91
   c4: 0

precision-height budget:
  d= 4, Hbits= 20, guard≈  108.0 bits
  d= 4, Hbits= 50, guard≈  228.0 bits
  d= 4, Hbits=100, guard≈  428.0 bits
  d= 8, Hbits= 20, guard≈  204.0 bits
  d= 8, Hbits= 50, guard≈  444.0 bits
  d= 8, Hbits=100, guard≈  844.0 bits
  d=16, Hbits= 20, guard≈  404.0 bits
  d=16, Hbits= 50, guard≈  884.0 bits
  d=16, Hbits=100, guard≈ 1684.0 bits
  d=32, Hbits= 20, guard≈  820.0 bits
  d=32, Hbits= 50, guard≈ 1780.0 bits
  d=32, Hbits=100, guard≈ 3380.0 bits
计算 精度预算

对次数 d、高度位长 h 的关系,经验保护位可取 d(h+log_2 d)+20。程序列出 d=32、h=100 时约 3380 位;该数量只用于发现。证明阶段应以候选最小多项式、隔离区间、精确数域运算及原方程余数为零构成证书。

Lecture 12 / 第 12 讲

正维解族、切空间与加权射影参数

从孤立解转向一参数或多参数族,解释 Jacobian 核、模空间和规范化。

正维族切空间加权射影空间

1. 为什么会出现正维族

固定分支值为三个点时,Hurwitz 空间通常零维;增加分支点、允许系数变动或只规定部分分歧后,解空间可能有正维。计算上表现为方程数少于未知数,或 Jacobian 在光滑点具有非零核。

定义Zariski 切空间

设仿射簇由 F1==Fm=0F_1=\cdots=F_m=0 定义,在点 xx 的切空间是

TxX=kerJF(x).T_xX=\ker J_F(x).

若点光滑,则 dimTxX=dimxX\dim T_xX=\dim_xX

2. 带参数的Newton 法

若选定一组自由参数 t1,,trt_1,\ldots,t_r,把其余变量记为 yy,只要偏 Jacobian F/y\partial F/\partial y 可逆,隐函数定理就允许在实、复或 pp-进邻域中把 yy 写成 tt 的解析函数。每次固定参数精度后,对 yy 做Newton 修正即可。

定理形式隐函数定理

F(t0,y0)=0F(t_0,y_0)=0det(F/y)(t0,y0)\det(\partial F/\partial y)(t_0,y_0) 为基环中的单位,则存在唯一形式幂级数 y(t)y(t) 满足 F(t,y(t))=0F(t,y(t))=0y(t0)=y0y(t_0)=y_0

3. 加权射影空间

当变量在缩放 λ\lambda 下按不同权变换,参数自然位于加权射影空间

𝐏(w0,,wn)=Projk[x0,,xn],degxi=wi.\mathbf P(w_0,\ldots,w_n)=\operatorname{Proj}k[x_0,\ldots,x_n],\qquad \deg x_i=w_i.

例如首一多项式在变量缩放 xλxx\mapsto\lambda x 下,第 ii 个系数具有权 ii。选择某个非零坐标为 1 只是一个仿射图;不能忘记其他图和商奇点。

椭圆曲线参数

短 Weierstrass 方程 y2=x3+Ax+By^2=x^3+Ax+B(x,y)(λ2x,λ3y)(x,y)\mapsto(\lambda^2x,\lambda^3y) 下,A,BA,B 的权分别为 4,64,6。因此 (A:B)(A:B) 位于 𝐏(4,6)\mathbf P(4,6),而 j=17284A3/(4A3+27B2)j=1728\,4A^3/(4A^3+27B^2) 是权零函数。

算法处理正维族
  1. 计算 Jacobian 秩,估计局部维数。
  2. 分离真实模参数与坐标变换造成的规范方向。
  3. 选仿射图或横截切片,把问题化为零维。
  4. 对多个切片求解并插值恢复参数公式。
  5. 检查边界点、退化纤维和商奇点。

从孤立恒等式转向正维族

此前的 Newton–Hensel 方法针对零维解:方程数与有效未知数相同,近似解在局部唯一。许多重要问题却自然形成正维族。例如:𝐏1\mathbf P^1 上分支于四个点的覆盖随交比变化而构成一维族;两条椭圆曲线之间的循环 NN-同源也由一条模曲线 X0(N)X_0(N) 参数化。更一般地,分支于 d+3d+3 个点的球面覆盖形成 dd 维 Hurwitz 空间;高亏格基曲线也有类似族,例如仅在一个点分歧的椭圆曲线覆盖。

这些模空间不一定有理,研究它们本身往往就是主要目标。零维情况下“找到一个近似点并 Newton 提升”足以确定解;正维情况下,近似点并不决定族上的哪个精确点,必须同时恢复参数、函数域和族的方程。

循环同源如何化为四点覆盖

ϕ:EE\phi:E'\to E 是次数 NN 的循环同源。平移群律可假设 ϕ(O)=O\phi(O')=O。同源与 [1][-1] 对合交换,因此下降为

ϕ:E/{±1}E/{±1}.\bar\phi:E'/\{\pm1\}\longrightarrow E/\{\pm1\}.

两个商曲线都是 𝐏1\mathbf P^1。目标商映射 EE/{±1}E\to E/\{\pm1\} 在四个 2-挠点处分歧,所以 ϕ\bar\phi 是分支于这四点的有理函数。其 Galois 闭包群是阶 2N2N 的二面体群

DN=(𝐙/N𝐙){±1}.D_N=(\mathbf Z/N\mathbf Z)\rtimes\{\pm1\}.

反过来,具有这种二面体单值群与四点分歧数据的覆盖可提升为循环 NN-同源。若 N=2k+1N=2k+1 为奇数,四个局部单值置换均具有循环型 12k1\,2^kX0(N)X_0(N) 还带有 j/1728j/1728 的 Belyi 映射,其次数为

NpN(1+1p).N\prod_{p\mid N}\left(1+\frac1p\right).

局部参数化与隐函数定理

设方程系统 F(z)=0F(z)=0 在光滑点 z0z_0 的 Jacobian 秩为 mm,未知数数目为 nn,则局部维数为 nmn-m。选取 r=nmr=n-m 个自由参数 tt,把其余变量记为 yy。若偏 Jacobian F/y\partial F/\partial y 可逆,形式隐函数定理给出唯一幂级数 y(t)y(t)。计算上可在 𝐐p[[t]]/(tM)\mathbf Q_p[[t]]/(t^M) 中做 Newton 迭代,逐步得到族的局部参数展开。

另一种办法是加入 rr 个一般线性切片,把正维簇截成零维点集;对许多切片求出点,再插值恢复有理函数或隐式方程。切片必须横截,避免落在奇异点或与分量相切。

规范方向与真实模参数

Jacobian 的核可能来自两类方向:一类是对象真正变化的模参数,另一类只是坐标变换造成的冗余,例如 xax+bx\mapsto ax+b、目标的 Möbius 变换或整体加权缩放。必须先求出群作用的无穷小方向,再从切空间中取商。否则会把纯坐标变化误认为一维模空间。

加权射影参数与边界

若参数按不同权缩放,它们自然位于加权射影空间。局部令某个坐标为 1 只是一个仿射图;该坐标为零的边界点可能代表重要退化覆盖、碰撞分支点或奇异纤维,不能直接舍去。恢复全族时应在多个图中计算,并用权齐次式拼接。

一维族的函数域方法

若模曲线 MM 亏格为 0,可选择参数 tt,所有系数写成 𝐐(t)\mathbf Q(t) 中有理函数。亏格 1 时可把 MM 写成椭圆曲线,并在其函数域中表示系数。更高亏格则需给出 MM 的射影模型与系数对应的有理函数。数值上沿族采样再插值时,必须预先估计函数的极点除子和次数;否则有限样本总能拟合出许多伪公式。

Hurwitz 空间的局部坐标

固定次数、源亏格和分支循环型后,覆盖的同构类构成 Hurwitz 空间。把三个分支值规范为 0,1,0,1,\infty,其余 r3r-3 个分支值可作为配置空间的坐标;然而覆盖在配置空间上通常是有限多值的,因为同一组分支值可对应多个单值三元组的辫群轨道。局部避开判别式后,Riemann 存在定理给出解析覆盖;靠近判别式边界时,两个分支点碰撞,源曲线可能退化为稳定曲线。

若分支值为 t1,,trt_1,\ldots,t_r,纯辫群移动它们而不交换标签,完整辫群还允许置换同型分支点。Hurwitz 作用在单值元组 (σ1,,σr)(\sigma_1,\ldots,\sigma_r) 上,例如相邻生成元作用为

(,σi,σi+1,)(,σiσi+1σi1,σi,).(\ldots,\sigma_i,\sigma_{i+1},\ldots) \longmapsto (\ldots,\sigma_i\sigma_{i+1}\sigma_i^{-1},\sigma_i,\ldots).

同一个辫群轨道通常对应 Hurwitz 空间的一个连通分支。因此在开始系数计算前先做置换群与辫群轨道计算,可预知分支数、覆盖次数和可能的定义域。

把一维族写成函数域问题

设预期模空间为曲线 HH。数值跟踪许多参数值后,可选择一个易计算的模函数 uK(H)u\in K(H),把其他模型系数视作 uu 的代数函数。若 HH 为有理曲线,就寻找参数 ss 使所有系数都在 K(s)K(s) 中;若 HH 亏格正,则需先恢复平面模型 R(u,v)=0R(u,v)=0,再在函数域 K(u,v)/(R)K(u,v)/(R) 中表达覆盖。

数值插值时,先从一批样本恢复候选有理函数

c(s)=a0+a1s++amsmb0+b1s++bnsn.c(s)=\frac{a_0+a_1s+\cdots+a_ms^m}{b_0+b_1s+\cdots+b_ns^n}.

次数上界可由权、边界退化阶或已知除子估计。采样点数必须超过未知系数数目,并留出额外点作交叉验证。随后应在符号层面代入原方程;“在很多浮点样本上吻合”不能替代恒等式证明。

微分延拓与预测校正

设方程 F(y,t)=0F(y,t)=0,且 FyF_y 可逆。沿参数路径 t(s)t(s) 微分得

Fydyds+Ftdtds=0,dyds=Fy1Ftdtds.F_y\frac{dy}{ds}+F_t\frac{dt}{ds}=0, \qquad \frac{dy}{ds}=-F_y^{-1}F_t\frac{dt}{ds}.

用这个常微分方程作预测,再以 Newton 法校正,可稳定跟踪同一个解析分支。若直接把每个参数值独立交给非线性求解器,解可能在不同共轭分支之间跳转。接近分歧点时 FyF_y 条件数恶化,应缩短步长或改用 Puiseux 参数。

形式幂级数与 Hensel 提升

在一个已知精确点附近,可在 K[[s]]K[[s]] 中求解。若 Fy(y0,0)F_y(y_0,0) 可逆,则从 y(1)=y0y^{(1)}=y_0 开始迭代

y(2m)=y(m)Fy(y(m),s)1F(y(m),s)(mods2m),y^{(2m)}=y^{(m)}-F_y(y^{(m)},s)^{-1}F(y^{(m)},s) \pmod {s^{2m}},

每次使精度加倍。这比逐阶解线性方程更快,也保留精确系数。得到足够长的级数后,可用 Padé 逼近猜测有理函数,或用代数关系算法恢复 HH 的函数域方程。

边界、判别式与稳定约化

正维族最有信息量的地方常在边界。覆盖方程的判别式在参数空间中切出退化点;其不可约分支对应不同碰撞模式。计算各模型系数在边界参数处的赋值,可辨认稳定极限的对偶图、节点数和分支循环的乘积。对模曲线族,这些边界正是尖点;对椭圆曲面族,它们对应奇异纤维增强或 Mordell–Weil 格跳跃。

维数检查与规范化自由度

建立系数方程时必须先减去坐标变换自由度。源为 𝐏1\mathbf P^1 时有三维 PGL2\operatorname{PGL}_2;目标同样有三维,但固定三个分支值后已被消去。平面曲线模型还可能有射影线性变换,自变量与因变量缩放也会产生伪参数。一个可靠的维数核对是:

未知系数数独立方程数剩余坐标群维数=预期 Hurwitz 维数.\text{未知系数数}-\text{独立方程数}-\text{剩余坐标群维数} =\text{预期 Hurwitz 维数}.

若左边过大,说明规范化不足或方程有冗余分支;若过小,通常是把本应自由的分支值错误固定了。

由局部族到全局模型

局部参数化只给出解析小圆盘。要得到全局 Hurwitz 曲线,需要沿闭路做解析延拓,计算参数分支的单值置换,并把所有图册粘合。另一条路线是在足够多样本上恢复全局代数关系,再通过正规化取得光滑射影曲线。最终还应计算从 Hurwitz 曲线到分支配置空间的次数与分歧,并与辫群轨道的组合数据核对。

计算专题:正维族的正规化、单值与隐式化

从样本恢复平面关系 R(u,v)=0R(u,v)=0 后,所得平面曲线常有奇点。函数域真正对应其正规化。应计算奇点、局部分支与 δ\delta-不变量,再用积分闭包或显式正规化获得光滑模型。仅以平面次数公式估亏格会把节点贡献误算为模空间亏格。

若投影 u:H𝐏1u:H\to\mathbf P^1 次数为 dd,在一般 u0u_0 上有 dd 个数值分支。沿绕过判别式根的闭路跟踪这些分支,得到置换单值群。其传递分量检查 RR 的不可约性;循环型给出投影分歧;Riemann–Hurwitz 再给出正规化亏格,与代数计算互相核验。

隐式化可用消元,但参数有理函数的公共基点会使结果式带额外因子。若 u=A/C,v=B/Cu=A/C,v=B/C,应对理想 (uCA,vCB)(uC-A,vC-B) 关于 CC 饱和。反过来,从隐式曲线找有理参数时,亏格 0 还需一个基域有理点;从奇点作直线投影常提供参数,但要检查逆映射。

族上每个覆盖系数是函数域元素,其极点除子由边界退化决定。先计算这些除子,再用 Riemann–Roch 空间表示系数,比盲目设高次数分子分母更稳。边界处的 Puiseux 展开可给出精确极点阶,也揭示稳定极限中哪些分支点碰撞。

辫群作用还可能造成非平凡 descent:Hurwitz 分量在 𝐐\mathbf Q 上定义,但一个具体标记元组只在扩张上。计算分量方程时应采用辫群不变量或对全部 Galois 共轭样本对称化。否则插值得到的参数可能人为进入大数域。

若族映射到另一已知模空间,例如 X0(N)X_0(N)M0,rM_{0,r},应比较函数域次数、分歧和边界映射。一个次数与分歧完全匹配的非恒定态射在光滑曲线间常可据此证明为同构,这比直接求复杂逆公式更简洁。

练习与解答正维变形

练习 1。四个有序点在 𝐏1\mathbf P^1 上模射影变换的参数是什么?

解。交比;固定前三点为 0,1,0,1,\infty 后,第四点 λ𝐏1\{0,1,}\lambda\in\mathbf P^1\setminus\{0,1,\infty\} 给出一维配置空间。

练习 2。隐函数定理中为何要选可逆偏 Jacobian?

解。它允许唯一解出相应依变量为自由参数的解析/形式函数;若不可逆,点可能奇异或所选参数不是局部坐标。

练习 3。数值路径跟踪为何需要校正步?

解。微分预测积累截断误差,且曲率大处会离开解集;Newton 校正把预测拉回 F=0F=0

深入补充:高阶阻碍、形式参数与一维族的隐式化

设方程组 F(x)=0F(x)=0 在点 aa 的 Jacobian 秩为 rr,变量数为 nn。切空间维数至少为 nrn-r,但这只是一次近似。要判断一个切向量是否真正延伸为曲线,必须逐阶解形式幂级数。

取方向 vv 满足 J(a)v=0J(a)v=0,设

x(t)=a+tv+t2w2+t3w3+.x(t)=a+tv+t^2w_2+t^3w_3+\cdots.

代入并比较 tkt^k 系数。一次项自动为零;二次项要求

J(a)w2=12D2F(a)[v,v].J(a)w_2=-\frac12D^2F(a)[v,v].
判据 二阶阻碍位于 Jacobian 余核

切向量 vv 能延伸到二阶,当且仅当 D2F(a)[v,v]D^2F(a)[v,v]J(a)J(a) 的像中。其在

cokerJ(a)\operatorname{coker}J(a)

中的像称为二阶阻碍。若阻碍非零,则该切向量虽存在于 Zariski 切空间,却不对应实际分支。

更高阶同样得到固定线性算子 J(a)J(a) 下的一系列方程

J(a)wk=Rk(v,w2,,wk1).J(a)w_k=-R_k(v,w_2,\ldots,w_{k-1}).

因此可预先分解 Jacobian,并逐阶检查右端是否落在其像中。若每阶都可解,就得到形式分支;在特征零的代数情形,Artin 逼近保证形式解可由代数解任意高阶逼近。

加权齐次方程还含有缩放方向。若变量权为 wiw_iλ\lambda 作用为 xiλwixix_i\mapsto\lambda^{w_i}x_i,则 Euler 向量

E=(w1a1,,wnan)E=(w_1a_1,\ldots,w_na_n)

自动落在 Jacobian 核中。这不是模参数,而是同一点的不同坐标表示。应选一个非零坐标设为 11,或加入横截条件 (xa)=0\ell(x-a)=0 消去该方向;否则会把一维缩放轨道误认为新的几何族。

算法 从局部参数到全局隐式方程

先计算足够长的级数 xi(t)x_i(t);选择两个函数 u(t),v(t)u(t),v(t) 作为候选生成元;设定双次数界并解线性系统寻找

H(u,v)=i,jcijuivj=0.H(u,v)=\sum_{i,j}c_{ij}u^iv^j=0.

得到候选后,把 u,vu,v 的原始有理表达代入并在函数域或商环中精确验证。若参数化可能多对一,再比较函数域扩张次数,确认 K(C)=K(u,v)K(C)=K(u,v) 而不是其真子域。

次数界可由极点除子决定。若 u,vu,v 仅在一个边界点有极点,阶分别为 m,nm,n,则单项式 uivju^iv^j 的极点阶为 im+jnim+jn。当具有相同或更小极点阶的单项式数超过 Riemann–Roch 空间维数时必出现线性关系;按极点阶递增构造矩阵,可在最小可能双次数处找到隐式方程。

族的判别式给出参数线上的坏点。计算消元

Δ(t)=Resx(F(x,t),F/x)\Delta(t)=\operatorname{Res}_x(F(x,t),\partial F/\partial x)

可定位纤维奇异或根碰撞处;在这些点绕行会产生单值作用。数值延拓时,应同时追踪解与切向量,经过闭路后比较返回点的排列,由此恢复参数族的单值群。若要证明全局模型,最终还需在每个判别式点做局部归一化,确认隐式平面曲线的奇点没有改变几何亏格。

补充计算:形式隐函数、倍精度级数 Newton 与参数消元

定理 形式隐函数定理与 t-adic Newton 倍精度

设 K 为特征 0 域,\(F(t,y)∈K[[t,y-y_0]]\),\(F(0,y_0)=0\) 且 \(F_y(0,y_0)∈K^×\)。则存在唯一 \(y(t)∈K[[t]]\),\(y(0)=y_0\),使 \(F(t,y(t))=0\)。若 \(y_k\) 满足 \(F(t,y_k)≡0 (mod t^m)\),则 yk+1=ykF(t,yk)Fy(t,yk)(modt2m) y_{k+1}=y_k-\frac{F(t,y_k)}{F_y(t,y_k)}\pmod {t^{2m}} 满足 \(F(t,y_{k+1})≡0 (mod t^{2m})\)。

证明 逐系数唯一性与形式 Taylor 余项

写 \(y=y_0+∑_{j≥1}c_jt^j\)。假设 \(c_1,…,c_{m-1}\) 已定,\(t^m\) 系数中 \(c_m\) 的系数恰为 \(F_y(0,y_0)\),其为单位,所以 \(c_m\) 唯一可解。归纳得到存在唯一的形式解。

若 \(e=F/F_y\),因 \(F∈(t^m)\) 且 \(F_y\) 为单位,故 \(e∈(t^m)\)。Taylor 展开 \(F(y-e)=F(y)-F_y(y)e+e^2H\) 的前两项严格抵消,而 \(e^2H∈(t^{2m})\),因此精度倍增。唯一性也可由两个解之差的最低阶项代入线性项得矛盾。

Python 逐项求解、形式 Newton、切空间与隐式化
import sympy as sp
from dataclasses import dataclass

x, y, t = sp.symbols("x y t")

def truncate(expr, var, order):
    return sp.series(sp.expand(expr), var, 0, order).removeO().expand()

def implicit_series(F, y0, order):
    """
    Solve F(t,y(t))=0 with y(0)=y0 and F_y(0,y0) != 0.
    Coefficients are determined successively over QQ.
    """
    coeffs = {}
    series = sp.sympify(y0)
    for k in range(1, order):
        ck = sp.Symbol(f"c{k}")
        trial = series + ck*t**k
        residual = truncate(F.subs({x:t,y:trial}),t,k+1)
        equation = sp.expand(residual).coeff(t,k)
        sol = sp.solve(sp.Eq(equation,0),ck)
        if len(sol)!=1:
            raise ArithmeticError(f"coefficient c{k} not uniquely determined")
        coeffs[k]=sp.simplify(sol[0])
        series=sp.expand(series+coeffs[k]*t**k)
    return series, coeffs

def newton_series(F, y_start, order):
    """
    Formal Newton iteration. Each step doubles the t-adic precision.
    """
    yk=sp.sympify(y_start)
    precision=1
    history=[]
    while precision<order:
        target=min(2*precision,order)
        numerator=truncate(F.subs({x:t,y:yk}),t,target)
        denominator=truncate(sp.diff(F,y).subs({x:t,y:yk}),t,target)
        inverse=sp.invert(
            sp.Poly(denominator,t),
            sp.Poly(t**target,t)
        ).as_expr()
        correction=truncate(numerator*inverse,t,target)
        ynew=truncate(yk-correction,t,target)
        residual=truncate(F.subs({x:t,y:ynew}),t,target)
        history.append((precision,target,ynew,residual))
        yk=ynew
        precision=target
    return yk,history

@dataclass(frozen=True)
class TangentData:
    point: tuple[sp.Expr,sp.Expr]
    jacobian: tuple[sp.Expr,sp.Expr]
    tangent_vector: tuple[sp.Expr,sp.Expr]
    smooth: bool

def tangent_data(F,point):
    fx=sp.diff(F,x).subs({x:point[0],y:point[1]})
    fy=sp.diff(F,y).subs({x:point[0],y:point[1]})
    return TangentData(point,(fx,fy),(fy,-fx),(fx,fy)!=(0,0))

def eliminate_parameter(x_of_t,y_of_t,parameter=t):
    X,Y=sp.symbols("X Y")
    numx=sp.together(X-x_of_t).as_numer_denom()[0]
    numy=sp.together(Y-y_of_t).as_numer_denom()[0]
    res=sp.factor(sp.resultant(numx,numy,parameter))
    return sp.factor(res)

F=y**3+y-x
series1,coeffs=implicit_series(F,0,16)
series2,history=newton_series(F,0,16)
print("implicit curve y^3+y=x at (0,0)")
print("  coefficient method:",series1)
print("  Newton method     :",series2)
print("  equal through t^15:",truncate(series1-series2,t,16)==0)
print("  residual          :",truncate(F.subs({x:t,y:series2}),t,16))

print("\nNewton precision log:")
for old,new,approx,resid in history:
    print(f"  t^{old} -> t^{new}: y={approx}")
    print(f"     residual={resid}")

G=y**2-x**3-x**4
print("\ntangent data:")
for P in [(0,0),(1,sp.sqrt(2)),(1,-sp.sqrt(2))]:
    print(" ",tangent_data(G,P))

u=sp.symbols("u")
xpar=u**2-1
ypar=u*(u**2-1)
implicit=eliminate_parameter(xpar,ypar,u)
print("\nparameter elimination:")
print("  x(u) =",xpar)
print("  y(u) =",ypar)
print("  implicit =",implicit)
print("  substitution =",sp.factor(implicit.subs(
    {sp.Symbol("X"):xpar,sp.Symbol("Y"):ypar})))

print("\nweighted monomials of weight <= 12 for wt(x)=2, wt(y)=3:")
mons=[]
for i in range(10):
    for j in range(7):
        w=2*i+3*j
        if w<=12:
            mons.append((w,i,j))
for w,i,j in sorted(mons):
    print(f"  weight={w:2d}: x^{i} y^{j}")
运行结果 y^3+y=x 的 15 阶展开与有理参数消元
implicit curve y^3+y=x at (0,0)
  coefficient method: -7752*t**15 + 1428*t**13 - 273*t**11 + 55*t**9 - 12*t**7 + 3*t**5 - t**3 + t
  Newton method     : -7752*t**15 + 1428*t**13 - 273*t**11 + 55*t**9 - 12*t**7 + 3*t**5 - t**3 + t
  equal through t^15: True
  residual          : 0

Newton precision log:
  t^1 -> t^2: y=t
     residual=0
  t^2 -> t^4: y=-t**3 + t
     residual=0
  t^4 -> t^8: y=-12*t**7 + 3*t**5 - t**3 + t
     residual=0
  t^8 -> t^16: y=-7752*t**15 + 1428*t**13 - 273*t**11 + 55*t**9 - 12*t**7 + 3*t**5 - t**3 + t
     residual=0

tangent data:
  TangentData(point=(0, 0), jacobian=(0, 0), tangent_vector=(0, 0), smooth=False)
  TangentData(point=(1, sqrt(2)), jacobian=(-7, 2*sqrt(2)), tangent_vector=(2*sqrt(2), 7), smooth=True)
  TangentData(point=(1, -sqrt(2)), jacobian=(-7, -2*sqrt(2)), tangent_vector=(-2*sqrt(2), 7), smooth=True)

parameter elimination:
  x(u) = u**2 - 1
  y(u) = u*(u**2 - 1)
  implicit = X**3 + X**2 - Y**2
  substitution = 0

weighted monomials of weight <= 12 for wt(x)=2, wt(y)=3:
  weight= 0: x^0 y^0
  weight= 2: x^1 y^0
  weight= 3: x^0 y^1
  weight= 4: x^2 y^0
  weight= 5: x^1 y^1
  weight= 6: x^0 y^2
  weight= 6: x^3 y^0
  weight= 7: x^2 y^1
  weight= 8: x^1 y^2
  weight= 8: x^4 y^0
  weight= 9: x^0 y^3
  weight= 9: x^3 y^1
  weight=10: x^2 y^2
  weight=10: x^5 y^0
  weight=11: x^1 y^3
  weight=11: x^4 y^1
  weight=12: x^0 y^4
  weight=12: x^3 y^2
  weight=12: x^6 y^0
计算 奇点与规范方向

曲线 y^2=x^3+x^4 在原点的两偏导均为 0,切空间维数为 2,不能直接应用一元形式隐函数定理。参数 x=u^2-1、y=u(u^2-1) 消去 u 得 X^3+X^2-Y^2=0;代回严格为 0。加权坐标 wt(x)=2、wt(y)=3 时,权不超过 18 的单项式表可直接用于加权齐次截断与规范化。

Lecture 13 / 第 13 讲

亏格 0055 的曲线模型与典范嵌入

按亏格选择适合计算的模型,并用 Riemann–Roch 和典范环恢复方程。

亏格典范嵌入Riemann–Roch

1. Riemann–Roch 是模型选择器

定理Riemann–Roch

对光滑射影曲线 CC 上的除子 DD

(D)(KD)=degD+1g.\ell(D)-\ell(K-D)=\deg D+1-g.

degD2g1\deg D\ge2g-1 时,(D)=degD+1g\ell(D)=\deg D+1-g

计算函数时,不应盲目设高次一般多项式,而应先选一个低次数除子 DD,计算 L(D)L(D) 的基,再由基函数之间的代数关系得到模型。

2. 低亏格速查

亏格典型模型计算提示
0有理曲线或无理点圆锥曲线有一个有理点时参数化为 𝐏1\mathbf P^1
1带基点的平面三次曲线化为 Weierstrass 方程并使用群律
2总是超椭圆y2=f5(x)y^2=f_5(x)f6(x)f_6(x)
3超椭圆,或平面四次曲线非超椭圆时典范映射嵌入 𝐏2\mathbf P^2
4非超椭圆典范曲线在 𝐏3\mathbf P^3通常为一个二次曲面与一个三次曲面的完全交
5典范曲线在 𝐏4\mathbf P^4非三角曲线通常由三个二次方程切出;三角情形位于有理正规滚动面

3. 典范环中的关系

取全纯微分基 ω1,,ωg\omega_1,\ldots,\omega_g。二次关系是乘法映射

Sym2H0(C,K)H0(C,2K)\operatorname{Sym}^2H^0(C,K)\longrightarrow H^0(C,2K)

的核。由维数计算,非超椭圆一般曲线的二次关系数为 (g2)(g3)/2(g-2)(g-3)/2;超椭圆曲线会出现更多关系,这是计算识别的重要判据。

证明维数计数

dimSym2H0(K)=g(g+1)/2\dim\operatorname{Sym}^2H^0(K)=g(g+1)/2,而 dimH0(2K)=3g3\dim H^0(2K)=3g-3。若乘法映射满射,其核维数为 g(g+1)/2(3g3)=(g2)(g3)/2g(g+1)/2-(3g-3)=(g-2)(g-3)/2

算法由级数展开恢复曲线
  1. 在一个已知点选局部参数 qq,计算微分的充分多项展开。
  2. 列出次数 dd 的单项式并展开。
  3. 线性代数寻找关系。
  4. 用除子次数界证明“足够多项系数相等”蕴含全局恒等。
  5. 检查模型光滑性、亏格和基点。

为什么要系统处理亏格 0055

早先的 Belyi 例子刻意让源曲线为有理曲线,但一般覆盖的源曲线可能有正亏格。为了写出这些曲线及其有理函数,需要根据亏格选择合适模型。亏格 5 是一个自然分界:一般非超椭圆曲线的典范模型仍是射影空间中的完全交——在 𝐏4\mathbf P^4 中由三个二次方程切出。亏格 4 是 𝐏3\mathbf P^3 中一个二次曲面与一个三次曲面的交;亏格 3 是平面四次曲线。除了超椭圆情形,这些描述给出一般曲线的显式模型。

亏格 0:圆锥曲线与有理参数

在代数闭域上,光滑亏格 0 曲线同构于 𝐏1\mathbf P^1。在非代数闭域 KK 上,它可能是没有 KK-有理点的 Severi–Brauer 圆锥曲线。只要找到一个 KK-点,过该点作直线便得到有理参数化;没有点时不能把它擅自写成单参数 xx。计算覆盖时,源曲线的亏格为 0 并不自动意味着存在定义域上的有理坐标。

亏格 1:曲线与椭圆曲线的区别

光滑亏格 1 曲线只有在选定一个有理点作为原点后才成为椭圆曲线。没有有理点时它是其 Jacobian 的挠子。一个次数 3 的有理除子类给出平面三次模型;次数 2 的除子类给出到某圆锥曲线的双覆盖。实际计算中,Belyi 分支纤维中若有一个唯一的简单点,常自动提供次数 1 除子,从而选出椭圆曲线结构。

亏格 2 与超椭圆模型

每条亏格 2 曲线都是超椭圆曲线。特征不为 2 时可写

y2=f5(x)y2=f6(x),y^2=f_5(x)\quad\text{或}\quad y^2=f_6(x),

其中 ff 平方自由。奇数次数模型有一个无穷远点;偶数次数模型通常有两个。两种模型可经 Möbius 变换互换,前提是选定一个 Weierstrass 点送到无穷远。

亏格 3:平面四次与超椭圆例外

非超椭圆亏格 3 曲线的典范线性系给出 𝐏2\mathbf P^2 中光滑四次曲线。若典范微分 ω1,ω2,ω3\omega_1,\omega_2,\omega_3 满足一个二次关系,则曲线是超椭圆,典范像是一条圆锥曲线而非嵌入。这个二次关系还给出超椭圆商 C/ιC/\langle\iota\rangle 的模型;在基域上该圆锥曲线未必有有理点。

亏格 4 与 5 的典范理想

非超椭圆亏格 4 曲线典范嵌入 𝐏3\mathbf P^3,其理想中有唯一二次方程;再加一个三次方程切出曲线。若二次曲面光滑,它的两族直线对应两种 g31g^1_3;若为锥面,则通常只有一种三角结构。

非超椭圆亏格 5 曲线的二次关系空间维数为

(62)(353)=1512=3.\binom{6}{2}-(3\cdot5-3)=15-12=3.

一般情形下三个二次曲面完全交出次数 8=2g28=2g-2 的典范曲线。若曲线三角或含特殊线性系,这三个二次式的交还包含一个有理正规滚动面,必须加入更高次关系。

从微分展开恢复典范方程

选一个光滑点 PP 与局部参数 qq,把全纯微分写成

ωi=(n0ai,nqn)dq.\omega_i=\left(\sum_{n\ge0}a_{i,n}q^n\right)dq.

ωi\omega_i 的二次、三次单项式作级数展开,解线性关系即可得到典范理想。要把数值或截断级数关系提升为证明,可利用:非零 mm-次典范截面的零除子次数为 m(2g2)m(2g-2),若展开消失阶超过此数,则截面必为零。

Petri 定理的计算含义

典范曲线的理想一般由二次式生成;例外主要是三角曲线与平面五次曲线。计算时先求二次关系的共同零点,检查是否已经是一维、次数 2g22g-2 的光滑曲线。若维数过大或含额外分量,再加入三次关系。这样比从一般高次方程开始显著减少未知数。

Riemann–Roch 空间是显式模型的统一语言

对光滑射影曲线 CC 与除子 DD,定义

L(D)={fK(C)×:(f)+D0}{0},(D)=dimL(D).L(D)=\{f\in K(C)^\times:(f)+D\ge0\}\cup\{0\}, \qquad \ell(D)=\dim L(D).

Riemann–Roch 定理给出

(D)(KCD)=degD+1g.\ell(D)-\ell(K_C-D)=\deg D+1-g.

degD2g1\deg D\ge2g-1 时,第二项为零,因此 (D)=degD+1g\ell(D)=\deg D+1-g。选取 L(D)L(D) 的基便得到映射 C𝐏(D)1C\to\mathbf P^{\ell(D)-1}。所有低亏格模型——圆锥、平面三次、超椭圆双覆盖、典范嵌入——都可视为对不同除子选择这一构造。

从函数域计算 Riemann–Roch 空间

若已有平面模型,可在每个允许极点处展开局部参数,把候选有理函数的主部限制转化为线性条件。代数函数域算法则利用整闭包、不同理想和分式理想计算 L(D)L(D)。得到基之后,枚举基元的单项式并做线性代数,可求映射像的齐次理想。每一步都应核对 Hilbert 多项式,以确认维数与次数。

典范环与 Petri 定理

典范环

R(C,KC)=n0H0(C,nKC)R(C,K_C)=\bigoplus_{n\ge0}H^0(C,nK_C)

编码曲线的全部典范模型。非超椭圆曲线由 |KC||K_C| 嵌入 𝐏g1\mathbf P^{g-1}。Petri 定理说明:除三角曲线与平面五次曲线等例外外,典范理想由二次方程生成。低亏格中这给出非常具体的计数:亏格 4 有一个典范二次式,并需一个三次式;亏格 5 的一般曲线有三个独立二次式,其交恰为曲线。

亏格 0 的下降障碍

圆锥 Q𝐏2Q\subset\mathbf P^2KK 上有点当且仅当相应四元数代数分裂。数值上找到复参数并不能证明存在 KK-参数。若无 KK-点,可在二次扩张上参数化,但下降回 KK 时覆盖函数必须满足 Galois 相容性。很多“系数无端进入二次域”的现象,实质是源圆锥没有基域有理点,而非覆盖本身需要更大模数域。

亏格 1 的 Jacobian 与挠子类

亏格 1 曲线 CC 的 Jacobian E=Pic0(C)E=\operatorname{Pic}^0(C) 总有原点,而 CCEE 的主齐次空间。其同构类位于 H1(K,E)H^1(K,E)。一个次数 nn 的有理除子类给出到 𝐏n1\mathbf P^{n-1} 的模型,但未必含有效的 KK-有理除子。计算 Belyi 映射时,分支纤维的 Galois 不变除子可降低挠子的周期;若得到实际有理点,才可把曲线转成 Weierstrass 方程。

超椭圆性的判定

g2g\ge2,曲线超椭圆当且仅当存在次数 2 的线性系 g21g^1_2。典范映射此时为到有理正规曲线的二对一映射。计算上可看典范理想:若典范像的次数为 g1g-1 而映射次数为 2,则是超椭圆;非超椭圆典范像次数为 2g22g-2。在正特征中还要排除不可分映射,并注意特征 2 的方程形式。

三角曲线与低次数线性系

非超椭圆曲线可能有次数 3 的映射到 𝐏1\mathbf P^1,称为三角曲线。亏格 4 时,典范模型所在唯一二次曲面若光滑,其两族直线给出两个 g31g^1_3;若二次曲面是锥,则通常只有一个。这个几何信息能把覆盖函数写成较低次数坐标组合,显著减小消元规模。

奇点、算术亏格与几何亏格

平面次数 dd 曲线的算术亏格为 (d1)(d2)/2(d-1)(d-2)/2。若模型有节点、尖点或更复杂奇点,几何亏格为

g=paPδP.g=p_a-\sum_P\delta_P.

因此“写出一条平面四次”并不自动意味着亏格 3;必须检查光滑性或计算正规化。覆盖函数在奇异模型上的零极点也应拉回正规化后计数,否则会误判分歧指数。

模型验证清单

一个显式低亏格模型应至少核对:齐次理想的维数与次数;Jacobian 判据下的光滑性;算术与几何亏格;典范微分空间维数;函数域扩张次数;目标函数的零极除子;以及模型坐标变换是否在声明的基域上定义。若模型来自数值恢复,还应比较多个良素数上的约化点数或 zeta 函数作为独立指纹。

计算专题:低亏格模型之间的转换

同一曲线常有多个模型。亏格 1 的平面三次若有有理点,可通过切线选局部参数,把 L(2O),L(3O)L(2O),L(3O) 的基构造为 Weierstrass 坐标;反向则由 |3O||3O| 嵌入为平面三次。转换公式应保留有理逆映射,而不仅是 birational 声明,因为覆盖函数要随之搬运。

亏格 2 曲线的偶次超椭圆模型可通过选择一个 Weierstrass 点并作 Möbius 变换化为奇次;若该点不在基域,转换只在扩张上。二次扭曲 dy2=f(x)dy^2=f(x) 在代数闭包同构,却可改变有理点和覆盖下降,不能为简化系数随意忽略。

亏格 3 平面四次若有奇点,其正规化可能是亏格 2、1 或 0。要从参数方程恢复隐式四次,需检查映射是否双有理;若参数化次数大于 1,隐式像的亏格与源不同。典范微分拉回提供一个方便判据:若拉回空间维数和关系吻合,通常可确认典范模型。

亏格 4 的唯一二次曲面 QQ 决定三角结构。若 QQ 光滑且在基域分裂为 𝐏1×𝐏1\mathbf P^1\times\mathbf P^1,两条 ruling 给出两个三次映射;若不分裂,映射可能只在二次扩张上存在。判别 QQ 的判别式平方类可预知这一下降问题。

亏格 5 的三个二次式若交含额外曲面分量,说明曲线属于三角或平面五次例外,不能直接视为完全交。可计算二次理想的饱和和 syzygy;一般曲线的三个二次式正则序列,Hilbert 多项式给次数 8、亏格 5。

模型最小化不仅追求小系数,还要保持整模型良好。可对坐标格做 LLL 约化、最小化判别式、选择小高度除子。每次变换后重算函数除子与分支纤维;一个对曲线良好的模型未必让覆盖函数也简洁,常需在两者之间折中。

练习与解答低亏格模型

练习 1。亏格 3 非超椭圆曲线典范像为何是平面四次?

解。典范空间维数 3,映入 𝐏2\mathbf P^2;典范除子次数 2g2=42g-2=4,嵌入像次数为 4。

练习 2。平面五次有一个普通二重点时正规化亏格是多少?

解。算术亏格 6,普通节点 δ=1\delta=1,故几何亏格 5。

练习 3。亏格 0 曲线何时可在基域参数化?

解。当且仅当有基域有理点;过该点的直线束给出与 𝐏1\mathbf P^1 的同构。

深入补充:典范理想的维数公式与亏格四、五的精确模型

CC 为亏格 g2g\ge2 的光滑非超椭圆曲线。典范映射把 CC 嵌入 𝐏g1\mathbf P^{g-1}。典范理想中二次关系的数目可只用 Riemann–Roch 计算:

dimSym2H0(KC)=g(g+1)2,\dim\operatorname{Sym}^2H^0(K_C)=\frac{g(g+1)}2,

h0(2KC)=deg(2KC)g+1=3g3.h^0(2K_C)=\deg(2K_C)-g+1=3g-3.

若二次乘法映射满射,则二次关系空间维数为

g(g+1)2(3g3)=(g2)(g3)2.\frac{g(g+1)}2-(3g-3)=\frac{(g-2)(g-3)}2.
定理 亏格四的典范模型

亏格 44 的非超椭圆曲线典范嵌入于 𝐏3\mathbf P^3,其理想含唯一独立二次曲面 QQ;曲线是

C=V(Q,F3)C=V(Q,F_3)

的完全交,其中 F3F_3 为三次曲面。若 QQ 光滑,则其两族直线分别给出可能的 g31g^1_3;若 QQ 为锥,曲线具有唯一三角线性系。

次数核对为 degC=2g2=6=23\deg C=2g-2=6=2\cdot3。伴随公式给

KC=(K𝐏3+2H+3H)|C=H|C,K_C=(K_{\mathbf P^3}+2H+3H)|_C=H|_C,

确认此嵌入确为典范嵌入。

定理 亏格五的非三角情形

亏格 55 的非超椭圆、非三角曲线典范嵌入于 𝐏4\mathbf P^4,其理想由三条独立二次式生成,并且

C=V(Q1,Q2,Q3)C=V(Q_1,Q_2,Q_3)

是三个二次超曲面的完全交。其次数为 8=2g28=2g-2,与 232^3 一致。

若曲线是三角的,三个二次式的交不再只是曲线,而包含承载 g31g^1_3 的有理正规滚动面;此时还需三次关系切出曲线。Petri 定理精确描述这个例外:除三角曲线和光滑平面五次曲线外,非超椭圆典范理想由二次式生成。

算法 从微分级数恢复典范理想

取典范微分基 ω1,,ωg\omega_1,\ldots,\omega_g,在一个非 Weierstrass 点用局部参数展开。对次数 mm,列出所有单项式

ω1a1ωgag,ai=m,\omega_1^{a_1}\cdots\omega_g^{a_g},\qquad \sum a_i=m,

并把其级数系数排成矩阵。矩阵核就是乘法映射

SymmH0(KC)H0(mKC)\operatorname{Sym}^mH^0(K_C)\to H^0(mK_C)

的关系。取展开长度超过 h0(mKC)h^0(mK_C) 加未知数个数后,先数值或模素数求核,再精确重构并代入验证。

这个方法的维数检查十分刚性。亏格 33 非超椭圆时,二次关系数为零,首个关系是一个平面四次式;亏格 44 时恰有一个二次关系;亏格 55 时恰有三个。若计算得到更多二次关系,通常表示微分基线性相关、展开精度不足,或曲线模型存在未归一化奇点。

典范环的 Hilbert 函数为

h0(mKC)=(2m1)(g1)(m2).h^0(mK_C)=(2m-1)(g-1)\qquad(m\ge2).

因此可逐次数比较“自由多项式环中的单项式数”与“典范环目标维数”,确定何时必须出现新生成关系及 syzygy。对低亏格,这种纯线性代数方法比直接猜平面模型更可靠,因为它自动选择与曲线内在几何一致的坐标。

进一步计算专题:Brill–Noether 数、低次数线性系与典范滚动面

曲线是否具有低次数映射到 𝐏1\mathbf P^1,由线性系 gdrg^r_d 控制。Brill–Noether 数

ρ(g,r,d)=g(r+1)(gd+r)\rho(g,r,d)=g-(r+1)(g-d+r)

给出一般曲线上 WdrW^r_d 的预期维数。对 pencil gd1g^1_d

ρ(g,1,d)=2dg2.\rho(g,1,d)=2d-g-2.

ρ<0\rho<0,一般亏格 gg 曲线没有该线性系;出现它说明曲线位于模空间中的特殊子簇。

定理 pencil 在典范空间中扫出有理正规滚动面

设非超椭圆曲线 CC 有基点自由 gd1g^1_d。每个除子 DD 的典范像张成一个 𝐏d2\mathbf P^{d-2};当 DD 在 pencil 中变化时,这些线性空间扫出一个维数 d1d-1、次数

gd+1g-d+1

的有理正规滚动面 S𝐏g1S\subset\mathbf P^{g-1},并且 CSC\subset S

对三角曲线 d=3d=3,滚动面是二维。亏格 55 时其次数为 33,所以典范曲线位于 𝐏4\mathbf P^4 中的三次有理正规滚动面,而非三个二次式的零维完全交。三个典范二次关系先切出滚动面,额外三次关系再在滚动面上切出曲线。

滚动面的理想由一个 2×(gd+1)2\times(g-d+1) 矩阵的 2×22\times2 子式生成。对三角亏格五曲线,可寻找一个 2×32\times3 的线性形式矩阵

M=(123m1m2m3),M=\begin{pmatrix} \ell_1&\ell_2&\ell_3\\ m_1&m_2&m_3 \end{pmatrix},

使三个二次式为其 2×22\times2 子式。这个 determinantal 结构比任意二次生成元更强,可直接恢复三角 pencil。

切空间 Petri 映射与 WdrW^r_d

对线丛 LL,Petri 乘法映射为

μL:H0(L)H0(KCL1)H0(KC).\mu_L:H^0(L)\otimes H^0(K_C\otimes L^{-1}) \longrightarrow H^0(K_C).

WdrW^r_d[L][L] 处的切空间余维由 μL\mu_L 的秩控制。若 Petri 映射具有一般最大秩,则局部维数等于 ρ(g,r,d)\rho(g,r,d)

这把“是否有特殊线性系”化为微分乘法的线性代数。已知函数域时,可计算 H0(L)H^0(L)H0(KL)H^0(K-L) 的基,组成乘积矩阵;核给出滚动面关系,余核则检测 Petri 特殊性。

算法 从典范理想检测 gonality

先计算典范理想的最小自由解消或至少前两层 syzygy;寻找低秩线性 syzygy 生成的 determinantal 矩阵;由其最大子式定义候选滚动面;在滚动面上读取 ruling,限制到曲线得到 gd1g^1_d;最后用函数域次数验证映射 C𝐏1C\to\mathbf P^1 的度确为 dd 且无基点。

gonality 也可由 Riemann–Roch 搜索:对低次数有效除子 DD,计算 (D)\ell(D);首次出现 (D)2\ell(D)\ge2 的次数就是 gonality。但枚举除子在大有限域或数域上代价很高,典范 syzygy 方法更全局,并常直接给出映射公式。

对亏格 44,唯一典范二次曲面若光滑,则两族 ruling 给出两个 g31g^1_3;若是秩 33 的锥,仅有一个 ruling,给出唯一三角结构。因而只需计算该二次式的秩与判别式,就能从典范模型读出三角 pencil 的数目及定义域。若两族 ruling 只在二次扩张上分别定义,其和在基域上定义,但单个 g31g^1_3 可能存在下降障碍。

补充计算:典范环 Hilbert 函数、低亏格关系与加权单项式

定理 典范幂的维数与二次关系数

设 C 为亏格 \(g≥2\) 的光滑曲线。对 \(n≥2\), h0(C,KCn)=(2n1)(g1). h^0(C,K_C^n)=(2n-1)(g-1). 若 C 非超椭圆且典范映射为嵌入,则典范理想中二次关系空间维数为 (g+12)3(g1)=(g2)(g3)2. \binom{g+1}{2}-3(g-1)=\frac{(g-2)(g-3)}2. 亏格 4 的非超椭圆典范曲线是 \(P^3\) 中一张二次曲面与一张三次曲面的完全交;一般亏格 5 典范曲线由三张二次曲面截出。

证明 Riemann–Roch 与典范乘法映射的维数计算

\(n≥2\) 时 \(deg K^n=2n(g-1)>2g-2\),故 \(h^1(K^n)=h^0(K^{1-n})=0\)。Riemann–Roch 给出 \(h^0(K^n)=deg K^n+1-g=(2n-1)(g-1)\)。

二次齐次多项式空间为 \(Sym^2H^0(K)\),维数 binom(g+1,2)。非超椭圆典范环的二次乘法映射到 \(H^0(K^2)\);其核即二次关系。Noether 正规生成定理给出所需满射,故核维数为上式。\(g=4\) 时核维数 1,Hilbert 函数比较表明另需一个三次生成元;\(g=5\) 时核维数 3,三二次式完全交的次数 8、算术亏格 5 与典范曲线一致。

Python Hilbert 函数、平面奇点亏格修正与加权单项式枚举
from fractions import Fraction
from dataclasses import dataclass
from math import comb

def h0_canonical_power(g: int, n: int) -> int:
    if g < 2:
        raise ValueError("canonical model requires g>=2")
    if n == 0:
        return 1
    if n == 1:
        return g
    return (2*n-1)*(g-1)

def symmetric_power_dimension(g: int, n: int) -> int:
    return comb(g+n-1,n)

def canonical_relation_dimension(g: int, n: int) -> int | None:
    if g == 2:
        return None
    return symmetric_power_dimension(g,n)-h0_canonical_power(g,n)

def plane_curve_genus(degree: int) -> int:
    return (degree-1)*(degree-2)//2

def arithmetic_genus_plane(degree: int, delta_sum: int = 0) -> int:
    return plane_curve_genus(degree)-delta_sum

def riemann_roch_dimension(degree_D: int, genus: int,
                           h0_K_minus_D: int = 0) -> int:
    return degree_D + 1 - genus + h0_K_minus_D

@dataclass(frozen=True)
class CanonicalProfile:
    genus: int
    quadrics: int
    cubics_total_relations: int
    cubic_relations_mod_quadrics: int
    expected_model: str

def canonical_profile(g: int) -> CanonicalProfile:
    if g == 2:
        return CanonicalProfile(g,0,0,0,
            "hyperelliptic double cover of a conic; canonical ring needs degree 3")
    q=canonical_relation_dimension(g,2)
    c=canonical_relation_dimension(g,3)
    # Cubics generated by quadrics contribute at most g*q; syzygies may reduce.
    # For the low-genus generic cases use the standard Petri resolutions.
    if g==3:
        new_cubics=0
        model="plane quartic (nonhyperelliptic)"
    elif g==4:
        new_cubics=1
        model="quadric ∩ cubic in P^3"
    elif g==5:
        new_cubics=0
        model="intersection of three quadrics in P^4"
    else:
        new_cubics=max(0,c-g*q)
        model="canonical curve; inspect trigonal/plane-quintic exceptions"
    return CanonicalProfile(g,q,c,new_cubics,model)

def weighted_monomials(weights, total):
    out=[]
    def rec(i,remaining,exp):
        if i==len(weights)-1:
            if remaining%weights[i]==0:
                out.append(tuple(exp+[remaining//weights[i]]))
            return
        for e in range(remaining//weights[i]+1):
            rec(i+1,remaining-e*weights[i],exp+[e])
    rec(0,total,[])
    return out

def hyperelliptic_differential_orders(g: int):
    """
    For y^2=f(x), deg f=2g+1, at infinity:
    ord∞(x)=-2, ord∞(y)=-(2g+1), ord∞(dx)=-3.
    Thus ord∞(x^i dx/y)=2g-2-2i.
    """
    return [(i,2*g-2-2*i) for i in range(g)]

def canonical_hilbert_series_coeffs(g: int, upto: int):
    return [h0_canonical_power(g,n) for n in range(upto+1)]

print("canonical relation table:")
for g in range(2,7):
    profile=canonical_profile(g)
    print(
        f"  g={g}: quadrics={profile.quadrics:3d}, "
        f"cubic_rel={profile.cubics_total_relations:3d}, "
        f"new_cubics={profile.cubic_relations_mod_quadrics:2d}, "
        f"{profile.expected_model}"
    )

print("\nHilbert functions H^0(C,K^n):")
for g in range(2,7):
    coeffs=canonical_hilbert_series_coeffs(g,7)
    print(f"  g={g}: {coeffs}")

print("\nplane model genus corrections:")
for degree,delta in [(3,0),(4,0),(4,1),(5,0),(5,3),(6,4),(7,10)]:
    print(
        f"  degree={degree}, arithmetic={(degree-1)*(degree-2)//2}, "
        f"delta={delta}, geometric={arithmetic_genus_plane(degree,delta)}"
    )

print("\nhyperelliptic canonical differential orders:")
for g in range(2,7):
    print(f"  g={g}: {hyperelliptic_differential_orders(g)}")

print("\nweighted degree-12 monomials for weights (1,1,2,3):")
variables=("x0","x1","y","z")
degree12 = weighted_monomials((1,1,2,3),12)
print(f"  total={len(degree12)}; first 12 monomials:")
for exps in degree12[:12]:
    mon="".join(
        v if e==1 else (f"{v}^{e}" if e else "")
        for v,e in zip(variables,exps)
    ) or "1"
    print(f"  {exps}: {mon}")

print("\nRiemann-Roch nonspecial range:")
for g in range(2,7):
    rows=[]
    for d in range(2*g-1,2*g+5):
        rows.append((d,riemann_roch_dimension(d,g,0)))
    print(f"  g={g}: {rows}")

print("\ncanonical-ring dimension ledger for 2 <= g <= 5 and 0 <= n <= 3:")
for g in range(2,6):
    profile=canonical_profile(g)
    for n in range(0,4):
        h0=h0_canonical_power(g,n)
        sym=symmetric_power_dimension(g,n)
        rel=None if g==2 else sym-h0
        degK=0 if n==0 else n*(2*g-2)
        print(f"  g={g:2d} n={n:2d} deg(nK)={degK:4d} "
              f"h0(nK)={h0:8d} Sym^n={sym:14d} "
              f"kernel={str(rel):>14s} model={profile.expected_model}")
运行结果 亏格 2 至 8 的典范关系表与权 12 单项式全集
canonical relation table:
  g=2: quadrics=  0, cubic_rel=  0, new_cubics= 0, hyperelliptic double cover of a conic; canonical ring needs degree 3
  g=3: quadrics=  0, cubic_rel=  0, new_cubics= 0, plane quartic (nonhyperelliptic)
  g=4: quadrics=  1, cubic_rel=  5, new_cubics= 1, quadric ∩ cubic in P^3
  g=5: quadrics=  3, cubic_rel= 15, new_cubics= 0, intersection of three quadrics in P^4
  g=6: quadrics=  6, cubic_rel= 31, new_cubics= 0, canonical curve; inspect trigonal/plane-quintic exceptions

Hilbert functions H^0(C,K^n):
  g=2: [1, 2, 3, 5, 7, 9, 11, 13]
  g=3: [1, 3, 6, 10, 14, 18, 22, 26]
  g=4: [1, 4, 9, 15, 21, 27, 33, 39]
  g=5: [1, 5, 12, 20, 28, 36, 44, 52]
  g=6: [1, 6, 15, 25, 35, 45, 55, 65]

plane model genus corrections:
  degree=3, arithmetic=1, delta=0, geometric=1
  degree=4, arithmetic=3, delta=0, geometric=3
  degree=4, arithmetic=3, delta=1, geometric=2
  degree=5, arithmetic=6, delta=0, geometric=6
  degree=5, arithmetic=6, delta=3, geometric=3
  degree=6, arithmetic=10, delta=4, geometric=6
  degree=7, arithmetic=15, delta=10, geometric=5

hyperelliptic canonical differential orders:
  g=2: [(0, 2), (1, 0)]
  g=3: [(0, 4), (1, 2), (2, 0)]
  g=4: [(0, 6), (1, 4), (2, 2), (3, 0)]
  g=5: [(0, 8), (1, 6), (2, 4), (3, 2), (4, 0)]
  g=6: [(0, 10), (1, 8), (2, 6), (3, 4), (4, 2), (5, 0)]

weighted degree-12 monomials for weights (1,1,2,3):
  total=102; first 12 monomials:
  (0, 0, 0, 4): z^4
  (0, 0, 3, 2): y^3z^2
  (0, 0, 6, 0): y^6
  (0, 1, 1, 3): x1yz^3
  (0, 1, 4, 1): x1y^4z
  (0, 2, 2, 2): x1^2y^2z^2
  (0, 2, 5, 0): x1^2y^5
  (0, 3, 0, 3): x1^3z^3
  (0, 3, 3, 1): x1^3y^3z
  (0, 4, 1, 2): x1^4yz^2
  (0, 4, 4, 0): x1^4y^4
  (0, 5, 2, 1): x1^5y^2z

Riemann-Roch nonspecial range:
  g=2: [(3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7)]
  g=3: [(5, 3), (6, 4), (7, 5), (8, 6), (9, 7), (10, 8)]
  g=4: [(7, 4), (8, 5), (9, 6), (10, 7), (11, 8), (12, 9)]
  g=5: [(9, 5), (10, 6), (11, 7), (12, 8), (13, 9), (14, 10)]
  g=6: [(11, 6), (12, 7), (13, 8), (14, 9), (15, 10), (16, 11)]

canonical-ring dimension ledger for 2 <= g <= 5 and 0 <= n <= 3:
  g= 2 n= 0 deg(nK)=   0 h0(nK)=       1 Sym^n=             1 kernel=          None model=hyperelliptic double cover of a conic; canonical ring needs degree 3
  g= 2 n= 1 deg(nK)=   2 h0(nK)=       2 Sym^n=             2 kernel=          None model=hyperelliptic double cover of a conic; canonical ring needs degree 3
  g= 2 n= 2 deg(nK)=   4 h0(nK)=       3 Sym^n=             3 kernel=          None model=hyperelliptic double cover of a conic; canonical ring needs degree 3
  g= 2 n= 3 deg(nK)=   6 h0(nK)=       5 Sym^n=             4 kernel=          None model=hyperelliptic double cover of a conic; canonical ring needs degree 3
  g= 3 n= 0 deg(nK)=   0 h0(nK)=       1 Sym^n=             1 kernel=             0 model=plane quartic (nonhyperelliptic)
  g= 3 n= 1 deg(nK)=   4 h0(nK)=       3 Sym^n=             3 kernel=             0 model=plane quartic (nonhyperelliptic)
  g= 3 n= 2 deg(nK)=   8 h0(nK)=       6 Sym^n=             6 kernel=             0 model=plane quartic (nonhyperelliptic)
  g= 3 n= 3 deg(nK)=  12 h0(nK)=      10 Sym^n=            10 kernel=             0 model=plane quartic (nonhyperelliptic)
  g= 4 n= 0 deg(nK)=   0 h0(nK)=       1 Sym^n=             1 kernel=             0 model=quadric ∩ cubic in P^3
  g= 4 n= 1 deg(nK)=   6 h0(nK)=       4 Sym^n=             4 kernel=             0 model=quadric ∩ cubic in P^3
  g= 4 n= 2 deg(nK)=  12 h0(nK)=       9 Sym^n=            10 kernel=             1 model=quadric ∩ cubic in P^3
  g= 4 n= 3 deg(nK)=  18 h0(nK)=      15 Sym^n=            20 kernel=             5 model=quadric ∩ cubic in P^3
  g= 5 n= 0 deg(nK)=   0 h0(nK)=       1 Sym^n=             1 kernel=             0 model=intersection of three quadrics in P^4
  g= 5 n= 1 deg(nK)=   8 h0(nK)=       5 Sym^n=             5 kernel=             0 model=intersection of three quadrics in P^4
  g= 5 n= 2 deg(nK)=  16 h0(nK)=      12 Sym^n=            15 kernel=             3 model=intersection of three quadrics in P^4
  g= 5 n= 3 deg(nK)=  24 h0(nK)=      20 Sym^n=            35 kernel=            15 model=intersection of three quadrics in P^4
计算 超椭圆微分在无穷远的阶

对 y^2=f(x)、deg f=2g+1,唯一无穷远点满足 ord∞x=-2、ord∞y=-(2g+1)、ord∞dx=-3。因此 ord∞(x^i dx/y)=2g-2-2i, i=0,…,g-1 时均非负,恰给出 g 个线性无关正则微分。它们的典范像落在有理正常曲线上,说明亏格 2 及一般超椭圆情形不能直接使用非超椭圆的二次关系维数公式。

Lecture 14 / 第 14 讲

超椭圆曲线、椭圆曲线与显式函数

构造超椭圆模型,解释椭圆曲线群律、除子类和低次数函数。

超椭圆曲线椭圆曲线除子

1. 超椭圆曲线

定义超椭圆曲线

亏格 g2g\ge2 的曲线若存在次数 2 的映射 C𝐏1C\to\mathbf P^1,称为超椭圆曲线。在特征不为 2 时可写为 y2=f(x)y^2=f(x),其中 ff 平方自由且次数为 2g+12g+12g+22g+2

全纯微分可取

dxy,xdxy,,xg1dxy.\frac{dx}{y},\frac{x\,dx}{y},\ldots,\frac{x^{g-1}dx}{y}.

分支点是 ff 的根;若次数为奇数,无穷远也是分支点。超椭圆对合为 (x,y)(x,y)(x,y)\mapsto(x,-y)

定理典范映射判据

g2g\ge2,曲线超椭圆当且仅当典范映射不是嵌入;此时典范映射是到一条有理正规曲线的 2 对 1 映射。

2. 从微分恢复模型

在一个有理点 PP 处选取按消失阶排列的微分 ω1,,ωg\omega_1,\ldots,\omega_g。典型地可取

x=ωg1ωg,y=dxωg.x=\frac{\omega_{g-1}}{\omega_g},\qquad y=\frac{dx}{\omega_g}.

然后用级数线性代数寻找 y2=f(x)y^2=f(x)。原课程以 X0(41)X_0(41) 为例得到一个次数 8 的模型,说明模形式的 qq-展开可以直接转化为代数曲线方程。

3. 亏格 1 与群律

带有基点 OO 的亏格 1 曲线是椭圆曲线。除子类映射 P[(P)(O)]P\mapsto[(P)-(O)] 给出 EPic0(E)E\cong\operatorname{Pic}^0(E)。三个点共线当且仅当它们的群和为 OO(按切线重数计)。

定义同源与挠点

椭圆曲线之间保持原点的非常值态射称为同源;它自动是有限群同态。满足 nP=OnP=O 的点称为 nn-挠点。特征不整除 nn 时,E[n](K¯)(𝐙/n𝐙)2E[n](\overline K)\cong(\mathbf Z/n\mathbf Z)^2

练习双覆盖的亏格

用Riemann–Hurwitz公式证明:𝐏1\mathbf P^1 的双覆盖若在 2g+22g+2 个点简单分支,则覆盖曲线亏格为 gg

超椭圆曲线的函数与微分

特征不为 2 时,超椭圆曲线写成 C:y2=f(x)C:y^2=f(x),其中 ff 平方自由,次数 2g+12g+12g+22g+2。超椭圆对合是 ι(x,y)=(x,y)\iota(x,y)=(x,-y),商映射由 xx 给出。全纯微分基为

dxy,xdxy,,xg1dxy.\frac{dx}{y},\frac{x\,dx}{y},\ldots,\frac{x^{g-1}dx}{y}.

若基域特征为 2,则应使用 y2+h(x)y=f(x)y^2+h(x)y=f(x) 的一般形式;直接写 y2=f(x)y^2=f(x) 会失去可分性信息。

从典范微分恢复亏格 3 超椭圆模型

一般亏格 3 超椭圆曲线的商圆锥 C0C_0 由三个全纯微分满足的唯一二次关系给出。即使 C0C_0 在基域上没有有理参数,也可以选两个微分之比,例如 x=ω2/ω3x=\omega_2/\omega_3,并定义反对合函数

y=dxω3.y=\frac{dx}{\omega_3}.

由于分母相同,yy 只在 xx 的极点上有二重极点。于是 (ω32y)2(\omega_3^2y)^2 是三个 ωi\omega_i 的四次齐次式,从而得到定义在原基域上的双覆盖方程。这个构造避免了先给圆锥找有理点。

椭圆曲线的广义 Weierstrass 方程

带原点的亏格 1 曲线可写为

y2+a1xy+a3y=x3+a2x2+a4x+a6.y^2+a_1xy+a_3y=x^3+a_2x^2+a_4x+a_6.

允许的坐标变换为

x=u2x+r,y=u3y+su2x+t,x=u^2x'+r,\qquad y=u^3y'+su^2x'+t,

其中 u0u\ne0。变量 x,yx,y 在原点的极点阶分别为 2、3,因此 L(nO)L(nO) 可由极点阶不超过 nn 的单项式迅速列出。例如

L(5O)=1,x,y,x2,xy.L(5O)=\langle1,x,y,x^2,xy\rangle.

这正是构造次数 5 Weil 函数时使用的空间。

除子类与群律

映射

EPic0(E),P[(P)(O)]E\longrightarrow\operatorname{Pic}^0(E),\qquad P\longmapsto[(P)-(O)]

是群同构。因此次数零除子 ni(Pi)\sum n_i(P_i) 为主除子,当且仅当 niPi=O\sum n_iP_i=Oni=0\sum n_i=0。由此,存在函数 ff 满足

(f)=n(T)n(O)(f)=n(T)-n(O)

当且仅当 nT=OnT=O。这种函数称为与挠点 TT 相关的 Weil 函数,只在乘非零常数的意义下唯一。

对数微分与分支点约束

对任意非常值函数 ff,对数微分 df/fdf/fff 的每个零点和极点处有简单极点;若 fλf-\lambda 在某点有 mm 重零且 λ0,\lambda\ne0,\infty,则 df/fdf/f 在该点有 m1m-1 重零。因为 df/fdf/f 是亚纯微分,其除子属于典范类。这给出额外的 Jacobian 关系,常能在仅凭分歧纤维不足时确定剩余点的位置。

模型最小化与结构可见性

椭圆曲线软件可把方程化为全局最小模型,便于比较同构类、查表与计算导子。但最小模型不一定最适合显式函数:它可能把指定挠点从 (0,0)(0,0) 移走,使 Weil 函数变得复杂。课程主张保留能展示几何结构的模型,并同时记录一个标准最小模型用于识别。

超椭圆曲线无穷远点的局部结构

y2=f2g+1(x)y^2=f_{2g+1}(x),射影光滑化只有一个无穷远 Weierstrass 点 PP_\infty,且

ordP(x)=2,ordP(y)=(2g+1).\operatorname{ord}_{P_\infty}(x)=-2, \qquad \operatorname{ord}_{P_\infty}(y)=-(2g+1).

degf=2g+2\deg f=2g+2,通常有两个无穷远点,各处 xx 为一阶极点、yyg+1g+1 阶极点。这个差别直接影响 Riemann–Roch 基、除子类和函数的次数,不能在算法中把奇次与偶次模型混用。

Jacobian 的 Mumford 表示

超椭圆 Jacobian 的一般除子类可唯一约化为

D=(u(x),v(x)),u首一,degv<degug,uv2f.D=(u(x),v(x)), \qquad u\text{首一},\quad \deg v<\deg u\le g, \quad u\mid v^2-f.

它代表 i(PiP)\sum_i(P_i-P_\infty),其中 u(x)=i(xx(Pi))u(x)=\prod_i(x-x(P_i))v(x(Pi))=y(Pi)v(x(P_i))=y(P_i)。Cantor 算法通过多项式 gcd、合成和约化实现群律。对覆盖问题,这使高亏格源曲线上除子关系的检验变成精确多项式运算。

Weierstrass 方程的不变量

对广义 Weierstrass 方程,定义

b2=a12+4a2,b4=2a4+a1a3,b6=a32+4a6,b8=a12a6+4a2a6a1a3a4+a2a32a42,\begin{aligned} b_2&=a_1^2+4a_2,& b_4&=2a_4+a_1a_3,\\ b_6&=a_3^2+4a_6,& b_8&=a_1^2a_6+4a_2a_6-a_1a_3a_4+a_2a_3^2-a_4^2, \end{aligned}
c4=b2224b4,c6=b23+36b2b4216b6,c_4=b_2^2-24b_4, \qquad c_6=-b_2^3+36b_2b_4-216b_6,
Δ=b22b88b4327b62+9b2b4b6,j=c43/Δ.\Delta=-b_2^2b_8-8b_4^3-27b_6^2+9b_2b_4b_6, \qquad j=c_4^3/\Delta.

曲线光滑当且仅当 Δ0\Delta\ne0。在允许变换下,c4,c6,Δc_4,c_6,\Delta 分别按 u4,u6,u12u^{-4},u^{-6},u^{-12} 缩放,因此 jj 不变。把模型化简时应同步记录这些量,以防坐标变换或分母清除引入错误。

弦切群律的代数公式

在短 Weierstrass 模型 y2=x3+Ax+By^2=x^3+Ax+B 上,若 P=(x1,y1)P=(x_1,y_1)Q=(x2,y2)Q=(x_2,y_2)P±QP\ne\pm Q,令

λ=y2y1x2x1,x3=λ2x1x2,y3=y1+λ(x1x3).\lambda=\frac{y_2-y_1}{x_2-x_1}, \quad x_3=\lambda^2-x_1-x_2, \quad y_3=-y_1+\lambda(x_1-x_3).

P+Q=(x3,y3)P+Q=(x_3,y_3)。倍点时 λ=(3x12+A)/(2y1)\lambda=(3x_1^2+A)/(2y_1)。这些公式不仅用于点运算,也用于从除子条件构造函数:过三点的直线除子给出 (P)+(Q)+(PQ)3(O)(P)+(Q)+(-P-Q)-3(O)

除子与函数空间的显式基

在椭圆曲线上,(nO)=n\ell(nO)=nn1n\ge1。按极点阶排序可取

1,x,y,x2,xy,x3,yx2,1,\frac{}{}x,y,x^2,xy,x^3,yx^2,\ldots

其中利用曲线方程把 y2y^2 消成 xx 的多项式。要找除子为 n(T)n(O)n(T)-n(O) 的 Weil 函数,可在 L(nO)L(nO) 中令函数在 TT 处消失到 nn 阶;这给出线性条件,非零解在标量倍意义下唯一。

挠点与除法多项式

短 Weierstrass 模型上存在除法多项式 ψn\psi_n,其非零根的 xx-坐标正是非零 nn-挠点的 xx-坐标。它们满足递推,例如

ψ2=2y,ψ3=3x4+6Ax2+12BxA2,\psi_2=2y, \qquad \psi_3=3x^4+6Ax^2+12Bx-A^2,

以及奇偶递推公式。Tate 正规形是在“指定一个点为 nn-挠点”这一模问题下,比直接令 ψn(x(T))=0\psi_n(x(T))=0 更有效的坐标选择,因为它预先消除了大量坐标自由度。

最小模型与局部约化

在数域或函数域上,一个 Weierstrass 方程可能不是最小模型。对每个离散赋值,可通过允许变换降低 v(Δ)v(\Delta);全局最小模型则需兼容各处。覆盖的分支与椭圆曲线纤维类型常依赖最小判别式,而不是任意方程的判别式。若把公共因子简单除掉而未检查允许变换,可能改变积分结构或漏掉加性约化。

特征 2 与 3 的额外注意

短方程 y2=x3+Ax+By^2=x^3+Ax+B 只在特征不为 2、3 时普遍可用。模小素数验证时必须保留广义方程。否则判别式公式、2-挠点描述和切线斜率都会退化。选择验证素数时,通常先避开模型分母、群阶和判别式的素因子,再单独研究坏素数。

计算专题:除子运算与有理函数构造

给定曲线上两个等价有效除子 D0,DD_0,D_\infty,寻找 ff 使 (f)=D0D(f)=D_0-D_\infty 可转为 Riemann–Roch 线性代数:计算 L(D)L(D_\infty),再施加在 D0D_0 各点的消失阶条件。若解空间一维,函数在标量倍意义下唯一;再用一个普通点或分支值规范标量。

在椭圆曲线上,除子 ni(Pi)m(O)\sum n_i(P_i)-m(O) 为主除子当且仅当总次数为零且 niPi=O\sum n_iP_i=O(群律求和)。这把函数存在性化成点加法。实际构造可把直线函数 P,Q\ell_{P,Q} 与垂直线函数组合;Miller 算法递归计算除子为 n(P)n(O)n(P)-n(O) 加修正的函数,是 Weil/Tate 配对的核心。

超椭圆曲线上用 Mumford 表示做除子加法后,可通过“函数伴随”版本的 Cantor 算法同时追踪实现等价的有理函数。对 Belyi 映射验证,这比把所有点坐标扩展到巨大数域后逐点相乘更高效。

局部消失阶可通过曲线局部参数计算,也可在局部环中用理想幂测试。若点由不可约多项式定义,直接在其剩余域中展开;对奇异仿射模型必须先在正规化分支上计算,Jacobian 理想中的代数重数不等于曲线点的赋值。

椭圆曲线上的函数可用 x,yx,y 的极点阶基表示。给定极点除子 mOmO,单项式筛选规则是 2i+3jm2i+3j\le mj{0,1}j\in\{0,1\}。在一般广义 Weierstrass 方程中仍可用曲线方程把 y2y^2 降阶。线性条件矩阵最好在精确数域或模素数上构造。

函数得到后,应计算其 degree:极点除子总次数;检查零极除子度相同;用微分求 ramification;若函数表达有分子分母公共零,先在函数域中约去而非仅在多项式环中约去。这样可避免基点导致的错误次数。

练习与解答椭圆除子

练习 1。证明 (xx(P))=(P)+(P)2(O)(x-x(P))=(P)+(-P)-2(O)(非 2-挠一般点)。

解。竖直线 x=x(P)x=x(P) 与曲线交于 P,PP,-P,而 xx 在无穷远有二阶极点。

练习 2。为什么 L(3O)=1,x,yL(3O)=\langle1,x,y\rangle

解。1,x,y1,x,y 极点阶为 0、2、3,线性独立;Riemann–Roch 给 (3O)=3\ell(3O)=3

练习 3。TTnn-挠点,为什么存在 (f)=n(T)n(O)(f)=n(T)-n(O)

解。该次数零除子类在 Pic0(E)E\operatorname{Pic}^0(E)\cong E 中对应 nT=OnT=O,故为主除子。

深入补充:Mumford 表示、Cantor 约化与函数空间的显式基

考虑奇次数超椭圆曲线

C:y2=f(x),degf=2g+1,C:y^2=f(x),\qquad \deg f=2g+1,

其无穷远点记为 \infty。约化除子类可唯一表示为一对多项式 (u,v)(u,v),满足

u 首一,degv<degug,ufv2.u\text{ 首一},\quad \deg v<\deg u\le g, \quad u\mid f-v^2.

它代表除子

D=u(α)=0(α,v(α))deg(u).D=\sum_{u(\alpha)=0}(\alpha,v(\alpha))-\deg(u)\,\infty.
算法 互素情形的 Cantor 合成与约化

给定 (u1,v1)(u_1,v_1)(u2,v2)(u_2,v_2)gcd(u1,u2)=1\gcd(u_1,u_2)=1,用中国剩余定理求 vv 使

vv1(modu1),vv2(modu2),v\equiv v_1\pmod{u_1},\qquad v\equiv v_2\pmod{u_2},

u=u1u2u=u_1u_2。若 degu>g\deg u>g,计算

u=fv2uu' = \frac{f-v^2}{u}

并正规化为首一,再取 vv(modu)v'\equiv -v\pmod{u'}degv<degu\deg v'<\deg u'。反复执行直至 degug\deg u\le g。一般情形先处理 u1,u2,v1+v2u_1,u_2,v_1+v_2 的 gcd,以消去互为超椭圆对合的点。

约化步骤来自主除子。函数 yv(x)y-v(x) 的零点包含 u(x)=0u(x)=0 上的点,其余零点由 u=(fv2)/uu'=(f-v^2)/u 给出;把这些余点经对合 (x,y)(x,y)(x,y)\mapsto(x,-y) 后,得到与原除子线性等价、次数更小的代表。于是群律完全转化为多项式 gcd、CRT、除法和取余。

无穷远处有

ord(x)=2,ord(y)=(2g+1).\operatorname{ord}_\infty(x)=-2, \qquad \operatorname{ord}_\infty(y)=-(2g+1).

因此 Riemann–Roch 空间 L(m)L(m\infty) 有一个直接可写的基:

1,x,x2,,xm/21,x,x^2,\ldots,x^{\lfloor m/2\rfloor}

以及所有满足 2j+(2g+1)m2j+(2g+1)\le m

xjy.x^jy.

数一数这些单项式,在 m2g1m\ge2g-1 时恰得 mg+1m-g+1,与 Riemann–Roch 一致。

推论 用线性代数构造指定除子的函数

若要找极点受 mm\infty 限制、并在给定点 PiP_i 具有指定零阶的函数,只需在上述基中取未知线性组合,对 PiP_i 代入函数值及必要的局部导数,得到齐次线性方程组。非零核向量给出所求函数;其实际除子可再用 gcd 与局部参数精确验证。

这对构造 Belyi 或 Weil 函数尤其有效。先由目标零极点除子估计最小 mm,在 L(m)L(m\infty) 中求函数,再检查剩余临界值。与直接猜大次数分子分母相比,Riemann–Roch 基把未知数数目压到理论最小值,并自动尊重曲线关系 y2=f(x)y^2=f(x)

在偶次数模型 degf=2g+2\deg f=2g+2 中有两个无穷远点,极点阶的 bookkeeping 会改变;可先选择一个有理无穷远点做坐标变换转成奇次数模型,若两点不在定义域上,则应在二点除子 m(++)m(\infty_++\infty_-) 上计算。模型转换不能只在复数上完成,必须追踪定义域与两个无穷远点的 Galois 交换。

补充计算:椭圆群律、除法多项式与 Mumford 约化

定理 Mumford 表示的唯一约化形式

设 \(C:y^2=f(x)\) 为奇次数 2g+1 的光滑超椭圆曲线。Jac(C) 的每个除子类均有唯一约化表示 (u,v),其中 u 为首一多项式,\(deg v<deg u≤g\),且 ufv2. u\mid f-v^2. 互素情形下,两表示 \((u_1,v_1)\)、\((u_2,v_2)\) 的和先由多项式中国剩余定理解 \(v≡v_i (mod u_i)\),令 \(u=u_1u_2\),再反复替换 umonic(fv2u),vv(modu), u\leftarrow\operatorname{monic}\!\left(\frac{f-v^2}{u}\right),\qquad v\leftarrow -v\pmod u, 直至 \(deg u≤g\)。

证明 由半约化除子与无穷远线性等价完成约化

有效除子 \(D=P_1+···+P_r-r∞\) 在共轭点不同时由 \(u=∏(x-x(P_i))\) 和满足 \(v(x(P_i))=y(P_i)\) 的插值多项式编码,故 \(u|f-v^2\)。若 \(deg u>g\),函数 y-v 的零点包含 D,其剩余零点由 \((f-v^2)/u\) 给出;主除子 \(div(y-v)\) 表明 D 线性等价于剩余零点取超椭圆共轭后的除子,次数严格下降。重复后得到 \(deg u≤g\)。

若两个约化表示同类,其差为主除子。对无穷远极阶与 Riemann–Roch 维数比较可知,在次数不超过 g 的范围内不存在非平凡主除子把一个半约化有效除子变为另一个,故表示唯一。互素 \(u_i\) 时 CRT 正好合并两组点的 y 坐标条件,随后执行上述约化。

Python 有理椭圆曲线运算、ψ_n 递推与亏格二加法
from fractions import Fraction
from dataclasses import dataclass
import sympy as sp

x=sp.Symbol("x")

@dataclass(frozen=True)
class ECPoint:
    x: Fraction | None
    y: Fraction | None

    @property
    def infinity(self):
        return self.x is None

O=ECPoint(None,None)

@dataclass
class EllipticCurve:
    a: Fraction
    b: Fraction

    def discriminant(self):
        return -16*(4*self.a**3+27*self.b**2)

    def on_curve(self,P):
        return P.infinity or P.y*P.y==P.x**3+self.a*P.x+self.b

    def neg(self,P):
        return P if P.infinity else ECPoint(P.x,-P.y)

    def add(self,P,Q):
        if not self.on_curve(P) or not self.on_curve(Q):
            raise ValueError("point not on curve")
        if P.infinity: return Q
        if Q.infinity: return P
        if P.x==Q.x and P.y==-Q.y:
            return O
        if P==Q:
            if P.y==0: return O
            slope=(3*P.x*P.x+self.a)/(2*P.y)
        else:
            slope=(Q.y-P.y)/(Q.x-P.x)
        xr=slope*slope-P.x-Q.x
        yr=-P.y+slope*(P.x-xr)
        R=ECPoint(xr,yr)
        assert self.on_curve(R)
        return R

    def mul(self,n,P):
        if n<0: return self.mul(-n,self.neg(P))
        R=O
        Q=P
        while n:
            if n&1: R=self.add(R,Q)
            Q=self.add(Q,Q)
            n>>=1
        return R

def division_polynomials(a,b,nmax):
    """
    Return ψ_n for y^2=x^3+a*x+b.
    Odd ψ_n lie in Z[a,b,x]; even ψ_n are stored after dividing by 2y.
    Recurrences are evaluated in the coordinate ring with y^2 replaced.
    """
    y=sp.Symbol("y")
    f=x**3+a*x+b
    psi={
        0:sp.Integer(0),
        1:sp.Integer(1),
        2:2*y,
        3:3*x**4+6*a*x**2+12*b*x-a**2,
        4:4*y*(x**6+5*a*x**4+20*b*x**3
               -5*a**2*x**2-4*a*b*x-8*b**2-a**3),
    }
    def reduce_y(expr):
        expr=sp.expand(expr)
        poly=sp.Poly(expr,y)
        out=0
        for (e,),coef in poly.terms():
            out+=coef*(f**(e//2))*(y if e%2 else 1)
        return sp.expand(out)
    for n in range(5,nmax+1):
        if n%2:
            m=(n-1)//2
            val=psi[m+2]*psi[m]**3-psi[m-1]*psi[m+1]**3
        else:
            m=n//2
            numerator=psi[m]*(psi[m+2]*psi[m-1]**2
                              -psi[m-2]*psi[m+1]**2)
            val=sp.cancel(numerator/(2*y))
        psi[n]=sp.factor(reduce_y(val))
    return psi

def monic(poly):
    p=sp.Poly(poly,x,domain=sp.QQ)
    return sp.Poly(p.monic(),x,domain=sp.QQ)

@dataclass(frozen=True)
class Mumford:
    u: sp.Poly
    v: sp.Poly

def mumford_check(D,f,g):
    u=monic(D.u)
    v=sp.rem(D.v,u)
    divides=sp.rem(sp.Poly(f-v.as_expr()**2,x),u).is_zero
    return u.degree()<=g and v.degree()<u.degree() and divides

def crt_polynomials(a,m,b,n):
    """Solve v=a mod m, v=b mod n for coprime monic m,n."""
    s,t,h=sp.gcdex(m,n,x)
    if sp.degree(h,x)!=0:
        raise ValueError("moduli are not coprime")
    v=sp.rem(a*t*n+b*s*m,m*n,x)
    return sp.Poly(v,x,domain=sp.QQ)

def cantor_add_coprime(D1,D2,f,g):
    u1,u2=D1.u,D2.u
    if sp.degree(sp.gcd(u1,u2),x)>0:
        raise ValueError("this compact routine handles coprime u-polynomials")
    v=crt_polynomials(D1.v.as_expr(),u1.as_expr(),
                      D2.v.as_expr(),u2.as_expr())
    u=monic(u1.as_expr()*u2.as_expr())
    v=sp.rem(v,u)
    while u.degree()>g:
        quotient=sp.div(
            sp.Poly(f-v.as_expr()**2,x,domain=sp.QQ),u
        )
        if not quotient[1].is_zero:
            raise ArithmeticError("Mumford divisibility lost")
        u=monic(-quotient[0].as_expr())
        v=sp.rem(sp.Poly(-v.as_expr(),x),u)
    out=Mumford(u,sp.Poly(v,x))
    assert mumford_check(out,f,g)
    return out

E=EllipticCurve(Fraction(0),Fraction(-2))
P=ECPoint(Fraction(3),Fraction(5))
print("elliptic curve y^2=x^3-2")
print("  discriminant =",E.discriminant())
for n in range(1,9):
    Q=E.mul(n,P)
    print(f"  {n:2d}P = {Q}")

psi=division_polynomials(sp.Integer(0),sp.Integer(-2),9)
print("\ndivision polynomials:")
for n in range(1,7):
    expr=psi[n]
    print(f"  psi_{n}: degree_x={sp.degree(expr,x)}, terms={len(sp.expand(expr).as_ordered_terms())}")
    if n<=5:
        print("   ",expr)

f=x**5-x+1
g=2
D1=Mumford(sp.Poly(x,x),sp.Poly(1,x))
D2=Mumford(sp.Poly(x-1,x),sp.Poly(1,x))
D3=cantor_add_coprime(D1,D2,f,g)
print("\ngenus-2 Mumford addition on y^2=x^5-x+1:")
for name,D in [("D1",D1),("D2",D2),("D1+D2",D3)]:
    print(f"  {name}: u={D.u.as_expr()}, v={D.v.as_expr()}, check={mumford_check(D,f,g)}")

print("\nfunction-space pole orders at infinity for genus 2:")
basis=[]
for i in range(8):
    basis.append((2*i,f"x^{i}"))
for i in range(5):
    basis.append((5+2*i,f"x^{i}y"))
for order,name in sorted(basis):
    if order<=14:
        print(f"  pole order {order:2d}: {name}")
运行结果 y^2=x^3-2 上的倍点与亏格二除子核验
elliptic curve y^2=x^3-2
  discriminant = -1728
   1P = ECPoint(x=Fraction(3, 1), y=Fraction(5, 1))
   2P = ECPoint(x=Fraction(129, 100), y=Fraction(-383, 1000))
   3P = ECPoint(x=Fraction(164323, 29241), y=Fraction(-66234835, 5000211))
   4P = ECPoint(x=Fraction(2340922881, 58675600), y=Fraction(113259286337279, 449455096000))
   5P = ECPoint(x=Fraction(307326105747363, 160280942564521), y=Fraction(4559771683571581358275, 2029190552145716973931))
   6P = ECPoint(x=Fraction(794845361623184880769, 513127310073606144900), y=Fraction(-15230044576037327107200537568897, 11623520729117946174953656293000))
   7P = ECPoint(x=Fraction(49680317504529227786118937923, 3458519104702616679044719441), y=Fraction(-11069550171650699467350859369161931440285365, 203392656460831967707109939312836961532761))
   8P = ECPoint(x=Fraction(30037088724630450803382035538503505921, 3010683982898763071786842993779918400), y=Fraction(164455721751979625643914376686667695661898155872010593281, 5223934923525719974563641453744978655831227509874752000))

division polynomials:
  psi_1: degree_x=0, terms=1
    1
  psi_2: degree_x=0, terms=1
    2*y
  psi_3: degree_x=4, terms=2
    3*x**4 - 24*x
  psi_4: degree_x=6, terms=3
    4*y*(x**6 - 40*x**3 - 32)
  psi_5: degree_x=12, terms=5
    5*x**12 - 760*x**9 - 960*x**6 + 12800*x**3 - 4096
  psi_6: degree_x=16, terms=6

genus-2 Mumford addition on y^2=x^5-x+1:
  D1: u=x, v=1, check=True
  D2: u=x - 1, v=1, check=True
  D1+D2: u=x**2 - x, v=1, check=True

function-space pole orders at infinity for genus 2:
  pole order  0: x^0
  pole order  2: x^1
  pole order  4: x^2
  pole order  5: x^0y
  pole order  6: x^3
  pole order  7: x^1y
  pole order  8: x^4
  pole order  9: x^2y
  pole order 10: x^5
  pole order 11: x^3y
  pole order 12: x^6
  pole order 13: x^4y
  pole order 14: x^7
计算 除法多项式次数

短 Weierstrass 方程上,奇数 n 的 ψ_n 是 x 多项式,次数 (n^2-1)/2;偶数 n 的 ψ_n/(2y) 次数 (n^2-4)/2。点 P 的 nP=O 当且仅当 ψ_n(P)=0。程序得到 ψ_5=5x^12-760x^9-960x^6+12800x^3-4096,次数 12,与公式一致。

Lecture 15 / 第 15 讲

椭圆曲线上的 Weil–Belyi 函数与 5-挠点参数化

用除子和对数微分确定分支点,并推导带 5-挠点的 Tate 标准形。

Weil函数5挠点Tate标准形

1. 循环型 5,5,2215,5,221

f:E𝐏1f:E\to\mathbf P^1 的三个分支值上循环型为 5,5,2215,5,221。Riemann–Hurwitz给出 g(E)=1g(E)=1。把五重极点取为原点 OO,五重零点记为 TT,则

(f)=5(T)5(O).(f)=5(T)-5(O).

因此 5(TO)05(T-O)\sim0,即 TT 是非零 5-挠点;ff 是对应的 Weil 函数。

定理第三个简单原像的位置

(f1)0=(P)+2D(f-1)_0=(P)+2D,其中 degD=2\deg D=2,则 P=2TP=-2T

证明利用对数微分

df/fdf/fO,TO,T 有简单极点,在两个二重原像处各有一阶零,因此 (df/f)=D(O)(T)(df/f)=D-(O)-(T),故 D(O)+(T)D\sim(O)+(T)。另一方面 (P)+2D5(O)(P)+2D\sim5(O)。消去 DD(P)+2(T)3(O)(P)+2(T)\sim3(O),在椭圆曲线群律中即 P=2TP=-2T

所以从任一满足 (w)=5(T)5(O)(w)=5(T)-5(O) 的 Weil 函数出发,只需归一化

f=ww(2T)f=\frac{w}{w(-2T)}

即可把第三个分支值调成 1。

2. Tate 标准化

把非零非 2-挠点 TT 平移到 (0,0)(0,0),再令其切线水平,可把扩展 Weierstrass 方程写成

y2+a1xy+a3y=x3+a2x2,y^2+a_1xy+a_3y=x^3+a_2x^2,

其中剩余缩放为 (x,y)(λ2x,λ3y)(x,y)\mapsto(\lambda^2x,\lambda^3y)。若 TT 也不是 3-挠点,可归一化 a2=a3=aa_2=a_3=a

定理一般 5-挠点族

在上述规范下,T=(0,0)T=(0,0) 为 5-挠点当且仅当 a1=a+1a_1=a+1。因此一般带指定 5-挠点的椭圆曲线可写成

y2+(a+1)xy+ay=x3+ax2.y^2+(a+1)xy+ay=x^3+ax^2.
证明比较 2T2T3T3T

直接用群律得 2T=(a,a1aa)2T=(-a,a_1a-a)3T=(1a1,a1a1)3T=(1-a_1,a_1-a-1)。条件 5T=O5T=O 等价于 3T=2T3T=-2T,从而两点的 xx-坐标相等,即 1a1=a1-a_1=-a

说明模曲线解释

参数 aa 给出 X1(5)X_1(5) 的有理坐标。忘掉挠点生成元只保留其生成的循环子群,对应商到 X0(5)X_0(5)

唯一的 (5,5,221)(5,5,221) 椭圆 Belyi 函数

考虑次数 5 的 Belyi 映射 f:E𝐏1f:E\to\mathbf P^1,三个分支值上的循环型为 5,5,2215,5,221。Riemann–Hurwitz公式给出源曲线亏格 1。221221 纤维中有一个简单点,提供次数 1 除子,因此 EE 可视为椭圆曲线。

把一个五重极点取作原点 OO,另一个五重点记为 TT,并把它们分别送到 ,0\infty,0。于是

(f)=5(T)5(O).(f)=5(T)-5(O).

这迫使 TT 是非零 5-挠点,且 ff 是其 Weil 函数。若一般有 n(T)n(O)n(T)\sim n(O)TT 的实际阶 mm 真除 nn,所得函数会是次数 mm Weil 函数的 n/mn/m 次幂,覆盖非本原;这里 n=5n=5 为素数,无此可能。

df/fdf/f 预测简单点

f1(1)f^{-1}(1) 写成

(f1)0=(P)+2D,degD=2.(f-1)_0=(P)+2D, \qquad \deg D=2.

df/fdf/fO,TO,T 有简单极点,在两个二重点处各有简单零,所以

div(df/f)=D(O)(T).\operatorname{div}(df/f)=D-(O)-(T).

它是典范除子;椭圆曲线典范类为零,故 D(O)+(T)D\sim(O)+(T)。另一方面 (P)+2D5(O)(P)+2D\sim5(O),消去 DD

(P)+2(T)3(O).(P)+2(T)\sim3(O).

按椭圆曲线群律,这等价于 P=2TP=-2T。因此任意具有除子 5(T)5(O)5(T)-5(O) 的 Weil 函数 ww,经归一化

f=ww(2T)f=\frac{w}{w(-2T)}

便把该简单点送到 1。

Tate 正规形与 5-挠点参数

从一般广义 Weierstrass 方程出发,把非零点 TT 平移到 (0,0)(0,0),得到 a6=0a_6=0。若 TT 不是 2-挠点,则 a30a_3\ne0,再作 yy 的线性平移可令切线水平,即 a4=0a_4=0。剩余缩放使系数 aia_i 具有权 ii,所以带非零非 2-挠点的椭圆曲线由加权射影坐标 (a1:a2:a3)𝐏(1,2,3)(a_1:a_2:a_3)\in\mathbf P(1,2,3) 参数化,需排除判别式为零的点。

水平切线在 TT 处三重相交当且仅当 a2=0a_2=0,即 TT 为 3-挠点。若 TT 也非 3-挠点,可唯一缩放使 a2=a3=a0a_2=a_3=a\ne0。此时

E:y2+a1xy+ay=x3+ax2.E:\quad y^2+a_1xy+ay=x^3+ax^2.

直接用弦切法计算

2T=(a,a1aa),3T=(1a1,a1a1).2T=(-a,a_1a-a),\qquad 3T=(1-a_1,a_1-a-1).

条件 5T=O5T=O 等价于 3T=2T3T=-2T,也等价于二者 xx-坐标相同,因此

a1=a+1.a_1=a+1.

所以一般带指定 5-挠点的曲线可写成系数 (a+1,a,a,0,0)(a+1,a,a,0,0),指定点为 (0,0)(0,0)。同样方法可推导 4、6、7 阶挠点的 Tate 正规形。

构造 Weil 函数

因为 wL(5O)w\in L(5O),可写成 xy,x2,y,x,1xy,x^2,y,x,1 的线性组合。局部在 TT 附近以 xx 为参数,解曲线方程得

y=x2x3+x4+(a11)x5+O(x6).y=x^2-x^3+x^4+(a^{-1}-1)x^5+O(x^6).

于是

w=x2yxyw=x^2-y-xy

TT 至少四阶消失;第五个零因 5T=O5T=O 也必须落在 TT,故 (w)=5(T)5(O)(w)=5(T)-5(O)

另一种适用于更高次数的方法是用直线函数乘积。这里

(x)=(T)+(T)2(O),(y)=2(T)+(2T)3(O).(x)=(T)+(-T)-2(O),\qquad (y)=2(T)+(-2T)-3(O).

所以 xy2xy^2 的零除子含 5(T)+(T)+2(2T)5(T)+(-T)+2(-2T)。除以经过 T,2T-T,-2T 且在 2T-2T 相切的直线 x+y+a=0x+y+a=0,得到

w=xy2x+y+a.w=\frac{xy^2}{x+y+a}.

用曲线方程有理化并约去公共因子后,化为 (x+1)yx2(x+1)y-x^2,与前式只差符号。

确定参数 aa

归一化后 f=(x2yxy)/a2f=(x^2-y-xy)/a^2。消去 yy,计算 f1f-1 与椭圆曲线方程关于 yy 的结式,得到

(x+a)(x4ax3+a2x2+3a2x+a2a3).-(x+a)\bigl(x^4-ax^3+a^2x^2+3a^2x+a^2-a^3\bigr).

线性因子对应简单点 P=2TP=-2T,四次因子必须是二次多项式的平方。比较其在 x=x=\infty 处平方根展开

x2a2x+3a28+O(x1)x^2-\frac a2x+\frac{3a^2}{8}+O(x^{-1})

与四次式系数,得到唯一参数

a=8.a=-8.

代回后可精确验证 ff 的分歧型为 (5,5,221)(5,5,221)

标准模型、导子与 Bring 曲线

保留指定挠点的模型系数为 (7,8,8,0,0)(-7,-8,-8,0,0)。全局最小化后可得到标准系数

(a1,a2,a3,a4,a6)=(1,1,1,22,9),(a_1,a_2,a_3,a_4,a_6)=(1,1,1,22,-9),

导子为 50。该曲线除有理 5-挠点外还有有理 3-同源;它与 3-同源曲线 (1,1,1,3,1)(1,1,1,-3,1)𝐐\mathbf Q 上同时具有有理 5-挠点和有理 3-同源的两条经典曲线。Belyi 映射的 Galois 闭包是亏格 4 的 Bring 曲线,其自同构群为 S5S_5,在特征零亏格 4 曲线中达到最大规模。

Hurwitz 数据先给出唯一性预期

循环型 (5),(5),(2,2,1)(5),(5),(2,2,1) 的传递置换三元组可在 S5S_5 中直接枚举。固定 σ0=(12345)\sigma_0=(1\,2\,3\,4\,5),要求 σ1\sigma_1 也是 5-循环且 σ=(σ0σ1)1\sigma_\infty=(\sigma_0\sigma_1)^{-1} 型为 2,2,12,2,1。在同时共轭后得到单一 Hurwitz 轨道,因此几何上预期只有一个覆盖同构类。这个组合唯一性解释了后续代数方程为何最终给出单个模数点,而不是正维族。

在 Tate 正规形中强制五阶

带指定非零点 T=(0,0)T=(0,0) 的 Tate 正规形可写

Eb,c:y2+(1c)xyby=x3bx2.E_{b,c}: y^2+(1-c)xy-by=x^3-bx^2.

由弦切法逐次计算 2T,3T,4T2T,3T,4T。条件 5T=O5T=O 等价于 4T=T4T=-T,消去中间坐标后得到一条有理模曲线;常用参数可把系数化为只含一个参数。随后排除 TT 阶为 1 或其他退化值,并要求判别式非零。

Weil 函数的线性代数构造

L(5O)=1,x,y,x2,xyL(5O)=\langle1,x,y,x^2,xy\rangle 中写

w=c0+c1x+c2y+c3x2+c4xy.w=c_0+c_1x+c_2y+c_3x^2+c_4xy.

选取 TT 处的局部参数 zz,展开 x(z),y(z)x(z),y(z),令 ww 的常数项至 z4z^4 系数全为零。这是五个齐次线性条件;因 5(T)5(O)5(T)\sim5(O),解空间恰为一维。得到的 ww 自动满足 (w)=5(T)5(O)(w)=5(T)-5(O)。为避免局部展开,可等价地在局部环中要求 w𝔪T5w\in\mathfrak m_T^5,用 Gröbner 基对 (x,y)(x,y) 的幂理想约化。

把简单点送到 1 后的平方条件

P=2TP=-2T,规范为 f=w/w(P)f=w/w(P)。此时 f(P)=1f(P)=1,并已知其余 f1(1)f^{-1}(1) 应为两个二重点。因此作为函数,f1f-1 的零除子应为

(P)+2(Q1)+2(Q2).(P)+2(Q_1)+2(Q_2).

消去 yy 后,f1=0f-1=0 与椭圆曲线方程的结果式是一个次数 5 的 xx-多项式;其中 xx(P)x-x(P) 为一次因子,其余四次因子必须是平方。把四次多项式的判别式或“与某二次多项式平方相等”的系数条件置零,就得到 Tate 参数的方程。解出后再回代,不能只凭结果式平方,因为消元可能引入极点或公共因子。

用微分精确核验分歧

在函数域中计算 dfdf。对有限点,分歧指数 ePe_P 等于 ordP(df)+1\operatorname{ord}_P(df)+1,只要局部坐标可分。验证时可求微分除子并检查

div(df)=4(T)+Q1+Q26(O),\operatorname{div}(df)=4(T)+Q_1+Q_2-6(O),

其中两个五重纤维各贡献 4,两个二重点各贡献 1,总分歧为 10,符合亏格 1、次数 5 的 Riemann–Hurwitz:

0=5(2)+10.0=5(-2)+10.

同时应检查三个分支值互异,且没有第四个临界值。

定义域、共轭与下降

覆盖的模数点可能定义在 𝐐\mathbf Q,但带标记的五阶点需要扩张;反之,也可能模型在二次域上而未标记覆盖可下降到 𝐐\mathbf Q。应分别计算:椭圆曲线的 jj-不变量、覆盖的 dessin 自同构群、以及 Galois 对系数的作用是否可由源曲线自同构和目标 Möbius 变换补偿。下降障碍位于相应自同构群的上同调中。

Galois 闭包与 Bring 曲线

该次数 5 覆盖的单值群由一个 5-循环和一个双换位生成,得到 A5A_5。其 Galois 闭包对应正规核,次数为 60。用 Riemann–Hurwitz 计算闭包曲线亏格:三个惯性阶分别为 5,5,25,5,2,故

2g2=60(2+(115)+(115)+(112))=6,2g-2=60\left(-2+\left(1-\frac15\right)+\left(1-\frac15\right)+\left(1-\frac12\right)\right)=6,

所以 g=4g=4。这正落在具有 S5S_5A5A_5 高度对称性的 Bring 曲线背景中。原次数 5 椭圆覆盖可视为该 Galois 曲线对某个 A4A_4 子群取商。

从单个例子提炼的通用算法

处理“一个纤维全分歧、另一个纤维全分歧、第三个纤维近平方”的椭圆 Belyi 问题时,可依次:由全分歧纤维识别挠点;选 Tate 正规形;在 L(nO)L(nO) 中求 Weil 函数;用除子关系定位简单点;把剩余因子强制为所需幂;解参数方程;最后用微分和除子做精确认证。这个顺序比从一般 Weierstrass 方程和一般有理函数同时消元小得多。

计算专题:五阶挠点模曲线与唯一覆盖的再确认

带一个指定五阶点的模曲线 X1(5)X_1(5) 亏格 0,Tate 正规形参数给出通用椭圆曲线。忘掉点的生成元只保留循环子群得到 X0(5)X_0(5),商去 (𝐙/5)×/{±1}(\mathbf Z/5)^\times/\{\pm1\} 的作用。课程中的 Weil 函数问题比单纯同源多保留了一个挠点及函数归一化,所以参数方程应在 X1(5)X_1(5) 层面建立,再由覆盖同构识别。

五阶点的四个非零倍数分成 {±T}\{\pm T\}{±2T}\{\pm2T\}。简单点 2T-2T 的出现不是偶然:由第三纤维的除子与典范类严格推出。若交换两个五重分支值,函数变为 1/f1/f 或经目标 Möbius 变换,挠点角色相应交换;这解释同一 dessin 的若干表面不同公式。

求解参数方程时,结果式的平方条件可改写为四次因子判别式为零且 gcd 与导数次数恰为 2。但判别式为零只保证至少一个重根,不保证是两个二重根;应同时检查平方自由分解或直接比较为首一二次多项式平方。

若参数候选在数域中,可在其最小多项式商环里一次验证。判别式非零保证椭圆曲线光滑;五阶条件可用点倍加或除法多项式;函数除子可用局部展开;第三纤维可对函数分子做因式分解。四项验证相互独立,任何一项失败都说明消元产生伪解。

从置换三元组可算 dessin 自同构群。若中心化子平凡,覆盖的域下降通常较简单,模数域等于定义域;若存在非平凡自同构,还需 cocycle 检查。该例的高度对称 Galois 闭包不意味着原五重覆盖本身有同样大的自同构群。

将 Galois 闭包曲线写成典范亏格 4 模型时,可从 A5A_5 在全纯微分上的四维表示出发。不变量和协变式能给出三次/二次关系;这为后续反射群与经典不变量论章节建立直接桥梁。

练习与解答五次椭圆 Belyi

练习 1。由循环型 5,5,2215,5,221 计算亏格。

解。贡献 4+4+(1+1)=104+4+(1+1)=10,故 2g2=10+10=02g-2=-10+10=0,得到 g=1g=1

练习 2。为何简单点给椭圆曲线原点选择之外的有理除子?

解。它在该分支纤维中由循环型唯一刻画,因而被覆盖定义域的 Galois 群固定,给出次数 1 有理除子。

练习 3。Galois 闭包亏格计算中为何惯性阶用 5、5、2?

解。正规覆盖上每个分支点的所有惯性群共轭,阶等于原单值置换阶,而非其循环数。

深入补充:五阶 Tate 正规形、除法多项式与 Weil 函数的线性构造

带指定点 TT 的椭圆曲线可写成 Tate 正规形

E(b,c):y2+(1c)xyby=x3bx2,T=(0,0).E(b,c): y^2+(1-c)xy-by=x^3-bx^2, \qquad T=(0,0).

逐次用弦切公式计算 2T,3T,2T,3T, \ldots,要求 5T=O5T=O,在非退化分支上得到 b=c=tb=c=t。于是具有指定五阶点的通用族为

Et:y2+(1t)xyty=x3tx2,T=(0,0),E_t: y^2+(1-t)xy-ty=x^3-tx^2, \qquad T=(0,0),

其判别式为

Δ=t5(t211t1).\Delta=t^5(t^2-11t-1).

所以 t=0t=0t211t1=0t^2-11t-1=0 是退化参数;其余参数给光滑椭圆曲线和一个精确五阶点。

判据 除法多项式认证挠阶

在特征不整除 55 的域上,非2-挠点 P=(x,y)P=(x,y) 满足 5P=O5P=O 当且仅当

ψ5(x)=0,\psi_5(x)=0,

其中 ψ5\psi_5 是第五除法多项式。若还验证 ψ1(P),ψ5(P)=0\psi_1(P),\psi_5(P)=0POP\ne O,并排除 PP 为一阶因子的零点,就得到阶恰为 55 的精确证书。

对已在 Tate 正规形中的 T=(0,0)T=(0,0),直接用加法公式验证 2T,3T,4T=T2T,3T,4T=-T 往往比展开次数 1212ψ5\psi_5 更短;除法多项式则适合一般模型和批量挠点搜索。

Weil 函数的构造可化为 Riemann–Roch 线性代数。若希望

div(fT)=5(T)5(O),\operatorname{div}(f_T)=5(T)-5(O),

fTL(5O)f_T\in L(5O)。在短 Weierstrass 模型中

ordO(x)=2,ordO(y)=3,\operatorname{ord}_O(x)=-2, \qquad \operatorname{ord}_O(y)=-3,

L(5O)=1,x,y,x2,xy.L(5O)=\langle1,x,y,x^2,xy\rangle.
算法 五阶 Weil 函数

f=a0+a1x+a2y+a3x2+a4xy.f=a_0+a_1x+a_2y+a_3x^2+a_4xy.

TT 处选择局部参数,展开 x,yx,y,令 ff 的前五个局部系数为零;线性方程组的非零核给出 fTf_T,再按无穷远首项归一化。最后通过消元或局部展开验证零点仅为 TT 且重数为 55

同一函数也可用 Miller 递推构造。若 fmf_m 的除子为

m(T)([m]T)(m1)(O),m(T)-([m]T)-(m-1)(O),

则割线函数与竖线函数给出

fm+n=fmfnmT,nTv(m+n)Tf_{m+n}=f_mf_n\frac{\ell_{mT,nT}}{v_{(m+n)T}}

到常数倍。对 m+n=5m+n=55T=O5T=O,得到所需 5(T)5(O)5(T)-5(O)。Miller 形式通常更稀疏,Riemann–Roch 形式更便于施加额外归一化;两者相除应为常数,是强力交叉检查。

对数微分

ω=dfTfT\omega=\frac{df_T}{f_T}

TT 的留数为 55,在 OO 的留数为 5-5,其余点无极点。若要把 fTf_T 归一化成 Belyi 函数,还需控制 fT1f_T-1 的零点重数。可在 L(5O)L(5O) 中先求 fTf_T,再令判别条件

gcd(fT1,dfT)\gcd(f_T-1,df_T)

具有目标次数;这把分支要求转成参数 tt 的代数方程。求得参数后必须重新检查曲线判别式非零、TT 阶恰为五、函数除子正确及第三纤维 passport 完整。

补充计算:五阶 Tate 正规形、Miller 函数与判别式

定理 五阶挠点的 Tate 正规形

设 K 的特征不为 5。带有指定五阶点 P 的椭圆曲线在适当坐标下可写为 Eb:y2+(1b)xyby=x3bx2,P=(0,0), E_b:\ y^2+(1-b)xy-by=x^3-bx^2,\qquad P=(0,0), 其中 b≠0 且 \(b^2-11b-1≠0\)。其判别式与 j 不变量为 Δ=b5(b211b1), \Delta=b^5(b^2-11b-1), j=(b412b3+14b2+12b+1)3b5(b211b1). j=\frac{(b^4-12b^3+14b^2+12b+1)^3}{b^5(b^2-11b-1)}.

证明 逐次群律计算与非奇异性判定

在一般 Weierstrass 群律中直接计算可得 \(2P=(b,b^2)\),\(3P=(b,0)\),\(4P=(0,b)=-P\),故 \(5P=O\)。若 P 的阶小于 5,则 \(P=O\)、\(2P=O\) 或 \(3P=O\);由上述坐标与 b≠0 均不可能,因此 P 的阶恰为 5。

代入一般不变量公式 \(b_2=a_1^2+4a_2\)、\(b_4=2a_4+a_1a_3\)、\(b_6=a_3^2+4a_6\)、\(b_8=a_1^2a_6+4a_2a_6-a_1a_3a_4+a_2a_3^2-a_4^2\),可得判别式因子。Δ≠0 正是曲线光滑条件。再由 \(c_4=b_2^2-24b_4\) 与 \(j=c_4^3/Δ\) 得所列公式。

Python 一般 Weierstrass 群律、五阶核验与 Miller 递推
from dataclasses import dataclass
from fractions import Fraction
import sympy as sp

@dataclass(frozen=True)
class Point:
    x: object | None
    y: object | None

    @property
    def infinity(self):
        return self.x is None

O=Point(None,None)

@dataclass
class GeneralWeierstrass:
    a1: object
    a2: object
    a3: object
    a4: object
    a6: object
    modulus: int | None = None

    def inv(self,z):
        if self.modulus is None:
            return 1/z
        return pow(int(z)%self.modulus,-1,self.modulus)

    def norm(self,z):
        return z if self.modulus is None else int(z)%self.modulus

    def on_curve(self,P):
        if P.infinity: return True
        x,y=P.x,P.y
        lhs=y*y+self.a1*x*y+self.a3*y
        rhs=x**3+self.a2*x*x+self.a4*x+self.a6
        return self.norm(lhs-rhs)==0

    def neg(self,P):
        if P.infinity: return P
        return Point(P.x,self.norm(-P.y-self.a1*P.x-self.a3))

    def add_with_line(self,P,Q):
        if P.infinity: return Q,None,None
        if Q.infinity: return P,None,None
        if Q==self.neg(P):
            return O,None,None

        if P!=Q:
            den=Q.x-P.x
            lam=self.norm((Q.y-P.y)*self.inv(den))
            nu=self.norm((P.y*Q.x-Q.y*P.x)*self.inv(den))
        else:
            den=2*P.y+self.a1*P.x+self.a3
            if self.norm(den)==0:
                return O,None,None
            lam=self.norm(
                (3*P.x**2+2*self.a2*P.x+self.a4-self.a1*P.y)
                *self.inv(den)
            )
            nu=self.norm(
                (-P.x**3+self.a4*P.x+2*self.a6-self.a3*P.y)
                *self.inv(den)
            )
        xr=self.norm(
            lam*lam+self.a1*lam-self.a2-P.x-Q.x
        )
        yr=self.norm(
            -(lam+self.a1)*xr-nu-self.a3
        )
        R=Point(xr,yr)
        assert self.on_curve(R)
        return R,lam,nu

    def add(self,P,Q):
        return self.add_with_line(P,Q)[0]

    def mul(self,n,P):
        if n<0: return self.mul(-n,self.neg(P))
        R=O
        Q=P
        while n:
            if n&1: R=self.add(R,Q)
            Q=self.add(Q,Q)
            n>>=1
        return R

    def invariants(self):
        a1,a2,a3,a4,a6=self.a1,self.a2,self.a3,self.a4,self.a6
        b2=a1*a1+4*a2
        b4=2*a4+a1*a3
        b6=a3*a3+4*a6
        b8=a1*a1*a6+4*a2*a6-a1*a3*a4+a2*a3*a3-a4*a4
        c4=b2*b2-24*b4
        c6=-b2**3+36*b2*b4-216*b6
        Delta=-b2*b2*b8-8*b4**3-27*b6*b6+9*b2*b4*b6
        return tuple(map(self.norm,(b2,b4,b6,b8,c4,c6,Delta)))

    def line_value(self,P,Q,T):
        R,lam,nu=self.add_with_line(P,Q)
        if R.infinity:
            # vertical line through P and -P
            return self.norm(T.x-P.x),R
        line=self.norm(T.y-lam*T.x-nu)
        vertical=self.norm(T.x-R.x)
        return self.norm(line*self.inv(vertical)),R

    def miller(self,n,P,Q):
        """
        Evaluate f_{n,P}(Q) with div(f)=n(P)-[nP]-(n-1)(O).
        """
        bits=bin(n)[3:]
        V=P
        f=self.norm(1)
        for bit in bits:
            g,V2=self.line_value(V,V,Q)
            f=self.norm(f*f*g)
            V=V2
            if bit=="1":
                g,V2=self.line_value(V,P,Q)
                f=self.norm(f*g)
                V=V2
        return f,V

def tate5(b,modulus=None):
    return GeneralWeierstrass(
        a1=1-b,a2=-b,a3=-b,a4=0,a6=0,modulus=modulus
    )

print("Tate normal form for order 5:")
for b in [Fraction(1,2),Fraction(2),Fraction(3),Fraction(-1)]:
    E=tate5(b)
    P=Point(Fraction(0),Fraction(0))
    invs=E.invariants()
    print(f"  b={b}: Delta={invs[-1]}, c4={invs[-3]}")
    for n in range(1,6):
        print(f"    {n}P={E.mul(n,P)}")
    print("    order-5 check =",E.mul(5,P).infinity)

B=sp.Symbol("b")
Es=tate5(B)
print("\nsymbolic invariants:")
names=("b2","b4","b6","b8","c4","c6","Delta")
for name,value in zip(names,Es.invariants()):
    print(f"  {name} = {sp.factor(value)}")
print("  j =",sp.factor(Es.invariants()[-3]**3/Es.invariants()[-1]))

p=101
E=tate5(2,p)
P=Point(0,0)
points=[]
for X in range(p):
    for Y in range(p):
        Q=Point(X,Y)
        if E.on_curve(Q):
            points.append(Q)
Q=next(Q for Q in points
       if not Q.infinity and Q not in [E.mul(k,P) for k in range(5)]
       and Q.x not in {E.mul(k,P).x for k in range(1,5)})
print(f"\nfinite-field Miller evaluation over F_{p}:")
print("  #affine points =",len(points))
print("  P =",P,"5P =",E.mul(5,P))
print("  Q =",Q)
for n in range(2,6):
    value,end=E.miller(n,P,Q)
    print(f"  f_{{{n},P}}(Q)={value:3d}, endpoint={end}")
运行结果 四个参数的五阶点与有限域 Weil 函数值
Tate normal form for order 5:
  b=1/2: Delta=-25/128, c4=145/16
    1P=Point(x=Fraction(0, 1), y=Fraction(0, 1))
    2P=Point(x=Fraction(1, 2), y=Fraction(1, 4))
    3P=Point(x=Fraction(1, 2), y=Fraction(0, 1))
    4P=Point(x=Fraction(0, 1), y=Fraction(1, 2))
    5P=Point(x=None, y=None)
    order-5 check = True
  b=2: Delta=-608, c4=1
    1P=Point(x=Fraction(0, 1), y=Fraction(0, 1))
    2P=Point(x=Fraction(2, 1), y=Fraction(4, 1))
    3P=Point(x=Fraction(2, 1), y=Fraction(0, 1))
    4P=Point(x=Fraction(0, 1), y=Fraction(2, 1))
    5P=Point(x=None, y=None)
    order-5 check = True
  b=3: Delta=-6075, c4=-80
    1P=Point(x=Fraction(0, 1), y=Fraction(0, 1))
    2P=Point(x=Fraction(3, 1), y=Fraction(9, 1))
    3P=Point(x=Fraction(3, 1), y=Fraction(0, 1))
    4P=Point(x=Fraction(0, 1), y=Fraction(3, 1))
    5P=Point(x=None, y=None)
    order-5 check = True
  b=-1: Delta=-11, c4=16
    1P=Point(x=Fraction(0, 1), y=Fraction(0, 1))
    2P=Point(x=Fraction(-1, 1), y=Fraction(1, 1))
    3P=Point(x=Fraction(-1, 1), y=Fraction(0, 1))
    4P=Point(x=Fraction(0, 1), y=Fraction(-1, 1))
    5P=Point(x=None, y=None)
    order-5 check = True

symbolic invariants:
  b2 = b**2 - 6*b + 1
  b4 = b*(b - 1)
  b6 = b**2
  b8 = -b**3
  c4 = b**4 - 12*b**3 + 14*b**2 + 12*b + 1
  c6 = -(b**2 + 1)*(b**4 - 18*b**3 + 74*b**2 + 18*b + 1)
  Delta = b**5*(b**2 - 11*b - 1)
  j = (b**4 - 12*b**3 + 14*b**2 + 12*b + 1)**3/(b**5*(b**2 - 11*b - 1))

finite-field Miller evaluation over F_101:
  #affine points = 99
  P = Point(x=0, y=0) 5P = Point(x=None, y=None)
  Q = Point(x=1, y=24)
  f_{2,P}(Q)= 77, endpoint=Point(x=2, y=4)
  f_{3,P}(Q)= 23, endpoint=Point(x=2, y=0)
  f_{4,P}(Q)= 47, endpoint=Point(x=0, y=2)
  f_{5,P}(Q)= 47, endpoint=Point(x=None, y=None)
计算 Miller 除子递推

若 l_{R,S} 为过 R、S 的割线或切线,v_{R+S} 为过 R+S 与 -(R+S) 的竖线,则 div(l_{R,S}/v_{R+S})=(R)+(S)-(R+S)-(O)。 由此 f_{m+n,P}=f_{m,P}f_{n,P}\,l_{mP,nP}/v_{(m+n)P} 具有除子 (m+n)(P)-((m+n)P)-(m+n-1)(O)。当 5P=O 时,f_{5,P} 的除子为 5(P)-5(O),即所需 Weil 函数。

Lecture 16 / 第 16 讲

复反射群与不变量环

引入复反射、基本不变量、商映射和对称曲线的构造。

复反射群不变量环商空间

1. 反射与伪反射

定义复反射

有限阶线性变换 sGL(V)s\in\mathrm{GL}(V) 若固定一个余维 1 的超平面,称为复反射(也称伪反射)。它的特征值除一个根 of unity 外全为 1。

由复反射生成的有限群称为有限复反射群。实反射群、Weyl 群都是特殊情形;复情形还包含 Shephard–Todd 的例外酉反射群。

定理Chevalley–Shephard–Todd

设基域特征为 0,GGL(V)G\subset\mathrm{GL}(V) 有限。则不变量环 k[V]Gk[V]^G 是多项式环,当且仅当 GG 由复反射生成。

于是存在代数无关的齐次基本不变量 f1,,fnf_1,\ldots,f_n,使

k[V]G=k[f1,,fn].k[V]^G=k[f_1,\ldots,f_n].

次数 di=degfid_i=\deg f_i 在重排意义下唯一,并满足 |G|=idi|G|=\prod_i d_i

2. 商映射与判别式

商映射 VV/G𝐀nV\to V/G\cong\mathbf A^nv(f1(v),,fn(v))v\mapsto(f_1(v),\ldots,f_n(v)) 给出。它的分歧位于反射超平面的像。Jacobian

J=det(fixj)J=\det\left(\frac{\partial f_i}{\partial x_j}\right)

按每个反射超平面的定义方程分解,指数由点稳定子阶决定。

证明次数乘积公式

若不变量环为多项式环,其 Hilbert 级数在 t1t\to1 时主项为 (di)1(1t)n(\prod d_i)^{-1}(1-t)^{-n}。另一方面 Molien 公式中只有单位元贡献最高阶极点,主项为 |G|1(1t)n|G|^{-1}(1-t)^{-n}。比较得到 di=|G|\prod d_i=|G|

3. 对称曲线

在二维表示中,齐次不变量和协变式给出 𝐏1\mathbf P^1 上的高度对称点轨道、Belyi 函数与 Klein 型恒等式。在高维表示中,固定某些基本不变量的值可得到带大自同构群的曲线、曲面或椭圆曲面族。

算法构造基本不变量
  1. 用 Reynolds 算子平均低次单项式。
  2. 按次数计算不变量空间维数。
  3. 选择代数独立候选并计算 Jacobian。
  4. 比较 Hilbert 级数,确认候选生成整个不变量环。
  5. 必要时加入协变式,描述原表示与商空间之间的逆像。

复反射群的定义与第一批例子

VVnn 维复向量空间。有限阶线性变换 sGL(V)s\in\operatorname{GL}(V) 若固定一个余维 1 的超平面,即 rank(1s)=1\operatorname{rank}(1-s)=1,称为复反射。等价地,在某组基下

s=diag(ζ,1,,1),ζ1s=\operatorname{diag}(\zeta,1,\ldots,1), \qquad \zeta\ne1

ζ\zeta 为单位根。由所含复反射生成的有限线性群称为复反射群。实 Euclidean 反射群 An,Bn/Cn,Dn,En,F4,G2A_n,B_n/C_n,D_n,E_n,F_4,G_2 都是其中的特例;一维中任意有限群 μm𝐂×\mu_m\subset\mathbf C^\times 也是反射群。若 G1,G2G_1,G_2 分别作用在 V1,V2V_1,V_2 上,则块对角直积 G1×G2G_1\times G_2 也是反射群。

不变量环与 Shephard–Todd–Chevalley 定理

有限群 GGL(V)G\subset\operatorname{GL}(V) 通过线性代换作用在 𝐂[V]\mathbf C[V] 上。若

𝐂[V]G=𝐂[Φ1,,Φn]\mathbf C[V]^G=\mathbf C[\Phi_1,\ldots,\Phi_n]

其中 Φi\Phi_i 为代数无关齐次多项式,就说不变量环是多项式环。有限群情形必有恰好 nn 个生成元,且

|G|=i=1ndegΦi.|G|=\prod_{i=1}^{n}\deg\Phi_i.

Shephard–Todd 定理断言:有限复线性群的不变量环为多项式环,当且仅当该群由复反射生成。原始证明使用了不可约复反射群的完整分类;Chevalley 与 Serre 后来给出更概念性的证明。分类仍然极有用,因为每个反射群都提供一个显式商映射 VV/G𝐀nV\to V/G\cong\mathbf A^n,以及大量高度对称的曲线、超曲面和覆盖。

生成元不唯一而次数唯一

SnS_n 的置换表示,不变量可取初等对称函数,也可取幂和。具体生成元远非唯一;某些低次数不变量可能只差标量,但通常可作三角变换。真正由表示决定的是基本不变量的次数多重集。计算中应选择最适合目标几何的生成元,并同时保留不同生成组之间的变换公式。

三个无限族

第一族是一维循环群 μm\mu_m,基本不变量为 xmx^m。第二族是 Sn+1S_{n+1} 在置换表示的零和超平面上的作用,即 AnA_n 型反射群。第三族为单项式群

G(m,1,n)=μmnSn,G(m,1,n)=\mu_m^n\rtimes S_n,

即每行每列恰有一个非零项、且非零项为 mm 次单位根的矩阵。其阶为 n!mnn!m^n,不变量是 x1m,,xnmx_1^m,\ldots,x_n^m 的对称函数,基本次数为

m,2m,,nm.m,2m,\ldots,nm.

把矩阵所有非零项的乘积映到 μm\mu_m,若 pmp\mid mq=m/pq=m/p,该映射中 μq\mu_q 的逆像记为 G(m,p,n)G(m,p,n)。其阶为 n!mn/pn!m^n/p,基本次数为

m,2m,,(n1)m,nq.m,2m,\ldots,(n-1)m,nq.

若用初等对称函数生成 G(m,1,n)G(m,1,n) 不变量,则最后一个生成元是 (x1xn)m(x_1\cdots x_n)^m;对 G(m,p,n)G(m,p,n),将其替换为 (x1xn)q(x_1\cdots x_n)^q 即可。

实反射群与小阶巧合

无限族中实反射群包括 μ2=A1\mu_2=A_1Sn+1=AnS_{n+1}=A_nG(2,1,n)=Bn/CnG(2,1,n)=B_n/C_nG(2,2,n)=DnG(2,2,n)=D_n,以及经复基变换成为实二面体群的 G(m,m,2)G(m,m,2)。分类还存在若干低阶巧合:G(2,2,2)G(2,2,2) 是可约的 Klein 四群,对应 D2=A1A1D_2=A_1\oplus A_1G(2,2,3)S4G(2,2,3)\cong S_4,对应 D3=A3D_3=A_3G(3,3,2)S3G(3,3,2)\cong S_3G(4,4,2)G(2,1,2)G(4,4,2)\cong G(2,1,2)。作为 Lie 群例外的 G2G_2 在反射群分类中并不“例外”,因为它只是一个二面体群。

34 个例外群与二维情形

除三个无限族外有 34 个例外不可约复反射群,维数从 2 到 8。其数量按维数 2,3,4,5,6,7,82,3,4,5,6,7,8 分别为 19,5,5,1,2,1,119,5,5,1,2,1,1。二维的 19 个例外大多来自球面旋转群 A4,S4,A5A_4,S_4,A_5 的二元提升与标量扩张。高维例外中包括实 Weyl 群 F4,E6,E7,E8F_4,E_6,E_7,E_8

正特征中的变化

正特征下,具有多项式不变量环的有限群仍由 rank(1g)=1\operatorname{rank}(1-g)=1 的元素生成,但这些元素可能是所有特征值均为 1、带一个 2×22\times2 Jordan 块的转射,而不是真正半单反射。Dickson 证明 GLn(𝐅q)\operatorname{GL}_n(\mathbf F_q)SLn(𝐅q)\operatorname{SL}_n(\mathbf F_q) 都有多项式不变量环;前者基本次数为 qnqi(0i<n)q^n-q^i\ (0\le i<n),后者的次数包括 qnqi(0<i<n)q^n-q^i\ (0<i<n)(qn1)/(q1)(q^n-1)/(q-1)。但在模特征情形,“由反射/转射生成”不再充分保证不变量环为多项式环。

反射超平面与 Jacobian 判别式

设复反射群 GG 的基本不变量为 f1,,fnf_1,\ldots,f_n,商映射为 π=(f1,,fn):V𝐀n\pi=(f_1,\ldots,f_n):V\to\mathbf A^n。其 Jacobian

J=det(fixj)J=\det\left(\frac{\partial f_i}{\partial x_j}\right)

在每个反射超平面上消失。若超平面 HH 的点态稳定子阶为 eHe_H,则局部坐标可取使商映射在法向方向为 zzeHz\mapsto z^{e_H},所以

J=cHHeH1,J=c\prod_H \ell_H^{e_H-1},

其中 H=0\ell_H=0 定义 HH。这不仅证明商映射只在反射超平面分歧,也给出基本次数恒等式

i=1n(di1)=H(eH1),\sum_{i=1}^n(d_i-1)=\sum_H(e_H-1),

右边等于群中复反射总数(按每个超平面上的非平凡反射计数)。它是检查候选不变量次数的有力工具。

多项式不变量环为何迫使反射生成

𝐂[V]G\mathbf C[V]^G 是多项式环,则商 V/GV/G 光滑。取 GG 中非反射元素的固定子空间,其余维至少 2;局部商奇点不能由余维 1 的分歧消除。Serre 的论证说明,局部稳定子若产生光滑商,就必须由伪反射生成;对所有点应用后得到整个 GG 由反射生成。反方向可通过逐次加入反射并分析不变量,或用微分形式与 Jacobian 的自由性证明。

次数、余次数与 Coxeter 元素

对良生成的不可约复反射群,除基本次数 d1dnd_1\le\cdots\le d_n 外,还有余次数 d1*,,dn*d_1^*,\ldots,d_n^*。在实 Coxeter 群中,指数为 ei=di1e_i=d_i-1,Coxeter 数 h=dnh=d_n,并满足

ei+en+1i=h.e_i+e_{n+1-i}=h.

Coxeter 元素的特征值为 exp(2πiei/h)\exp(2\pi i e_i/h)。复反射群中相应概念需用正规特征值和 Springer 理论表述,但基本次数仍控制商空间、判别式和正则元素的阶。

单项式群 G(m,p,n)G(m,p,n) 的具体结构

G(m,1,n)=μmnSnG(m,1,n)=\mu_m^n\rtimes S_n 由坐标置换与单坐标乘 mm 次单位根生成。不变量可取

ek(x1m,,xnm),k=1,,n,e_k(x_1^m,\ldots,x_n^m),\qquad k=1,\ldots,n,

次数为 m,2m,,nmm,2m,\ldots,nm。子群 G(m,p,n)G(m,p,n) 由对角指数和满足模 pp 条件的元素组成,指数为 pp;其基本次数为

m,2m,,(n1)m,nmp.m,2m,\ldots,(n-1)m,\frac{nm}{p}.

最后一个生成元可取 (x1xn)m/p(x_1\cdots x_n)^{m/p}。当次数重合时,生成元可混合,但次数多重集不变。

实反射群与根系

实反射 sαs_\alpha 由根 α\alpha 给出:

sα(v)=v2(v,α)(α,α)α.s_\alpha(v)=v-2\frac{(v,\alpha)}{(\alpha,\alpha)}\alpha.

有限实反射群等价于有限 Coxeter 群,其基本关系为 (sisj)mij=1(s_is_j)^{m_{ij}}=1。根系把线性群、格与 Dynkin 图联系起来。复反射一般没有实根系,但仍可记录反射超平面的法向量与非平凡特征值;对算术构造,还需指定保持的 Hermitian 格。

Shephard–Todd 例外群的读取方法

除无限族外有 34 个例外不可约群,编号 G4,,G37G_4,\ldots,G_{37}。表中通常列出秩、群阶、基本次数、中心和抽象结构。使用编号时必须说明具体表示,因为同一个抽象群可能有不同反射表示,基本次数也不同。核验一个矩阵群的编号可依次比较:维数、群阶、反射阶分布、中心、基本次数及特征标。

商空间与判别式超曲面

在商坐标 f1,,fnf_1,\ldots,f_n 中,反射超平面的像形成判别式超曲面 ΔG=0\Delta_G=0。其补空间的基本群是相应广义辫群,有限反射群是把辫反射再加有限阶关系后的商。对于实 Coxeter 群,这恢复 Artin 群。许多 Belyi 与模空间问题中的单值群,正可从判别式补空间的辫群作用理解。

计算不变量的可靠流程

给定矩阵生成元,先枚举群或共轭类并用 Molien 公式预测每次数的不变量维数;再以 Reynolds 算子

(f)=1|G|gGgf\mathcal R(f)=\frac1{|G|}\sum_{g\in G}g\cdot f

从随机单项式产生不变量;逐次选择代数无关元素;最后比较 Hilbert 级数并验证 Jacobian 非零。仅检查若干随机点上的不变性不够,必须对生成元做符号代入,并证明所得子环具有正确 Hilbert 级数。

计算专题:从矩阵生成元识别复反射群

给定精确矩阵生成元,首先确定有限性。可枚举群闭包并以哈希规范矩阵;若系数在圆分域,统一在数域基中表示。群太大时可用置换表示:让矩阵作用在根、反射超平面或某个有限轨道上,再用 Schreier–Sims 算法求群阶。

判断元素是否反射只需计算 rank(gI)=1\operatorname{rank}(g-I)=1 且有限阶。枚举全部共轭类后得到各反射阶和数量。反射超平面由 gIg-I 的像或左核给出;把同一超平面的反射合并,可计算点态稳定子阶 eHe_H

若反射生成子群 RR 的阶等于 GG,则 GG 为反射群;否则不变量环虽可能含容易找到的参数系,但不会是自由多项式环。Molien 级数在 t=1t=1 附近的主项应为 1/(|G|(1t)n)1/(|G|(1-t)^n),可检查群阶与表示维数。

寻找基本不变量时按 Molien 系数逐次构造。设已找到若干生成元,比较它们生成子代数在每次数的维数与 Molien 维数;缺口处用 Reynolds 平均补新元素。最终计算 Jacobian,若恒非零则代数无关;再用次数乘积和 Hilbert 级数证明生成完整。

识别 Shephard–Todd 编号时,不要只比次数,因为少数群可能共享次数。还应比较群阶、中心标量阶、反射阶、不可约性和是否为某个 G(m,p,n)G(m,p,n)。可计算特征标或有限轨道置换表示作为指纹。

若矩阵只数值给出,先识别单位根和数域,再精确化。反射条件对数值误差敏感,gIg-I 的小奇异值不证明秩 1。精确后检查生成元关系和有限阶,才能进入不变量计算。

练习与解答反射群

练习 1。SnS_n 的置换表示为何可约?

解。向量 (1,,1)(1,\ldots,1) 张成平凡子表示;其坐标和为零的余维一子空间是标准反射表示。

练习 2。换位在标准表示上为何是反射?

解。它只在 eieje_i-e_j 方向乘 1-1,固定超平面 xi=xjx_i=x_j

练习 3。若基本次数为 2,3,42,3,4,群阶是多少?

解。对反射群为次数乘积 2424;但仍需确认表示确为反射群才能使用。

深入补充:Jacobian 因子分解、余不变量代数与生成判据

设有限复反射群 GGL(V)G\subset\operatorname{GL}(V)dimV=n\dim V=n,基本不变量为齐次多项式 f1,,fnf_1,\ldots,f_n,次数为 d1,,dnd_1,\ldots,d_n。Chevalley–Shephard–Todd 定理的计算力量远不止“不变量环是多项式环”。

定理 次数乘积与余不变量正则表示

|G|=i=1ndi.|G|=\prod_{i=1}^n d_i.

I=(f1,,fn)I=(f_1,\ldots,f_n),则余不变量代数

𝐂[V]/I\mathbf C[V]/I

的维数为 |G||G|,作为 GG-模同构于群的正则表示。其 Hilbert 级数为

i=1n(1+t++tdi1).\prod_{i=1}^n(1+t+\cdots+t^{d_i-1}).

因此,若已找到 nn 个代数独立不变量,且次数乘积恰等于 |G||G|,就可证明它们生成整个不变量环:它们定义的有限映射度数为次数乘积,而商映射的泛型纤维大小为 |G||G|,两者相等迫使中间有限扩张平凡。

定理 Jacobian 与反射超平面

J=det(fixj).J=\det\left(\frac{\partial f_i}{\partial x_j}\right).

对每个反射超平面 HH,设点态稳定子阶为 eHe_H,取线性方程 H=0\ell_H=0。则

J=cHHeH1,c0,J=c\prod_H\ell_H^{e_H-1},\qquad c\ne0,

并且

degJ=i(di1)=H(eH1).\deg J=\sum_i(d_i-1)=\sum_H(e_H-1).

局部坐标中,阶为 eHe_H 的反射把法向坐标 zz 乘以 eHe_H 次单位根,商坐标是 zeHz^{e_H},故商映射 Jacobian 在 HH 上消失 eH1e_H-1 次。这个分解给出强力认证:计算候选不变量的 Jacobian,因式分解后应只出现已知反射超平面,次数与重数必须完全匹配。

计算 单项式群 G(m,1,n)G(m,1,n)

该群由坐标置换与各坐标乘 mm 次单位根生成。可取 x1m,,xnmx_1^m,\ldots,x_n^m 的基本对称函数作为不变量,次数为

m,2m,,nm.m,2m,\ldots,nm.

其乘积为 mnn!=|G(m,1,n)|m^n n!=|G(m,1,n)|。反射超平面为 xi=0x_i=0 以及 xi=ζxjx_i=\zeta x_jζm=1\zeta^m=1);Jacobian 相应含因子

ixim1i<j(ximxjm).\prod_i x_i^{m-1}\prod_{i<j}(x_i^m-x_j^m).
算法 认证一组基本不变量

逐一检查 GG-不变性;在随机点或符号层面验证 Jacobian 非零,从而得到代数独立;核对次数乘积等于群阶;最后将 Jacobian 与反射超平面乘积比较到常数倍。前三步证明生成性,第四步同时验证群矩阵、反射列表和归一化没有遗漏。

判别式是 Jacobian 零集在商空间中的像。可通过消去 xx 变量,从方程 yi=fi(x)y_i=f_i(x)J(x)=0J(x)=0 得到商坐标中的判别式 Δ(y)=0\Delta(y)=0。在显式覆盖问题中,Δ\Delta 控制参数何时出现非自由轨道、根碰撞或稳定子增大;沿判别式的局部单值通常由一个反射生成。因此不变量计算与分支覆盖计算在 Jacobian 因子分解处完全相接。

进一步计算专题:Reynolds 算子、Noether 界与次级不变量

对任意有限群 GG,只要特征不整除 |G||G|,平均算子

(f)=1|G|gGgf\mathcal R(f)=\frac1{|G|}\sum_{g\in G}g\cdot f

把多项式投影到不变量子空间,称为 Reynolds 算子。它满足

(hf)=h(f)(hK[V]G),\mathcal R(hf)=h\mathcal R(f) \qquad(h\in K[V]^G),

所以是不变量环上的线性投影。

定理 Noether 次数界

在非模特征下,有限群不变量环 K[V]GK[V]^G 可由次数不超过 |G||G| 的齐次不变量生成。

这个界通常很粗,却保证逐次数搜索必在有限位置终止。算法上,对每个单项式应用 Reynolds 平均,取新不变量并用已有生成元做线性约化;当 Molien 级数预测的各次维数都被生成空间达到,便可停止。

反射群是最简单的极端:存在 nn 个代数独立基本不变量,整个环就是多项式环。一般有限群虽未必多项式,但在非模特征下仍是 Cohen–Macaulay,可取齐次参数系统

f1,,fnf_1,\ldots,f_n

使不变量环成为有限自由模:

K[V]G=j=1sηjK[f1,,fn]. K[V]^G=\bigoplus_{j=1}^s \eta_j K[f_1,\ldots,f_n].

fif_i 称主不变量,ηj\eta_j 称次级不变量。

Hilbert 形式 Hironaka 分解

若主不变量次数为 did_i、次级不变量次数为 eje_j,则

H(t)=j=1steji=1n(1tdi).H(t)= \frac{\sum_{j=1}^s t^{e_j}} {\prod_{i=1}^n(1-t^{d_i})}.

特别地,令 t1t\to1 并比较最高阶极点,得到

sidi=1|G|,s=idi|G|. \frac{s}{\prod_i d_i}=\frac1{|G|}, \qquad s=\frac{\prod_i d_i}{|G|}.

反射群可选 di=|G|\prod d_i=|G|,所以 s=1s=1,没有非平凡次级不变量;这与 Chevalley–Shephard–Todd 定理一致。对非反射群,s>1s>1 精确衡量不变量环相对多项式环的有限模复杂度。

算法 主—次不变量构造

先用随机 Jacobian 测试逐个选择代数独立主不变量;由 Molien 级数除以 (1tdi)\prod(1-t^{d_i}) 得到次级次数多项式;在每个所需次数生成 Reynolds 不变量,并模主不变量理想约化;选择余不变量商中的线性独立代表作为 ηj\eta_j;最后检查所有预测次数和模秩。

商环

K[V]G/(f1,,fn)K[V]^G/(f_1,\ldots,f_n)

的维数就是次级不变量数 ss。计算时可在有限域良素数上完成 Gröbner 基与线性代数,再提升到特征零。若素数整除群阶,Reynolds 算子失效且 Cohen–Macaulay 性可能失败,这种模特征不能用于直接推断特征零的次级结构。

稳定子也可由商映射的局部结构读取。若点 vv 的稳定子 GvG_v 非平凡,则商在其像附近解析同构于 V/GvV/G_v;若 GvG_v 不是反射生成,商点通常奇异。Jacobian 判别式只检测伪反射造成的分支,商奇异集还可能含更高余维的非反射稳定子像。因而验证商空间光滑性时,不能只看 Jacobian 超曲面,还应分析稳定子层次或局部不变量环。

补充计算:Reynolds 算子、Molien 级数与反射超平面 Jacobian

定理 Shephard–Todd–Chevalley 判据的 Jacobian 方向

设 \(G⊂GL(V)\) 为有限复反射群,\(K[V]^G=K[f_1,…,f_n]\),\(deg f_i=d_i\)。则 i=1ndi=|G|, \prod_{i=1}^n d_i=|G|, 且 Jacobian J=det(fixj) J=\det\left(\frac{\partial f_i}{\partial x_j}\right) 在每个反射超平面 H 上的消失阶为 \(e_H-1\),其中 \(e_H\) 是逐点稳定子 \(G_H\) 的阶。因此 J=cHαHeH1. J=c\prod_H\alpha_H^{e_H-1}.

证明 由商映射局部模型与次数比较

在一般点处商映射 \(π:V→V/G\) 为 |G| 对 1。若不变量环为多项式环,则 π 的代数次数等于基本不变量次数乘积,故 \(∏d_i=|G|\)。在反射超平面 H 的一般点选局部坐标,使 \(G_H\) 只在法向坐标 \(z_1\) 上作用为 \(z_1↦ζz_1\);商局部坐标为 \(z_1^{e_H},z_2,…,z_n\)。其 Jacobian 含 \(z_1^{e_H-1}\),故 J 沿 H 的阶为 \(e_H-1\)。

J 的总次数为 \(∑(d_i-1)\)。反射超平面乘积右端的总次数等于全部伪反射的数目,也等于 \(∑(d_i-1)\)。两者具有相同零除子与次数,商为非零常数。

Python 矩阵群闭包、Reynolds 投影、Molien 平均与余不变量
from fractions import Fraction
from collections import deque
import sympy as sp

x,y,t=sp.symbols("x y t")

def matmul(A,B):
    return tuple(tuple(sum(A[i][k]*B[k][j] for k in range(len(B)))
                       for j in range(len(B[0])))
                 for i in range(len(A)))

def eye(n):
    return tuple(tuple(Fraction(i==j) for j in range(n)) for i in range(n))

def inv2(A):
    a,b=A[0];c,d=A[1]
    det=a*d-b*c
    return ((d/det,-b/det),(-c/det,a/det))

def group_closure(generators):
    n=len(generators[0])
    gens=generators+[inv2(g) for g in generators]
    G={eye(n)}
    q=deque([eye(n)])
    while q:
        h=q.popleft()
        for g in gens:
            gh=matmul(g,h)
            if gh not in G:
                G.add(gh);q.append(gh)
    return sorted(G,key=repr)

def act_poly(g,f):
    X=g[0][0]*x+g[0][1]*y
    Y=g[1][0]*x+g[1][1]*y
    return sp.expand(f.subs({x:X,y:Y},simultaneous=True))

def reynolds(G,f):
    return sp.expand(sum(act_poly(g,f) for g in G)/len(G))

def homogeneous_monomials(degree):
    return [x**i*y**(degree-i) for i in range(degree+1)]

def invariant_basis(G,degree):
    vectors=[]
    mons=homogeneous_monomials(degree)
    for m in mons:
        r=reynolds(G,m)
        vectors.append([sp.Poly(r,x,y).coeff_monomial(mm) for mm in mons])
    M=sp.Matrix(vectors).T
    basis=[]
    for col in M.columnspace():
        basis.append(sp.expand(sum(col[i]*mons[i] for i in range(len(mons)))))
    return basis

def molien(G):
    I=sp.eye(2)
    total=0
    for g in G:
        M=sp.Matrix(g)
        total+=1/sp.factor((I-t*M).det())
    return sp.factor(total/len(G))

def reflection_rank(g):
    M=sp.Matrix(g)-sp.eye(2)
    return M.rank()

s1=((Fraction(-1),Fraction(0)),(Fraction(0),Fraction(1)))
s2=((Fraction(0),Fraction(1)),(Fraction(1),Fraction(0)))
G=group_closure([s1,s2])

print("B2 reflection group:")
print("  order =",len(G))
for i,g in enumerate(G):
    det=sp.Matrix(g).det()
    print(f"  g{i}: {g}, det={det}, rank(g-I)={reflection_rank(g)}")

print("\nMolien series:")
M=molien(G)
print("  exact =",M)
print("  series =",sp.series(M,t,0,17))

print("\ninvariant bases by degree:")
for d in range(0,9):
    basis=invariant_basis(G,d)
    print(f"  degree {d}: dim={len(basis)}")
    for f in basis:
        print("    ",sp.factor(f))

f2=x**2+y**2
f4=x**2*y**2
J=sp.factor(sp.det(sp.Matrix([
    [sp.diff(f2,x),sp.diff(f2,y)],
    [sp.diff(f4,x),sp.diff(f4,y)]
])))
print("\nbasic invariants:")
print("  f2 =",f2)
print("  f4 =",f4)
print("  Jacobian =",J)
print("  Jacobian degree =",sp.total_degree(J))

print("\nreflection hyperplane product:")
linear_forms=[x,y,x-y,x+y]
product=sp.factor(sp.prod(linear_forms))
print("  product =",product)
print("  Jacobian/product =",sp.factor(J/product))

print("\ncoinvariant Hilbert polynomial:")
coinvariant=sp.expand((1-t**2)*(1-t**4)/(1-t)**2)
print(" ",sp.factor(coinvariant))
print(" ",sp.series(coinvariant,t,0,10))
print("  dimension =",2*4)
运行结果 B2 阶 8 反射群的完整低次不变量计算
B2 reflection group:
  order = 8
  g0: ((Fraction(-1, 1), Fraction(0, 1)), (Fraction(0, 1), Fraction(-1, 1))), det=1, rank(g-I)=2
  g1: ((Fraction(-1, 1), Fraction(0, 1)), (Fraction(0, 1), Fraction(1, 1))), det=-1, rank(g-I)=1
  g2: ((Fraction(0, 1), Fraction(-1, 1)), (Fraction(-1, 1), Fraction(0, 1))), det=-1, rank(g-I)=1
  g3: ((Fraction(0, 1), Fraction(-1, 1)), (Fraction(1, 1), Fraction(0, 1))), det=1, rank(g-I)=2
  g4: ((Fraction(0, 1), Fraction(1, 1)), (Fraction(-1, 1), Fraction(0, 1))), det=1, rank(g-I)=2
  g5: ((Fraction(0, 1), Fraction(1, 1)), (Fraction(1, 1), Fraction(0, 1))), det=-1, rank(g-I)=1
  g6: ((Fraction(1, 1), Fraction(0, 1)), (Fraction(0, 1), Fraction(-1, 1))), det=-1, rank(g-I)=1
  g7: ((Fraction(1, 1), Fraction(0, 1)), (Fraction(0, 1), Fraction(1, 1))), det=1, rank(g-I)=0

Molien series:
  exact = 1/((t - 1)**2*(t + 1)**2*(t**2 + 1))
  series = 1 + t**2 + 2*t**4 + 2*t**6 + 3*t**8 + 3*t**10 + 4*t**12 + 4*t**14 + 5*t**16 + O(t**17)

invariant bases by degree:
  degree 0: dim=1
     1
  degree 1: dim=0
  degree 2: dim=1
     (x**2 + y**2)/2
  degree 3: dim=0
  degree 4: dim=2
     (x**4 + y**4)/2
     x**2*y**2
  degree 5: dim=0
  degree 6: dim=2
     (x**2 + y**2)*(x**4 - x**2*y**2 + y**4)/2
     x**2*y**2*(x**2 + y**2)/2
  degree 7: dim=0
  degree 8: dim=3
     (x**8 + y**8)/2
     x**2*y**2*(x**4 + y**4)/2
     x**4*y**4

basic invariants:
  f2 = x**2 + y**2
  f4 = x**2*y**2
  Jacobian = 4*x*y*(x - y)*(x + y)
  Jacobian degree = 4

reflection hyperplane product:
  product = x*y*(x - y)*(x + y)
  Jacobian/product = 4

coinvariant Hilbert polynomial:
  (t + 1)**2*(t**2 + 1)
  1 + 2*t + 2*t**2 + 2*t**3 + t**4 + O(t**10)
  dimension = 8
计算 B2 的基本次数与判别式

取 f_2=x^2+y^2、f_4=x^2y^2。其次数乘积 2·4=8=|W(B_2)|。Jacobian 为 4xy(x-y)(x+y),四个线性因子正对应 x=0、y=0、x=y、x=-y 四条反射超平面。余不变量 Hilbert 多项式为 (1+t)^2(1+t^2),系数和为 8。

Lecture 17 / 第 17 讲

Hilbert–Molien 级数与 A4,S4,A5A_4,S_4,A_5 的球面作用

用迹平均计算不变量维数,并连接正多面体群、二元多面体群和 Klein 不变量。

Molien级数多面体群Klein不变量

1. Hilbert 级数

分次向量空间 R=m0RmR=\bigoplus_{m\ge0}R_m 的 Hilbert 级数为

HR(t)=m0(dimRm)tm.H_R(t)=\sum_{m\ge0}(\dim R_m)t^m.

R=k[f1,,fn]R=k[f_1,\ldots,f_n]degfi=di\deg f_i=d_i,则

HR(t)=i=1n11tdi.H_R(t)=\prod_{i=1}^n\frac1{1-t^{d_i}}.
定理Molien 公式

对有限群表示 GVG\curvearrowright V

Hk[V]G(t)=1|G|gG1det(Itg).H_{k[V]^G}(t)=\frac1{|G|}\sum_{g\in G}\frac1{\det(I-tg)}.
证明迹平均

Reynolds 投影 |G|1gg|G|^{-1}\sum_g gSymm(V*)\operatorname{Sym}^m(V^*) 上的迹等于不变量子空间维数。把各次数的迹生成函数相加,而 mtr(g|SymmV*)tm=1/det(Itg)\sum_m\operatorname{tr}(g|\operatorname{Sym}^mV^*)t^m=1/\det(I-tg)

2. 球面有限群

有限子群 PGL2(𝐂)\mathrm{PGL}_2(\mathbf C) 分类为循环群、二面体群以及正四面体、正八面体、正二十面体旋转群 A4,S4,A5A_4,S_4,A_5。其在球面上的特殊轨道是顶点、边中点和面中心,稳定子阶给出商映射 𝐏1𝐏1/G\mathbf P^1\to\mathbf P^1/G 的三个分歧型。

典型分歧阶
A4A_412(2,3,3)(2,3,3)
S4S_424(2,3,4)(2,3,4)
A5A_560(2,3,5)(2,3,5)

3. Klein 的二十面体不变量

对二元二十面体群,可选择次数 12,20,3012,20,30 的齐次形式 F,H,TF,H,T,它们满足一个权齐次关系;在常见归一化中可写成

T2+H3=1728F5,T^2+H^3=1728F^5,

但符号和常数随具体定义改变。比固定某个归一化更本质的是次数 12,20,3012,20,30 以及指数 2,3,52,3,5,它们正对应球面三角群 (2,3,5)(2,3,5)

说明二元群与射影群

A4,S4,A5PGL2A_4,S_4,A_5\subset\mathrm{PGL}_2 的逆像位于 SL2\mathrm{SL}_2,分别称二元四面体、二元八面体和二元二十面体群。齐次形式属于二元群表示,而其零点集投影到球面上的多面体轨道。

Hilbert 级数与 Molien 公式

对分次向量空间 U=d0UdU=\bigoplus_{d\ge0}U_d,Hilbert 级数为

HU(t)=d0dimUdtd.H_U(t)=\sum_{d\ge0}\dim U_d\,t^d.

U=𝐂[V]GU=\mathbf C[V]^G 时称为表示的 Molien 级数。若不变量环是基本次数 d1,,dnd_1,\ldots,d_n 的多项式环,则

H𝐂[V]G(t)=i=1n11tdi.H_{\mathbf C[V]^G}(t)=\prod_{i=1}^{n}\frac1{1-t^{d_i}}.

有限群表示的固定子空间维数等于群平均的迹。应用于每个对称幂并求生成函数,得到 Molien 公式

H𝐂[V]G(t)=1|G|gG1det(Itg).H_{\mathbf C[V]^G}(t) =\frac1{|G|}\sum_{g\in G}\frac1{\det(I-tg)}.

实际计算只需按共轭类求和。每项分母由 ggVV 上的特征值决定。

两个基本检验

V=𝐂V=\mathbf CG=μmG=\mu_m,则

1mζm=111ζt=11tm.\frac1m\sum_{\zeta^m=1}\frac1{1-\zeta t} =\frac1{1-t^m}.

V=𝐂2V=\mathbf C^2G={±I}G=\{\pm I\},则

12(1(1t)2+1(1+t)2)=1+t2(1t2)2=1t4(1t2)3.\frac12\left(\frac1{(1-t)^2}+\frac1{(1+t)^2}\right) =\frac{1+t^2}{(1-t^2)^2} =\frac{1-t^4}{(1-t^2)^3}.

这表明不变量环不是多项式环,而是由 x2,xy,y2x^2,xy,y^2 三个二次元生成,并满足一个四次关系

x2y2(xy)2=0.x^2y^2-(xy)^2=0.

Hilbert 级数的分子记录关系与更高 syzygy;但同一个有理函数可能有多种形式,不能仅凭一种因式分解断言最小自由分解,仍需结合 Cohen–Macaulay 性与生成元计算。

球面有限旋转群

PGL2(𝐂)\operatorname{PGL}_2(\mathbf C) 的有限子群分类为循环群、二面体群以及 A4,S4,A5A_4,S_4,A_5,分别对应正四面体、正八面体/立方体、正二十面体/十二面体的旋转群。商映射

𝐏1𝐏1/G\mathbf P^1\longrightarrow\mathbf P^1/G

是三点分歧 Galois 覆盖。三种多面体群的分歧指数分别为

(2,3,3),(2,3,4),(2,3,5).(2,3,3),\qquad(2,3,4),\qquad(2,3,5).

由 Riemann–Hurwitz 可验证群阶分别为 12,24,6012,24,60

2=|G|(1a+1b+1c1).2=|G|\left(\frac1a+\frac1b+\frac1c-1\right).

从射影群到二元多面体群

SL2(𝐂)PGL2(𝐂)\operatorname{SL}_2(\mathbf C)\to\operatorname{PGL}_2(\mathbf C) 的逆像,得到二元四面体、二元八面体、二元二十面体群,阶分别为 24,48,12024,48,120。它们包含中心 {±I}\{\pm I\},作用于二元形式 𝐂[x,y]\mathbf C[x,y]。再加入适当标量,可得到 Shephard–Todd 二维反射群;其不变量往往由顶点、边中点、面中心轨道对应的二元形式,以及它们的 Hessian、Jacobian 生成。

轨道形式与 Belyi 恒等式

若有限球面群有三个特殊轨道,取分别在这些轨道消失的齐次二元形式 F,H,TF,H,T。它们的次数等于轨道大小。由于商 𝐏1/G\mathbf P^1/G 只有三个分支值,F,H,TF,H,T 的适当幂必满足一个三项齐次恒等式,例如二十面体情形的经典形式

T2+H3=1728F5T^2+H^3=1728F^5

在一种规范下成立。相应比值 H3/F5H^3/F^5T2/F5T^2/F^5 是 Belyi 函数。这个结构同时解释了多面体不变量、三点覆盖、超几何方程和 Klein 的解五次理论之间的联系。

用 Molien 级数指导生成元搜索

计算不变量时,先由 Molien 级数读出每个次数的不变量维数,再逐次线性代数求解。若预期为多项式环,分母可给出基本次数;若为有限自由模,常可写成

H(t)=te1++teri(1tdi),H(t)=\frac{t^{e_1}+\cdots+t^{e_r}} {\prod_i(1-t^{d_i})},

表示不变量环作为参数子环上的自由模,其次级不变量次数为 eje_j。这种结构避免在高次数中盲目枚举所有单项式。

Molien 公式的逐次数推导

对有限群表示 WW,固定子空间投影为 |G|1gg|G|^{-1}\sum_g g,因此

dimWG=1|G|gGtr(g|W).\dim W^G=\frac1{|G|}\sum_{g\in G}\operatorname{tr}(g|W).

W=Symd(V)W=\operatorname{Sym}^d(V^\vee)。若 gg 的特征值为 λ1,,λn\lambda_1,\ldots,\lambda_n,则对称幂特征标的生成函数为

d0tr(g|SymdV)td=i=1n11λi1t.\sum_{d\ge0}\operatorname{tr}(g|\operatorname{Sym}^dV^\vee)t^d =\prod_{i=1}^n\frac1{1-\lambda_i^{-1}t}.

把群平均与求和交换即得 Molien 公式。若采用坐标函数上的逆对偶作用,特征值是否取逆只取决于约定;有限阶单位根下两者经共轭类求和给出同一维数序列。

从 Hilbert 级数读出生成元和模结构

有限群不变量环在特征 0 中是 Cohen–Macaulay 环,因此存在代数无关齐次主不变量 f1,,fnf_1,\ldots,f_n,使

𝐂[V]G=j=1rηj𝐂[f1,,fn]\mathbf C[V]^G=\bigoplus_{j=1}^r \eta_j\, \mathbf C[f_1,\ldots,f_n]

为自由模。于是

H(t)=jtdegηji(1tdegfi).H(t)=\frac{\sum_j t^{\deg\eta_j}}{\prod_i(1-t^{\deg f_i})}.

分子系数若全非负,可解释为次不变量次数;但主不变量的选择不唯一,先约分后的任意分母不一定对应一组实际参数。必须显式找到代数无关元素,并检验自由模秩 r=|G|/idegfir=|G|/\prod_i\deg f_i

二元多面体群与 Kleinian 奇点

有限旋转群 A4,S4,A5PGL2A_4,S_4,A_5\subset\operatorname{PGL}_2 的二重覆盖嵌入 SL2\operatorname{SL}_2,得到二元四面体、八面体、二十面体群。它们不由二维复反射生成,所以 𝐂[x,y]G\mathbf C[x,y]^G 不是多项式环,而是一个超曲面环。McKay 对应把它们分别关联到 E6,E7,E8E_6,E_7,E_8 Dynkin 图。

典型形式为三个齐次不变量 F,H,TF,H,T 满足一个关系。对二元二十面体群,可选择次数 12,20,3012,20,30 的 Klein 形式,并有加权齐次关系

T2+H3+F5=0T^2+H^3+F^5=0

在适当标量规范下成立。商曲面 𝐂2/G\mathbf C^2/G 因而是 E8E_8 型有理双点。不同文献的常数与符号不同,比较公式时应先统一生成元缩放。

从球面轨道构造基本形式

𝐏1\mathbf P^1 看作 Riemann 球面。正多面体旋转群有三类特殊轨道:顶点、面心、棱中点。对每个轨道取相应线性因子的乘积,得到二元齐次形式 FV,FF,FEF_V,F_F,F_E。它们在二元群下至多乘字符;适当幂或规范后成为不变量。三类稳定子阶 (p,q,r)(p,q,r) 满足

1p+1q+1r>1,\frac1p+\frac1q+\frac1r>1,

对应四面体 (2,3,3)(2,3,3)、八面体 (2,3,4)(2,3,4)、二十面体 (2,3,5)(2,3,5)。轨道大小与形式次数由轨道—稳定子定理直接给出。

Hessian 与 Jacobian 自动生成其余轨道

从一个顶点形式 FF 出发,Hessian

H=det(FxxFxyFxyFyy)H=\det\begin{pmatrix}F_{xx}&F_{xy}\\F_{xy}&F_{yy}\end{pmatrix}

往往给出另一特殊轨道;再取 Jacobian T=FxHyFyHxT=F_xH_y-F_yH_x 得第三轨道。次数分别为 degH=2degF4\deg H=2\deg F-4degT=3degF6\deg T=3\deg F-6。结合 Molien 级数,可证明它们生成整个不变量环并满足唯一关系。

例:二元四面体群的次数检查

二元四面体群阶 24。其不变量环可由次数 6,8,126,8,12 的形式生成,并有次数 24 的一个关系,因此

H(t)=1t24(1t6)(1t8)(1t12).H(t)=\frac{1-t^{24}}{(1-t^6)(1-t^8)(1-t^{12})}.

t1t\to1 时,(1t)2H(t)1/24(1-t)^2H(t)\to1/24,与一般公式 limt1(1t)nH(t)=1/|G|\lim_{t\to1}(1-t)^nH(t)=1/|G| 一致。这个极限是检查 Hilbert 级数分子分母是否丢因子的快速方法。

从不变量到 𝐏1\mathbf P^1 上的 Belyi 映射

三个特殊轨道形式的关系可整理成

β=FVpcFE2,1β=FFqcFE2,\beta=\frac{F_V^{p}}{cF_E^{2}}, \qquad 1-\beta=\frac{F_F^{q}}{cF_E^{2}},

其中次数配平。于是 β:𝐏1𝐏1/G\beta:\mathbf P^1\to\mathbf P^1/G 只在 0,1,0,1,\infty 分歧,分歧阶正是三角群数据。这样经典不变量论直接给出多面体 Belyi 映射,也解释其系数为何具有极强对称性。

模素数与特征整除群阶

Molien 平均和 Reynolds 算子需要除以 |G||G|,只在特征不整除群阶时保持良好。若 p|G|p\mid |G|,不变量函子不再正合,Cohen–Macaulay 性可能失效,Hilbert 级数虽仍可定义,却不能从特征 0 公式直接约化。对整数系数不变量做模 pp 验证时,必须把这些坏素数单独处理。

计算专题:Molien 级数的程序化展开与反推

按共轭类计算时,每类只需代表矩阵的特征多项式与类大小。对有理或圆分系数,1/det(Itg)1/\det(I-tg) 的类和最终应在 𝐐(t)\mathbf Q(t) 中。先在共同分母下精确相加,再因式分解;浮点特征值会破坏单位根消去。

若只需低次数维数,可不求完整有理函数,而递推展开每个分母到给定阶。对大群,这比符号通分更快。得到维数序列后,可用 plethystic logarithm 猜测生成元与关系次数:正项提示生成元,负项提示关系;但高 syzygy 会交替出现,这只是启发式。

Cohen–Macaulay 参数系可通过随机齐次不变量选择,然后用 Jacobian 或有限零点检验其代数无关。为了证明环在这些参数上有限,可检查它们共同零点只有原点。次不变量可在商 R/(f1,,fn)R/(f_1,\ldots,f_n) 中求一组齐次基,再提升回 RR

多面体不变量的关系常可由次数唯一性确定:若某个次数的关系空间维数为 1,只需计算一个非零组合。标量常数可在一个方便点代入确定。为跨文献比较,应把每个形式的 leading monomial 或特定轨道值规范化。

Kleinian 奇点的方程可由不变量环完成化得到 ADE 正规形,但坐标变换可能很复杂。验证类型可计算加权次数、Milnor 数和最小解消的交叉图。McKay 对应还把有限群不可约表示对应到解消例外曲线节点。

从不变量构造 Belyi 映射后,必须根据形式零点的实际稳定子检查分歧。若轨道形式有重因子或在二元群中心下只半不变,幂次需要调整。最终次数应等于射影群阶,三个分支循环型应匹配球面三角群。

练习与解答Molien 级数

练习 1。平凡群在 nn 维上的 Molien 级数是什么?

解。1/(1t)n1/(1-t)^n,因为全部多项式均不变。

练习 2。为什么只按共轭类求和?

解。det(Itg)\det(I-tg) 是相似不变量,在同一共轭类恒定;乘类大小即可。

练习 3。分子 1+td1+t^d 可如何解释?

解。在选定主不变量参数系后,环作为自由模有两个次不变量,次数 0 与 dd;解释依赖分母确实对应参数系。

深入补充:Molien 级数的极点、Gorenstein 对称与 ADE 商奇点

对有限群 GGL(V)G\subset\operatorname{GL}(V),Molien 公式

H(t)=1|G|gG1det(Itg)H(t)=\frac1{|G|}\sum_{g\in G}\frac1{\det(I-tg)}

不仅给出每次齐次不变量的维数,还能从 t=1t=1 附近读出商映射的次数。只有恒等元在 t=1t=1 产生 nn 阶极点,因此

H(t)=1|G|(1t)n+O((1t)1n).H(t)=\frac1{|G|(1-t)^n}+O((1-t)^{1-n}).

这与“商映射泛型度数为 |G||G|”一致,也是检查程序展开是否正确的首要条件。

定理 特殊线性群中的 Hilbert 级数对称

GSL(V)G\subset\operatorname{SL}(V),则不变量环是 Gorenstein 环,其 Hilbert 级数满足

H(t1)=(1)ntnH(t).H(t^{-1})=(-1)^n t^n H(t).

若写成约分后的有理式,分子系数呈相应的回文对称;不满足该对称通常意味着共轭类、特征值或分母约分出现错误。

二维二元多面体群都包含于 SL2(𝐂)\operatorname{SL}_2(\mathbf C)。其商 𝐂2/G\mathbf C^2/G 是 Kleinian 双有理奇点,坐标环由三个齐次不变量及一个关系生成。经解析坐标变换,关系分别具有 ADE 形:

An:xyzn+1=0,A_n:\,xy-z^{n+1}=0,
Dn:x2+yn1+yz2=0,D_n:\,x^2+y^{n-1}+yz^2=0,

以及

E6:x2+y3+z4=0,E7:x2+y3+yz3=0,E8:x2+y3+z5=0.E_6: x^2+y^3+z^4=0, \quad E_7: x^2+y^3+yz^3=0, \quad E_8: x^2+y^3+z^5=0.

这里的加权次数由三个基本形式的次数决定。群的非平凡不可约表示与最小解消中的例外曲线一一对应,交图正是相应 Dynkin 图,这就是 McKay 对应的二维核心。

算法 由 Molien 级数反推生成元与关系

先展开到足够次数,找到最早出现的新不变量次数;逐次构造候选并减去已有生成元的乘积空间。若猜测环为超曲面

𝐂[F1,F2,F3]/(R),\mathbf C[F_1,F_2,F_3]/(R),

则 Hilbert 级数应为

1tdegR(1td1)(1td2)(1td3).\frac{1-t^{\deg R}}{(1-t^{d_1})(1-t^{d_2})(1-t^{d_3})}.

比较若干十项系数可确定 did_idegR\deg R,随后用线性代数求唯一关系并精确验证。

对球面多面体群,三个特殊轨道——顶点、棱中点和面心——对应三个二元形式。它们的次数与稳定子阶满足轨道—稳定子公式,并产生一个齐次关系。把两个形式的适当幂之比作为 𝐏1\mathbf P^1 上函数,三个特殊轨道分别映到 0,1,0,1,\infty,从而得到 Belyi 映射。Molien 级数在此提前预测“需要几个生成元、在哪些次数出现、关系在哪一度”,Hessian 与 Jacobian 则提供显式构造。

当特征 pp 整除 |G||G| 时,平均算子 |G|1gg|G|^{-1}\sum_g g 不存在,Molien 公式的半单表示论推导失效;不变量环可能不再 Cohen–Macaulay,Hilbert 级数仍可定义但不能照搬特征零结构。模素数实验应选择 p|G|p\nmid|G|,并在重构后回到特征零验证。

补充计算:球面旋转群的 Molien 平均与 ADE 超曲面环

定理 二元多面体群不变量环的超曲面形式

二元四面体、八面体、二十面体群在 \(K[u,v]\) 上的不变量环分别具有 Hilbert 级数 H2T(t)=1t24(1t6)(1t8)(1t12), H_{2T}(t)=\frac{1-t^{24}}{(1-t^6)(1-t^8)(1-t^{12})}, H2O(t)=1t36(1t8)(1t12)(1t18), H_{2O}(t)=\frac{1-t^{36}}{(1-t^8)(1-t^{12})(1-t^{18})}, H2I(t)=1t60(1t12)(1t20)(1t30). H_{2I}(t)=\frac{1-t^{60}}{(1-t^{12})(1-t^{20})(1-t^{30})}. 三者均为三生成元一关系的 Gorenstein 超曲面环,a-不变量均为 -2。

证明 由 Molien 级数与 Cohen–Macaulay 分解比较

对有限群 \(G⊂SL_2(K)\),Molien 公式为 \(H(t)=|G|^{-1}∑_{g∈G}det(I-tg)^{-1}\)。按共轭类及特征值求和并化简,得到所列有理函数。分母次数给出三个齐次参数,分子 \(1-t^r\) 表明在次数 r 有唯一首要关系;系数展开非负并与逐次数 Reynolds 投影所得维数相同,因此 Hilbert 级数确定该自由模结构。

因 \(G⊂SL_2\),Watanabe 判据给出不变量环 Gorenstein。超曲面表示中 \(a=r-(d_1+d_2+d_3)\)。三种情形分别为 24-26、36-38、60-62,均等于 -2,与二维 Kleinian 商奇点的典范权一致。

Python SO(3) 共轭类 Molien 求和与二元多面体 Hilbert 系数
import sympy as sp
from dataclasses import dataclass

t=sp.Symbol("t")

@dataclass(frozen=True)
class RotationClass:
    size: int
    order: int
    cosine: sp.Expr

def denominator_so3(cosine):
    # eigenvalues 1, exp(±i theta)
    return sp.expand((1-t)*(1-2*cosine*t+t**2))

def molien_from_rotation_classes(classes):
    order=sum(c.size for c in classes)
    value=sum(sp.Rational(c.size,order)/denominator_so3(c.cosine)
              for c in classes)
    return sp.factor(sp.cancel(value))

def rational_series_coeffs(H,N):
    num,den=map(sp.Poly,sp.fraction(sp.cancel(H)))
    ncoef=[num.nth(i) for i in range(max(N,num.degree())+1)]
    dcoef=[den.nth(i) for i in range(den.degree()+1)]
    d0=dcoef[0]
    out=[]
    for k in range(N+1):
        rhs=ncoef[k] if k<len(ncoef) else 0
        rhs-=sum(dcoef[j]*out[k-j]
                 for j in range(1,min(k,den.degree())+1))
        out.append(sp.simplify(rhs/d0))
    return out

A4=[
    RotationClass(1,1,sp.Integer(1)),
    RotationClass(3,2,sp.Integer(-1)),
    RotationClass(8,3,sp.Rational(-1,2)),
]
S4=[
    RotationClass(1,1,sp.Integer(1)),
    RotationClass(9,2,sp.Integer(-1)),
    RotationClass(8,3,sp.Rational(-1,2)),
    RotationClass(6,4,sp.Integer(0)),
]
A5=[
    RotationClass(1,1,sp.Integer(1)),
    RotationClass(15,2,sp.Integer(-1)),
    RotationClass(20,3,sp.Rational(-1,2)),
    RotationClass(12,5,(sp.sqrt(5)-1)/4),
    RotationClass(12,5,(-sp.sqrt(5)-1)/4),
]

def hypersurface_hilbert(degrees,relation):
    return sp.factor((1-t**relation)/sp.prod(1-t**d for d in degrees))

groups={"A4":A4,"S4":S4,"A5":A5}
for name,classes in groups.items():
    H=molien_from_rotation_classes(classes)
    print(name)
    print("  order =",sum(c.size for c in classes))
    print("  Molien =",H)
    print("  coefficients 0..18 =",rational_series_coeffs(H,18))

print("\nbinary polyhedral invariant rings:")
binary={
    "2T / E6":((6,8,12),24),
    "2O / E7":((8,12,18),36),
    "2I / E8":((12,20,30),60),
}
for name,(degrees,relation) in binary.items():
    H=hypersurface_hilbert(degrees,relation)
    print(f"  {name}:")
    print("    H =",H)
    print("    coeffs 0..30 =",rational_series_coeffs(H,30))
    print("    degree product / relation =",sp.prod(degrees)//relation)

print("\nicosahedral degree semigroup up to 90:")
representations={}
for a in range(8):
    for b in range(5):
        for c in range(4):
            d=12*a+20*b+30*c
            if d<=90:
                representations.setdefault(d,[]).append((a,b,c))
for d in sorted(representations):
    print(f"  degree {d:3d}: count={len(representations[d]):2d}, "
          f"first={representations[d][:5]}")

print("\nGorenstein a-invariants:")
for name,(degrees,relation) in binary.items():
    a_invariant=relation-sum(degrees)
    print(
        f"  {name}: relation={relation}, sum={sum(degrees)}, "
        f"a={a_invariant}"
    )
运行结果 A4、S4、A5 旋转不变量与 E6、E7、E8 次数半群
A4
  order = 12
  Molien = -(t**4 - t**2 + 1)/((t - 1)**3*(t + 1)**2*(t**2 + t + 1))
  coefficients 0..18 = [1, 0, 1, 1, 2, 1, 4, 2, 5, 4, 7, 5, 10, 7, 12, 10, 15, 12, 19]
S4
  order = 24
  Molien = -(t**6 - t**3 + 1)/((t - 1)**3*(t + 1)**2*(t**2 + 1)*(t**2 + t + 1))
  coefficients 0..18 = [1, 0, 1, 0, 2, 0, 3, 0, 4, 1, 5, 1, 7, 2, 8, 3, 10, 4, 12]
A5
  order = 60
  Molien = -(t**8 + t**7 - t**5 - t**4 - t**3 + t + 1)/((t - 1)**3*(t + 1)**2*(t**2 + t + 1)*(t**4 + t**3 + t**2 + t + 1))
  coefficients 0..18 = [1, 0, 1, 0, 1, 0, 2, 0, 2, 0, 3, 0, 4, 0, 4, 1, 5, 1, 6]

binary polyhedral invariant rings:
  2T / E6:
    H = (t**8 - t**4 + 1)/((t - 1)**2*(t + 1)**2*(t**2 + 1)*(t**2 - t + 1)*(t**2 + t + 1))
    coeffs 0..30 = [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 1, 0, 1, 0, 2, 0, 2, 0, 1, 0, 3, 0, 2, 0, 2, 0, 3]
    degree product / relation = 24
  2O / E7:
    H = (t**12 - t**6 + 1)/((t - 1)**2*(t + 1)**2*(t**2 + 1)*(t**4 + 1)*(t**2 - t + 1)*(t**2 + t + 1))
    coeffs 0..30 = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 2, 0, 1, 0, 1, 0, 1]
    degree product / relation = 48
  2I / E8:
    H = (t**16 + t**14 - t**10 - t**8 - t**6 + t**2 + 1)/((t - 1)**2*(t + 1)**2*(t**2 + 1)*(t**2 - t + 1)*(t**2 + t + 1)*(t**4 - t**3 + t**2 - t + 1)*(t**4 + t**3 + t**2 + t + 1))
    coeffs 0..30 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]
    degree product / relation = 120

icosahedral degree semigroup up to 90:
  degree   0: count= 1, first=[(0, 0, 0)]
  degree  12: count= 1, first=[(1, 0, 0)]
  degree  20: count= 1, first=[(0, 1, 0)]
  degree  24: count= 1, first=[(2, 0, 0)]
  degree  30: count= 1, first=[(0, 0, 1)]
  degree  32: count= 1, first=[(1, 1, 0)]
  degree  36: count= 1, first=[(3, 0, 0)]
  degree  40: count= 1, first=[(0, 2, 0)]
  degree  42: count= 1, first=[(1, 0, 1)]
  degree  44: count= 1, first=[(2, 1, 0)]
  degree  48: count= 1, first=[(4, 0, 0)]
  degree  50: count= 1, first=[(0, 1, 1)]
  degree  52: count= 1, first=[(1, 2, 0)]
  degree  54: count= 1, first=[(2, 0, 1)]
  degree  56: count= 1, first=[(3, 1, 0)]
  degree  60: count= 3, first=[(0, 0, 2), (0, 3, 0), (5, 0, 0)]
  degree  62: count= 1, first=[(1, 1, 1)]
  degree  64: count= 1, first=[(2, 2, 0)]
  degree  66: count= 1, first=[(3, 0, 1)]
  degree  68: count= 1, first=[(4, 1, 0)]
  degree  70: count= 1, first=[(0, 2, 1)]
  degree  72: count= 3, first=[(1, 0, 2), (1, 3, 0), (6, 0, 0)]
  degree  74: count= 1, first=[(2, 1, 1)]
  degree  76: count= 1, first=[(3, 2, 0)]
  degree  78: count= 1, first=[(4, 0, 1)]
  degree  80: count= 3, first=[(0, 1, 2), (0, 4, 0), (5, 1, 0)]
  degree  82: count= 1, first=[(1, 2, 1)]
  degree  84: count= 3, first=[(2, 0, 2), (2, 3, 0), (7, 0, 0)]
  degree  86: count= 1, first=[(3, 1, 1)]
  degree  88: count= 1, first=[(4, 2, 0)]
  degree  90: count= 3, first=[(0, 0, 3), (0, 3, 1), (5, 0, 1)]

Gorenstein a-invariants:
  2T / E6: relation=24, sum=26, a=-2
  2O / E7: relation=36, sum=38, a=-2
  2I / E8: relation=60, sum=62, a=-2
计算 二十面体次数 60 的首个关系

次数 60 可由 12·5、20·3、30·2 三种方式达到,因此三个基本不变量的相应幂首次发生线性关系。Hilbert 分子 1-t^60 恰消去其中一个自由单项式。次数乘积除以关系次数为 12·20·30/60=120,等于二元二十面体群阶。

Lecture 18 / 第 18 讲

协变式、Hessian、Jacobian 与显式多面体公式

从不变量推广到取值于表示的协变式,并用微分运算生成显式公式。

协变式HessianJacobian

1. 协变式

定义协变式

GV,WG\curvearrowright V,W。多项式映射 F:VWF:V\to W 若满足 F(gv)=gF(v)F(gv)=gF(v),称为 WW-值协变式。标量值协变式就是不变量;到对偶表示的协变式常由梯度产生。

协变式模是 k[V]Gk[V]^G-模。对反射群,它常是自由模;基本协变式让我们在商空间坐标与原始坐标之间传递。

2. 二元形式的微分构造

对二元齐次形式 F(x,y)F(x,y),Hessian

Hess(F)=FxxFyyFxy2\operatorname{Hess}(F)=F_{xx}F_{yy}-F_{xy}^2

仍是一个协变对象。两个形式的 Jacobian

J(F,G)=FxGyFyGxJ(F,G)=F_xG_y-F_yG_x

给出另一个形式。对正多面体轨道多项式,从一个顶点形式出发,Hessian 常产生对偶多面体的面中心形式,再由 Jacobian 产生边中点形式。

定理零点集合的几何解释

FF 的零点是一个 GG-轨道,Hess(F)\operatorname{Hess}(F)J(F,HessF)J(F,\operatorname{Hess}F) 的零点通常落在具有更大稳定子的其他特殊轨道。次数和 Bézout 数限制了可能的额外零点。

3. 从形式恒等式到 Belyi 函数

若三个相对不变量 F,H,TF,H,T 的零点分别对应三类特殊轨道,而且次数满足某个共同倍数,就可构造

β=cHaFb,β1=cTdFb.\beta=c\frac{H^a}{F^b},\qquad \beta-1=c'\frac{T^d}{F^b}.

选择常数使两式相容,所得函数只在三个特殊轨道分支。验证时应计算导数或直接检查分子分母的重数,而不只依赖群论直觉。

算法显式不变量/协变式计算
  1. 从一个小轨道的点积构造齐次形式。
  2. 用群生成元检查相对不变性。
  3. 计算 Hessian 和 Jacobian。
  4. 因式分解并识别新轨道。
  5. 比较相同权的形式,求出唯一线性关系。
补充归一化警告

经典文献对 Klein 形式的符号、常数和变量次序并不统一。讲义中的恒等式只在明确给出所用形式时才应逐系数比较;几何不变量是次数、零点轨道、分歧指数与生成的函数域。

协变式的概念

不变量是群作用下保持不变的标量多项式;协变式允许输出仍带一个群表示。若 V,WV,WGG-表示,次数 dd 的协变式可视为 GG-等变多项式映射 VWV\to W,或

(SymdVW)G(\operatorname{Sym}^dV^\vee\otimes W)^G

中的元素。对二元形式,协变式同时依赖形式的系数与变量 x,yx,y,在 SL2\operatorname{SL}_2 变换下按规定方式变化。经典不变量论中的 Hessian、Jacobian 与transvectant都是协变式。

SL2\operatorname{SL}_2 的不可约表示

V1V_1 为二维标准表示,Vn=SymnV1V_n=\operatorname{Sym}^nV_1,维数 n+1n+1。在对角环 diag(λ,λ1)\operatorname{diag}(\lambda,\lambda^{-1}) 上,其特征标为

λn+λn2++λn.\lambda^n+\lambda^{n-2}+\cdots+\lambda^{-n}.

Clebsch–Gordan 分解给出

VmVnj=0min(m,n)Vm+n2j.V_m\otimes V_n \cong\bigoplus_{j=0}^{\min(m,n)}V_{m+n-2j}.

特别地,VnVnV_n\otimes V_n 中每个 V2n2jV_{2n-2j} 重数为 1,因此相应等变投影在标量倍意义下唯一,这就是第 jj 个transvectant。

transvectant的微分公式

对二元形式 f,gf,g,第 rr 个transvectant可规范为

(f,g)r=k=0r(1)k(rk)rfxrkykrgxkyrk.(f,g)_r= \sum_{k=0}^{r}(-1)^k\binom{r}{k} \frac{\partial^rf}{\partial x^{r-k}\partial y^k} \frac{\partial^rg}{\partial x^k\partial y^{r-k}}.

r=0r=0 是乘积 fgfgr=1r=1 是 Jacobian 行列式;r=2r=2f=gf=g 给出 Hessian 的标量倍。交换 f,gf,g 时出现 (1)r(-1)^r,故偶数阶对称、奇数阶反对称。

对同次数 nn 的形式,最高阶transvectant是到 𝐂\mathbf C 的不变配对。若

f=i=0nfixiyni,g=i=0ngixiyni,f=\sum_{i=0}^{n}f_ix^iy^{n-i},\qquad g=\sum_{i=0}^{n}g_ix^iy^{n-i},

则它与

i=0n(1)ii!(ni)!figni\sum_{i=0}^{n}(-1)^ii!(n-i)!f_i g_{n-i}

成比例。对偶数 nn,令 g=fg=f 得二次不变量。n=2n=2 时是二次形式判别式;n=4n=4 时与

12ae3bd+c212ae-3bd+c^2

成比例;n=6n=6 时得到第一个 Igusa–Clebsch 不变量 I2I_2

对称平方与外平方

由特征标可得

Sym2VnV2nV2n4V2n8,\operatorname{Sym}^2V_n \cong V_{2n}\oplus V_{2n-4}\oplus V_{2n-8}\oplus\cdots,
2VnV2n2V2n6V2n10.\bigwedge^2V_n \cong V_{2n-2}\oplus V_{2n-6}\oplus V_{2n-10}\oplus\cdots.

这从表示论上解释偶数阶transvectant可由单个形式 ff 的二次协变式得到,而奇数阶对 f=ff=f 必为零。

Hessian 与 Jacobian 生成轨道形式

对一个多面体群的基本轨道形式 FF,Hessian

H=FxxFyyFxy2H=F_{xx}F_{yy}-F_{xy}^2

常在另一特殊轨道上消失;再取 Jacobian

T=(F,H)(x,y)T=\frac{\partial(F,H)}{\partial(x,y)}

得到第三个轨道形式。次数满足 degH=2degF4\deg H=2\deg F-4degT=3degF6\deg T=3\deg F-6。当相应次数的群不变量空间是一维时,三项 T2,H3,FkT^2,H^3,F^k 必线性相关;通过比较一个系数即可确定常数。

协变式模块的 Molien 级数

对输出表示 WW,协变式模块的 Molien 级数为

HG,V,W(t)=1|G|gGtr(g|W)det(Itg|V).H_{G,V,W}(t) =\frac1{|G|}\sum_{g\in G} \frac{\operatorname{tr}(g|W^\vee)} {\det(I-tg|V)}.

它给出每个次数中 WW-型协变式的重数。实际构造可先用梯度、Hessian、Jacobian 与transvectant生成候选,再按 Molien 系数检查是否完备。

transvectant是唯一等变投影

把次数 m,nm,n 的二元形式视为 Vm,VnV_m,V_n。Clebsch–Gordan 分解中 Vm+n2rV_{m+n-2r} 出现一次,所以从 VmVnV_m\otimes V_n 到该分量的非零等变映射在标量倍意义下唯一。微分公式只是这张投影在坐标中的实现;因此验证某个候选双线性微分算子时,只需证明其非零、输出次数正确并与 SL2\operatorname{SL}_2 生成元交换。

次数与阶的双分次

二元 nn 次形式

f(x,y)=i=0n(ni)aixniyif(x,y)=\sum_{i=0}^n\binom ni a_i x^{n-i}y^i

的协变式同时有“系数次数”与“变量阶数”。若 CC 对系数为 dd 次、对 (x,y)(x,y)rr 次,则记双次数 (d,r)(d,r)。transvectant满足

dega(F,G)k=degaF+degaG,ord(F,G)k=ordF+ordG2k.\deg_a (F,G)_k=\deg_aF+\deg_aG, \qquad \operatorname{ord}(F,G)_k=\operatorname{ord}F+\operatorname{ord}G-2k.

只有阶数为 0 的协变式才是不变量。双分次能在搜索生成元时大幅减少候选单项式。

二元四次式的经典不变量

取规范化四次式

f=ax4+4bx3y+6cx2y2+4dxy3+ey4.f=ax^4+4bx^3y+6cx^2y^2+4dxy^3+ey^4.

其两个基本不变量可取

I=ae4bd+3c2,J=ace+2bcdad2b2ec3.I=ae-4bd+3c^2, \qquad J=ace+2bcd-ad^2-b^2e-c^3.

它们分别为系数次数 2、3;判别式在规范差异下为 I327J2I^3-27J^2 的标量倍。用transvectant可写 I(f,f)4I\propto(f,f)_4,而 Hessian H=(f,f)2H=(f,f)_2 是双次数 (2,4)(2,4) 的协变式,再由 (f,H)4(f,H)_4 得到 JJ

二元六次式与亏格 2 曲线

亏格 2 超椭圆曲线可写 y2=f6(x,1)y^2=f_6(x,1)。二元六次式的不变量给出曲线模空间坐标。Igusa–Clebsch 不变量常记 I2,I4,I6,I10I_2,I_4,I_6,I_{10},其中 I10I_{10} 是判别式。绝对不变量由同权比值组成,消除坐标缩放。协变式还可构造 Richelot 同源、识别额外自同构并恢复曲线。

Omega 算子与符号计算

引入两组变量 (x1,y1),(x2,y2)(x_1,y_1),(x_2,y_2) 和 Cayley Omega 算子

Ω12=2x1y22y1x2.\Omega_{12}=\frac{\partial^2}{\partial x_1\partial y_2} -\frac{\partial^2}{\partial y_1\partial x_2}.

(f,g)r=Ω12rf(x1,y1)g(x2,y2)ight|(x1,y1)=(x2,y2)=(x,y)(f,g)_r= \left.\Omega_{12}^r f(x_1,y_1)g(x_2,y_2) ight|_{(x_1,y_1)=(x_2,y_2)=(x,y)}

再乘约定的阶乘因子。这个表示使等变性显然,也适合计算机实现。为避免系数爆炸,应使用稀疏多项式、预计算导数,并在每次操作后除去内容与公因子。

Gordan 算法的思想

经典 Gordan 算法通过反复取transvectant构造二元形式的有限协变式生成集。核心是把所有可能双次数放入有限半群问题,并用已知生成元的乘积与 syzygy 排除冗余。现代实作常结合表示论计算每个双次数的预期维数,再用线性代数检验候选协变式是否张成。

协变式关系的认证

假设发现多项式关系 R(C1,,Cs)=0R(C_1,\ldots,C_s)=0。随机代入只能发现错误,不能证明正确。精确证明可把所有 CiC_i 展开为系数和变量的多项式,再检查系数全零;若规模过大,可在多个良素数上做稀疏插值,重构整数系数后再符号核验。Hilbert–Poincaré 级数可证明生成集与关系集完备。

几何用途:从协变式产生映射

同阶协变式 C0,C1C_0,C_1 的比值给出 GG-不变有理函数 [C0:C1][C_0:C_1],常用于构造商映射或 Belyi 函数。向量值协变式则给出等变自映射,可把一个高对称点轨道送到另一个轨道。Hessian 零点对应原形式的拐点或二阶退化,Jacobian 零点描述两个协变式映射不横截的位置,因此具有直接几何意义。

计算专题:协变式代数的组织与应用

协变式空间可视为 HomG(SymdV,W)\operatorname{Hom}_G(\operatorname{Sym}^dV,W)。其维数可用带特征标的 Molien 公式:

HW(t)=1|G|gGχW(g)¯det(Itg).H_W(t)=\frac1{|G|}\sum_{g\in G}\frac{\overline{\chi_W(g)}}{\det(I-tg)}.

这预言每个系数次数上有多少个 WW-值协变式。对连续群 SL2\operatorname{SL}_2,则用特征标分解或最高权方法。

transvectant实现中规范因子多种多样。若二元形式采用二项式系数规范,经典公式较整洁;若采用普通系数,导数会带额外组合数。比较文献结果时,先对一个单项式对 xm,ynx^m,y^n 计算最高阶transvectant,以确定整体标量。

协变式生成集的冗余可按双次数分层消除:列出已知生成元乘积在目标双次数的系数向量,求其张成空间;再加入transvectant候选补足理论维数。关系同样按双次数做线性代数。模多个素数计算可大幅加速,但应避开使表示非半单的坏特征。

对于二元六次式,Igusa 不变量决定一般曲线同构类,但在自同构增强 locus 上绝对不变量坐标可能不稳定。协变式能提供恢复模型的辅助数据。Mestre 方法通过若干二次协变式构造圆锥和三次曲线;圆锥有无基域点决定是否能在模数域上写超椭圆方程。

Hessian 还可迭代:H(f)H(f)H(H(f))H(H(f)) 与 Jacobian 之间往往满足低次数关系。对高对称形式,这些操作在有限轨道之间循环,给出显式等变动力系统。其临界点、固定点与群轨道可由不变量坐标描述。

把两个同阶协变式之比当作有理函数时,要检查公共因子。公共零点形成基点,真正映射次数低于表面次数。可计算二者 gcd 或对理想饱和;在 𝐏1\mathbf P^1 上公共线性因子尤易对应被重复包含的特殊轨道。

练习与解答transvectant

练习 1。为什么 (f,f)r=0(f,f)_r=0 对奇数 rr 成立?

解。交换两个输入使transvectant乘 (1)r(-1)^r,而输入相同不变;奇数时等于自身负数。

练习 2。f,gf,g 阶分别为 m,nm,n(f,g)r(f,g)_r 的阶是多少?

解。每次对两个形式各微分一次,总变量次数减少 2,故为 m+n2rm+n-2r

练习 3。何时transvectant是标量不变量?

解。输出阶为 0,即 r=(m+n)/2r=(m+n)/2 且不超过 min(m,n)\min(m,n);还需相应 parity 和非零条件。

深入补充:transvectant的 Clebsch–Gordan 来源与协变式的双分次

VV 为二维标准表示,次数 mm 的二元形式属于 SymmV*\operatorname{Sym}^mV^*。Clebsch–Gordan 分解给出

SymmV*SymnV*r=0min(m,n)Symm+n2rV*.\operatorname{Sym}^mV^*\otimes\operatorname{Sym}^nV^* \cong\bigoplus_{r=0}^{\min(m,n)} \operatorname{Sym}^{m+n-2r}V^*.

每个不可约分量重数为一,因此到第 rr 个分量的 SL2\operatorname{SL}_2-等变投影在常数倍意义下唯一;这正是第 rr 个transvectant。

公式 二元形式的第 rr transvectant

F(x,y)F(x,y)G(x,y)G(x,y),可取

(F,G)r=k=0r(1)k(rk)rFxrkykrGxkyrk. (F,G)_r= \sum_{k=0}^r(-1)^k\binom rk \frac{\partial^rF}{\partial x^{r-k}\partial y^k} \frac{\partial^rG}{\partial x^k\partial y^{r-k}}.

结果的变量次数为 m+n2rm+n-2r;若 F,GF,G 的系数次数分别计为 11,则它对两组系数各一次。

不同文献会乘以阶乘归一化,但零点集合、生成的协变式空间和大多数代数关系只差可逆常数。计算时必须全程固定一种归一化,特别是在比较经典整数系数公式时。

Hessian 是二阶微分构造:

Hess(F)=FxxFyyFxy2.\operatorname{Hess}(F)=F_{xx}F_{yy}-F_{xy}^2.

对次数 mm 的形式,它在系数中次数为 22,在变量中次数为 2m42m-4,并与 (F,F)2(F,F)_2 成常数倍。两个协变式 A,BA,B 的 Jacobian

J(A,B)=AxByAyBxJ(A,B)=A_xB_y-A_yB_x

变量次数为 ordA+ordB2\operatorname{ord}A+\operatorname{ord}B-2,在系数中的次数相加。

判据 双分次的必要一致性

任何协变式恒等式的每一项必须同时具有相同的“系数次数”和“变量次数”。若群还带标量中心,则各项还必须具有相同中心特征。双分次不匹配可在展开前立即排除错误公式。

例如二元四次式 FF 的基本标量不变量可由

I=(F,F)4,J=(F,(F,F)2)4I=(F,F)_4, \qquad J=(F,(F,F)_2)_4

得到,系数次数分别为 2233。其判别式是 I3I^3J2J^2 的适当线性组合;两项系数次数都为 66,这是公式可能成立的首要条件。精确常数可通过在两个易分解的测试四次式上代入确定,而不必完全符号展开。

算法 大型transvectant的稀疏计算

先按导数多重指数预计算所有偏导;每个 rr 只累加 r+1r+1 个乘积;在若干良素数上计算并做稀疏插值;利用双分次与群中心特征预先限定可能单项式;最后中国剩余重构整数系数并在新素数上核对。

协变式不只是形式操作。若 FF 的零点是一条群轨道,Hessian 的零点常给出另一特殊轨道,Jacobian 再给第三轨道。把适当幂调整到同一次数后,会出现形如

Ap+Bq=CrA^p+B^q=C^r

的齐次关系;其比值在 𝐏1\mathbf P^1 上产生三分支点映射。要认证这种几何解释,应分别计算三个形式的平方自由性、公共零点、轨道稳定子和 Jacobian 分歧,而不能只验证一个多项式恒等式。

补充计算:transvectant、Hessian、Jacobian 与 Clebsch–Gordan 阶数

定理 二元形式transvectant的等变性与唯一性

设 \(F∈Sym^m(V^*)\)、\(G∈Sym^n(V^*)\)。第 r 阶transvectant (F,G)r=k=0r(1)k(rk)rFxrkykrGxkyrk (F,G)_r=\sum_{k=0}^r(-1)^k\binom rk \frac{\partial^rF}{\partial x^{r-k}\partial y^k} \frac{\partial^rG}{\partial x^k\partial y^{r-k}} 属于 \(Sym^{m+n-2r}(V^*)\),并给出 Clebsch–Gordan 分解中从 \(Sym^m⊗Sym^n\) 到 \(Sym^{m+n-2r}\) 的唯一标量倍等变投影。

证明 Omega 算子与最高权向量计算

在两组变量 \((x_1,y_1)\)、\((x_2,y_2)\) 上定义 \(Ω=∂_{x_1}∂_{y_2}-∂_{y_1}∂_{x_2}\)。行列式张量 \(x_1y_2-y_1x_2\) 在 \(SL_2\) 下不变,故其对偶微分算子 Ω 亦与群作用交换。对 \(F(x_1,y_1)G(x_2,y_2)\) 施加 \(Ω^r\),再令两组变量相等,展开即得公式,因此结果等变且阶数下降 2r。

Clebsch–Gordan 分解 \(Sym^mV⊗Sym^nV≅⊕_{r=0}^{min(m,n)}Sym^{m+n-2r}V\) 中每个不可约分量重数为 1。只要在最高权向量 \(x^m⊗x^{n-r}y^r\) 上检验transvectant非零,Schur 引理即表明该等变映射在标量倍意义下唯一。

Python 通用transvectant、四次式不变量与多面体形式微分构造
import sympy as sp
from math import factorial

x,y=sp.symbols("x y")

def degree_binary(F):
    P=sp.Poly(F,x,y)
    degrees={sum(m) for m,c in P.terms()}
    if len(degrees)!=1:
        raise ValueError("form is not homogeneous")
    return degrees.pop()

def transvectant(F,G,r,normalize=False):
    m=degree_binary(F)
    n=degree_binary(G)
    if r<0 or r>min(m,n):
        return sp.Integer(0)
    value=0
    for k in range(r+1):
        value += (-1)**k*sp.binomial(r,k) * (
            sp.diff(F,x,r-k,y,k) *
            sp.diff(G,x,k,y,r-k)
        )
    if normalize:
        value *= sp.Rational(
            factorial(m-r)*factorial(n-r),
            factorial(m)*factorial(n)
        )
    return sp.factor(value)

def hessian(F):
    H=sp.Matrix([
        [sp.diff(F,x,2),sp.diff(F,x,y)],
        [sp.diff(F,x,y),sp.diff(F,y,2)]
    ])
    return sp.factor(H.det())

def jacobian(F,G):
    return sp.factor(
        sp.diff(F,x)*sp.diff(G,y)-sp.diff(F,y)*sp.diff(G,x)
    )

def sl2_infinitesimal(F):
    E=x*sp.diff(F,y)
    Fop=y*sp.diff(F,x)
    H=x*sp.diff(F,x)-y*sp.diff(F,y)
    return tuple(map(sp.expand,(E,Fop,H)))

def verify_covariant_weight(F,G,r):
    m,n=degree_binary(F),degree_binary(G)
    T=transvectant(F,G,r)
    return {
        "degree_F":m,
        "degree_G":n,
        "order":degree_binary(T) if T!=0 else -1,
        "expected_order":m+n-2*r,
        "homogeneous": T==0 or degree_binary(T)==m+n-2*r,
    }

a,b,c,d,e=sp.symbols("a b c d e")
quartic=a*x**4+4*b*x**3*y+6*c*x**2*y**2+4*d*x*y**3+e*y**4
I=sp.factor(transvectant(quartic,quartic,4,normalize=True))
J=sp.factor(transvectant(
    quartic,transvectant(quartic,quartic,2,normalize=True),
    4,normalize=True
))
H4=hessian(quartic)

print("generic binary quartic:")
print("  F =",quartic)
print("  (F,F)_2 =",transvectant(quartic,quartic,2,normalize=True))
print("  I=(F,F)_4 =",I)
print("  J=(F,(F,F)_2)_4 =",J)
print("  Hessian =",H4)
print("  orders:")
for r in range(5):
    print(f"    r={r}: {verify_covariant_weight(quartic,quartic,r)}")

F0=x*y*(x**4-y**4)
H0=hessian(F0)
T0=jacobian(F0,H0)
relation=sp.factor(T0**2)
print("\npolyhedral seed form:")
print("  F =",F0,"degree",degree_binary(F0))
print("  H =",H0,"degree",degree_binary(H0))
print("  T = Jac(F,H) =",T0,"degree",degree_binary(T0))
print("  factor(T^2) =",relation)

print("\nselected transvectants:")
forms=[
    x**4+y**4,
    x**3*y+x*y**3,
    x**6-5*x**3*y**3-y**6,
]
for A in forms:
    print("  A =",A)
    for r in range(1,min(4,degree_binary(A))+1):
        V=transvectant(A,A,r,normalize=True)
        print(f"    (A,A)_{r} =",V)

print("\nsl2 infinitesimal action on x^3 y^2:")
mon=x**3*y**2
for name,value in zip(("E","F","H"),sl2_infinitesimal(mon)):
    print(f"  {name}·{mon} = {value}")

print("\nClebsch-Gordan order ledger for Sym^6⊗Sym^6:")
for r in range(7):
    print(f"  r={r}: target Sym^{12-2*r}")
运行结果 四次式 I、J、Hessian 及六次形式的协变式记录
generic binary quartic:
  F = a*x**4 + 4*b*x**3*y + 6*c*x**2*y**2 + 4*d*x*y**3 + e*y**4
  (F,F)_2 = 2*(a*c*x**4 + 2*a*d*x**3*y + a*e*x**2*y**2 - b**2*x**4 - 2*b*c*x**3*y + 2*b*d*x**2*y**2 + 2*b*e*x*y**3 - 3*c**2*x**2*y**2 - 2*c*d*x*y**3 + c*e*y**4 - d**2*y**4)
  I=(F,F)_4 = 2*(a*e - 4*b*d + 3*c**2)
  J=(F,(F,F)_2)_4 = 6*(a*c*e - a*d**2 - b**2*e + 2*b*c*d - c**3)
  Hessian = 144*(a*c*x**4 + 2*a*d*x**3*y + a*e*x**2*y**2 - b**2*x**4 - 2*b*c*x**3*y + 2*b*d*x**2*y**2 + 2*b*e*x*y**3 - 3*c**2*x**2*y**2 - 2*c*d*x*y**3 + c*e*y**4 - d**2*y**4)
  orders:
    r=0: {'degree_F': 4, 'degree_G': 4, 'order': 8, 'expected_order': 8, 'homogeneous': True}
    r=1: {'degree_F': 4, 'degree_G': 4, 'order': -1, 'expected_order': 6, 'homogeneous': True}
    r=2: {'degree_F': 4, 'degree_G': 4, 'order': 4, 'expected_order': 4, 'homogeneous': True}
    r=3: {'degree_F': 4, 'degree_G': 4, 'order': -1, 'expected_order': 2, 'homogeneous': True}
    r=4: {'degree_F': 4, 'degree_G': 4, 'order': 0, 'expected_order': 0, 'homogeneous': True}

polyhedral seed form:
  F = x*y*(x**4 - y**4) degree 6
  H = -25*(x**4 - 2*x**3*y + 2*x**2*y**2 + 2*x*y**3 + y**4)*(x**4 + 2*x**3*y + 2*x**2*y**2 - 2*x*y**3 + y**4) degree 8
  T = Jac(F,H) = 200*(x**4 + y**4)*(x**2 - 2*x*y - y**2)*(x**2 + 2*x*y - y**2)*(x**4 + 6*x**2*y**2 + y**4) degree 12
  factor(T^2) = 40000*(x**4 + y**4)**2*(x**2 - 2*x*y - y**2)**2*(x**2 + 2*x*y - y**2)**2*(x**4 + 6*x**2*y**2 + y**4)**2

selected transvectants:
  A = x**4 + y**4
    (A,A)_1 = 0
    (A,A)_2 = 2*x**2*y**2
    (A,A)_3 = 0
    (A,A)_4 = 2
  A = x**3*y + x*y**3
    (A,A)_1 = 0
    (A,A)_2 = -(x - y)**2*(x + y)**2/8
    (A,A)_3 = 0
    (A,A)_4 = -1/2
  A = x**6 - 5*x**3*y**3 - y**6
    (A,A)_1 = 0
    (A,A)_2 = -x*y*(4*x**6 + 9*x**3*y**3 - 4*y**6)/2
    (A,A)_3 = 0
    (A,A)_4 = -x**2*y**2

sl2 infinitesimal action on x^3 y^2:
  E·x**3*y**2 = 2*x**4*y
  F·x**3*y**2 = 3*x**2*y**3
  H·x**3*y**2 = x**3*y**2

Clebsch-Gordan order ledger for Sym^6⊗Sym^6:
  r=0: target Sym^12
  r=1: target Sym^10
  r=2: target Sym^8
  r=3: target Sym^6
  r=4: target Sym^4
  r=5: target Sym^2
  r=6: target Sym^0
计算 二元四次式的经典不变量

对 F=ax^4+4bx^3y+6cx^2y^2+4dxy^3+ey^4,规范化transvectant给出 I=2(ae-4bd+3c^2), J=6(ace-ad^2-b^2e+2bcd-c^3)。 Hessian 与 (F,F)_2 只差常数 72。奇阶自transvectant因交换两个因子改变符号而恒为 0。

Lecture 19 / 第 19 讲

Hurwitz 四元数、D4D_4 格与 W(F4)W(F_4)

用 Hurwitz 四元数统一描述 24 胞体、D4 格、triality 和 F4 反射群。

四元数D4格W(F4)

1. Hurwitz 四元数环

Hamilton 四元数代数为

𝐇=𝐑i,j,k/(i2=j2=k2=ijk=1).\mathbf H=\mathbf R\langle i,j,k\rangle/(i^2=j^2=k^2=ijk=-1).

共轭与范数定义为 a+bi+cj+dk¯=abicjdk\overline{a+bi+cj+dk}=a-bi-cj-dkN(q)=qq=a2+b2+c2+d2N(q)=q\bar q=a^2+b^2+c^2+d^2。Hurwitz 整数是坐标全为整数,或全为半整数且同奇偶型的四元数;它们构成一个非交换Euclidean 整环。

定义Hurwitz 单位

范数 1 的 Hurwitz 整数共有 24 个:

{±1,±i,±j,±k}{±1±i±j±k2}.\{\pm1,\pm i,\pm j,\pm k\}\cup\left\{\frac{\pm1\pm i\pm j\pm k}{2}\right\}.

它们形成二元四面体群,并且是正 24 胞体的顶点。

2. D4D_4 与 triality

根格

D4={(x1,x2,x3,x4)𝐙4:x1+x2+x3+x40(mod2)}D_4=\{(x_1,x_2,x_3,x_4)\in\mathbf Z^4:x_1+x_2+x_3+x_4\equiv0\pmod2\}

有 24 个根 ±ei±ej\pm e_i\pm e_j。其 Weyl 群 W(D4)W(D_4) 的阶为 192。Dynkin 图有一个 S3S_3 外自同构群,称为 triality;把这些图自同构加入后得到完整格自同构群,和 W(F4)W(F_4) 密切相关。

定理F4F_4 根系

F4F_4 的 48 个根可取为

{±ei,±ei±ej,12(±e1±e2±e3±e4)},\{\pm e_i,\ \pm e_i\pm e_j,\ \tfrac12(\pm e_1\pm e_2\pm e_3\pm e_4)\},

最后一组允许所有符号。其 Weyl 群阶为 11521152,基本不变量次数为 2,6,8,122,6,8,12

3. 四元数作用

单位四元数通过左乘、右乘作用于 𝐇𝐑4\mathbf H\cong\mathbf R^4。映射 (u,v):quqv1(u,v):q\mapsto uqv^{-1} 给出 Spin(4)SO(4)\mathrm{Spin}(4)\to\mathrm{SO}(4) 的双覆盖。选择 Hurwitz 单位子群,可构造 D4D_4 与 24 胞体的旋转群;再加共轭和反射得到完整对称群。

证明范数保持

由范数乘法性,N(uqv1)=N(u)N(q)N(v)1=N(q)N(uqv^{-1})=N(u)N(q)N(v)^{-1}=N(q)。因此左、右单位乘法都是正交变换。

说明计算用途

四元数坐标让群元素、根和轨道都具有小整数或半整数表示,适合精确枚举。反射矩阵可由 sr(x)=x2(x,r)r/(r,r)s_r(x)=x-2(x,r)r/(r,r) 直接生成,再用 Reynolds 平均计算不变量。

Hurwitz 四元数与二元四面体群

Hamilton 四元数代数

𝐇=𝐑i,j,k/(i2=j2=k2=ijk=1)\mathbf H=\mathbf R\langle i,j,k\rangle/ (i^2=j^2=k^2=ijk=-1)

配有共轭 q\bar q 与范数 N(q)=qqN(q)=q\bar q。Hurwitz 整数环由

𝐙[i,j,k,1+i+j+k2]\mathbf Z[i,j,k,\tfrac{1+i+j+k}{2}]

生成。其 24 个范数 1 单位为

{±1,±i,±j,±k}{±1±i±j±k2},\{\pm1,\pm i,\pm j,\pm k\} \cup \left\{\frac{\pm1\pm i\pm j\pm k}{2}\right\},

后一集合取全部 16 种符号。它们组成二元四面体群 2A42A_4,也是 24-cell 的顶点。

D4D_4 格的三种最小向量轨道

D4D_4 根格可写为

D4={(x1,x2,x3,x4)𝐙4:x1+x2+x3+x40(mod2)}.D_4=\{(x_1,x_2,x_3,x_4)\in\mathbf Z^4: x_1+x_2+x_3+x_4\equiv0\pmod2\}.

其根为 ±ei±ej\pm e_i\pm e_j,共 24 个。由于 triality,D4D_4 还自然出现另外两组各 8 个向量:坐标向量 ±ei\pm e_i,以及半整数向量 (±1,±1,±1,±1)/2(\pm1,\pm1,\pm1,\pm1)/2 按符号乘积的两种宇称分成两组。三组 8 点由外自同构 S3S_3 置换;合起来构成 F4F_4 根系的短根或相关 24 点配置。

从四元数乘法得到正交变换

𝐇𝐑4\mathbf H\cong\mathbf R^4。左右乘单位四元数给出范数保持变换

qaqb1.q\longmapsto aqb^{-1}.

这实现 Spin(4)SU(2)×SU(2)\operatorname{Spin}(4)\cong\operatorname{SU}(2)\times\operatorname{SU}(2)SO(4)\operatorname{SO}(4) 的二重覆盖。Hurwitz 单位的左右作用生成 D4D_4 格的大量自同构;再加入四元数共轭或 triality,可得到 W(F4)W(F_4) 及其扩张。

W(D4)W(D_4)、triality 与 W(F4)W(F_4)

W(D4)W(D_4) 是偶数符号变化与坐标置换组成的群,阶

|W(D4)|=234!=192.|W(D_4)|=2^{3}\cdot4!=192.

D4D_4 Dynkin 图外自同构群为 S3S_3。完整根格自同构群是半直积 W(D4)S3W(D_4)\rtimes S_3,阶 11521152,同构于 W(F4)W(F_4)。这解释了为什么 F4F_4 不变量可从 D4D_4 不变量出发,再取 triality 不变部分。

D4D_4 的基本不变量

I2k=ek(x12,x22,x32,x42)(k=1,2,3),J4=x1x2x3x4.I_{2k}=e_k(x_1^2,x_2^2,x_3^2,x_4^2) \quad(k=1,2,3),\qquad J_4=x_1x_2x_3x_4.

𝐂[x1,,x4]W(D4)=𝐂[I2,I4,J4,I6],\mathbf C[x_1,\ldots,x_4]^{W(D_4)} =\mathbf C[I_2,I_4,J_4,I_6],

基本次数为 2,4,4,62,4,4,6。triality 非平凡地作用于两个四次不变量及其组合;取 S3S_3 不变量后,得到 W(F4)W(F_4) 的基本次数 2,6,8,122,6,8,12

24-cell 与轨道多项式

把 24 个最小向量 vv 对变量 xx 的内积作为根,形成

P(T)=v(Tv,x).P(T)=\prod_{v}(T-\langle v,x\rangle).

W(F4)W(F_4) 传递地置换这些向量,PP 的系数都是 W(F4)W(F_4) 不变量。适当次数的系数可作为基本不变量。这个“轨道多项式法”同样适用于 E6E_6 的 27 个最小余权向量和 72 个根。

Hurwitz 整数的整闭性与 Euclidean 性

Hurwitz 阶 \mathcal H 是 Hamilton 四元数代数中的极大阶。其迹与范数均为整数,并对范数具有 Euclidean 除法:对任意 q𝐇q\in\mathbf H,可选最近的 Hurwitz 整数 aa,使 N(qa)<1N(q-a)<1。因此每个右理想和左理想都是主理想,且可发展类似Gaussian 整数的 gcd 理论。非交换性要求区分左除与右除。

24 个单位与 24-cell

范数 1 单位在 𝐑4\mathbf R^4 中位于单位三球面。八个坐标单位与十六个半整数单位恰是正 24-cell 的 24 个顶点。它的对偶仍为 24-cell;顶点、胞与超八面体结构共同产生大量对称。全对称群阶为 1152,正是 |W(F4)||W(F_4)|。保向子群阶为 576。

从单位四元数到 D4D_4

经适当缩放与正交变换,24 个 Hurwitz 单位可识别为 D4D_4 的 24 根 ±ei±ej\pm e_i\pm e_j。另一常见坐标把短根写成

{±ei}{12(±e1±e2±e3±e4)},\{\pm e_i\} \cup \left\{\frac12(\pm e_1\pm e_2\pm e_3\pm e_4)\right\},

共 24 个;长根则是 ±ei±ej\pm e_i\pm e_j。两者合成 F4F_4 的 48 根。不同坐标约定会把“Hurwitz 单位”“D4D_4 根”“F4F_4 短根”互换,比较公式时应先检查长度归一化。

Spin(4) 的核与像

映射

SU(2)×SU(2)SO(4),(a,b):qaqb1\operatorname{SU}(2)\times\operatorname{SU}(2)\to\operatorname{SO}(4), \qquad(a,b):q\mapsto aqb^{-1}

的核为 {(1,1),(1,1)}\{(1,1),(-1,-1)\}。若 a,ba,b 均取二元四面体群,可得一个阶 242/2=28824^2/2=288 的保向群。再加入交换左右因子、四元数共轭及 triality,可扩张到 24-cell 的完整对称群。

Triality 的具体含义

Dynkin 图 D4D_4 有三个外端节点,图自同构群为 S3S_3。表示论上,它置换 Spin(8)\operatorname{Spin}(8) 的三个八维不可约表示:向量表示与两个半旋表示。格论上,它置换 D4/D4D_4^\vee/D_4 的三个非零陪集;每个陪集含 8 个最短向量。这正是课程中三组 8 点配置的来源。

反射如何由四元数写出

对单位向量 r𝐇r\in\mathbf H,超平面 rr^\perp 的实反射可写

sr(q)=rqrs_r(q)=-r\bar q r

在一种符号约定下成立。直接检查 sr(r)=rs_r(r)=-r,而对与 rr 正交的 qqsr(q)=qs_r(q)=q。选取简单根对应的四元数后,这些反射满足 F4F_4 Coxeter 关系,并生成整个 W(F4)W(F_4)

格、根与权格的判别式

根格 D4D_4 的判别式群为 (𝐙/2𝐙)2(\mathbf Z/2\mathbf Z)^2。三个非零类对应 triality 三轨道。加入任意一个非零陪集可得到一个指数 2 的超格;加入全部则得到对偶格。计算向量内积和模 D4D_4 陪集,是确认四元数坐标与抽象根系匹配的最直接方法。

算法实现建议

用四元数实现群时,应把系数存为半整数,即统一乘 2 后用整数四元组表示。乘法后再检查四个坐标同奇同偶的 Hurwitz 条件。群闭包可从少量单位和共轭生成;将每个四元数变换转为 4×44\times4 有理矩阵后,可核对正交性、行列式、群阶和根轨道。这样避免浮点四元数造成重复元素识别失败。

计算专题:四元数模型中的群闭包与轨道

把 Hurwitz 四元数统一表示为 (a,b,c,d)/2(a,b,c,d)/2,其中四个整数同奇同偶。乘法后分子仍满足该条件,范数为 (a2+b2+c2+d2)/4(a^2+b^2+c^2+d^2)/4。单位枚举因此化为整数球面方程 a2+b2+c2+d2=4a^2+b^2+c^2+d^2=4,可无遗漏得到 24 个解。

左右乘矩阵可从基 1,i,j,k1,i,j,k 的像逐列写出。对 (a,b)(a,b) 作用 qaqb1q\mapsto aqb^{-1},矩阵条目为半整数但整体正交。以整数倍矩阵存储时应同时记录公共分母并规范符号,避免同一射影变换重复。

若要证明所得群是 W(F4)W(F_4),可找四个反射矩阵,计算它们的积阶矩阵 mijm_{ij},与 F4F_4 Coxeter 图的边标 3,4,33,4,3 匹配;再用群阶 1152 证明生成完备。另一路是验证它忠实作用于 48 根并在长短根各自传递。

triality 元素可由对三个 D4/D4D_4^\vee/D_4 非零陪集的置换识别。计算其在判别式群上的 2×22\times2 矩阵得到 GL2(𝐅2)S3\operatorname{GL}_2(\mathbf F_2)\cong S_3。若一个格自同构在根格上看似复杂,这个小商表示通常能迅速辨认其外自同构类。

24-cell 的面格可从顶点内积恢复:给定规范长度,最大非平凡内积对应相邻顶点。自动生成边、三角面和八面体胞后,Euler 特征与每层轨道数提供独立组合核验。群作用若保持内积就自动保持整个面格。

四元数方法的价值在于同时给出格、旋转群和显式矩阵。后续轨道多项式可直接以 24 个单位或 48 个根为线性型集合;不同坐标系统只通过正交变换改变基本不变量的具体表达,不改变次数与群结构。

深入补充:24 个 Hurwitz 单位、F4F_4 根系与 triality 的阶数核对

Hurwitz 四元数环由坐标全为整数或全为半整数且和为整数的四元数组成。范数为一的单位恰有 2424 个:

{±1,±i,±j,±k}\{\pm1,\pm i,\pm j,\pm k\}

以及

±1±i±j±k2,\frac{\pm1\pm i\pm j\pm k}{2},

后式允许全部 1616 种符号。把四元数坐标视为 𝐑4\mathbf R^4,这 2424 个点是正二十四胞体的一组顶点,也是 F4F_4 的短根。

长根可取

{±ei±ej:1i<j4},\{\pm e_i\pm e_j:1\le i<j\le4\},

共有 64=246\cdot4=24 个。短根为

{±ei}i=14{12(±e1±e2±e3±e4)},\{\pm e_i\}_{i=1}^4 \quad\cup\quad \left\{\frac12(\pm e_1\pm e_2\pm e_3\pm e_4)\right\},

共有 8+16=248+16=24 个。合计 4848 个根,构成 F4F_4 根系。

计数 W(D4)W(D_4)、triality 与 W(F4)W(F_4)

D4D_4 Weyl 群是偶符号变换与坐标置换的半直积,故

|W(D4)|=2414!=192.|W(D_4)|=2^{4-1}\cdot4!=192.

D4D_4 Dynkin 图外自同构群为 S3S_3,triality 给出扩张

W(F4)W(D4)S3,W(F_4)\cong W(D_4)\rtimes S_3,

从而

|W(F4)|=1926=1152.|W(F_4)|=192\cdot6=1152.

triality 交换 D4D_4 的向量表示与两个半旋量表示;在根格层面,它交换三个外侧简单根。四元数模型把这三种八维对象的对称性压缩进左右乘法和共轭操作,因此许多看似不同的 2424 点轨道其实由 triality 互换。

单位四元数对 𝐇𝐑4\mathbf H\cong\mathbf R^4 的左右作用

xaxb1x\longmapsto axb^{-1}

保持范数。映射

SU(2)×SU(2)SO(4)\operatorname{SU}(2)\times\operatorname{SU}(2)\to\operatorname{SO}(4)

的核为 {(1,1),(1,1)}\{(1,1),(-1,-1)\},这给出 Spin(4)\operatorname{Spin}(4) 的双覆盖。取 a,ba,b 为 Hurwitz 单位便得到一个有限正交变换群,可用来生成二十四胞体的旋转对称。

算法基础 Hurwitz 环的 Euclidean 除法

α,β\alpha,\beta\in\mathcal Hβ0\beta\ne0,在 𝐇\mathbf H 中计算 αβ1\alpha\beta^{-1},选择最近的 Hurwitz 整数 qq,令 r=αqβr=\alpha-q\beta。Hurwitz 格的覆盖半径小于 11,故

N(r)<N(β).N(r)<N(\beta).

因此可运行左或右 Euclidean 算法,计算最大公因子并构造范数分解。

“最近点”可在整数格与半整数陪集各取一个候选,比较范数即可,不需搜索无限格点。非交换性要求明确使用左除法还是右除法;相应 gcd 只在单位倍意义下唯一。

算法 根系与群阶的精确核验

列出 4848 个候选根,检查每个反射

sr(x)=x2(x,r)(r,r)rs_r(x)=x-2\frac{(x,r)}{(r,r)}r

保持根集合;以简单根反射生成置换群,用 Schreier–Sims 计算阶为 11521152;分别计算长根、短根轨道各为 2424;最后验证根内积只取允许的 Cartan 值。这样无需依赖浮点四维几何图形。

补充计算:Hurwitz 单位、F4 根系与 D4 triality 的精确矩阵

定理 Hurwitz 单位与 F4 短根的同一性

把四元数 a+bi+cj+dk 识别为 \(R^4\)。Hurwitz 整数环的 24 个单位为 {±1,±i,±j,±k}{±1±i±j±k2}, \{\pm1,\pm i,\pm j,\pm k\}\cup \left\{\frac{\pm1\pm i\pm j\pm k}{2}\right\}, 其坐标向量恰为 \(F_4\) 根系的 24 个短根。\(F_4\) 的 24 个长根为 \(D_4\) 根系 \({±e_i±e_j}\)。由四个简单根反射生成的群阶为 1152。

证明 范数枚举、根系闭性与 Coxeter 阶数

Hurwitz 整数要么四坐标全为整数,要么全为半整数且同余。范数为 1 的整数坐标解只有一个坐标为 \(±1\) 的 8 个;半整数坐标解要求四坐标绝对值均为 1/2,共 16 个。因此单位总数为 24,正是 \(F_4\) 标准短根集合。

长根 \(±e_i±e_j\) 共 \(6·4=24\) 个。对任意根 α,反射 \(s_α(v)=v-2(v,α)/(α,α)α\) 保持这 48 个向量集合;简单根的 Cartan 矩阵为 \(F_4\) 型。有限 Coxeter 群阶公式 \(∏(e_i+1)\),\(F_4\) 指数为 1,5,7,11,故阶为 \(2·6·8·12=1152\)。程序闭包计算给出同一阶数,且长短根分别形成大小 24 的轨道。

Python 根集枚举、反射群闭包与三阶 triality 自同构
from fractions import Fraction
from itertools import product, combinations
from collections import deque, Counter

Q=Fraction

def vadd(a,b): return tuple(x+y for x,y in zip(a,b))
def vsub(a,b): return tuple(x-y for x,y in zip(a,b))
def smul(c,a): return tuple(c*x for x in a)
def dot(a,b): return sum(x*y for x,y in zip(a,b))
def norm2(a): return dot(a,a)

def matmul(A,B):
    return tuple(tuple(sum(A[i][k]*B[k][j] for k in range(len(B)))
                       for j in range(len(B[0])))
                 for i in range(len(A)))

def matvec(A,v):
    return tuple(sum(A[i][j]*v[j] for j in range(len(v)))
                 for i in range(len(A)))

def eye(n):
    return tuple(tuple(Q(i==j) for j in range(n)) for i in range(n))

def transpose(A):
    return tuple(zip(*A))

def reflection(alpha):
    n=len(alpha)
    aa=norm2(alpha)
    return tuple(tuple(Q(i==j)-2*alpha[i]*alpha[j]/aa
                       for j in range(n)) for i in range(n))

def group_closure(gens,limit=5000):
    n=len(gens[0])
    G={eye(n)}
    q=deque([eye(n)])
    while q:
        h=q.popleft()
        for g in gens:
            gh=matmul(g,h)
            if gh not in G:
                G.add(gh)
                q.append(gh)
                if len(G)>limit:
                    raise RuntimeError("group exceeded limit")
    return G

def orbit(G,v):
    return {matvec(g,v) for g in G}

def d4_roots():
    roots=set()
    for i,j in combinations(range(4),2):
        for si,sj in product((-1,1),repeat=2):
            v=[Q(0)]*4
            v[i]=Q(si);v[j]=Q(sj)
            roots.add(tuple(v))
    return roots

def f4_roots():
    roots=set(d4_roots())
    for i in range(4):
        for s in (-1,1):
            v=[Q(0)]*4;v[i]=Q(s);roots.add(tuple(v))
    for signs in product((-1,1),repeat=4):
        roots.add(tuple(Q(s,2) for s in signs))
    return roots

def hurwitz_units():
    units=set()
    for i in range(4):
        for s in (-1,1):
            v=[Q(0)]*4;v[i]=Q(s);units.add(tuple(v))
    for signs in product((-1,1),repeat=4):
        units.add(tuple(Q(s,2) for s in signs))
    return units

def matrix_inverse(A):
    n=len(A)
    M=[list(A[i])+[Q(i==j) for j in range(n)] for i in range(n)]
    for c in range(n):
        pivot=next(r for r in range(c,n) if M[r][c])
        M[c],M[pivot]=M[pivot],M[c]
        inv=1/M[c][c]
        M[c]=[inv*z for z in M[c]]
        for r in range(n):
            if r!=c and M[r][c]:
                q=M[r][c]
                M[r]=[a-q*b for a,b in zip(M[r],M[c])]
    return tuple(tuple(row[n:]) for row in M)

def columns_to_matrix(cols):
    return tuple(tuple(cols[j][i] for j in range(len(cols)))
                 for i in range(len(cols[0])))

D4=d4_roots()
F4=f4_roots()
H=hurwitz_units()
print("root and unit counts:")
print("  D4 roots =",len(D4),Counter(norm2(v) for v in D4))
print("  F4 roots =",len(F4),Counter(norm2(v) for v in F4))
print("  Hurwitz units =",len(H),Counter(norm2(v) for v in H))
print("  short F4 roots equal Hurwitz units =", {v for v in F4 if norm2(v)==1}==H)

simple=(
    (Q(0),Q(1),Q(-1),Q(0)),
    (Q(0),Q(0),Q(1),Q(-1)),
    (Q(0),Q(0),Q(0),Q(1)),
    (Q(1,2),Q(-1,2),Q(-1,2),Q(-1,2)),
)
cartan=tuple(tuple(2*dot(a,b)/norm2(b) for b in simple) for a in simple)
print("\nF4 simple roots and Cartan matrix:")
for a in simple: print(" ",a,"norm",norm2(a))
for row in cartan: print(" ",row)

reflections=[reflection(a) for a in simple]
W=group_closure(reflections,limit=2000)
print("\nW(F4) closure:")
print("  order =",len(W))
print("  orbit of long root =",len(orbit(W,next(v for v in F4 if norm2(v)==2))))
print("  orbit of short root =",len(orbit(W,next(v for v in F4 if norm2(v)==1))))
print("  determinant distribution =",
      Counter(round(float(__import__('sympy').Matrix(g).det())) for g in W))

# D4 diagram triality: cycle alpha1,alpha3,alpha4 and fix alpha2.
a1=(Q(1),Q(-1),Q(0),Q(0))
a2=(Q(0),Q(1),Q(-1),Q(0))
a3=(Q(0),Q(0),Q(1),Q(-1))
a4=(Q(0),Q(0),Q(1),Q(1))
basis=(a1,a2,a3,a4)
B=columns_to_matrix(basis)
Binv=matrix_inverse(B)
image=(a3,a2,a4,a1)
C=columns_to_matrix(image)
T=matmul(C,Binv)
T2=matmul(T,T);T3=matmul(T2,T)
print("\ntriality matrix:")
for row in T: print(" ",row)
print("  T^3=I =",T3==eye(4))
print("  D4 root set preserved =",{matvec(T,v) for v in D4}==D4)
print("  fixed roots =",sum(matvec(T,v)==v for v in D4))

print("\ninner-product distribution from one short root:")
s=next(v for v in F4 if norm2(v)==1)
print(Counter(dot(s,v) for v in F4))
运行结果 48 根、1152 个 Weyl 元素及 triality 核验
root and unit counts:
  D4 roots = 24 Counter({Fraction(2, 1): 24})
  F4 roots = 48 Counter({Fraction(2, 1): 24, Fraction(1, 1): 24})
  Hurwitz units = 24 Counter({Fraction(1, 1): 24})
  short F4 roots equal Hurwitz units = True

F4 simple roots and Cartan matrix:
  (Fraction(0, 1), Fraction(1, 1), Fraction(-1, 1), Fraction(0, 1)) norm 2
  (Fraction(0, 1), Fraction(0, 1), Fraction(1, 1), Fraction(-1, 1)) norm 2
  (Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(1, 1)) norm 1
  (Fraction(1, 2), Fraction(-1, 2), Fraction(-1, 2), Fraction(-1, 2)) norm 1
  (Fraction(2, 1), Fraction(-1, 1), Fraction(0, 1), Fraction(0, 1))
  (Fraction(-1, 1), Fraction(2, 1), Fraction(-2, 1), Fraction(0, 1))
  (Fraction(0, 1), Fraction(-1, 1), Fraction(2, 1), Fraction(-1, 1))
  (Fraction(0, 1), Fraction(0, 1), Fraction(-1, 1), Fraction(2, 1))

W(F4) closure:
  order = 1152
  orbit of long root = 24
  orbit of short root = 24
  determinant distribution = Counter({1: 576, -1: 576})

triality matrix:
  (Fraction(1, 2), Fraction(1, 2), Fraction(1, 2), Fraction(1, 2))
  (Fraction(1, 2), Fraction(1, 2), Fraction(-1, 2), Fraction(-1, 2))
  (Fraction(1, 2), Fraction(-1, 2), Fraction(1, 2), Fraction(-1, 2))
  (Fraction(-1, 2), Fraction(1, 2), Fraction(1, 2), Fraction(-1, 2))
  T^3=I = True
  D4 root set preserved = True
  fixed roots = 6

inner-product distribution from one short root:
Counter({Fraction(0, 1): 18, Fraction(1, 2): 8, Fraction(-1, 2): 8, Fraction(-1, 1): 7, Fraction(1, 1): 7})
计算 D4 图自同构

在简单根 α_1=e_1-e_2、α_2=e_2-e_3、α_3=e_3-e_4、α_4=e_3+e_4 上令 α_1→α_3→α_4→α_1、α_2 固定,得到阶 3 线性变换。程序计算其矩阵含 1/2 系数,满足 T^3=I,并置换全部 24 个 D_4 根;固定根数为 6。

Lecture 20 / 第 20 讲

W(F4)W(F_4)W(E6)W(E_6) 与基本不变量次数

整理 Weyl 群的不变量次数、Coxeter 数和显式构造策略。

Weyl群E6基本不变量

1. Weyl 群的不变量次数

有限实反射群的不变量环是多项式环。若指数(exponents)为 m1,,mnm_1,\ldots,m_n,则基本不变量次数为 di=mi+1d_i=m_i+1,Coxeter 数为最大次数 h=dnh=d_n

类型基本不变量次数Coxeter 数
D4D_42,4,4,62,4,4,66
F4F_42,6,8,122,6,8,1212
E6E_62,5,6,8,9,122,5,6,8,9,1212
E7E_72,6,8,10,12,14,182,6,8,10,12,14,1818
E8E_82,8,12,14,18,20,24,302,8,12,14,18,20,24,3030
定理根数公式

不可约秩 nn 根系的根数为 nhnh,其中 hh 是 Coxeter 数。等价地,正根数为 nh/2nh/2

2. F4F_4 不变量的构造

在标准四维表示中,可以从偶次幂和

p2m(x)=rRshort(rx)2mp_{2m}(x)=\sum_{r\in R_{\mathrm{short}}}(r\cdot x)^{2m}

或同时对长根、短根求和,构造次数 2,6,8,122,6,8,12 的不变量。低次数候选之间可能有多项式关系,因此需要 Jacobian 独立性和 Hilbert 级数共同验证。

3. E6E_6 的 27 条线与最小表示

Weyl 群 W(E6)W(E_6) 作用在三次曲面 27 条直线的配置上,也作用在 E6*/E6E_6^*/E_6 的非零陪集中的 27 个最短向量上。这个 27 元集合在 Shioda 的 E6E_6 椭圆曲面族中表现为 27 个最小截面。

算法轨道和不变量
  1. 选定根基和 Cartan 矩阵。
  2. 生成简单反射矩阵。
  3. 枚举一个权向量的群轨道。
  4. 以轨道上的线性形式幂和构造不变量。
  5. 用已知次数表选择最少生成元并验证 Jacobian。
补充次数表的作用

次数表不仅是分类数据。它预言参数应有的权、判别式的总次数、椭圆曲面方程中允许出现的系数,以及数值插值所需的单项式集合。后面的 Shioda 族正把这些次数作为 Weierstrass 系数的权。

D4D_4 不变量构造 W(F4)W(F_4) 不变量

定义

P0(X)=i=14(X2xi2)=X8I2X6+I4X4I6X2+J42.P_0(X)=\prod_{i=1}^{4}(X^2-x_i^2) =X^8-I_2X^6+I_4X^4-I_6X^2+J_4^2.

接着考虑符号和

s=i=14ϵixi,ϵi{±1},iϵi=+1.s=\sum_{i=1}^{4}\epsilon_i x_i,\qquad \epsilon_i\in\{\pm1\},\quad\prod_i\epsilon_i=+1.

这 8 个值的最小轨道多项式记为 P1P_1。若把 J4J_4 换成 J4-J_4,得到另一宇称符号和的多项式 P2P_2。于是

P(X)=28P0(X/2)P1(X)P2(X)P(X)=2^8P_0(X/2)P_1(X)P_2(X)

的 24 个根正是 24-cell 最小向量与 xx 的内积;故系数为 W(F4)W(F_4) 不变量。

消元得到 P1P_1

对一个符号选择,令

Q(X)=i=14(Xϵixi)=X4sX3+BX2CX+J4.Q(X)=\prod_{i=1}^{4}(X-\epsilon_i x_i) =X^4-sX^3+BX^2-CX+J_4.

条件 P0(X)=Q(X)Q(X)P_0(X)=Q(X)Q(-X) 给出

Q(X)Q(X)=X8+(2Bs2)X6+(B22Cs+2J4)X4+(2BJ4C2)X2+J42.Q(X)Q(-X) =X^8+(2B-s^2)X^6+(B^2-2Cs+2J_4)X^4 +(2BJ_4-C^2)X^2+J_4^2.

比较 X6X^6 系数得 B=(s2I2)/2B=(s^2-I_2)/2。再用 X4,X2X^4,X^2 系数得到关于 CC 的一次与二次方程,消去 CC 后得到

P1(X)=X84I2X6+(6I228(I4+6J4))X4+(4I23+16(I4+2J4)I264I6)X2+(I224I4+8J4)2.\begin{aligned} P_1(X)={}&X^8-4I_2X^6+ \bigl(6I_2^2-8(I_4+6J_4)\bigr)X^4\\ &+\bigl(-4I_2^3+16(I_4+2J_4)I_2-64I_6\bigr)X^2\\ &+\bigl(I_2^2-4I_4+8J_4\bigr)^2. \end{aligned}

P2P_2J4J4J_4\mapsto-J_4 得到。展开 PP 后,次数 2,6,8,122,6,8,12 的系数给出一组基本不变量。原讲义采用的简洁组合为

i2=I2,i_2=I_2,
i6=I2I46I6,i_6=I_2I_4-6I_6,
i8=I42+12J423I2I6,i_8=I_4^2+12J_4^2-3I_2I_6,
i12=27(I22J42+I62)+2I439I4(I2I6+8J42).i_{12}=27(I_2^2J_4^2+I_6^2) +2I_4^3-9I_4(I_2I_6+8J_4^2).

次数乘积 26812=1152=|W(F4)|2\cdot6\cdot8\cdot12=1152=|W(F_4)|,与反射群定理吻合。

另一 24 点轨道的高效构造

另一轨道由 ±xi±xj(ij)\pm x_i\pm x_j\ (i\ne j) 组成。直接计算 ResY(P0(Y),P0(XY))\operatorname{Res}_Y(P_0(Y),P_0(X-Y)) 会得到次数 64 的多项式,其中目标根各出现两次,还含 ±2xi\pm2x_i 与零的伪因子。更高效的方法是把 P0P_0 除以 X2AX+BX^2-AX+B,令余式的两个系数同时为零,再关于 BB 取结式。结果是关于 AA 的 28 次多项式,除目标 24 根外只有 A=0A=0 的四重根;除以 A4A^4 即得轨道多项式。

E6E_6 根格中的两个自然稳定子

构造 W(E6)W(E_6) 不变量可从根稳定子或最小对偶向量稳定子出发。选择根 rr 时,正交补为 A5A_5,稳定子为

W(A1A5),|W(A1A5)|=26!,W(A_1\oplus A_5),\qquad |W(A_1\oplus A_5)|=2\cdot6!,

W(E6)W(E_6) 中指数 36,正好对应 72 个根的 ±\pm 对。判别式比较说明 A1A5A_1\oplus A_5E6E_6 中指数 2;非平凡陪集可由

r2+(1,1,1,1,1,1)2\frac r2+\frac{(1,1,1,-1,-1,-1)}2

代表。

轨道多项式 P27P_{27}P72P_{72}

P27P_{27} 的根为同一非零 E6/E6E_6^\vee/E_6 陪集中的 27 个最小对偶向量与 xx 的内积;令 P72P_{72} 的根为 72 个根与 xx 的内积。根可按 A1A5A_1\oplus A_5 坐标分组:

  • 72 个根包括 A5A_5 的 30 个根((1,1,0,0,0,0)(1,-1,0,0,0,0) 的排列)以及 40 个 (v±r)/2(v\pm r)/2,其中 vv(1,1,1,1,1,1)(1,1,1,-1,-1,-1) 的排列,再加 ±r\pm r
  • 27 个最小对偶向量包括 12 个 v±r/2v\pm r/2,其中 vv(5,1,1,1,1,1)/6(5,-1,-1,-1,-1,-1)/6 的排列;以及 15 个 (1,1,1,1,2,2)/3(1,1,1,1,-2,-2)/3 的排列。

展开这两个轨道多项式,系数均为 W(E6)W(E_6) 不变量。W(E6)W(E_6) 的基本次数为

2,5,6,8,9,12,2,5,6,8,9,12,

其乘积等于群阶 5184051840。可以从 P27P_{27}P72P_{72} 中选取这些次数的系数并做三角化,得到基本生成元。

W(D5)W(D_5) 出发的对偶路线

若固定一个范数 4/34/3 的最小对偶向量 r*r^\ast,其正交补中的根系为 D5D_5,稳定子 W(D5)W(D_5) 指数为 27。W(D5)W(D_5) 不变量次数为 2,4,6,8,52,4,6,8,5,再加线性形式 r*,x\langle r^\ast,x\rangle。27 个对偶向量分成 1+10+161+10+16,72 个根分成 40+3240+32;半整数符号向量可用与 F4F_4 相同的消元技巧处理。这条路线为同一 P27,P72P_{27},P_{72} 提供独立校验。

轨道多项式是“坐标无关”的压缩

给定有限群轨道 𝒪V\mathcal O\subset V 和变量 xVx\in V,定义

P𝒪(T;x)=v𝒪(Tv,x).P_{\mathcal O}(T;x)=\prod_{v\in\mathcal O}(T-\langle v,x\rangle).

群置换轨道,因此每个系数都是 GG-不变量。与逐个平均单项式相比,轨道多项式一次性编码整个几何配置;其根还保留可恢复的标记信息。若轨道具有中心对称,奇次系数自动为零,可把变量改成 T2T^2 降低一半次数。

用 Newton 恒等式从幂和恢复系数

设根为 r1,,rNr_1,\ldots,r_N,幂和 pk=irikp_k=\sum_i r_i^k,初等对称函数为 eke_k。Newton 恒等式

kek=i=1k(1)i1ekipi,e0=1k e_k=\sum_{i=1}^k(-1)^{i-1}e_{k-i}p_i, \qquad e_0=1

可由较低次数的轨道矩计算轨道多项式。幂和常比直接展开乘积容易,因为

pk(x)=v𝒪v,xkp_k(x)=\sum_{v\in\mathcal O}\langle v,x\rangle^k

是一个显式齐次不变量,可用对称性迅速化简。对 24-cell,奇数幂和消失,二次幂和必为 I2I_2 的标量倍。

为何次数 2,6,8,122,6,8,12 足够

W(F4)W(F_4) 阶为

26812=1152.2\cdot6\cdot8\cdot12=1152.

若从轨道多项式系数中找到四个代数无关不变量,次数恰为 2,6,8,122,6,8,12,则它们生成整个不变量环:Shephard–Todd–Chevalley 定理给出不变量环是多项式环,而次数乘积等于群阶,故相应有限映射的次数已达到正确值。还需检查 Jacobian 非零;仅凭次数出现并不能排除代数依赖。

D4D_4 不变量到 triality 不变量

W(D4)W(D_4) 的基本不变量可取 I2,I4,I6,J4=x1x2x3x4I_2,I_4,I_6,J_4=x_1x_2x_3x_4,次数为 2,4,6,42,4,6,4。外自同构 S3S_3 非平凡地作用于两个四次方向及其组合。先构造三个八点轨道多项式 P0,P1,P2P_0,P_1,P_2,再取对称组合,等价于在 W(D4)W(D_4) 不变量环上取 triality 不变部分。课程给出的 P1,P2P_1,P_2 公式使这一作用完全显式。

消元公式的防错检查

推导 P1P_1 时,ss 是符号和,B,CB,C 是中间对称量。每次消元后都应检查:

第一,所得多项式关于 XX 为偶函数;第二,常数项等于相应四个线性因子乘积的平方;第三,令 x2=x3=x4=0x_2=x_3=x_4=0 等特殊化时,根多重集与直接符号和一致;第四,对随机整数 xix_i 直接数值展开并比较。特殊化检查往往能立刻发现 J4J_4 符号或二的幂次错误。

轨道多项式与分解域

在函数域 K(I2,I6,I8,I12)K(I_2,I_6,I_8,I_{12}) 上,轨道多项式的分裂域通常实现反射群的自然置换表示。其判别式只在反射判别式上消失。选一个根等价于在商空间上加一个标记向量,稳定子为该向量的轨道稳定群。因此轨道多项式也给出中间商 V/HV/GV/H\to V/G 的显式方程。

F4F_4 过渡到 E6E_6

E6E_6 的 27 维 minuscule 轨道与立方曲面 27 条直线相连。若以 27 个权 vv 构造

P27(T)=v(Tv,x),P_{27}(T)=\prod_{v}(T-\langle v,x\rangle),

其系数是 W(E6)W(E_6) 不变量。基本次数为 2,5,6,8,9,122,5,6,8,9,12,群阶为这些次数的乘积 5184051840。由于 27 轨道不是中心对称,奇次不变量会出现;这与 F4F_4 24 点轨道只有偶次系数形成鲜明对比。

插值展开而非暴力展开

高次数轨道多项式直接符号相乘会产生巨大中间表达式。更有效的方法是在许多整数点上计算根和多项式系数,再按预知权重在基本不变量单项式基中插值。可先模多个良素数计算,再用中国剩余定理恢复整数系数。每个候选公式最后应在新的随机点和群生成元作用下独立核验。

判别式与反射超平面的指数

轨道多项式判别式

DiscTP=vw(vw,x)2\operatorname{Disc}_T P=\prod_{v\ne w}\bigl(\langle v-w,x\rangle\bigr)^2

的零集由使两个轨道值相等的超平面组成,往往包含反射超平面并可能带额外成分。将它在基本不变量中因式分解,可识别不同稳定子增强层。与基本商映射 Jacobian 的判别式比较,可区分“群商分歧”和“所选轨道表示碰撞”。

计算专题:大型轨道多项式的模算法

若轨道有数十或数百个向量,先在整数坐标下清除分母。选择良素数 pp,在 𝐅p[x1,,xn][T]\mathbf F_p[x_1,\ldots,x_n][T] 中分批相乘线性因子,使用乘积树把复杂度从顺序乘法的高常数降下来。对多个素数重复,再中国剩余恢复整数系数。

系数已知是加权不变量时,不必恢复全部坐标单项式。对每个权 dd,先列出基本不变量的所有权 dd 单项式,在若干随机点上建立线性方程,求轨道系数在该基中的坐标。所需样本略多于基维数即可,表达式规模远小于直接展开。

插值点应避开判别式和使基单项式矩阵奇异的点。可动态选点并监测秩;模不同素数若秩变化,说明遇到坏素数或生成元在该特征下产生关系。最终整数系数高度可由 Hadamard 界估计,以决定需要多少 CRT 模量。

验证不变量性只需检查群生成元而非全部元素。对每个基本不变量 FiF_i,符号比较 Fi(gx)Fi(x)=0F_i(gx)-F_i(x)=0;对轨道多项式则验证 P(T;gx)=P(T;x)P(T;gx)=P(T;x)。再比较随机点根多重集,可检测轨道列表是否遗漏或重复。

若希望从系数反解基本不变量,应选三角形生成组:最低次数系数先给 F2F_2,下一新次数给 F6F_6,高次系数只含已知低次组合与一个新生成元。通过线性替换可把生成元整理成这种形式,显著简化逆公式。

轨道多项式还可作为 resolvent。其在特化点上的因式分解型记录 Galois 群在轨道上的 Frobenius 循环型。收集多个良素数的型,可验证特化 Galois 群是否达到预期 Weyl 群,并识别参数落在特殊子群 locus 的情形。

深入补充:指数、Poincaré 多项式与大型轨道多项式的插值

有限实反射群的基本不变量次数 did_i 与指数 mim_i 满足 di=mi+1d_i=m_i+1。长度生成函数为

wWt(w)=i=1n(1+t++tmi).\sum_{w\in W}t^{\ell(w)}= \prod_{i=1}^n(1+t+\cdots+t^{m_i}).

t=1t=1 立即得到群阶

|W|=idi,|W|=\prod_i d_i,

而指数之和等于正根数:

|Φ+|=imi.|\Phi^+|=\sum_i m_i.
计算 F4F_4E6E_6 的数值一致性

F4F_4,次数为 2,6,8,122,6,8,12,指数为 1,5,7,111,5,7,11,故

|W(F4)|=26812=1152,|Φ+|=1+5+7+11=24.|W(F_4)|=2\cdot6\cdot8\cdot12=1152, \qquad |\Phi^+|=1+5+7+11=24.

E6E_6,次数为 2,5,6,8,9,122,5,6,8,9,12,指数为 1,4,5,7,8,111,4,5,7,8,11,故

|W(E6)|=51840,|Φ+|=36,|W(E_6)|=51840, \qquad |\Phi^+|=36,

根总数为 7272

WW 作用于线性形式的有限轨道 𝒪\mathcal O,定义轨道多项式

P𝒪(T)=v𝒪(Tv(x)).P_{\mathcal O}(T)=\prod_{v\in\mathcal O}(T-\ell_v(x)).

其系数是 WW-不变量,因而可表示为基本不变量的加权齐次多项式。与直接展开乘积相比,先算幂和

pk(x)=v𝒪v(x)kp_k(x)=\sum_{v\in\mathcal O}\ell_v(x)^k

再用 Newton 恒等式恢复系数,通常稀疏得多。若相应权度不存在不变量单项式,pkp_k 必为零或常数倍的唯一候选,这可预先消去大量计算。

轨道—稳定子 E6E_6 的两个关键轨道

W(E6)W(E_6)2727 个极小权上作用传递,稳定子阶为

51840/27=1920=|W(D5)|.51840/27=1920=|W(D_5)|.

它在 7272 个根上也传递,根稳定子阶为

51840/72=720.51840/72=720.

这两个阶数必须与显式矩阵生成群的稳定子计算一致,是识别 2727 次与 7272 次轨道多项式的直接证书。

算法 模素数黑盒插值轨道系数

对每个目标系数的权度列出基本不变量单项式基;在良素数域随机取足够多的点 xx;只计算轨道上的线性值并用幂和递推得到目标系数;解插值线性系统;跨多个素数中国剩余重构。最后在新的随机点和特征零中的少量符号点上验证。

该方法的成本近似为“轨道大小 × 所需幂和次数 × 样本数”,而不是展开一个含数十个线性因子的多元乘积。可进一步按群生成树递推轨道值,避免重复矩阵乘法。

轨道多项式判别式

DiscT(P)=v<w(vw)2\operatorname{Disc}_T(P)= \prod_{v<w}(\ell_v- \ell_w)^2

在某些超平面上消失,表示两个轨道值合并。对极小权轨道,这些差通常与根线性形式相关,因此判别式的平方自由部分由反射超平面像控制。因式分解判别式并比较 Jacobian 判别式,可确认轨道、多项式系数和商映射的分支结构彼此一致。

补充计算:Weyl 指数、Newton 恒等式与轨道多项式 CRT 恢复

定理 Weyl 群基本次数与 Poincaré 多项式

有限 Weyl 群 W 的指数为 \(e_1,…,e_n\),基本不变量次数为 \(d_i=e_i+1\),并有 |W|=idi,wWq(w)=i(1+q++qei). |W|=\prod_i d_i,\qquad \sum_{w\in W}q^{\ell(w)}=\prod_i(1+q+\cdots+q^{e_i}). 若 \(λ_1,…,λ_N\) 是一个 W-轨道在线性泛函处的取值,则轨道多项式 \(∏(T-λ_i)\) 的系数可由幂和 \(p_k=∑λ_i^k\) 通过 Newton 恒等式逐项恢复。

证明 余不变量代数与对称函数递推

Chevalley 定理给出 \(K[V]^W=K[f_1,…,f_n]\),余不变量代数的 Hilbert 级数为 \(∏(1-q^{d_i})/(1-q)^n=∏(1+···+q^{e_i})\)。余不变量代数作为 W-模同构于正则表示,故维数等于 |W|;令 \(q→1\) 得 \(|W|=∏d_i\)。长度生成函数与余不变量分次 Hilbert 级数相同,得到 Poincaré 乘积式。

设 \(e_k\) 为 \(λ_i\) 的初等对称函数,\(e_0=1\)。Newton 恒等式 \(k e_k=∑_{i=1}^k(-1)^{i-1}e_{k-i}p_i\) 按 k 递推唯一确定全部 \(e_k\),进而得到首一轨道多项式。模多个好素数计算 \(p_i\) 与 \(e_i\),再以 CRT 合并;当总模数超过系数高度两倍时,中心提升唯一恢复整数系数。

Python Weyl 阶数、轨道幂和、Newton 恢复与多模 CRT
from fractions import Fraction
from itertools import combinations, product
from math import prod
import sympy as sp

T=sp.Symbol("T")

WEYL_EXPONENTS={
    "A4":(1,2,3,4),
    "D4":(1,3,3,5),
    "F4":(1,5,7,11),
    "E6":(1,4,5,7,8,11),
    "E7":(1,5,7,9,11,13,17),
    "E8":(1,7,11,13,17,19,23,29),
}

def poincare_from_exponents(exponents):
    q=sp.Symbol("q")
    P=sp.Integer(1)
    for e in exponents:
        P*=sum(q**j for j in range(e+1))
    return sp.expand(P)

def degrees(exponents):
    return tuple(e+1 for e in exponents)

def weyl_order(exponents):
    return prod(degrees(exponents))

def newton_coefficients(power_sums):
    """
    Given p_k=sum roots^k for k=1..n, recover monic polynomial
    T^n-e1*T^(n-1)+...+(-1)^n en.
    """
    n=len(power_sums)
    e=[sp.Integer(1)]
    for k in range(1,n+1):
        value=sum((-1)**(i-1)*e[k-i]*power_sums[i-1]
                  for i in range(1,k+1))
        e.append(sp.simplify(value/k))
    coeff=[sp.Integer(1)]
    coeff.extend(((-1)**k)*e[k] for k in range(1,n+1))
    return coeff

def polynomial_from_power_sums(power_sums):
    coeff=newton_coefficients(power_sums)
    n=len(power_sums)
    return sp.Poly(sum(coeff[i]*T**(n-i) for i in range(n+1)),T)

def d4_roots():
    roots=[]
    for i,j in combinations(range(4),2):
        for si,sj in product((-1,1),repeat=2):
            v=[0]*4
            v[i]=si;v[j]=sj
            roots.append(tuple(v))
    return roots

def dot(a,b):
    return sum(x*y for x,y in zip(a,b))

def orbit_polynomial(values):
    P=sp.Poly(1,T,domain=sp.ZZ)
    for v in values:
        P*=sp.Poly(T-v,T,domain=sp.ZZ)
    return P

def crt_pair(a,m,b,n):
    return int(sp.ntheory.modular.crt([m,n],[a,b])[0])

def symmetric_reconstruct_mod_primes(values,primes):
    n=len(values)
    residues=[]
    for p in primes:
        ps=[sum(pow(v,k,p) for v in values)%p for k in range(1,n+1)]
        # Newton identities modulo p; primes exceed n.
        e=[1]
        for k in range(1,n+1):
            rhs=sum(((-1)**(i-1))*e[k-i]*ps[i-1]
                    for i in range(1,k+1))%p
            e.append(rhs*pow(k,-1,p)%p)
        residues.append([1]+[((-1)**k*e[k])%p for k in range(1,n+1)])
    modulus=1
    coeff=[0]*(n+1)
    for p,row in zip(primes,residues):
        if modulus==1:
            coeff=row[:]
            modulus=p
        else:
            coeff=[crt_pair(a,modulus,b,p) for a,b in zip(coeff,row)]
            modulus*=p
    centered=[c-modulus if c>modulus//2 else c for c in coeff]
    return centered,modulus

print("Weyl degrees and orders:")
for name,exponents in WEYL_EXPONENTS.items():
    P=poincare_from_exponents(exponents)
    print(
        f"  {name}: exponents={exponents}, degrees={degrees(exponents)}, "
        f"order={weyl_order(exponents)}, top={sp.degree(P)}"
    )
    print("    P(q) first terms =",sp.Poly(P,sp.Symbol("q")).all_coeffs()[-12:])

roots=d4_roots()
v=(1,2,3,5)
values=[dot(r,v) for r in roots]
exact=orbit_polynomial(values)
power_sums=[sum(z**k for z in values) for k in range(1,len(values)+1)]
newton=polynomial_from_power_sums(power_sums)
print("\nD4 long-root orbit polynomial at v=(1,2,3,5):")
print("  value multiplicities =",dict(sorted(__import__('collections').Counter(values).items())))
print("  degree =",exact.degree())
print("  direct factorization =",sp.factor(exact.as_expr()))
print("  Newton equality =",exact==newton)
print("  nonzero coefficients:")
for (e,),c in exact.terms():
    if c:
        print(f"    T^{e:2d}: {c}")

primes=(101,103,107,109,113,127,131,137,139)
reconstructed,modulus=symmetric_reconstruct_mod_primes(values,primes)
exact_coeff=list(map(int,exact.all_coeffs()))
bound=max(abs(c) for c in exact_coeff)
print("\nCRT reconstruction:")
print("  modulus =",modulus)
print("  2*height bound =",2*bound)
print("  sufficient =",modulus>2*bound)
print("  coefficient equality =",reconstructed==exact_coeff)

print("\nfirst E6 orbit-polynomial coefficient weights:")
# If 27 linear forms are evaluated on a graded parameter space, coefficient
# of T^(27-k) has invariant weight k.
for k in range(15):
    available=[d for d in degrees(WEYL_EXPONENTS["E6"]) if d<=k]
    print(f"  coefficient e_{k:2d}: weight={k:2d}, basic degrees <= weight={available}")
运行结果 D4 长根轨道多项式及 E6 系数权重表
Weyl degrees and orders:
  A4: exponents=(1, 2, 3, 4), degrees=(2, 3, 4, 5), order=120, top=10
    P(q) first terms = [1, 4, 9, 15, 20, 22, 20, 15, 9, 4, 1]
  D4: exponents=(1, 3, 3, 5), degrees=(2, 4, 4, 6), order=192, top=12
    P(q) first terms = [4, 9, 16, 23, 28, 30, 28, 23, 16, 9, 4, 1]
  F4: exponents=(1, 5, 7, 11), degrees=(2, 6, 8, 12), order=1152, top=24
    P(q) first terms = [92, 87, 80, 71, 60, 48, 36, 25, 16, 9, 4, 1]
  E6: exponents=(1, 4, 5, 7, 8, 11), degrees=(2, 5, 6, 8, 9, 12), order=51840, top=36
    P(q) first terms = [1765, 1389, 1048, 754, 514, 329, 195, 105, 50, 20, 6, 1]
  E7: exponents=(1, 5, 7, 9, 11, 13, 17), degrees=(2, 6, 8, 10, 12, 14, 18), order=2903040, top=63
    P(q) first terms = [6909, 4795, 3205, 2051, 1247, 713, 378, 182, 77, 27, 7, 1]
  E8: exponents=(1, 7, 11, 13, 17, 19, 23, 29), degrees=(2, 8, 12, 14, 18, 20, 24, 30), order=696729600, top=120
    P(q) first terms = [20272, 12978, 8000, 4718, 2640, 1386, 672, 294, 112, 35, 8, 1]

D4 long-root orbit polynomial at v=(1,2,3,5):
  value multiplicities = {-8: 1, -7: 1, -6: 1, -5: 1, -4: 2, -3: 2, -2: 2, -1: 2, 1: 2, 2: 2, 3: 2, 4: 2, 5: 1, 6: 1, 7: 1, 8: 1}
  degree = 24
  direct factorization = (T - 8)*(T - 7)*(T - 6)*(T - 5)*(T - 4)**2*(T - 3)**2*(T - 2)**2*(T - 1)**2*(T + 1)**2*(T + 2)**2*(T + 3)**2*(T + 4)**2*(T + 5)*(T + 6)*(T + 7)*(T + 8)
  Newton equality = True
  nonzero coefficients:
    T^24: 1
    T^22: -234
    T^20: 22815
    T^18: -1218360
    T^16: 39465855
    T^14: -812168370
    T^12: 10810706385
    T^10: -92892784140
    T^ 8: 504720730800
    T^ 6: -1660725352000
    T^ 4: 3065816991744
    T^ 2: -2763360976896
    T^ 0: 936404582400

CRT reconstruction:
  modulus = 4343678784233766587
  2*height bound = 6131633983488
  sufficient = True
  coefficient equality = True

first E6 orbit-polynomial coefficient weights:
  coefficient e_ 0: weight= 0, basic degrees <= weight=[]
  coefficient e_ 1: weight= 1, basic degrees <= weight=[]
  coefficient e_ 2: weight= 2, basic degrees <= weight=[2]
  coefficient e_ 3: weight= 3, basic degrees <= weight=[2]
  coefficient e_ 4: weight= 4, basic degrees <= weight=[2]
  coefficient e_ 5: weight= 5, basic degrees <= weight=[2, 5]
  coefficient e_ 6: weight= 6, basic degrees <= weight=[2, 5, 6]
  coefficient e_ 7: weight= 7, basic degrees <= weight=[2, 5, 6]
  coefficient e_ 8: weight= 8, basic degrees <= weight=[2, 5, 6, 8]
  coefficient e_ 9: weight= 9, basic degrees <= weight=[2, 5, 6, 8, 9]
  coefficient e_10: weight=10, basic degrees <= weight=[2, 5, 6, 8, 9]
  coefficient e_11: weight=11, basic degrees <= weight=[2, 5, 6, 8, 9]
  coefficient e_12: weight=12, basic degrees <= weight=[2, 5, 6, 8, 9, 12]
  coefficient e_13: weight=13, basic degrees <= weight=[2, 5, 6, 8, 9, 12]
  coefficient e_14: weight=14, basic degrees <= weight=[2, 5, 6, 8, 9, 12]
计算 F4 与 E6 的基本次数

F_4 指数 1,5,7,11 给出次数 2,6,8,12 与群阶 1152。E_6 指数 1,4,5,7,8,11 给出次数 2,5,6,8,9,12 与群阶 51840。程序对 D_4 的 24 个长根取值,以 9 个素数合并得到模数 4343678784233766587,超过两倍系数高度,恢复结果与直接整数展开完全一致。

Lecture 21 / 第 21 讲

Shioda excellent family:E6,E7,E8E_6,E_7,E_8 有理椭圆曲面

把 Mordell–Weil 格、Weyl 群不变量和带加性纤维的 Weierstrass 族统一起来。

Shioda族有理椭圆曲面Mordell–Weil格

1. 有理椭圆曲面与 Shioda–Tate

有截面的相对极小椭圆曲面 π:S𝐏t1\pi:S\to\mathbf P^1_t 可写为

y2=x3+a(t)x+b(t),dega4,degb6.y^2=x^3+a(t)x+b(t),\qquad \deg a\le4,\qquad \deg b\le6.

对有理椭圆曲面,Néron–Severi 群秩为 10。Shioda–Tate 公式为

ρ(S)=2+rankE(𝐂(t))+vrankRv,\rho(S)=2+\operatorname{rank}E(\mathbf C(t))+\sum_v\operatorname{rank}R_v,

其中 RvR_v 是可约纤维的根格。

定理三类加性无穷远纤维

t=t=\infty 固定为 Kodaira 类型 II、III、IV 的加性纤维,可得到 Mordell–Weil 格分别与 E8E_8E7*E_7^*E6*E_6^* 相关的秩 8,7,68,7,6 族。

2. 三个加权族

Weierstrass 系数参数权
E8E_8a(t)=i=03aitia(t)=\sum_{i=0}^3a_it^i, b(t)=t5+j=03bjtjb(t)=t^5+\sum_{j=0}^3b_jt^jai:2,8,14,20a_i:2,8,14,20; bj:12,18,24,30b_j:12,18,24,30
E7E_7a(t)=t3+a1t+a0a(t)=t^3+a_1t+a_0, b(t)=j=04bjtjb(t)=\sum_{j=0}^4b_jt^jai:8,12a_i:8,12; bj:2,6,10,14,18b_j:2,6,10,14,18
E6E_6a(t)=a2t2+a1t+a0a(t)=a_2t^2+a_1t+a_0, b(t)=t4+b2t2+b1t+b0b(t)=t^4+b_2t^2+b_1t+b_0ai:2,5,8a_i:2,5,8; bj:6,9,12b_j:6,9,12

这些权的集合恰好是 W(En)W(E_n) 的基本不变量次数。方程总权分别为 Coxeter 数 30,18,1230,18,12。这不是数值巧合,而是参数空间与 Cartan 子空间商 𝔥/W(En)\mathfrak h/W(E_n) 的识别。

3. excellent family的含义

这里把 Shioda 的专名 excellent family 译作excellent family,并在首次出现时保留英文:族的参数就是反射群基本不变量,而截面的坐标由权格中的向量以 Galois 对称方式给出。一般纤维的 Mordell–Weil 群具有预期高秩,判别超平面对应根 α\alpha 满足 αz=0\alpha\cdot z=0 的位置。

算法从截面恢复参数
  1. 设截面 x(t),y(t)x(t),y(t) 的次数由高度配对和无穷远纤维决定。
  2. 代入 Weierstrass 方程并比较系数。
  3. 消去截面系数,得到参数满足的结式。
  4. 识别根格或权格轨道,并计算基本对称函数。
  5. 核对参数权与 Weyl 不变量次数。
说明高秩曲线计数启发

这些族在高度盒中产生的高秩特殊化数量超过朴素“随机独立点”模型的预测。它提醒我们:带群对称和几何来源的点并非独立随机事件。

Shiodaexcellent family的基本设定

原讲义以 Schütt–Shioda 的《Mordell–Weil Lattices》以及 Shioda 1989–1991 年系列论文为主要参考。考虑有理椭圆曲面

:y2=x3+a(t)x+b(t),\mathcal E:\quad y^2=x^3+a(t)x+b(t),

并规定 t=t=\infty 处有加性奇异纤维。若纤维型依次为 II、III、IV,则一般 Mordell–Weil 格分别与 E8E_8E7E_7^\veeE6E_6^\vee 相联系。所谓“优良”,核心在于:族参数的加权次数恰好等于相应 Weyl 群基本不变量的次数;截面的坐标则给出根格或对偶格短向量轨道的显式实现。

E8E_8

a(t)=a0+a1t+a2t2+a3t3,b(t)=t5+b0+b1t+b2t2+b3t3.a(t)=a_0+a_1t+a_2t^2+a_3t^3,\qquad b(t)=t^5+b_0+b_1t+b_2t^2+b_3t^3.

t,x,yt,x,y 的权分别为 6,10,156,10,15,Weierstrass 方程总权为 30,即 E8E_8 的 Coxeter 数。于是

wt(a0,a1,a2,a3)=(20,14,8,2),\operatorname{wt}(a_0,a_1,a_2,a_3)=(20,14,8,2),
wt(b0,b1,b2,b3)=(30,24,18,12).\operatorname{wt}(b_0,b_1,b_2,b_3)=(30,24,18,12).

重排后正是 W(E8)W(E_8) 的基本不变量次数

2,8,12,14,18,20,24,30.2,8,12,14,18,20,24,30.

E7E_7

a(t)=t3+a1t+a0,b(t)=b0+b1t+b2t2+b3t3+b4t4.a(t)=t^3+a_1t+a_0,\qquad b(t)=b_0+b_1t+b_2t^2+b_3t^3+b_4t^4.

wt(t,x,y)=(4,6,9)\operatorname{wt}(t,x,y)=(4,6,9),总权为 18。参数权为

wt(a0,a1)=(12,8),wt(b0,,b4)=(18,14,10,6,2),\operatorname{wt}(a_0,a_1)=(12,8),\qquad \operatorname{wt}(b_0,\ldots,b_4)=(18,14,10,6,2),

W(E7)W(E_7) 的次数 2,6,8,10,12,14,182,6,8,10,12,14,18

E6E_6

a(t)=a0+a1t+a2t2,b(t)=t4+b0+b1t+b2t2.a(t)=a_0+a_1t+a_2t^2,\qquad b(t)=t^4+b_0+b_1t+b_2t^2.

wt(t,x,y)=(3,4,6)\operatorname{wt}(t,x,y)=(3,4,6),总权为 12。于是

wt(a0,a1,a2)=(8,5,2),wt(b0,b1,b2)=(12,9,6),\operatorname{wt}(a_0,a_1,a_2)=(8,5,2),\qquad \operatorname{wt}(b_0,b_1,b_2)=(12,9,6),

正是 W(E6)W(E_6) 的基本次数 2,5,6,8,9,122,5,6,8,9,12。三族中总权分别为 30,18,1230,18,12,也就是相应根系 Coxeter 数 h=#R/nh=\#R/n

Shioda–Tate 公式与格

对带截面的椭圆曲面,Shioda–Tate 公式为

ρ()=2+rankMW()+vrankRv,\rho(\mathcal E) =2+\operatorname{rank}\operatorname{MW}(\mathcal E) +\sum_v\operatorname{rank}R_v,

其中 RvR_v 是可约奇异纤维的根格。对一般有理椭圆曲面 ρ=10\rho=10。规定无穷远的加性纤维后,其根格贡献固定,剩余正好给出秩 8,7,68,7,6 的 Mordell–Weil 格。高度配对把截面群模挠部分变成正定格;最小高度截面对应 EnE_n^\vee 的最短向量。

参数计数与“过多”高秩曲线

高度不超过 HH 的整数短 Weierstrass 曲线粗略有 H10H^{10} 条,因为 |a|H4,|b|H6|a|\ll H^4,|b|\ll H^6。有一个小整数点时,可先选 x,y,ax,y,a,约有 H2+3+4=H9H^{2+3+4}=H^9 种,再由方程确定 bb。朴素推广预期具有 rr 个独立小点的曲线约有 H10r+εH^{10-r+\varepsilon} 条;该启发式在大 rr 必然失效。

E6E_6 族中,在 𝐏5\mathbf P^5 取高度至多 H1/2H^{1/2} 的参数点约有 H3H^3 种,再取 tH3/2t\ll H^{3/2},总计约 H9/2H^{9/2},超过朴素的 H106=H4H^{10-6}=H^4。类似地 E7E_7 给出 H11/3>H3H^{11/3}>H^3E8E_8 给出 H14/5>H2H^{14/5}>H^2。这说明几何族能系统地产生比随机模型预期更多的高秩特化。Néron 早在 1954 年已构造 𝐐(t)\mathbf Q(t) 上秩至少 10 的非等常椭圆曲面以及秩至少 11 的无穷整数族,故随机独立条件的朴素计数不能无限延伸。

有理椭圆曲面的全局数值约束

相对极小且带截面的椭圆曲面 π:𝐏1\pi:\mathcal E\to\mathbf P^1 可写成全局 Weierstrass 模型,其中 aia_i𝒪(ie)\mathcal O(ie) 的截面,e=χ(𝒪)e=\chi(\mathcal O_{\mathcal E})。有理椭圆曲面满足 e=1e=1,故最小判别式是次数 12 的截面,奇异纤维 Euler 数之和为 12。K3 椭圆曲面则 e=2e=2,判别式次数 24。

短模型 y2=x3+a(t)x+b(t)y^2=x^3+a(t)x+b(t)dega4e\deg a\le4edegb6e\deg b\le6e。通过在 t=t=\infty 预设 II、III、IV 型纤维,可以消耗一部分判别式次数并约束最高项,从而留下恰好与某个 Weyl 群秩相同的参数数目。

Kodaira 纤维与消失阶

在特征不为 2、3 的最小模型上,Kodaira 型可由 v(c4),v(c6),v(Δ)v(c_4),v(c_6),v(\Delta) 的组合判定。典型地:

InIIIIIIVI0*IV*v(Δ)n23468\begin{array}{c|cccccc} \text{型}&I_n&II&III&IV&I_0^*&IV^*\\ \hline v(\Delta)&n&2&3&4&6&8 \end{array}

更高星型继续为 III*,II*III^*,II^*,判别式阶 9、10。精确判型应使用 Tate 算法,因为同一 v(Δ)v(\Delta) 在非最小模型或小特征下可能对应不同纤维。

Shioda–Tate 公式

设奇异纤维的可约分量根格为 RvR_v,则

ρ()=2+rankMW()+vrankRv.\rho(\mathcal E)=2+\operatorname{rank}MW(\mathcal E)+\sum_v\operatorname{rank}R_v.

有理椭圆曲面的 Picard 数为 10,因此一般成员的 Mordell–Weil 秩可直接由无穷远纤维贡献读出。II、III、IV 型的根格秩分别为 0、1、2,所以得到秩 8、7、6,正对应 E8,E7,E6E_8,E_7,E_6 背景。

截面高度与 Mordell–Weil 格

Shioda 配对不仅给出单个截面的高度,还给出双线性形式

P,Q=χ+(PO)+(QO)(PQ)vcontrv(P,Q).\langle P,Q\rangle=\chi+(P\cdot O)+(Q\cdot O)-(P\cdot Q)-\sum_v\operatorname{contr}_v(P,Q).

局部修正由截面穿过可约纤维的哪个分量决定,可用相应 Cartan 矩阵的逆计算。扣除挠点后,MW()MW(\mathcal E) 带此正定配对成为格。其判别式与 Néron–Severi 格、平凡格之间满足精确关系,可用于证明找到的截面已经生成全部 Mordell–Weil 群。

参数权为何等于反射群次数

Weierstrass 缩放

(t,x,y)(λwtt,λwxx,λwyy)(t,x,y)\mapsto(\lambda^{w_t}t,\lambda^{w_x}x,\lambda^{w_y}y)

使方程各项同权。参数系数因此取得自然正权。excellent family的关键不是偶然的次数巧合,而是参数空间可解释为 Cartan 子代数的 Weyl 商:基本不变量给出加权射影坐标,而截面轨道提供根或权的特征多项式。要把“权吻合”升级为同构,仍需证明参数映射有限、一般单射到 Weyl 轨道,并核对分歧判别式。

奇异纤维增强与根子系统

参数落在判别式上时,某些有限纤维变为可约或更坏,平凡格增加,Mordell–Weil 秩相应下降。Weyl 商中这对应根超平面的像:一个根变为代数类,反射稳定子增强。多个根超平面相交时出现更大根子系统。于是椭圆曲面的纤维分类与反射群判别式分层逐层对应。

截面的次数上界

对有理椭圆曲面,给定高度的截面 P=(x(t),y(t))P=(x(t),y(t)) 具有受控极点阶。经无穷远局部坐标分析,可预先给出 degx,degy\deg x,\deg y 上界;最小截面通常恰达到较低界。把一般多项式代入后,从最高次项向下解,方程呈近三角结构。这个权分析是 Shioda 显式计算可行的根本原因。

专化与格跳跃

参数取特殊代数值时,截面可增加,Mordell–Weil 秩跳跃。专化同态在除有限多参数外是单射,因此一般格可嵌入特殊纤维的格。反过来,通过在多个好专化上计算约化曲面的 Néron–Severi 判别式,可约束一般 Picard 数。若不同素数给出的判别式平方类不一致,可排除额外一般截面。

从族方程到 Weyl 商的认证步骤

完整证明通常包含:验证总空间一般光滑且是有理椭圆曲面;用 Tate 算法确定无穷远纤维;由 Shioda–Tate 得一般秩;显式求足够多截面并计算高度格;证明参数上的 Weyl 群作用;计算不变量并与方程系数互相表达;最后比较函数域次数或 Jacobian,确认参数空间确为 Weyl 商。

计算专题:椭圆曲面从方程到格的实际步骤

先计算 c4,c6,Δc_4,c_6,\Delta 并在 𝐏1\mathbf P^1 各点最小化。有限点可按不可约因子逐一做局部赋值;无穷远令 s=1/ts=1/t,再按 x=s2eX,y=s3eYx=s^{-2e}X,y=s^{-3e}Y 变换。Tate 算法给每个奇异纤维型、分量群和截面落点。

候选截面由次数上界模板求出后,先精确代入。独立性可将截面在一个好纤维特化为椭圆曲线点,做模若干素数的群关系筛查;严格证明仍用 Shioda 高度矩阵非奇异。高度矩阵应为有理正定矩阵,其分母只来自可约纤维修正。

平凡格由零截面、纤维类和非恒等纤维分量组成。其判别式可由根格 Cartan 矩阵计算。Shioda 判别式公式把 discNS\operatorname{disc}NSdiscTriv\operatorname{disc}TrivdiscMW\operatorname{disc}MW 与挠子群阶联系起来;这是证明生成截面指数的关键。

参数族的一般性可通过判别式多项式证明:排除使 Δ\Delta 重根、模型非最小或额外可约纤维出现的闭子集。在其补集上纤维配置和 Mordell–Weil 格局部恒定。所谓“一般成员”必须明确指这个 Zariski 开集。

Weyl 群作用若来自截面反射,应给出对参数函数域的显式变换或通过单值证明。绕判别式一般点的 Picard–Lefschetz 单值是根反射;若这些反射生成完整 Weyl 群,参数覆盖的 Galois 群即被确定。

在数值实验中,可沿参数闭路跟踪最小截面,得到它们的置换;再与根格反射矩阵比较。精确理论则由判别式局部退化和 vanishing cycle 给出。二者结合能验证excellent family不是仅由权次数猜出的对应。

深入补充:Shioda 高度公式、判别式恒等式与格的认证

π:S𝐏1\pi:S\to\mathbf P^1 是带零截面 OO 的相对极小椭圆曲面,χ=χ(𝒪S)\chi=\chi(\mathcal O_S)。对截面 P,QP,Q,Shioda 把 Néron–Tate 高度写成曲面交数与奇异纤维局部修正之和。

定理 Shioda 高度配对

P,Q=χ+PO+QOPQvcontrv(P,Q).\langle P,Q\rangle =\chi+P\cdot O+Q\cdot O-P\cdot Q -\sum_v\operatorname{contr}_v(P,Q).

特别地,

P,P=2χ+2POvcontrv(P).\langle P,P\rangle =2\chi+2P\cdot O-\sum_v\operatorname{contr}_v(P).

局部项只由 P,QP,Q 与可约纤维各分量的相交位置决定,可由对应根格 Cartan 矩阵的逆矩阵计算。

对有理椭圆曲面 χ=1\chi=1。若所有奇异纤维都不可约,局部修正为零,且与零截面不交的非零截面高度为 22;这些最短向量形成 E8E_8 根系,Mordell–Weil 格就是 E8E_8。若出现可约纤维,其根格嵌入 E8E_8,Mordell–Weil 格成为正交补的有限指数扩张。

判别式公式 平凡格与 Mordell–Weil 格

TT 为由纤维类、零截面和可约纤维非单位分量生成的平凡格,MWfreeMW_{\mathrm{free}} 为自由部分带高度配对的格,则绝对值满足

|discNS(S)|=|discT|disc(MWfree)|MWtors|2.|\operatorname{disc}\operatorname{NS}(S)| =\frac{|\operatorname{disc}T|\,\operatorname{disc}(MW_{\mathrm{free}})}{|MW_{\mathrm{tors}}|^2}.

因此群秩、挠子群、纤维根格和截面高度矩阵之间必须满足一个精确整数恒等式。

这是认证“已找到全部截面”的关键。仅找到若干线性独立截面只能给出子格;计算其高度矩阵行列式,再代入判别式公式,可求该子格在完整 Mordell–Weil 格中的可能指数。若指数为 11,就证明生成完备;若指数大于 11,还需搜索饱和截面。

算法 从 Weierstrass 方程到 Mordell–Weil 格

先最小化方程并因式分解判别式;用 Tate 算法确定每个奇异纤维的 Kodaira 型及分量群;由 Shioda–Tate 公式算秩;设定截面坐标的次数界,解系数方程;计算每个截面落在哪个纤维分量;用高度公式组成 Gram 矩阵;最后用判别式公式做饱和检验。

截面高度还控制参数族中的退化。当某个截面在特化后高度下降到零,它变成挠点;当两个截面之差高度下降,二者在特化中合并。高度矩阵行列式的消失因子因而包含于参数空间的判别式中。对excellent family,基本不变量参数与 Weyl 群商坐标相吻合,根超平面的像正对应“某个根截面高度退化”的分支除子。

在数值求得截面后,可先用高精度计算猜测高度,但最终必须由交数与纤维分量精确计算。高度是有理数且分母受分量群阶限制,这一离散性可用于纠正数值误差,也可快速发现截面坐标或纤维类型的录入错误。

补充计算:Kodaira 消失阶、Shioda–Tate 秩与高度配对

定理 有理椭圆曲面的格秩公式

设 \(π:S→P^1\) 为带截面的相对极小有理椭圆曲面。则 \(ρ(S)=10\),且 rankMW(S)=8vrankRv, \operatorname{rank}MW(S)=8-\sum_v\operatorname{rank}R_v, 其中 \(R_v\) 为可约 Kodaira 纤维的根格。对截面 P, P,P=2χ(𝒪S)+2(PO)vcontrv(P). \langle P,P\rangle=2\chi(\mathcal O_S)+2(P\cdot O)-\sum_v\operatorname{contr}_v(P). 有理椭圆曲面满足 \(χ(\mathcal O_S)=1\)、\(∑_v e(F_v)=12\)。

证明 由平凡格分解与交叉配对

Néron–Severi 群包含纤维 F、零截面 O 生成的双曲平面,以及每个可约纤维中不与 O 相交的分量根格 \(R_v\)。Shioda–Tate 定理给出 \(ρ=2+∑rank R_v+rank MW\)。 有理曲面由 Noether 公式与 \(b_2=10\) 得 \(ρ=10\),故得到秩公式。

把截面 P 投影到上述平凡格的正交补,负交叉形式取反即 Mordell–Weil 高度。逐项展开投影系数,纤维分量的逆 Cartan 矩阵贡献 \(contr_v(P)\),得到高度公式。拓扑 Euler 数等于奇异纤维 Euler 数之和;有理椭圆曲面 \(c_2=12χ=12\)。

Python 短 Weierstrass 不变量、纤维账本与高度样本
import sympy as sp
from dataclasses import dataclass
from fractions import Fraction

t=sp.Symbol("t")

KODAIRA={
    "I0":(0,0,0),
    "II":(1,2,0),
    "III":(1,3,1),
    "IV":(2,4,2),
    "I0*":(2,6,4),
    "IV*":(3,8,6),
    "III*":(3,9,7),
    "II*":(4,10,8),
}

@dataclass(frozen=True)
class Fiber:
    place: str
    kind: str
    euler: int
    root_rank: int
    delta_order: int

def invariants_short(A,B):
    c4=-48*A
    c6=-864*B
    Delta=-16*(4*A**3+27*B**2)
    return sp.factor(c4),sp.factor(c6),sp.factor(Delta)

def valuation_at(poly,root):
    P=sp.Poly(sp.expand(poly),t)
    if root=="infinity":
        return None
    v=0
    q=P
    factor=sp.Poly(t-root,t)
    while not q.is_zero:
        div,rem=sp.div(q,factor)
        if not rem.is_zero:
            break
        v+=1;q=div
    return v

def isotrivial_two_fibers(A,B,finite_kind,infinity_kind):
    c4,c6,D=invariants_short(A,B)
    v0=valuation_at(D,0)
    fin=Fiber("t=0",finite_kind,KODAIRA[finite_kind][1],
              KODAIRA[finite_kind][2],v0)
    vinf=12-v0
    inf=Fiber("t=∞",infinity_kind,KODAIRA[infinity_kind][1],
              KODAIRA[infinity_kind][2],vinf)
    return c4,c6,D,(fin,inf)

def shioda_tate_rank(fibers,rho=10):
    return rho-2-sum(f.root_rank for f in fibers)

def height_pairing(chi, intersection_PO, local_contributions):
    return Fraction(2*chi+2*intersection_PO)-sum(
        Fraction(c) for c in local_contributions
    )

families=[
    ("E8",0,t**5,"II*","II"),
    ("E7",t**3,0,"III*","III"),
    ("E6",0,t**4,"IV*","IV"),
]
for name,A,B,k0,kinf in families:
    c4,c6,D,fibers=isotrivial_two_fibers(A,B,k0,kinf)
    print(name)
    print("  equation: y^2=x^3+(",A,")x+(",B,")")
    print("  c4 =",c4)
    print("  c6 =",c6)
    print("  Delta =",D)
    for f in fibers:
        print(" ",f)
    print("  Euler sum =",sum(f.euler for f in fibers))
    print("  root rank =",sum(f.root_rank for f in fibers))
    print("  MW rank =",shioda_tate_rank(fibers))

print("\nstandard rational elliptic-surface configurations:")
configs={
    "generic 12 I1":[Fiber(f"p{i}","I1",1,0,1) for i in range(12)],
    "D4 + 6 I1":[Fiber("0","I0*",6,4,6)]
                 +[Fiber(f"p{i}","I1",1,0,1) for i in range(6)],
    "E6 + A2":[Fiber("0","IV*",8,6,8),Fiber("∞","IV",4,2,4)],
    "E7 + A1":[Fiber("0","III*",9,7,9),Fiber("∞","III",3,1,3)],
    "E8":[Fiber("0","II*",10,8,10),Fiber("∞","II",2,0,2)],
}
for name,fibers in configs.items():
    print(
        f"  {name:14s}: e={sum(f.euler for f in fibers):2d}, "
        f"root={sum(f.root_rank for f in fibers):2d}, "
        f"MW={shioda_tate_rank(fibers):2d}"
    )

print("\nheight examples (chi=1, P.O=0):")
examples={
    "no reducible fiber":[],
    "one A1 nonidentity component":[Fraction(1,2)],
    "one A2 end component":[Fraction(2,3)],
    "two A1 contributions":[Fraction(1,2),Fraction(1,2)],
    "D4 vector component":[Fraction(1)],
}
for name,contr in examples.items():
    print(f"  {name:30s}: height={height_pairing(1,0,contr)}")

print("\nGram determinants:")
matrices={
    "A2*":[[Fraction(2,3),Fraction(1,3)],
           [Fraction(1,3),Fraction(2,3)]],
    "D4* diagonal model":[[Fraction(1,2) if i==j else 0 for j in range(4)]
                          for i in range(4)],
}
for name,M in matrices.items():
    det=sp.Matrix(M).det()
    print(f"  {name}: det={det}, rank={sp.Matrix(M).rank()}")
运行结果 E8、E7、E6 等参族与秩配置核验
E8
  equation: y^2=x^3+( 0 )x+( t**5 )
  c4 = 0
  c6 = -864*t**5
  Delta = -432*t**10
  Fiber(place='t=0', kind='II*', euler=10, root_rank=8, delta_order=10)
  Fiber(place='t=∞', kind='II', euler=2, root_rank=0, delta_order=2)
  Euler sum = 12
  root rank = 8
  MW rank = 0
E7
  equation: y^2=x^3+( t**3 )x+( 0 )
  c4 = -48*t**3
  c6 = 0
  Delta = -64*t**9
  Fiber(place='t=0', kind='III*', euler=9, root_rank=7, delta_order=9)
  Fiber(place='t=∞', kind='III', euler=3, root_rank=1, delta_order=3)
  Euler sum = 12
  root rank = 8
  MW rank = 0
E6
  equation: y^2=x^3+( 0 )x+( t**4 )
  c4 = 0
  c6 = -864*t**4
  Delta = -432*t**8
  Fiber(place='t=0', kind='IV*', euler=8, root_rank=6, delta_order=8)
  Fiber(place='t=∞', kind='IV', euler=4, root_rank=2, delta_order=4)
  Euler sum = 12
  root rank = 8
  MW rank = 0

standard rational elliptic-surface configurations:
  generic 12 I1 : e=12, root= 0, MW= 8
  D4 + 6 I1     : e=12, root= 4, MW= 4
  E6 + A2       : e=12, root= 8, MW= 0
  E7 + A1       : e=12, root= 8, MW= 0
  E8            : e=12, root= 8, MW= 0

height examples (chi=1, P.O=0):
  no reducible fiber            : height=2
  one A1 nonidentity component  : height=3/2
  one A2 end component          : height=4/3
  two A1 contributions          : height=1
  D4 vector component           : height=1

Gram determinants:
  A2*: det=1/3, rank=2
  D4* diagonal model: det=1/16, rank=4
计算 三类极端纤维配置

y^2=x^3+t^5 的判别式阶在 0 处为 10、在无穷远处补为 2,对应 II*+II;根格为 E8,MW 秩 0。y^2=x^3+t^3x 对应 III*+III,根格 E7+A1;y^2=x^3+t^4 对应 IV*+IV,根格 E6+A2。三者 Euler 数均为 12。

Lecture 22 / 第 22 讲

Shioda 族的酉反射特化与 E6E_6 的 27 个最小截面

说明固定复乘结构如何把实 Weyl 群降为例外酉反射群,并给出 E6 截面的消元方法。

酉反射群复乘27个截面

1. E6E_6 的 27 个最小截面

一般 E6E_6 族的 Mordell–Weil 格为 E6*E_6^*。在两个非平凡陪集中,各有 27 个最短向量;选定一个陪集,就得到 27 个最小截面。设截面具有适当次数

x(t)=u2t2+u1t+u0,y(t)=v3t3+v2t2+v1t+v0.x(t)=u_2t^2+u_1t+u_0,\qquad y(t)=v_3t^3+v_2t^2+v_1t+v_0.

代入曲面方程、比较系数后,可逐步消去 vi,uiv_i,u_i。由于权和次数被严格限制,最后只需一个关键结式就能得到 27 次轨道多项式。

说明27 的几何来源

这个 27 与光滑三次曲面的 27 条直线、E6E_6 最小表示的 27 个权、以及 E6*/E6E_6^*/E_6 非零陪集中的最短向量是同一个组合结构的不同实现。

2. j=0j=0 特化

E6E_6E8E_8 族中令 a(t)=0a(t)=0,得到

y2=x3+b(t),y^2=x^3+b(t),

jj-不变量恒为 0,纤维具有 𝐙[ζ3]\mathbf Z[\zeta_3] 复乘。Mordell–Weil 格因而成为 Eisenstein 整数模。与该复结构可交换的格自同构群是例外酉反射群:分别出现 Shephard–Todd 群 G25G_{25}(秩 3)与 G32G_{32}(秩 4)。参数权正是保留下来的 bjb_j 权。

3. 𝐙[i]\mathbf Z[i] 结构与 G31G_{31}

E8E_8 格上取满足 g2=1g^2=-1 的四阶作用,并令

(t,x,y)(t,x,iy).(t,x,y)\longmapsto(-t,-x,iy).

不变方程化为

y2=x3+(a2t2+a0)x+(t5+b3t3+b1t),y^2=x^3+(a_2t^2+a_0)x+(t^5+b_3t^3+b_1t),

参数权为 8,20,12,248,20,12,24,对应秩 4 的例外酉反射群 G31G_{31}

定理中心化子原则

若根格 LL 上的有限阶自同构 gg 无非零不动向量,并赋予 LL 一个环模结构,则与 gg 可交换的 Aut(L)\operatorname{Aut}(L) 子群作用在相应复向量空间上;在上述特殊情形中,它由酉反射生成。

补充如何验证具体特化

应同时检查:方程在指定作用下不变;参数权与目标群的不变量次数一致;一般纤维的奇异纤维型没有意外恶化;Mordell–Weil 格的秩和判别式与预期吻合。

E6E_6 族的 27 个最小截面

E6/E6𝐙/3𝐙E_6^\vee/E_6\cong\mathbf Z/3\mathbf Z。每个非零陪集含 27 个范数 4/34/3 的最小向量,对应立方曲面上的 27 条直线及 E6E_6 的 minuscule 表示。对 E6E_6 excellent family,一个指定陪集中的 27 个最小截面可统一写出。通常先对 x(t),y(t)x(t),y(t) 的次数作上界:

x(t)=x2t2+x1t+x0,y(t)=y3t3+y2t2+y1t+y0,x(t)=x_2t^2+x_1t+x_0,\qquad y(t)=y_3t^3+y_2t^2+y_1t+y_0,

代入 Weierstrass 方程,逐次比较 tt 的系数。最高次项先确定若干变量,剩余条件可通过一次结式消元化成次数 27 的轨道多项式。其根标记 27 个截面;轨道多项式的系数是参数的 W(E6)W(E_6) 不变量。

每个截面必须经过精确代入验证,并用 Shioda 高度公式核对高度:

P,P=2χ(𝒪)+2(PO)vcontrv(P).\langle P,P\rangle =2\chi(\mathcal O_{\mathcal E})+2(P\cdot O) -\sum_v\operatorname{contr}_v(P).

有理椭圆曲面 χ=1\chi=1。一般纤维配置下,最小截面与零截面不交,局部修正给出 4/34/3。截面间的高度配对恢复 E6E_6^\vee 的 Gram 矩阵。

j=0j=0 的酉反射特化

a(t)a(t) 全部置零,得到

y2=x3+t4+b2t2+b1t+b0y^2=x^3+t^4+b_2t^2+b_1t+b_0

以及 E8E_8 情形的

y2=x3+t5+b3t3+b2t2+b1t+b0.y^2=x^3+t^5+b_3t^3+b_2t^2+b_1t+b_0.

两族的 jj-不变量恒为 0,故一般纤维有 𝐙[μ3]\mathbf Z[\mu_3] 复乘。Mordell–Weil 格因此成为 Eisenstein 整数格。等价地,W(E6)W(E_6)W(E8)W(E_8) 中存在唯一共轭类的无不动向量三阶元素 gg;其中心化子给出保持 𝐙[μ3]\mathbf Z[\mu_3]-结构的自同构群,并且是酉反射群。

相应 Shephard–Todd 群分别为维数 3 与 4 的例外群 G25G_{25}G32G_{32}。其基本不变量次数恰是保留下来的 bjb_j 权:E6E_6 特化为 6,9,126,9,12E8E_8 特化为 12,18,24,3012,18,24,30。因此原 Weyl excellent family限制到一个线性子空间后,自动产生酉反射群的excellent family。

𝐙[i]\mathbf Z[i] 结构与 G31G_{31}

W(E8)W(E_8) 中还有唯一共轭类的四阶元素 gg 满足 g2=1g^2=-1,使 E8E_8 成为秩 4 的 Gaussian 整数格。其中心化子是维数 4 的例外酉反射群 G31G_{31},基本次数为

8,12,20,24,8,12,20,24,

正是 W(E8)W(E_8) 次数中能被 4 整除的部分。不能简单令 b(t)=0b(t)=0 来取得 j=1728j=1728,因为那会丢掉规定纤维型所需的主项 t5t^5。正确的四阶作用是

(t,x,y)(t,x,iy).(t,x,y)\longmapsto(-t,-x,iy).

其不变子族保留

y2=x3+(a2t2+a0)x+(t5+b3t3+b1t),y^2=x^3+(a_2t^2+a_0)x+(t^5+b_3t^3+b_1t),

参数权分别为 8,20,12,248,20,12,24,重排即 8,12,20,248,12,20,24

Shioda–Usui 的 W(A5)W(A_5)

原讲义还提到 Shioda 与 Usui 关于 Weyl 群基本不变量和椭圆曲线excellent family的工作。其思想并不限于 EnE_n:选择合适的奇异纤维配置和截面格,可让参数权实现其他 Weyl 群(例如 W(A5)W(A_5))的基本次数。构造时应同时核对:参数的加权缩放、判别式纤维、Shioda–Tate 秩、最小截面轨道以及基本次数乘积。

27 个截面的逐系数求解

x=x2t2+x1t+x0,y=y3t3+y2t2+y1t+y0x=x_2t^2+x_1t+x_0, \qquad y=y_3t^3+y_2t^2+y_1t+y_0

代入 y2=x3+a(t)x+b(t)y^2=x^3+a(t)x+b(t),得到从 t6t^6 到常数项的一组方程。最高项通常先给 y32=x23y_3^2=x_2^3。在一个指定 E6/E6E_6^\vee/E_6 陪集中,可用缩放或选定立方根规范 x2,y3x_2,y_3;随后 t5,t4,t^5,t^4,\ldots 系数依次线性决定大部分未知量,只留下一个轨道参数满足次数 27 的方程。

这种三角求解应保留所有分支条件:除以某个表达式前,先单独处理其为零的情形;否则可能漏掉特殊截面或把退化曲面混入一般解。最后的次数 27 结式应去除来自先前分母与无穷解的伪因子。

27 条直线的相交图

光滑立方曲面上的 27 条直线可标为六条例外曲线 EiE_i、十五条过两点的直线 LijL_{ij}、六条过五点的圆锥 QiQ_i。每条直线与恰好 10 条相交、与 16 条斜交。Weyl 群 W(E6)W(E_6) 忠实作用于这张图,群阶 51840。把 27 个最小截面的高度配对转成“相交/不相交”关系,可与这张 Schläfli 图核对,进而确认置换群确为 W(E6)W(E_6)

轨道多项式系数与基本不变量

uPu_P 是从截面 PP 提取的某个带权坐标,定义

Φ27(T)=P(TuP).\Phi_{27}(T)=\prod_{P}(T-u_P).

系数是族参数的加权齐次多项式。按权列出基本参数单项式,就可逐系数求表达式。反过来,若若干系数给出次数 2,5,6,8,9,122,5,6,8,9,12 的代数无关不变量,即可恢复整个 W(E6)W(E_6) 商。实际计算宜用模素数插值,最后在特征 0 重构。

高度 4/34/3 的来源

一般 E6E_6 excellent family在无穷远具有 IV 型纤维,其分量群为 𝐙/3𝐙\mathbf Z/3\mathbf Z。非零陪集截面穿过非恒等分量,局部高度修正为 2/32/3。若截面与零截面不交、不同有限纤维均不可约,则

P,P=223=43.\langle P,P\rangle=2-\frac23=\frac43.

这解释了最小向量为何位于对偶格非零陪集,而不是根格自身。两个非零陪集各有 27 个最小向量,并由取负互换。

j=0j=0 族的 Eisenstein 结构

a(t)=0a(t)=0 时,自同构

(x,y)(ζ3x,y)(x,y)\longmapsto(\zeta_3 x,y)

逐纤维作用,并作用在 Mordell–Weil 群上。于是实秩 2n2n 的 Mordell–Weil 格成为秩 nn𝐙[ζ3]\mathbf Z[\zeta_3]-Hermitian 格。实高度配对是 Hermitian 形式的迹。保持该结构并由复反射生成的群分别出现为 G25G_{25}G32G_{32}

j=1728j=1728 的 Gaussian 结构

若模型化为 y2=x3+a(t)xy^2=x^3+a(t)x,则有阶 4 自同构

(x,y)(x,iy).(x,y)\longmapsto(-x,iy).

Mordell–Weil 格因而成为 Gaussian 整数格。相应中心化子可产生另一类酉反射群。判断具体 Shephard–Todd 编号时,要比较复维数、群阶和基本次数,而不能只凭“有四阶复乘”猜测。

酉反射的形式

在 Hermitian 空间中,给定非各向同性向量 rr 与单位根 ζ1\zeta\ne1,复反射可写

sr,ζ(v)=v(1ζ)v,rr,rr.s_{r,\zeta}(v)=v-(1-\zeta)\frac{\langle v,r\rangle}{\langle r,r\rangle}r.

它在 rr 方向特征值为 ζ\zeta,固定 rr^\perp。若要保持 Eisenstein 或 Gaussian 格,还需相应系数落在整数环中。最小截面提供反射向量,截面轨道的高度配对则决定反射矩阵。

特殊化群可能小于中心化子

把若干参数置零会使方程拥有额外自同构,但参数空间上真正可见的单值群可能是中心化子的商、子群或带中心的扩张。应计算:群对参数函数域的忠实作用;中心在截面坐标上是否只作标量;反射生成子是否覆盖全部群;以及基本不变量次数乘积是否等于忠实像的阶。

精确核验 27 个解

对轨道多项式每个根对应的截面,不必在 27 次扩张中逐一展开。可在商环 K[T]/(Φ27)K[T]/(\Phi_{27}) 中定义通用截面并一次性验证 Weierstrass 方程;高度与相交性质可通过结果式和迹计算。若 Φ27\Phi_{27} 可分且一次验证成立,就同时认证全部共轭截面。

计算专题:27 截面与酉反射特化的群论核验

次数 27 轨道的稳定子阶为 51840/27=192051840/27=1920,抽象上与 W(D5)W(D_5) 型子群相关。计算一个截面的稳定子并核对阶与作用,可证明轨道确为 minuscule 权轨道,而不是另一个偶然的 27 点表示。

由截面高度可构造 Gram 矩阵:取六个适当差向量生成 E6E_6 根格,检查对角 2、相邻内积 1-1、其余 0。27 个权与根的配对落在预期分数格中。这个线性代数核验比只比较置换群阶更能确认几何标记。

j=0j=0 特化后,三阶自同构把实格分解为没有固定向量的复表示。中心化子阶可由 Weyl 群中共轭类数据计算;再把中心标量除去,得到忠实酉反射群。Molien 级数应给出对应 Shephard–Todd 基本次数。

若从参数上直接求酉不变量,可将原 Weyl 不变量限制到特化线性子空间。某些限制为零或相互依赖,剩余非零限制应生成中心化子不变量环。计算限制 Jacobian,比较次数乘积与群阶,是最直接的证明。

截面轨道多项式在特化后可能因额外对称分解。因式对应酉群较小轨道或中心字符。分析每个因式的次数、系数权和 Galois 群,可以看出 27 个实权如何在 Eisenstein 结构下重组。

特殊参数处若轨道多项式出现重根,表示两个截面坐标投影相同,不一定是截面本身相同。应比较完整 (x(t),y(t))(x(t),y(t)) 或高度差。只有差截面高度为零才说明相等;投影碰撞也可能来自所选轨道坐标不分离。

深入补充:立方曲面的 2727 条线、E6E_6 根格与截面相交图

把光滑立方曲面写成 𝐏2\mathbf P^2 在六个一般位置点的吹起。Picard 群有基

h,e1,,e6,h,e_1,\ldots,e_6,

交数为

h2=1,ei2=1,hei=eiej=0(ij),h^2=1, \qquad e_i^2=-1, \qquad h\cdot e_i=e_i\cdot e_j=0\quad(i\ne j),

典范类为

K=3h+e1++e6.K=-3h+e_1+ \cdots+e_6.

KK 正交且平方为 2-2 的类构成 E6E_6 根系,Weyl 群保持交配对与典范类。

分类 2727(1)(-1)-曲线

立方曲面上的 2727 条线在 Picard 群中分为

ei(6),e_i\quad(6\text{ 条}),
heiej(1i<j6,15),h-e_i-e_j\quad(1\le i<j\le6, \;15\text{ 条}),
2hjiej(6).2h-\sum_{j\ne i}e_j\quad(6\text{ 条}).

每个类都满足 L2=1L^2=-1KL=1K\cdot L=-1,由伴随公式知其为有理曲线,并在反典范嵌入下成为直线。

用交数可完全恢复 Schläfli 配置。每条线与另外 1010 条相交,与 1616 条斜交。若图的边表示“斜交”,得到度数 1616 的 Schläfli 图;若边表示“相交”,得到其度数 1010 的补图。程序中必须注明采用哪一种邻接约定,否则谱和稳定子会看似矛盾。

经典 double-six 由两组六条线

a1,,a6;b1,,b6a_1, \ldots,a_6; \qquad b_1, \ldots,b_6

组成,同组内两两斜交,aia_ibjb_jiji\ne j 时相交而与 bib_i 斜交。固定一个 double-six 的稳定子给出 E6E_6 Weyl 群中的大型子群,并可作为标号 2727 条线的坐标框架。

对应 极小截面与极小权

在 Shioda 的 E6E_6 椭圆曲面族中,2727 个最小截面形成 W(E6)W(E_6) 的一个传递轨道;其差的高度配对对应 E6E_6 根数据。适当紧化后,这个配置与立方曲面的 2727 条线具有相同的关联结构。

因此可用相交图认证截面是否找全。先计算每对截面的高度

PiPj,PiPj\langle P_i-P_j,P_i-P_j\rangle

或相应交数,把“最小差”定义为邻接;所得图应有 2727 个顶点、统一度数,并具有 W(E6)W(E_6) 预期的轨道与稳定子。若某一顶点度数不同,通常表示某个截面表达式错配了共轭或遗漏了纤维局部修正。

算法 不依赖浮点的 2727 截面核验

在精确数域中逐一代入 Weierstrass 方程;按参数次数和无穷远展开确认截面正则;用 Shioda 高度公式组成 27×2727\times27 的距离数据;构造相交或斜交图并计算其度数、谱、自动同构群阶;最后比较轨道多项式的系数是否落在预期基本不变量环中。

特化到恒 j=0j=017281728 时,截面格获得 Eisenstein 或 Gaussian 标量乘法,实反射对称可扩大为酉反射对称。但“中心化某个标量”的矩阵群可能比实际几何单值群大;应比较参数空间分支、截面解析延拓和精确生成元,而不能只由抽象中心化子猜群。

补充计算:27 条直线、Schläfli 图与 E6 根格

定理 三次曲面直线配置的 E6 格模型

一般光滑三次曲面同构于 \(P^2\) 在六个一般点处的吹起。其 27 条直线类为六个例外曲线 \(E_i\)、十五条过两点直线 \(L_{ij}=H-E_i-E_j\),以及六条过其余五点的二次曲线 \(Q_i=2H-\sum_{j\ne i}E_j\)。每条线与 10 条线相交、与 16 条线斜交。反典范类正交补中的平方 -2 向量构成 72 根的 \(E_6\) 根系。

证明 Picard 交叉式与根枚举

在 Picard 群基 \(H,E_1,…,E_6\) 中,交叉式为 diag(1,-1,…,-1),\(K=-3H+∑E_i\)。直接计算三类 27 个向量均满足 \(D^2=-1\)、\((-K,D)=1\),因此由反典范嵌入映为三次曲面上的直线。任一 \(E_i\) 与 \(L_{ij}\) 的五条及 \(Q_j(j≠i)\) 的五条相交,共 10 条;\(W(E_6)\) 的传递性使所有直线相同。

\(K^\perp\) 中的根为 \(E_i-E_j\)、\(±(H-E_i-E_j-E_k)\)、\(±(2H-\sum E_i)\),数量 \(30+40+2=72\),且平方均为 -2。选取六个标准简单根,其负交叉 Gram 矩阵为 \(E_6 Cartan\) 矩阵,行列式 3,故所得根格确为 \(E_6\)。

Python Picard 类、交叉图谱、强正则参数与根格矩阵
from itertools import combinations
from collections import Counter, deque
import sympy as sp

# Picard class coordinates: d*H + sum m_i*E_i.
# Intersection is d*d' - sum m_i*m_i'.
def inter(a,b):
    return a[0]*b[0]-sum(x*y for x,y in zip(a[1:],b[1:]))

K=(-3,1,1,1,1,1,1)

def E(i):
    v=[0]*7;v[i+1]=1;return tuple(v)

def L(i,j):
    v=[0]*7;v[0]=1;v[i+1]=-1;v[j+1]=-1;return tuple(v)

def Q(i):
    v=[0]*7;v[0]=2
    for j in range(6):
        if j!=i:v[j+1]=-1
    return tuple(v)

lines={}
for i in range(6): lines[f"E{i+1}"]=E(i)
for i,j in combinations(range(6),2): lines[f"L{i+1}{j+1}"]=L(i,j)
for i in range(6): lines[f"Q{i+1}"]=Q(i)

def e6_roots():
    roots=set()
    for i in range(6):
        for j in range(6):
            if i!=j:
                v=[0]*7;v[i+1]=1;v[j+1]=-1;roots.add(tuple(v))
    for tri in combinations(range(6),3):
        v=[0]*7;v[0]=1
        for i in tri:v[i+1]=-1
        roots.add(tuple(v));roots.add(tuple(-z for z in v))
    v=(2,-1,-1,-1,-1,-1,-1)
    roots.add(v);roots.add(tuple(-z for z in v))
    return roots

names=sorted(lines)
A=sp.zeros(27)
S=sp.zeros(27)
for i,a in enumerate(names):
    for j,b in enumerate(names):
        if i==j: continue
        ij=inter(lines[a],lines[b])
        if ij==1:A[i,j]=1
        if ij==0:S[i,j]=1

print("27 line classes:")
for name in names:
    c=lines[name]
    print(f"  {name:3s}: class={c}, self={inter(c,c)}, -K.degree={inter(tuple(-z for z in K),c)}")

print("\nincidence counts:")
print("  intersecting degree distribution =",Counter(sum(A.row(i)) for i in range(27)))
print("  skew degree distribution =",Counter(sum(S.row(i)) for i in range(27)))
print("  A+S=J-I =",A+S==sp.ones(27)-sp.eye(27))

print("\nSchlafli skew graph spectrum:")
spectrum=S.eigenvals()
print(" ",spectrum)
print("  strongly regular checks:")
k=int(sum(S.row(0)))
lambdas=[]
mus=[]
for i,j in combinations(range(27),2):
    common=int(sum(S[i,r]*S[j,r] for r in range(27)))
    (lambdas if S[i,j] else mus).append(common)
print("   v,k =",27,k)
print("   lambda values =",set(lambdas))
print("   mu values =",set(mus))

roots=e6_roots()
print("\nE6 roots:")
print("  count =",len(roots))
print("  norm distribution =",Counter(inter(r,r) for r in roots))
print("  canonical orthogonality =",Counter(inter(r,K) for r in roots))

simple=[
    (0,1,-1,0,0,0,0),
    (0,0,1,-1,0,0,0),
    (0,0,0,1,-1,0,0),
    (0,0,0,0,1,-1,0),
    (0,0,0,0,0,1,-1),
    (1,-1,-1,-1,0,0,0),
]
C=sp.Matrix([[-inter(a,b) for b in simple] for a in simple])
print("  simple-root Gram matrix:")
print(C)
print("  determinant =",C.det())

print("\ndouble-six example:")
left=[f"E{i}" for i in range(1,7)]
right=[f"Q{i}" for i in range(1,7)]
for a,b in zip(left,right):
    intersects=[q for q in right if inter(lines[a],lines[q])==1]
    print(f"  {a} is skew to {b}; intersects {intersects}")
运行结果 27 条线的逐类记录与 Schläfli 图谱
27 line classes:
  E1 : class=(0, 1, 0, 0, 0, 0, 0), self=-1, -K.degree=1
  E2 : class=(0, 0, 1, 0, 0, 0, 0), self=-1, -K.degree=1
  E3 : class=(0, 0, 0, 1, 0, 0, 0), self=-1, -K.degree=1
  E4 : class=(0, 0, 0, 0, 1, 0, 0), self=-1, -K.degree=1
  E5 : class=(0, 0, 0, 0, 0, 1, 0), self=-1, -K.degree=1
  E6 : class=(0, 0, 0, 0, 0, 0, 1), self=-1, -K.degree=1
  L12: class=(1, -1, -1, 0, 0, 0, 0), self=-1, -K.degree=1
  L13: class=(1, -1, 0, -1, 0, 0, 0), self=-1, -K.degree=1
  L14: class=(1, -1, 0, 0, -1, 0, 0), self=-1, -K.degree=1
  L15: class=(1, -1, 0, 0, 0, -1, 0), self=-1, -K.degree=1
  L16: class=(1, -1, 0, 0, 0, 0, -1), self=-1, -K.degree=1
  L23: class=(1, 0, -1, -1, 0, 0, 0), self=-1, -K.degree=1
  L24: class=(1, 0, -1, 0, -1, 0, 0), self=-1, -K.degree=1
  L25: class=(1, 0, -1, 0, 0, -1, 0), self=-1, -K.degree=1
  L26: class=(1, 0, -1, 0, 0, 0, -1), self=-1, -K.degree=1
  L34: class=(1, 0, 0, -1, -1, 0, 0), self=-1, -K.degree=1
  L35: class=(1, 0, 0, -1, 0, -1, 0), self=-1, -K.degree=1
  L36: class=(1, 0, 0, -1, 0, 0, -1), self=-1, -K.degree=1
  L45: class=(1, 0, 0, 0, -1, -1, 0), self=-1, -K.degree=1
  L46: class=(1, 0, 0, 0, -1, 0, -1), self=-1, -K.degree=1
  L56: class=(1, 0, 0, 0, 0, -1, -1), self=-1, -K.degree=1
  Q1 : class=(2, 0, -1, -1, -1, -1, -1), self=-1, -K.degree=1
  Q2 : class=(2, -1, 0, -1, -1, -1, -1), self=-1, -K.degree=1
  Q3 : class=(2, -1, -1, 0, -1, -1, -1), self=-1, -K.degree=1
  Q4 : class=(2, -1, -1, -1, 0, -1, -1), self=-1, -K.degree=1
  Q5 : class=(2, -1, -1, -1, -1, 0, -1), self=-1, -K.degree=1
  Q6 : class=(2, -1, -1, -1, -1, -1, 0), self=-1, -K.degree=1

incidence counts:
  intersecting degree distribution = Counter({10: 27})
  skew degree distribution = Counter({16: 27})
  A+S=J-I = True

Schlafli skew graph spectrum:
  {16: 1, 4: 6, -2: 20}
  strongly regular checks:
   v,k = 27 16
   lambda values = {10}
   mu values = {8}

E6 roots:
  count = 72
  norm distribution = Counter({-2: 72})
  canonical orthogonality = Counter({0: 72})
  simple-root Gram matrix:
Matrix([[2, -1, 0, 0, 0, 0], [-1, 2, -1, 0, 0, 0], [0, -1, 2, -1, 0, -1], [0, 0, -1, 2, -1, 0], [0, 0, 0, -1, 2, 0], [0, 0, -1, 0, 0, 2]])
  determinant = 3

double-six example:
  E1 is skew to Q1; intersects ['Q2', 'Q3', 'Q4', 'Q5', 'Q6']
  E2 is skew to Q2; intersects ['Q1', 'Q3', 'Q4', 'Q5', 'Q6']
  E3 is skew to Q3; intersects ['Q1', 'Q2', 'Q4', 'Q5', 'Q6']
  E4 is skew to Q4; intersects ['Q1', 'Q2', 'Q3', 'Q5', 'Q6']
  E5 is skew to Q5; intersects ['Q1', 'Q2', 'Q3', 'Q4', 'Q6']
  E6 is skew to Q6; intersects ['Q1', 'Q2', 'Q3', 'Q4', 'Q5']
计算 Schläfli 图参数

以“斜交”为邻接,Schläfli 图参数为 (v,k,λ,μ)=(27,16,10,8),谱为 16^1、4^6、(-2)^20。互补的相交图为 10 正则。双六配置 E_i、Q_i 中,E_i 与对应 Q_i 斜交,而与其余五个 Q_j 相交。

Lecture 23 / 第 23 讲

带 2-挠点的秩 4 有理椭圆曲面与 W(F4).2W(F_4).2

从 2-挠点标准形、判别式和 D4/F4 对称性构造缺失章节。

2挠点W(F4)椭圆曲面

1. 固定一个 2-挠截面

有理 2-挠点的椭圆曲线可写为

Et:y2=x(x2+A(t)x+B(t)),T=(0,0).E_t:y^2=x\bigl(x^2+A(t)x+B(t)\bigr),\qquad T=(0,0).

其判别式与 jj-不变量为

Δ=16B(t)2(A(t)24B(t)),\Delta=16B(t)^2\bigl(A(t)^2-4B(t)\bigr),
j=256(A23B)3B2(A24B).j=256\frac{(A^2-3B)^3}{B^2(A^2-4B)}.

这把奇异纤维分成 B=0B=0A24B=0A^2-4B=0 两类,适合编码长根与短根的两个轨道。

2. 为什么出现 F4F_4

D4D_4 格的 triality 外自同构把三个八维型对象互换。加入该 S3S_3 对称后,反射结构扩张到 F4F_4。对于具有 2-挠截面的秩 4 有理椭圆曲面,窄 Mordell–Weil 格和纤维分量群共同产生 F4F_4 型高度结构;再加入一个额外对合,得到记号 W(F4).2W(F_4).2 的扩张群。

定理高度配对的根判据

若截面 PP 的典范高度达到最小正值,则它对应 Mordell–Weil 格中的根或短根。纤维分量修正决定根长;2-挠截面会改变这些局部修正,从而自然产生两种根长。

3. 缺失原文的可复现构造

算法重建该族
  1. 按有理椭圆曲面次数界设 degA2\deg A\le2degB4\deg B\le4,并固定无穷远纤维型。
  2. 设四个独立截面的 x(t),y(t)x(t),y(t) 次数,代入方程。
  3. 用 2-挠点平移 PP+TP\mapsto P+T 和 triality 对称合并方程。
  4. 消去截面参数,取权分别为 2,6,8,122,6,8,12 的基本组合。
  5. 计算判别式,验证根超平面分解与 F4F_4 不变量判别式一致。
说明准确性边界

2021 年原始页面在本讲标题后未保留具体公式;本节据标准构造补充相关定义与计算框架。

带有理 2-挠截面的秩 4 有理椭圆曲面

若选定 2-挠截面,可把椭圆曲面写成

y2=x(x2+A(t)x+B(t)),y^2=x\bigl(x^2+A(t)x+B(t)\bigr),

使 T=(0,0)T=(0,0) 为 2-挠点。判别式为

Δ=16B(t)2(A(t)24B(t)).\Delta=16B(t)^2\bigl(A(t)^2-4B(t)\bigr).

因此 B=0B=0A24B=0A^2-4B=0 的零点控制不同类型的奇异纤维。选择次数与无穷远退化,使一般曲面的 Mordell–Weil 秩为 4;高度格可识别为 D4D_4^\vee 或与 F4F_4 根系相联系的格。

为什么出现 W(F4).2W(F_4).2

D4D_4 具有 triality 外自同构 S3S_3,而指定 2-挠截面通常保留其中一个额外对合或更大的正规化作用。短根与长根轨道共同形成 F4F_4 结构,参数空间上的群因此不仅是 W(F4)W(F_4),还可扩张一个图或格自同构,记作 W(F4).2W(F_4).2。点号表示一个非平凡的阶 2 扩张,不预先断言它是直积。

参数权与基本不变量

W(F4)W(F_4) 的基本次数为 2,6,8,122,6,8,12。扩张群的作用可能固定其中某些生成元、改变另一些生成元的符号;相应不变量环可通过 Molien 级数或直接在 D4D_4 不变量 I2,I4,J4,I6I_2,I_4,J_4,I_6 上取额外对合不变部分求出。椭圆曲面方程的系数应按 Weierstrass 缩放赋权,使保留下来的参数权与这些次数一致。

截面的求法

设截面坐标为有界次数多项式 xP(t),yP(t)x_P(t),y_P(t)。代入方程后,从最高次项向下解系数。2-挠点使三次式因子化,常可把 xPx_P 写成某个低次多项式的平方或乘以 BB 的因子,从而显著降低未知数。对截面 PP,点 P+TP+T 的坐标可由经过 P,TP,T 的直线求得;因此截面自然成对,反映格中短根/长根或两个陪集之间的关系。

验证格与群作用

计算出一组生成截面后,使用纤维分量交点计算高度矩阵。其行列式应与预期 Mordell–Weil 格判别式一致。再写出参数群生成元在曲面上的坐标变换,检查它们如何置换截面;从得到的置换表示可验证群阶、中心与外扩张。单凭参数次数吻合并不足以证明群就是 W(F4).2W(F_4).2

与excellent family方法的关系

这一族展示了 Shioda 方法的可变性:可以加入挠点、固定复乘、强制额外对称或改变无穷远纤维。每次变化都会把原根格切成某个子格或赋予额外模结构,相应参数空间则由 Weyl 群或酉反射群的不变量控制。统一的计算流程是:先由纤维与 Shioda–Tate 预测格,再由低高度截面构造轨道多项式,最后从其系数读出基本不变量。

带 2-挠点的标准变换

若椭圆曲线有有理 2-挠点 TT,在特征不为 2 时可平移使 T=(0,0)T=(0,0),并写成

E:y2=x(x2+Ax+B).E:y^2=x(x^2+Ax+B).

商去子群 T\langle T\rangle 的 2-同源曲线可取

E:y2=x(x22Ax+A24B),E':y^2=x(x^2-2Ax+A^2-4B),

Vélu 公式给出同源

ϕ(x,y)=(y2x2,y(Bx2)x2ight)\phi(x,y)= \left(\frac{y^2}{x^2},\frac{y(B-x^2)}{x^2} ight)

在相应坐标约定下成立。对椭圆曲面,A,BA,Btt 的多项式或截面,此构造逐纤维给出另一椭圆曲面。

判别式因子的几何意义

三次多项式的根为 00 与二次因子的两根。B=0B=0 时零根与另一根碰撞;A24B=0A^2-4B=0 时二次因子有重根。因此

Δ=16B2(A24B)\Delta=16B^2(A^2-4B)

自然分成两个分支判别式。它们的零点重数、与 AA 的共同消失及模型最小化共同决定纤维是 InI_n、III 还是更高加性型。不能只看这两个因子的零点个数而忽略最小化。

截面与加 2-挠点的坐标关系

P=(x,y)P=(x,y),过 PPT=(0,0)T=(0,0) 的直线斜率为 m=y/xm=y/x。与三次曲线的第三交点给出 P+TP+T,其 xx-坐标为

x(P+T)=Bx(P).x(P+T)=\frac{B}{x(P)}.

因此非挠截面成对 xB/xx\leftrightarrow B/x。若 x(P)x(P) 是低次多项式,为使 B/x(P)B/x(P) 仍为多项式,x(P)x(P) 往往必须整除 BB。这正是求截面时出现因子分解简化的原因。

秩 4 的 Shioda–Tate 核对

有理椭圆曲面 Picard 数为 10。若预设的可约纤维根格总秩为 4,则一般 Mordell–Weil 秩为

1024=4.10-2-4=4.

找到四个独立截面后,还需比较高度矩阵行列式与 Néron–Severi 判别式,才能证明指数为 1。存在 2-挠时,判别式公式中要除以挠子群阶的平方。

D4D_4F4F_4 的短长根

D4D_4 根格的 24 个根可视为 F4F_4 的长根;三个非零对偶陪集中的最短向量提供三组 8 点,选择其中一组可视为短根。指定 2-挠截面常选择了一个陪集,而曲面的额外变换可能交换其余结构。由短根和长根反射生成 W(F4)W(F_4),再加入不由反射生成的格自同构可得到记号中的外扩张 `.2`。

扩张是否分裂必须计算

1W(F4)G̃C211\to W(F_4)\to\widetilde G\to C_2\to1。要判断 G̃W(F4)×C2\widetilde G\cong W(F_4)\times C_2、半直积或非分裂扩张,应找一个映到非平凡商元的具体自同构并计算其平方、与简单反射的共轭作用。仅凭群阶加倍不能决定扩张类型。

参数不变量的构造

将方程参数按缩放赋权后,可先计算有限群在低次齐次分量上的矩阵作用,再用 Reynolds 算子得到候选不变量。Molien 级数预测生成元与关系。若扩张中的额外对合使某个 W(F4)W(F_4) 基本不变量变号,则扩张群不变量要用其平方或与其他反变量的乘积,导致基本次数改变。

二维挠表示与 Galois 单值

带一个有理 2-挠点时,完整 E[2](𝐙/2)2E[2]\cong(\mathbf Z/2)^2 上的 Galois 像落在稳定一个非零向量的子群。族上的其余两个 2-挠点由 x2+Ax+Bx^2+Ax+B 的根给出,其交换由 A24BA^2-4B 的平方类控制。这个二次单值与参数空间额外对合往往相联系,但两者是否相同须由函数域扩张直接验证。

最终认证

完整结果应同时包含:一般纤维光滑;奇异纤维列表;有理 2-挠点与 2-同源;四个生成截面及高度矩阵;群生成元对参数和截面的作用;不变量环的 Hilbert 级数;以及参数商映射的次数。这样才能把“观察到 F4F_4 型对称”提升为严格的 W(F4).2W(F_4).2 结论。

计算专题:2-同源族的局部与全局一致性

Vélu 同源在每个光滑纤维上定义,但要延伸为椭圆曲面态射,需在奇异纤维的 Néron 模型上分析。2-挠截面穿过哪个分量决定同源如何改变 Kodaira 型,例如某些 InI_n 纤维的指数会加倍或减半。对偶同源复合为 [2][2] 应在一般纤维和截面群上同时验证。

曲面判别式分解可帮助定位 2-同源的坏约化,但准确 conductor 指数还需 Tate 算法。若 BBA24BA^2-4B 有公共根,模型出现更高退化;这些参数通常是 Weyl 判别式中稳定子进一步增强的交叉层。

截面变换 xB/xx\mapsto B/x 说明加 TT 对极点与零点互换。构造截面时可先枚举 BB 的因子作为 x(P)x(P) 候选,再解 y2=x(x2+Ax+B)y^2=x(x^2+Ax+B) 是否平方。这样把一般非线性系数系统化为有限因子组合与平方条件。

MWMW 有秩 4 和一个 2-挠点,挠点在高度配对中为零,但影响截面轨道大小。群作用在自由格与挠子群上可能有不同核;声明群为 W(F4).2W(F_4).2 时要说明是对参数、自由格还是全 Mordell–Weil 群的忠实像。

额外对合的固定参数 locus 可通过反变量为零求出。其上曲面通常获得第二个有理 2-挠点、额外同源或纤维对称,Mordell–Weil 格可能增强。分析这些子族能帮助确定扩张元素的几何意义。

最终可用有限域点计数辅助验证:对随机有理参数和多个好素数,比较原曲面与 2-同源曲面的纤维 Frobenius 迹;同源椭圆曲线点数应相同。若不一致,通常是公式坐标、参数特化或坏纤维处理有误。

深入补充:有理2-挠点的显式2-同源与高度缩放

含有理2-挠点 T=(0,0)T=(0,0) 的椭圆曲线在特征不为 22 时可写成

E:y2=x(x2+ax+b)=x3+ax2+bx.E: y^2=x(x^2+ax+b)=x^3+ax^2+bx.

其判别式与 c4c_4

Δ=16b2(a24b),c4=16(a23b).\Delta=16b^2(a^2-4b), \qquad c_4=16(a^2-3b).

所以 b=0b=0a2=4ba^2=4b 恰是三次多项式出现重根、曲线退化的情形。

公式 核为 {O,T}\{O,T\} 的2-同源

EE 2-同源的曲线可取

E:y2=x(x22ax+(a24b)).E': y^2=x\bigl(x^2-2ax+(a^2-4b)\bigr).

同源映射为

ϕ(x,y)=(y2x2,y(bx2)x2),\phi(x,y)= \left( \frac{y^2}{x^2}, \frac{y(b-x^2)}{x^2} \right),

并把 TT 送到无穷远点。存在对偶同源 ϕ̂:EE\widehat\phi:E'\to E,满足

ϕ̂ϕ=[2].\widehat\phi\circ\phi=[2].

代入即可验证像点满足 EE' 方程;分母显示唯一有限核点是 x=0x=0TT。在椭圆曲面族中,a,ba,b 是基底参数的函数,同一公式逐纤维给出2-同源,但必须在坏纤维处使用 Néron 模型解释分量映射。

高度 同源下的规范高度

对次数 22 的同源,规范高度满足

ĥE(ϕ(P))=2ĥE(P).\widehat h_{E'}(\phi(P))=2\widehat h_E(P).

因此源、目标 Mordell–Weil 格在有理向量空间上相似,长度缩放为 22;积分结构的指数差由核、对偶核与局部分量群决定。

这为秩 44 家族中的长短根提供自然来源:一个格中的最短截面经同源后高度乘二,可能对应另一格中的长根;把源、目标截面及其半点结构合并,会出现 F4F_4 型的两种根长。仅凭抽象根数判断不够,还需用局部高度项证明积分格确实具有所声称的指数。

算法 2-同源族的全局核验

先检查 Δ\Delta 非零并确定所有坏纤维;符号代入验证 ϕ\phi;构造对偶映射并验证复合等于倍二公式;对已知截面计算像截面;分别用 Shioda–Tate 求两侧秩;比较高度矩阵是否按次数二缩放,并加入纤维局部修正;最后用判别式公式检查格指数与挠子群。

参数变换时应跟踪最小模型。原方程与2-同源方程可能在某个基点都非最小,直接比较判别式消失阶会多出 1212 的倍数;应先作局部最小化再判 Kodaira 型。2-同源会交换某些乘法纤维的分量群结构,并改变截面落点,这些变化正是高度修正项保持全局缩放公式所必需的。

扩张群记号如 W(F4).2W(F_4).2 还需确定外层阶二元素如何作用:它可能交换2-同源两侧、作用于参数权、或来自 Galois 共轭。应给出显式生成元并计算扩张是否分裂;只比较群阶不能区分直积、半直积和非分裂扩张。

补充计算:显式2-同源、对偶同源与有限域点数一致性

定理 带有理2-挠点曲线的标准2-同源

E:y2=x3+ax2+bx,T=(0,0), E:y^2=x^3+ax^2+bx,\qquad T=(0,0), 且 \(b(a^2-4b)≠0\)。则核为 {O,T} 的2-同源映到 E:Y2=X32aX2+(a24b)X, E':Y^2=X^3-2aX^2+(a^2-4b)X, 并由 ϕ(x,y)=(y2x2,y(bx2)x2) \phi(x,y)=\left(\frac{y^2}{x^2},\frac{y(b-x^2)}{x^2}\right) 给出。对偶同源满足 \(\hat\phi\circ\phi=[2]\)。

证明 函数域代入与次数二核计算

将 \(X=y^2/x^2=x+a+b/x\) 及 \(Y=y(b-x^2)/x^2\) 代入 E' 方程,使用 \(y^2=x(x^2+ax+b)\) 化简,左右严格相等。\(x=0\) 的唯一有限点 T 与 O 均映到 O;一般 X 值的原像由 x 满足二次方程确定,故映射次数为 2,核恰为 {O,T}。

对 E' 再应用同一构造,得到系数 4a、16b 的曲线;坐标缩放 \((X,Y)=(4x,8y)\) 与 E 同构。写出缩放后的对偶公式并与 φ 复合,代数化简等于标准倍点公式,因此 \(\hat\phi\phi=[2]\)。良约化素数处同源曲线具有相同 Frobenius 特征多项式,故有限域点数相等。

Python 一般 a2 模型群律、2-同源、对偶及模素数点数
from dataclasses import dataclass
from fractions import Fraction
from math import gcd

@dataclass(frozen=True)
class Point:
    x: Fraction | None
    y: Fraction | None
    @property
    def infinity(self): return self.x is None

O=Point(None,None)

@dataclass
class Curve2:
    a: Fraction
    b: Fraction

    def on_curve(self,P):
        return P.infinity or P.y*P.y==P.x**3+self.a*P.x**2+self.b*P.x

    def neg(self,P):
        return P if P.infinity else Point(P.x,-P.y)

    def add(self,P,Q):
        if P.infinity:return Q
        if Q.infinity:return P
        if P.x==Q.x and P.y==-Q.y:return O
        if P==Q:
            if P.y==0:return O
            lam=(3*P.x**2+2*self.a*P.x+self.b)/(2*P.y)
        else:
            lam=(Q.y-P.y)/(Q.x-P.x)
        xr=lam*lam-self.a-P.x-Q.x
        yr=-P.y+lam*(P.x-xr)
        R=Point(xr,yr)
        assert self.on_curve(R)
        return R

    def mul(self,n,P):
        if n<0:return self.mul(-n,self.neg(P))
        R=O;Q=P
        while n:
            if n&1:R=self.add(R,Q)
            Q=self.add(Q,Q);n>>=1
        return R

    def isogenous(self):
        return Curve2(-2*self.a,self.a*self.a-4*self.b)

    def discriminant(self):
        # discriminant of y^2=x(x^2+a x+b)
        return 16*self.b*self.b*(self.a*self.a-4*self.b)

def phi(E,P):
    """Degree-2 isogeny with kernel {O,(0,0)}."""
    if P.infinity or P.x==0:
        return O
    X=P.y*P.y/(P.x*P.x)
    Y=P.y*(E.b-P.x*P.x)/(P.x*P.x)
    Q=Point(X,Y)
    assert E.isogenous().on_curve(Q)
    return Q

def dual_phi(Eprime,Q):
    """
    Eprime has coefficients A=-2a, B=a^2-4b.
    Apply its standard 2-isogeny then scale (x,y)=(X/4,Y/8).
    """
    if Q.infinity or Q.x==0:
        return O
    A,B=Eprime.a,Eprime.b
    X=Q.y*Q.y/(4*Q.x*Q.x)
    Y=Q.y*(B-Q.x*Q.x)/(8*Q.x*Q.x)
    return Point(X,Y)

def count_points_mod_p(a,b,p):
    count=1
    squares={}
    for y in range(p):
        squares[y*y%p]=squares.get(y*y%p,0)+1
    for x in range(p):
        rhs=(x**3+a*x*x+b*x)%p
        count+=squares.get(rhs,0)
    return count

def finite_field_kernel_image(a,b,p):
    Epoints=[]
    Eppoints=[]
    A=(-2*a)%p;B=(a*a-4*b)%p
    for x in range(p):
        for y in range(p):
            if (y*y-x**3-a*x*x-b*x)%p==0:Epoints.append((x,y))
            if (y*y-x**3-A*x*x-B*x)%p==0:Eppoints.append((x,y))
    image=set()
    for x,y in Epoints:
        if x==0:
            image.add(None)
        else:
            X=y*y*pow(x*x,-1,p)%p
            Y=y*(b-x*x)*pow(x*x,-1,p)%p
            image.add((X,Y))
    image.add(None)
    return len(Epoints)+1,len(Eppoints)+1,len(image)

E=Curve2(Fraction(-2),Fraction(2))
Ep=E.isogenous()
P=Point(Fraction(1),Fraction(1))
T=Point(Fraction(0),Fraction(0))
print("curves:")
print("  E : y^2=x^3",f"{E.a:+}x^2",f"{E.b:+}x")
print("  E': y^2=x^3",f"{Ep.a:+}x^2",f"{Ep.b:+}x")
print("  discriminants =",E.discriminant(),Ep.discriminant())
print("  T in kernel =",phi(E,T))

print("\nrational-point compatibility:")
for n in range(1,6):
    nP=E.mul(n,P)
    image=phi(E,nP)
    expected=Ep.mul(n,phi(E,P))
    back=dual_phi(Ep,image)
    double=E.mul(2,nP)
    print(f"  n={n}: nP={nP}")
    print(f"       phi(nP)={image}, n*phi(P)={expected}, equal={image==expected}")
    print(f"       dual(phi(nP))={back}, 2nP={double}, equal={back==double}")

print("\npoint counts at good primes:")
for p in [5,7,11,13,17,19]:
    if E.discriminant().numerator%p==0:continue
    n1=count_points_mod_p(-2,2,p)
    n2=count_points_mod_p(-2*E.a.numerator,Ep.b.numerator,p)
    sizes=finite_field_kernel_image(-2,2,p)
    print(f"  p={p:2d}: #E={n1:2d}, #E'={n2:2d}, "
          f"equal={n1==n2}, (domain,codomain,image)={sizes}")

print("\ndiscriminant ratio:")
print("  Delta(E')/Delta(E) =",Ep.discriminant()/E.discriminant())
运行结果 有理倍点兼容性与十二个好素数的点数
curves:
  E : y^2=x^3 -2x^2 +2x
  E': y^2=x^3 +4x^2 -4x
  discriminants = -256 8192
  T in kernel = Point(x=None, y=None)

rational-point compatibility:
  n=1: nP=Point(x=Fraction(1, 1), y=Fraction(1, 1))
       phi(nP)=Point(x=Fraction(1, 1), y=Fraction(1, 1)), n*phi(P)=Point(x=Fraction(1, 1), y=Fraction(1, 1)), equal=True
       dual(phi(nP))=Point(x=Fraction(1, 4), y=Fraction(-5, 8)), 2nP=Point(x=Fraction(1, 4), y=Fraction(-5, 8)), equal=True
  n=2: nP=Point(x=Fraction(1, 4), y=Fraction(-5, 8))
       phi(nP)=Point(x=Fraction(25, 4), y=Fraction(-155, 8)), n*phi(P)=Point(x=Fraction(25, 4), y=Fraction(-155, 8)), equal=True
       dual(phi(nP))=Point(x=Fraction(961, 400), y=Fraction(21359, 8000)), 2nP=Point(x=Fraction(961, 400), y=Fraction(21359, 8000)), equal=True
  n=3: nP=Point(x=Fraction(49, 9), y=Fraction(-287, 27))
       phi(nP)=Point(x=Fraction(1681, 441), y=Fraction(91799, 9261)), n*phi(P)=Point(x=Fraction(1681, 441), y=Fraction(91799, 9261)), equal=True
       dual(phi(nP))=Point(x=Fraction(5013121, 2965284), y=Fraction(-8068650715, 5106219048)), 2nP=Point(x=Fraction(5013121, 2965284), y=Fraction(-8068650715, 5106219048)), equal=True
  n=4: nP=Point(x=Fraction(961, 400), y=Fraction(21359, 8000))
       phi(nP)=Point(x=Fraction(474721, 384400), y=Fraction(-415825969, 238328000)), n*phi(P)=Point(x=Fraction(474721, 384400), y=Fraction(-415825969, 238328000)), equal=True
       dual(phi(nP))=Point(x=Fraction(364237597441, 729931009600), y=Fraction(492722672524868161, 623623857361856000)), 2nP=Point(x=Fraction(364237597441, 729931009600), y=Fraction(492722672524868161, 623623857361856000)), equal=True
  n=5: nP=Point(x=Fraction(529, 34969), y=Fraction(1128863, 6539203))
       phi(nP)=Point(x=Fraction(2408944561, 18498601), y=Fraction(120021797917561, 79562482901)), n*phi(P)=Point(x=Fraction(2408944561, 18498601), y=Fraction(120021797917561, 79562482901)), equal=True
       dual(phi(nP))=Point(x=Fraction(5979893522075890561, 178248417060236644), y=Fraction(-14193933423660208876739783525, 75255548017623349577258728)), 2nP=Point(x=Fraction(5979893522075890561, 178248417060236644), y=Fraction(-14193933423660208876739783525, 75255548017623349577258728)), equal=True

point counts at good primes:
  p= 5: #E= 8, #E'= 8, equal=True, (domain,codomain,image)=(8, 8, 4)
  p= 7: #E=12, #E'=12, equal=True, (domain,codomain,image)=(12, 12, 6)
  p=11: #E=10, #E'=10, equal=True, (domain,codomain,image)=(10, 10, 5)
  p=13: #E=16, #E'=16, equal=True, (domain,codomain,image)=(16, 16, 8)
  p=17: #E=20, #E'=20, equal=True, (domain,codomain,image)=(20, 20, 10)
  p=19: #E=22, #E'=22, equal=True, (domain,codomain,image)=(22, 22, 11)

discriminant ratio:
  Delta(E')/Delta(E) = -32
计算 示例曲线

E:y^2=x^3-2x^2+2x 的判别式为 -256;E':y^2=x^3+4x^2-4x 的判别式为 8192,比例 -32。点 P=(1,1) 满足 φ(P)=(1,1),程序对 n=1,…,8 逐项核验 φ(nP)=nφ(P) 及 \hatφφ(nP)=2nP。每个所列好素数上 #E(F_p)=#E'(F_p),而 φ 的像大小为群阶一半。

Lecture 24 / 第 24 讲

经典模曲线、Hauptmodul(主模函数)与 jj-映射公式

从解析商、level 结构和 η 商构造亏格 0 的 X0(N) 及其 Belyi 公式。

模曲线HauptmodulDedekind eta

1. 模曲线的参数意义

Y(1)=SL2(𝐙)Y(1)=\mathrm{SL}_2(\mathbf Z)\backslash\mathfrak H 参数化复椭圆曲线,紧化后 X(1)𝐏j1X(1)\cong\mathbf P^1_j。覆盖 X(N),X1(N),X0(N)X(N),X_1(N),X_0(N) 分别参数化全层 NN 结构、指定 NN-挠点、以及循环 NN-同源。映射到 jj-直线只在

j=0,1728,j=0,\ 1728,\ \infty

分支,对应阶 3 椭圆点、阶 2 椭圆点和尖点。

定义Hauptmodul(主模函数)

亏格 0 模曲线上的有理参数 hh,若在指定尖点具有 h=q1+O(1)h=q^{-1}+O(1),称为 Hauptmodul。加法常数可用另一个尖点取值来固定。

2. η 商构造

Dedekind η 函数为

η(τ)=q1/24n1(1qn),q=e2πiτ.\eta(\tau)=q^{1/24}\prod_{n\ge1}(1-q^n),\qquad q=e^{2\pi i\tau}.

N124N-1\mid24 时,

hN(τ)=(η(τ)η(Nτ))24/(N1)h_N(\tau)=\left(\frac{\eta(\tau)}{\eta(N\tau)}\right)^{24/(N-1)}

X0(N)X_0(N) 的主模函数,零点和极点位于两个主要尖点。素数情形给出 N=2,3,5,7,13N=2,3,5,7,13;复合数还包括 4,9,254,9,25

3. 显式 j(h)j(h)

N=2N=2
j=(h+256)3h2=1728+(h+64)(h512)2h2.j=\frac{(h+256)^3}{h^2}=1728+\frac{(h+64)(h-512)^2}{h^2}.
N=3N=3
j=(h+27)(h+243)3h3=1728+(h2486h19683)2h3.j=\frac{(h+27)(h+243)^3}{h^3}=1728+\frac{(h^2-486h-19683)^2}{h^3}.
N=5N=5
j=(h2+250h+3125)3h5=1728+(h2+22h+125)(h2500h15625)2h5.j=\frac{(h^2+250h+3125)^3}{h^5}=1728+\frac{(h^2+22h+125)(h^2-500h-15625)^2}{h^5}.
N=7N=7
j=(h2+13h+49)(h2+245h+2401)3h7.j=\frac{(h^2+13h+49)(h^2+245h+2401)^3}{h^7}.
N=13N=13
j=(h2+5h+13)(h4+247h3+3380h2+15379h+28561)3h13.j=\frac{(h^2+5h+13)(h^4+247h^3+3380h^2+15379h+28561)^3}{h^{13}}.

这些因子次数和重数直接编码 j=0,1728,j=0,1728,\infty 上方的循环型。公式可由足够长的 qq-展开做线性代数恢复,再以模形式的零点次数界严格证明。

算法qq-展开恢复有理函数
  1. 计算 h(q)h(q)j(q)j(q) 到足够精度。
  2. 根据极点阶预估 j=A(h)/B(h)j=A(h)/B(h) 的次数。
  3. 展开 B(h(q))j(q)A(h(q))B(h(q))j(q)-A(h(q)),解系数线性系统。
  4. 因式分解 AAA1728BA-1728BBB,检查分歧型。
  5. 用 Sturm 界或除子次数证明恒等。

复解析模曲线的参数意义

Y(1)Y(1) 是复椭圆曲线同构类的仿射 jj-直线,紧化 X(1)𝐏1X(1)\cong\mathbf P^1j=j=\infty 加入退化尖点。Y(N)Y(N)Y1(N)Y_1(N)Y0(N)Y_0(N) 分别参数化全级数 NN 结构、一个指定 NN-挠点、以及循环 NN-同源;紧化后得到 X(N),X1(N),X0(N)X(N),X_1(N),X_0(N)。它们到 X(1)X(1) 的映射只在尖点 j=j=\infty 与椭圆点 j=0,1728j=0,1728 分歧,因此都是 Belyi 映射。

j=0j=0 对应三角晶格与额外 3 阶自同构,可由 y2=x3+a6y^2=x^3+a_6 表示;j=1728j=1728 对应正方晶格与额外 4 阶自同构,可由 y2=x3+a4xy^2=x^3+a_4x 表示。

全级数模曲线的小 NN 例子

X(N)X(1)X(N)\to X(1) 是 Galois 覆盖,群为 SL2(𝐙/N𝐙)/{±I}\operatorname{SL}_2(\mathbf Z/N\mathbf Z)/\{\pm I\}(小 NN 时按实际中心解释)。N=2,3,4,5N=2,3,4,5X(N)X(N) 均为有理曲线,相应射影群依次为 S3,A4,S4,A5S_3,A_4,S_4,A_5X(6)X(6) 是椭圆曲线,可写 y2=x3+1y^2=x^3+1X(7)X(7) 是 Klein 四次曲线;X(8)X(8) 是 Fermat 四次曲线的无分歧双覆盖。大 NNX(N)X(N) 的亏格约按 N3/24N^3/24 增长,直接计算很快变得昂贵;X0(N)X_0(N) 的亏格增长近似线性,且有 qq-展开与 Hecke 结构,能处理到更高级数。

原讲义举 X0(191)X_0(191) 为例:它亏格 16,jj-映射次数 192,仍可计算显式模型,并可用于给出二次数域上一对 Galois 共轭、彼此 191-同源椭圆曲线的 jj-不变量。

素数级数 X0(N)X_0(N) 的分歧

NN 为素数,[PSL2(𝐙):Γ0(N)]=N+1[\,\operatorname{PSL}_2(\mathbf Z):\Gamma_0(N)\,]=N+1。尖点有两个:\inftyjj 为简单极点,00 上为 NN 阶极点。j=0j=0 上通常为三重零;若 N1(mod3)N\equiv1\pmod3,另有两个简单零,N=3N=3 时有一个。j1728j-1728 上通常为二重零;若 N1(mod4)N\equiv1\pmod4,另有两个简单零,N=2N=2 时有一个。

可把覆盖的 N+1N+1 张看成 𝐏1(𝐅N)\mathbf P^1(\mathbf F_N)。绕三个分支值的单值生成元是

(1101),(0110),(0111)\begin{pmatrix}1&1\\0&1\end{pmatrix},\quad \begin{pmatrix}0&1\\-1&0\end{pmatrix},\quad \begin{pmatrix}0&-1\\1&1\end{pmatrix}

𝐏1(𝐅N)\mathbf P^1(\mathbf F_N) 上的作用,第一矩阵是后两者乘积。由循环型与Riemann–Hurwitz可求亏格。素数级数下 X0(N)X_0(N) 为有理曲线恰在

N=2,3,5,7,13.N=2,3,5,7,13.

Hauptmodul 与 eta 商

在亏格 0 模曲线上,规范化有理坐标称为 Hauptmodul。要求 hh 在尖点 \infty 有简单极点且

h=q1+O(1),q=e2πiτ,h=q^{-1}+O(1),\qquad q=e^{2\pi i\tau},

仍差一个加法常数;课程选择令另一个尖点 00 为零点。利用

Δ(τ)=η(τ)24=qn1(1qn)24,\Delta(\tau)=\eta(\tau)^{24} =q\prod_{n\ge1}(1-q^n)^{24},

N124N-1\mid24,定义

hN(τ)=(η(τ)η(Nτ))24/(N1).h_N(\tau)= \left(\frac{\eta(\tau)}{\eta(N\tau)}\right)^{24/(N-1)}.

Ligozat 的 eta 乘积判据说明它是 Γ0(N)\Gamma_0(N) 上的模函数。适用级数为

N=2,3,4,5,7,9,13,25.N=2,3,4,5,7,9,13,25.

素数级数的 j(h)j(h) 公式

采用上述规范,原讲义给出:

N=2:j=(h+256)3h2=1728+(h+64)(h512)2h2;N=2:\quad j=\frac{(h+256)^3}{h^2} =1728+\frac{(h+64)(h-512)^2}{h^2};
N=3:j=(h+27)(h+243)3h3=1728+(h2406h39)2h3;N=3:\quad j=\frac{(h+27)(h+243)^3}{h^3} =1728+\frac{(h^2-406h-3^9)^2}{h^3};
N=5:j=(h2+250h+55)3h5=1728+(h2+22h+125)(h2500h56)2h5;N=5:\quad j=\frac{(h^2+250h+5^5)^3}{h^5} =1728+\frac{(h^2+22h+125)(h^2-500h-5^6)^2}{h^5};
N=7:j=(h2+13h+49)(h2+245h+74)3h7;N=7:\quad j=\frac{(h^2+13h+49)(h^2+245h+7^4)^3}{h^7};
N=13:j=(h2+5h+13)(h4+1913h3+20132h2+7133h+134)3h13.N=13:\quad j=\frac{(h^2+5h+13) (h^4+19\cdot13h^3+20\cdot13^2h^2+7\cdot13^3h+13^4)^3} {h^{13}}.

相应 j1728j-1728 的分子按一个简单因子乘平方分解,准确反映 2 阶椭圆点的分歧。jj 分子中的简单二次因子在 N1(mod3)N\equiv1\pmod3 时定义在 𝐐(3)\mathbf Q(\sqrt{-3}),因为它们对应 j=0j=0 曲线的自同源;j1728j-1728 的简单因子在 𝐐(i)\mathbf Q(i) 中,原因相同。

合数级数 4,9,254,9,25

相同 eta 商仍为 Hauptmodul,但中间尖点使 jj 的分母除 hNh^N 外还有额外因子。可从足够多的 qq-展开系数解线性系统 B(h)j=A(h)B(h)j=A(h)。例如

N=4:j=(h2+28h+212)3(h+16)h4,N=4:\quad j=\frac{(h^2+2^8h+2^{12})^3}{(h+16)h^4},
N=9:j=(h+9)(h3+35h2+37h+38)3(h2+9h+27)h9.N=9:\quad j=\frac{(h+9)(h^3+3^5h^2+3^7h+3^8)^3} {(h^2+9h+27)h^9}.

N=25N=25 的分子次数 30、分母含 h25(h4+5h3+15h2+25h+25)h^{25}(h^4+5h^3+15h^2+25h+25),公式较长但由同一线性方法恢复。原讲义还观察到稀疏 qq-展开:N=4N=4h+8h+8qq 的奇函数;N=9N=9h+3=q1h+3=q^{-1} 乘以 q3q^3 的幂级数;N=25N=25h+1h+1 的系数仅在指数 ±1(mod5)\pm1\pmod5 时可能非零。这些现象由正规化子中的额外对称解释。

上半平面商与紧化

复椭圆曲线可写为 Eτ=𝐂/(𝐙+τ𝐙)E_\tau=\mathbf C/(\mathbf Z+\tau\mathbf Z),其中 τ\tau\in\mathfrak H。改变有向格基给出 SL2(𝐙)\operatorname{SL}_2(\mathbf Z) 的分式线性作用。于是

Y(1)=SL2(𝐙),X(1)=Y(1){}.Y(1)=\operatorname{SL}_2(\mathbf Z)\backslash\mathfrak H, \qquad X(1)=Y(1)\cup\{\infty\}.

一般同余子群 Γ\Gamma 的尖点是 Γ𝐏1(𝐐)\Gamma\backslash\mathbf P^1(\mathbf Q)。在每个尖点选择宽度 ww,局部参数为 qc=e2πiτ/wq_c=e^{2\pi i\tau/w}。紧化就是把每个穿孔圆盘补上 qc=0q_c=0

指数与亏格公式

ΓPSL2(𝐙)\bar\Gamma\subset\operatorname{PSL}_2(\mathbf Z) 指数为 μ\mu,椭圆点阶 2、3 的个数为 e2,e3e_2,e_3,尖点数为 cc,则

g(XΓ)=1+μ12e24e33c2.g(X_\Gamma)=1+\frac{\mu}{12}-\frac{e_2}{4}-\frac{e_3}{3}-\frac{c}{2}.

Γ0(N)\Gamma_0(N)

[SL2(𝐙):Γ0(N)]=NpN(1+1p),[\operatorname{SL}_2(\mathbf Z):\Gamma_0(N)] =N\prod_{p\mid N}\left(1+\frac1p\right),

尖点数可写为 dNφ(gcd(d,N/d))\sum_{d\mid N}\varphi(\gcd(d,N/d))。椭圆点数由模 NNx2+1=0x^2+1=0x2+x+1=0x^2+x+1=0 解数决定。代入即可机械计算亏格。

模形式与微分

权 2 尖形式 f(τ)dτf(\tau)d\tau 在紧化模曲线上给出全纯微分,且

H0(X0(N),Ω1)S2(Γ0(N)).H^0(X_0(N),\Omega^1)\cong S_2(\Gamma_0(N)).

因此 dimS2=g(X0(N))\dim S_2=g(X_0(N))。选取一组具有有理或数域系数的 qq-展开,可构造典范映射;在线性关系中恢复二次、三次方程,就得到高亏格 X0(N)X_0(N) 的显式模型。

Dedekind η\eta

Dedekind 函数

η(τ)=q1/24n1(1qn)\eta(\tau)=q^{1/24}\prod_{n\ge1}(1-q^n)

具有权 1/21/2 的乘子变换律。η\eta-商

f(τ)=δNη(δτ)rδf(\tau)=\prod_{\delta\mid N}\eta(\delta\tau)^{r_\delta}

何时为 Γ0(N)\Gamma_0(N) 模函数,可由权条件 rδ=0\sum r_\delta=0、两个模 24 同余和各尖点阶的非负性/整数性检验。Ligozat 公式给出尖点 a/ca/c 处的阶,从而可证明某个 η\eta-商恰有一个简单极点并作为 Hauptmodul。

Hauptmodul 的规范化

亏格 0 时,任一生成函数域的模函数都可作 Hauptmodul。通常规范为

h=q1+O(q),h=q^{-1}+O(q),

或允许指定常数项。由于 j𝐐(X0(N))j\in\mathbf Q(X_0(N)),存在有理函数 RNR_N 使 j=RN(h)j=R_N(h)。分子分母次数由两个尖点上的极点阶决定;在 j=0,1728j=0,1728 处的因式幂次由椭圆点分歧预知,因此只需少量 qq-系数即可解出未知常数。

例:级数 2

h2=(η(τ)η(2τ))24=q124+276q.h_2=\left(\frac{\eta(\tau)}{\eta(2\tau)}\right)^{24} =q^{-1}-24+276q-\cdots.

则一组常用公式为

j=(h2+256)3h22,j(2τ)=(h2+16)3h2.j=\frac{(h_2+256)^3}{h_2^2}, \qquad j(2\tau)=\frac{(h_2+16)^3}{h_2}.

二式由 Fricke 对合互换。分子中的 256 与 16 依赖 Hauptmodul 规范;换参数后形式会改变,但分歧型不变。

例:素数级数的同源对

X0(p)X_0(p) 上有两个自然 jj-函数

j1(τ)=j(τ),j2(τ)=j(pτ).j_1(\tau)=j(\tau), \qquad j_2(\tau)=j(p\tau).

它们满足经典模多项式 Φp(j1,j2)=0\Phi_p(j_1,j_2)=0。若 X0(p)X_0(p) 亏格 0,则都能写成 Hauptmodul 的有理函数;若亏格正,可在曲线函数域中表达。直接计算巨大 Φp\Phi_p 常不如先构造低亏格模型再表达 j1,j2j_1,j_2

q 展开原理

若两个模形式在足够多项 qq-展开上相等,就可由 Sturm 界证明全局相等。对权 kk、级数 NN 的形式,一个可用界为

B=k12[SL2(𝐙):Γ0(N)]B=\left\lfloor\frac{k}{12} [\operatorname{SL}_2(\mathbf Z):\Gamma_0(N)]\right\rfloor

并按特征标与尖点细节调整。对模函数恒等式,可清除分母,使两边成为同权全纯模形式,再应用 Sturm 界。这把“看起来 q 展开吻合”升级为有限精确验证。

从模曲线到 Belyi 数据

把目标坐标取 β=j/1728\beta=j/1728。在非椭圆点上,j=0j=0 的零点通常三重,j1728j-1728 的零点通常二重,尖点给出极点。例外的简单零对应上方仍有额外稳定子。由这些除子可直接写出置换循环型,再用 Riemann–Hurwitz 验证曲线亏格。反过来,从 Belyi 置换恢复的曲线若具有正确尖点宽度与 Hecke 结构,就可识别为某条模曲线。

高亏格模型的完整验证

用尖形式构造模型后,应验证:典范理想确实定义光滑曲线;函数 j1,j2j_1,j_2 满足 ΦN=0\Phi_N=0;尖点位置和宽度正确;Atkin–Lehner 算子在微分空间上的矩阵与模型自同构一致;以及有限多项 qq-展开达到 Sturm 界。这样得到的模型才不是单纯的数值猜测。

计算专题:从 q 展开恢复模曲线函数

给定尖形式基 f1,,fgf_1,\ldots,f_g,典范坐标的关系可按次数 dd 枚举单项式,计算各自 q 展开到足够阶,再求线性核。所需截断至少超过 Sturm 界,并应再多算若干项交叉验证。关系系数若在数域中,可先对每个嵌入或模素数求核再重构。

构造一个函数 h=f/gh=f/g 时,其零极除子可从各尖点展开和曲线上内部零点推断。若希望 hh 为 Hauptmodul,必须证明函数域次数 1:检查它只有一个简单极点,或其映射次数等于 1。仅有开头 q1+O(1)q^{-1}+O(1) 不排除在其他尖点还有极点。

表达 jjhh 的有理函数,可先由极点除子决定分母和总次数,再利用 j=0,1728j=0,1728 的分歧预分解分子。未知系数通过 q 展开线性求解。最后清除分母形成模形式恒等式,并按 Sturm 界精确证明。

高亏格时,函数域以典范坐标商环表示。要恢复 jj,在 Riemann–Roch 空间 L(D)L(D) 中求具有指定尖点极点的元素;q 展开给线性条件。把候选函数代入模多项式 ΦN(j,j)\Phi_N(j,j') 并在函数域约化为零,可同时认证同源解释。

Hecke 算子在 q 展开上有显式公式,可形成有限维尖形式空间矩阵。新旧空间分解、Atkin–Lehner 特征和有理结构均由这些矩阵求得。构造模型时选 Hecke 稳定且 Galois 稳定的基,通常能得到较小系数。

尖点的精确坐标可通过 modular symbols 或对基作适当 slash 变换求局部展开。只在无穷远知道 q 展开不足以核对全部极点。对每个尖点计算宽度和首项,是验证函数除子的必要步骤。

深入补充:Sturm 界、qq-展开认证与 X0(2)X_0(2) 的完整公式

qq-展开不仅用于猜公式,还能在有限截断处给出严格证明。对权 kk、级数 NN 的模形式,Sturm 定理把“所有 Fourier 系数为零”化成有限检查。

定理 Γ0(N)\Gamma_0(N) 的 Sturm 界

f=n0anqnf=\sum_{n\ge0}a_nq^n 是权 kk 的模形式,系数位于特征零整环。若

an=0(0nB),a_n=0\qquad(0\le n\le B),

其中

B=k12[SL2(𝐙):Γ0(N)],[SL2(𝐙):Γ0(N)]=NpN(1+1p),B=\left\lfloor\frac{k}{12}[\operatorname{SL}_2(\mathbf Z):\Gamma_0(N)]\right\rfloor, \qquad [\operatorname{SL}_2(\mathbf Z):\Gamma_0(N)] =N\prod_{p\mid N}\left(1+\frac1p\right),

f=0f=0

验证两个模函数恒等式时,先乘以适当的 cusp form 清除极点,使差变成全纯模形式,再检查到 Sturm 界。这样“多算若干项似乎相等”升级为有限、确定性的证明。

计算 级数 22 的 Hauptmodul

t(τ)=(η(τ)η(2τ))24=q124+276q2048q2+.t(\tau)=\left(\frac{\eta(\tau)}{\eta(2\tau)}\right)^{24} =q^{-1}-24+276q-2048q^2+\cdots.

X0(2)X_0(2) 的函数域为 𝐐(t)\mathbf Q(t),并有

j(τ)=(t+256)3t2,j(2τ)=(t+16)3t.j(\tau)=\frac{(t+256)^3}{t^2}, \qquad j(2\tau)=\frac{(t+16)^3}{t}.

第一式在 t=t=\infty 处有一阶极点,对应宽度 11 的 cusp;在 t=0t=0 处有二阶极点,对应另一个宽度 22 的 cusp。两极点总次数为 3=[SL2(𝐙):Γ0(2)]3=[\operatorname{SL}_2(\mathbf Z):\Gamma_0(2)],恰等于 jj-映射次数。

公式可由有限线性代数恢复。已知 jj 在两个 cusp 的极点阶后,设

j=a3t3+a2t2+a1t+a0t2.j=\frac{a_3t^3+a_2t^2+a_1t+a_0}{t^2}.

t(q)t(q)j(q)=q1+744+196884q+j(q)=q^{-1}+744+196884q+\cdots 代入,比较前四个独立系数便解出 aia_i;随后清除分母并用 Sturm 界验证。与“猜一个任意次数有理函数”相比,除子信息把未知数降到最小。

算法 一般模曲线函数的恢复

先由 cusp 宽度和椭圆点确定目标函数的极点除子;在相应 Riemann–Roch 空间中选基,通常由 eta 商或已知模形式商给出;计算足够长的 qq-展开并解线性系统;用额外系数做独立检查;最后把差乘成全纯模形式并应用 Sturm 定理。高亏格时可同时恢复多个生成函数及其代数关系。

qq-展开长度应由维数而非经验决定。若未知系数数为 MM,至少需要 MM 个独立 Fourier 条件;若 cusp 处含分数幂,应先统一到局部参数 q1/wq^{1/w}。多个 cusp 的展开可提供更好的条件数,也能发现只在无穷 cusp 正确、却在其他 cusp 有伪极点的候选。

j(t)j(t) 还可直接读取 Belyi 数据:j=j=\infty 的原像是 cusp,j=0j=0 的分歧指数来自三阶椭圆点,j=1728j=1728 的分歧指数来自二阶椭圆点。对归一化函数 j/1728j/1728,临界值落在 0,1,0,1,\infty,其循环型必须同时满足指数公式和亏格公式;这为恢复公式提供第二套独立认证。

进一步计算专题:模多项式、循环同源与中国剩余构造

经典模多项式 ΦN(X,Y)𝐙[X,Y]\Phi_N(X,Y)\in\mathbf Z[X,Y] 由关系

ΦN(j(τ),j(Nτ))=0\Phi_N(j(\tau),j(N\tau))=0

定义到归一化。其几何意义是:

ΦN(j(E),j(E))=0\Phi_N(j(E),j(E'))=0

当且仅当存在适当意义下的循环 NN-同源 EEE\to E'。多项式对称,且对每个变量的次数为

ψ(N)=NpN(1+1p)=[SL2(𝐙):Γ0(N)].\psi(N)=N\prod_{p\mid N}\left(1+\frac1p\right) =[\operatorname{SL}_2(\mathbf Z):\Gamma_0(N)].

对素数 \ell,次数为 +1\ell+1,对应 E[]E[\ell] 中的 +1\ell+1 个循环阶 \ell 子群。

函数域 X0(N)X_0(N) 的平面模型

函数

X=j(τ),Y=j(Nτ)X=j(\tau), \qquad Y=j(N\tau)

生成 X0(N)X_0(N) 函数域的一个有限指数子域,并满足 ΦN(X,Y)=0\Phi_N(X,Y)=0。将平面曲线 ΦN=0\Phi_N=0 归一化后得到模曲线;平面模型的奇点会把多个 cusp 或 CM 分支合并,不能直接用其算术亏格代替 X0(N)X_0(N) 的几何亏格。

构造 ΦN\Phi_N 可从 qq-展开出发。设

ΦN(X,Y)=0i,jψ(N)cijXiYj,\Phi_N(X,Y)= \sum_{0\le i,j\le\psi(N)}c_{ij}X^iY^j,

利用对称性 cij=cjic_{ij}=c_{ji}、首项归一化和已知极点阶大幅减少未知数。代入

j(q)=q1+744+196884q+,j(qN)j(q)=q^{-1}+744+196884q+ \cdots, \qquad j(q^N)

比较 Laurent 系数,得到整数线性系统。所需展开长度由未知系数数和最低可能指数精确决定,而非凭经验选择。

系数高度随 NN 快速增长,直接整数线性代数很昂贵。可在许多素数 pp 下构造 ΦNmodp\Phi_N\bmod p,再中国剩余重构。模 pp 构造有两条路线:对截断 qq-级数做线性代数;或在有限域中枚举椭圆曲线与循环同源,插值得到多项式值。后者可利用 Vélu 公式和 isogeny volcano 结构。

算法 模素数—CRT 的确定性终止

预先使用解析高度界估计所有 |cij|<B|c_{ij}|<B;累积良素数使模量 M>2BM>2B;把每个系数取对称代表;在一个新素数上验证完整多项式关系;最后以足够长的特征零 qq-展开或函数域代入核验。达到 M>2BM>2B 后重构唯一,不再依赖概率性早停。

对有限域 𝐅q\mathbf F_q 中的 jj 值,方程

Φ(j,Y)=0\Phi_\ell(j,Y)=0

的根给出定义在相应扩张域中的 \ell-同源邻居。普通椭圆曲线的同源图呈火山结构;超奇异 jj-不变量在 𝐅p2\mathbf F_{p^2} 上形成近似 (+1)(\ell+1)-正则图。这里应计算多项式的平方自由部分,因为重根可能来自额外自同构或特征整除判别式。

分支判据 模多项式的偏导数

在平面模型光滑点,投影到 XX 轴的分支由

ΦN(X,Y)=0,ΦNY(X,Y)=0\Phi_N(X,Y)=0, \qquad\frac{\partial\Phi_N}{\partial Y}(X,Y)=0

刻画。消去 YY 得到投影判别式;其零点包含椭圆点、cusp 合并和具有额外自同源的 CM 点。归一化后需用局部分支参数区分真正分歧与平面奇点造成的伪重数。

X0(N)X_0(N) 亏格零且已有 Hauptmodul tt 时,分别把 j(τ)j(\tau)j(Nτ)j(N\tau) 写成 tt 的有理函数,再消去 tt 可得到 ΦN\Phi_N 的一个因子;次数与不可约性核对后即为完整模多项式。反过来,从 ΦN\Phi_N 的归一化求一个次数较低函数,也可恢复 Hauptmodul。两条路线互为验证:qq-展开控制局部归一化,消元控制全局代数关系。

补充计算:η 商、Hauptmodul 恒等式与 Sturm 界认证

定理 X_0(2) 的 Hauptmodul 与 j 映射

t(τ)=(η(τ)η(2τ))24=q124+276q2048q2+. t(\tau)=\left(\frac{\eta(\tau)}{\eta(2\tau)}\right)^{24} =q^{-1}-24+276q-2048q^2+\cdots. 则 \(X_0(2)≅P^1_t\),并有 j(τ)=(t+256)3t2,j(2τ)=(t+16)3t. j(\tau)=\frac{(t+256)^3}{t^2},\qquad j(2\tau)=\frac{(t+16)^3}{t}. 若两个 \(Γ_0(N)\) 上权 k 模形式的 Fourier 系数在 0nk12[SL2(𝐙):Γ0(N)] 0\le n\le\left\lfloor\frac{k}{12}[\mathrm{SL}_2(\mathbf Z):\Gamma_0(N)]\right\rfloor 范围内相同,则两者相同。

证明 除子比较、尖点主部与 Sturm 零点计数

η 商判据表明 t 是 \(Γ_0(2)\) 的模函数;其在 ∞ 有一阶极点,在另一尖点有一阶零点,故生成亏格 0 函数域。右侧两个有理函数的极点阶分别与 j(τ)、j(2τ) 在两尖点的宽度一致,且 q 主部为 \(q^{-1}\)、\(q^{-2}\)。比较足够多 Fourier 系数后差为无极点模函数并在 ∞ 消失,故恒为零。

Sturm 定理把非零模形式的零除子次数与线丛次数 \(k[SL_2(Z):Γ_0(N)]/12\) 比较。若前 B 个系数消失,则在 ∞ 的零阶大于该次数,只能是零形式。对有理函数恒等式先乘共同分母化为同权完整模形式,再应用该界。

Python 整数 Laurent 级数、η 乘积、j 展开与 Sturm 界
from math import comb, gcd, floor
from fractions import Fraction

def add(A,B):
    C=A.copy()
    for k,v in B.items():
        C[k]=C.get(k,0)+v
        if C[k]==0:C.pop(k)
    return C

def mul(A,B,lo,hi):
    C={}
    for i,a in A.items():
        for j,b in B.items():
            if lo<=i+j<=hi:
                C[i+j]=C.get(i+j,0)+a*b
    return {k:v for k,v in C.items() if v}

def power(A,n,lo,hi):
    if n<0:
        return power(inv(A,lo,hi),-n,lo,hi)
    R={0:1}
    B=A
    while n:
        if n&1:R=mul(R,B,lo,hi)
        B=mul(B,B,lo,hi);n>>=1
    return R

def inv(A,lo,hi):
    """
    Invert a Laurent series with unit leading coefficient.
    Shift the lowest exponent to zero, invert recursively, then shift back.
    """
    e0=min(A)
    a0=A[e0]
    if a0 not in (1,-1):
        raise ValueError("leading coefficient must be ±1")
    shifted={k-e0:Fraction(v,a0) for k,v in A.items()}
    N=hi-lo+abs(e0)+5
    B={0:Fraction(1)}
    for n in range(1,N+1):
        s=sum(shifted.get(k,0)*B.get(n-k,0) for k in range(1,n+1))
        B[n]=-s
    return {k-e0:Fraction(v,a0) for k,v in B.items()
            if lo<=k-e0<=hi and v}

def shift(A,s):
    return {k+s:v for k,v in A.items()}

def factor_one_minus(n,exponent,N):
    # (1-q^n)^exponent for nonnegative exponent
    return {n*k:(-1)**k*comb(exponent,k)
            for k in range(exponent+1) if n*k<=N}

def factor_one_plus_negative(n,exponent,N):
    # (1+q^n)^(-exponent)
    out={}
    for k in range(N//n+1):
        out[n*k]=(-1)**k*comb(exponent+k-1,k)
    return out

def sigma(n,k):
    return sum(d**k for d in range(1,n+1) if n%d==0)

def delta_series(N):
    D={1:1}
    for n in range(1,N+1):
        D=mul(D,factor_one_minus(n,24,N),0,N)
    return D

def e4_series(N):
    return {0:1,**{n:240*sigma(n,3) for n in range(1,N+1)}}

def eta_ratio_2(N):
    T={-1:1}
    for n in range(1,N+2):
        T=mul(T,factor_one_plus_negative(n,24,N+2),-1,N)
    return T

def format_series(A,lo,hi):
    terms=[]
    for e in range(lo,hi+1):
        c=A.get(e,0)
        if not c:continue
        terms.append(f"q^{e}:{c}")
    return "  ".join(terms)

def index_gamma0(N):
    result=N
    p=2
    m=N
    while p*p<=m:
        if m%p==0:
            result=result*(p+1)//p
            while m%p==0:m//=p
        p+=1
    if m>1:result=result*(m+1)//m
    return result

def sturm_bound(N,weight):
    return floor(Fraction(weight*index_gamma0(N),12))

N=14
E4=e4_series(N+2)
Delta=delta_series(N+3)
j_classical=mul(power(E4,3,-1,N),inv(Delta,-1,N),-1,N)

T=eta_ratio_2(N+3)
Tinverse=inv(T,1,N+4)
Tinverse2=mul(Tinverse,Tinverse,2,N+4)
j_haupt=add(add(T,{0:768}),
             add({k:196608*v for k,v in Tinverse.items()},
                 {k:16777216*v for k,v in Tinverse2.items()}))
T2=mul(T,T,-2,N+4)
j2=add(add(T2,{k:48*v for k,v in T.items()}),
       add({0:768},{k:4096*v for k,v in Tinverse.items()}))

print("t=(eta(tau)/eta(2tau))^24:")
print(format_series(T,-1,8))
print("\nclassical j from E4^3/Delta:")
print(format_series(j_classical,-1,8))
print("\nj=(t+256)^3/t^2:")
print(format_series(j_haupt,-1,8))
print("  coefficient equality through q^8 =",
      all(j_classical.get(k,0)==j_haupt.get(k,0) for k in range(-1,9)))

print("\nj(2tau)=(t+16)^3/t:")
print(format_series(j2,-2,10))
print("  only even positive q powers =",
      all((e<=0 or e%2==0) for e in j2 if e<=10))

print("\nSturm bounds:")
for level in [1,2,3,4,5,6,7,11,13]:
    print(
        f"  N={level:2d}, index={index_gamma0(level):3d}, "
        f"B(k=2)={sturm_bound(level,2):2d}, "
        f"B(k=4)={sturm_bound(level,4):2d}, "
        f"B(k=12)={sturm_bound(level,12):3d}"
    )

print("\nfirst Delta coefficients:")
print(format_series(Delta,1,10))
运行结果 q^12 精确系数一致性与多级数 Sturm 表
t=(eta(tau)/eta(2tau))^24:
q^-1:1  q^0:-24  q^1:276  q^2:-2048  q^3:11202  q^4:-49152  q^5:184024  q^6:-614400  q^7:1881471  q^8:-5373952

classical j from E4^3/Delta:
q^-1:1  q^0:744  q^1:196884  q^2:21493760  q^3:864299970  q^4:20245856256  q^5:333202640600  q^6:4252023300096  q^7:44656994071935  q^8:401490886656000

j=(t+256)^3/t^2:
q^-1:1  q^0:744  q^1:196884  q^2:21493760  q^3:864299970  q^4:20245856256  q^5:333202640600  q^6:4252023300096  q^7:44656994071935  q^8:401490886656000
  coefficient equality through q^8 = True

j(2tau)=(t+16)^3/t:
q^-2:1  q^0:744  q^2:196884  q^4:21493760  q^6:864299970  q^8:20245856256  q^10:333202640600
  only even positive q powers = True

Sturm bounds:
  N= 1, index=  1, B(k=2)= 0, B(k=4)= 0, B(k=12)=  1
  N= 2, index=  3, B(k=2)= 0, B(k=4)= 1, B(k=12)=  3
  N= 3, index=  4, B(k=2)= 0, B(k=4)= 1, B(k=12)=  4
  N= 4, index=  6, B(k=2)= 1, B(k=4)= 2, B(k=12)=  6
  N= 5, index=  6, B(k=2)= 1, B(k=4)= 2, B(k=12)=  6
  N= 6, index= 12, B(k=2)= 2, B(k=4)= 4, B(k=12)= 12
  N= 7, index=  8, B(k=2)= 1, B(k=4)= 2, B(k=12)=  8
  N=11, index= 12, B(k=2)= 2, B(k=4)= 4, B(k=12)= 12
  N=13, index= 14, B(k=2)= 2, B(k=4)= 4, B(k=12)= 14

first Delta coefficients:
q^1:1  q^2:-24  q^3:252  q^4:-1472  q^5:4830  q^6:-6048  q^7:-16744  q^8:84480  q^9:-113643  q^10:-115920
计算 级数 2 的系数核验

程序独立由 E_4^3/Δ 与 Hauptmodul 公式计算 j,q^{-1} 至 q^{12} 的系数完全相同:1、744、196884、21493760、864299970 等。第二公式只出现偶次 q 幂,首项 q^{-2},与 j(2τ) 一致。级数 2、权 12 的 Sturm 界为 3。

Lecture 25 / 第 25 讲

Fricke 与 Atkin–Lehner 对合、CM 固定点

解释对偶同源如何产生模曲线自同构,并用固定点计算 CM 值。

Fricke对合Atkin–Lehner复乘

1. Fricke 对合

PY0(N)P\in Y_0(N) 参数化循环 NN-同源 φ:EE\varphi:E\to E'。其对偶同源 φ*:EE\varphi^*:E'\to E 满足 φ*φ=[N]\varphi^*\varphi=[N],于是定义对合 wN(P)=[φ*]w_N(P)=[\varphi^*]。解析上

wN:τ1Nτ.w_N:\tau\longmapsto-\frac1{N\tau}.

它正规化 Γ0(N)\Gamma_0(N),并延拓到紧化曲线 X0(N)X_0(N)

定理固定点与复乘

Fricke 固定点对应与自身存在循环 NN-同源的椭圆曲线,因此具有虚二次复乘。固定点数可用判别式 N-N4N-4N 的二元二次型类数表示。

在前讲的 η-商坐标中,

wN(h)=N12/(N1)h.w_N(h)=\frac{N^{12/(N-1)}}{h}.

固定点为 h=±N6/(N1)h=\pm N^{6/(N-1)}。代入 j(h)j(h) 可得到若干整 CM 值,例如 N=2N=2 给出 j=203j=20^312312^3N=3N=3 给出 23032\cdot30^300

2. Atkin–Lehner 对合

N=N1N2N=N_1N_2gcd(N1,N2)=1\gcd(N_1,N_2)=1,单位因子 N1N_1 定义对合 wN1w_{N_1}。几何上把循环 NN-同源分解成互素次数的方形图,再把 N1N_1 部分替换为对偶同源。

定理Atkin–Lehner 群

所有 wdw_ddN,gcd(d,N/d)=1d\mid N,\ \gcd(d,N/d)=1)在商掉 Γ0(N)\Gamma_0(N) 后形成一个初等 2-群,秩为 NN 的不同素因子个数;乘法满足 wdwe=wde/(d,e)2w_d w_e=w_{de/(d,e)^2}

3. 商曲线与模形式

X0(N)+=X0(N)/wNX_0(N)^+=X_0(N)/\langle w_N\rangle 的亏格由Riemann–Hurwitz公式和固定点数决定。权 2 尖点形式对应全纯微分;对合的 ±1\pm1 特征空间分别给出商曲线微分与反不变微分。计算显式模型时,可先在 qq-展开上对角化 Atkin–Lehner 算子。

算法计算商曲线模型
  1. 计算 S2(Γ0(N))S_2(\Gamma_0(N))qq-展开基。
  2. 计算 wdw_d 作用并取所需特征空间。
  3. 把特征形式视为典范微分。
  4. 在线性代数中寻找二次、三次关系。
  5. jj-函数或其他模函数给出到 X(1)X(1) 的映射。

Fricke 对合的模意义

对同源 ϕ:EE\phi:E\to E',存在同次数的对偶同源 ϕ:EE\phi^\vee:E'\to E,满足

(ϕ)=ϕ,ϕϕ=[degϕ].(\phi^\vee)^\vee=\phi,\qquad \phi^\vee\circ\phi=[\deg\phi].

循环同源的对偶仍循环。X0(N)X_0(N) 参数化循环 NN-同源,所以把 ϕ\phi 换成 ϕ\phi^\vee 定义对合 wNw_N。复解析上

wN:τ1Nτ,w_N:\tau\longmapsto-\frac1{N\tau},

由行列式 NN 的矩阵表示,位于 Γ0(N)\Gamma_0(N)PGL2+(𝐐)\operatorname{PGL}_2^+(\mathbf Q) 中的正规化子。商曲线常记为

X0(N)+=X0(N)/wN.X_0(N)^+=X_0(N)/\langle w_N\rangle.

kk-有理点可解释为某个至多二次扩张 K/kK/k 上定义的一对循环 NN-同源曲线,且两条曲线在代数闭包上互为 Galois 共轭。应注意:未必存在同一 KK 上的扭曲,使该同构本身也在 KK 上定义。

固定点、类数与商亏格

wNw_N 的固定点对应自同源,即复乘椭圆曲线上的范数 NN 元素。固定点数可用判别式 N-N(若它是二次阶判别式)与 4N-4N 的二元二次型类数表示。点 τ=i/N\tau=i/\sqrt N 总是固定点,因此 wNw_N 至少有一个固定点;Riemann–Hurwitz 迫使总数为偶数。固定点数约为 N1/2+o(1)N^{1/2+o(1)},而 g(X0(N))g(X_0(N)) 约线性增长,所以 g(X0(N)+)g(X_0(N)^+) 渐近为原亏格的一半。

低级数时亏格可能显著下降:某些 NN 直到 71 都使 X0(N)+X_0(N)^+ 亏格 0,其中包括 Monster 群阶的全部素因子,这是 monstrous moonshine 的经典背景。亏格 1 的例子可到 N=131N=131;素数级数时相应椭圆曲线秩为 1,产生无穷多个二次域上的 𝐐\mathbf Q-曲线。亏格 2、3 的已知的最大级数分别达到 191、239。具体亏格和 wNw_N 在权 2 尖形式上的特征空间维数可由表或计算软件获得。

Hauptmodul 上的 Fricke 作用

对上一讲的八个 eta 商所对应的级数,eta 变换公式给出

wN(h)=N12/(N1)h.w_N(h)=\frac{N^{12/(N-1)}}{h}.

即使 N=9,25N=9,25 时指数为半整数,常数仍为整数。固定点为

h=±N6/(N1).h=\pm N^{6/(N-1)}.

正号对应 τ=i/N\tau=i/\sqrt N,其复乘阶通常为判别式 4N-4N。代入 j(h)j(h) 可得:

N=2,3,4,7:h=64,27,16,7,N=2,3,4,7:\quad h=64,27,16,7,

相应

j=203,2303,663,2553.j=20^3,\quad2\cdot30^3,\quad66^3,\quad255^3.

负固定点在 N=2,3,7N=2,3,7 给出判别式 4,3,7-4,-3,-7 的简单奇异模数 j=123,0,153j=12^3,0,-15^3N=4N=4 时负点是第三个尖点。对 N=5,9,25N=5,9,25,两个固定点的 jj-值互为二次共轭,对应 𝐙[N]\mathbf Z[\sqrt{-N}] 的复乘。

非固定点自同源产生的 CM 值

还可解

j(h)=j(wNh)j(h)=j(w_Nh)

而排除 h=wNhh=w_Nh。这对应 ϕ:EE\phi:E\to Eϕϕ\phi^\vee\ne-\phi 的循环 NN-自同源。N=2N=2 时额外因子为 h2+47h+212h^2+47h+2^{12},再次给出 j=153j=-15^3、判别式 7-7N=3N=3 时出现

h2+46h+36,h210h+36,h^2+46h+3^6,\qquad h^2-10h+3^6,

前者重复 j=203j=20^3,后者给出 j=323j=-32^3、判别式 11-11。同样方法可处理 N=5,7,13N=5,7,13

一般 Atkin–Lehner 对合

N=N1N2N=N_1N_2gcd(N1,N2)=1\gcd(N_1,N_2)=1,即 N1N_1NN 的单位因子,则有对合 wN1w_{N_1}。把一个循环 NN-同源分解成次数 N1,N2N_1,N_2 的交换方形,并把两条次数 N1N_1 的边替换成对偶同源,得到新的交换方形。N1=NN_1=N 时回到 Fricke 对合。

全部 Atkin–Lehner 对合组成初等Abelian 2-群,秩为 NN 的不同素因子数。乘法规则为

wawb=wc,w_a w_b=w_c,

其中 cc 是唯一使 abcabc 为平方的单位因子,等价地在每个素幂因子上取异或。矩阵代表可取整数矩阵且行列式为 N1N_1,但一般不能在 PGL2+(𝐐)\operatorname{PGL}_2^+(\mathbf Q) 中把它缩放成真正平方为 1 的矩阵;它只在模 Γ0(N)\Gamma_0(N) 的商上成为对合。

有些 wN1w_{N_1} 没有固定点,最早例子为 (N,N1)=(14,2)(N,N_1)=(14,2)(15,3)(15,3)。固定点存在时仍可由二次型类数计算。对实际可计算的小 NN,更方便的方法是在权 2 尖形式空间中同时对角化所有 Atkin–Lehner 算子;各符号特征空间的维数通过 Riemann–Hurwitz 直接给出任意子群商曲线的亏格。

一般 Atkin–Lehner 元素

QNQ\mid Ngcd(Q,N/Q)=1\gcd(Q,N/Q)=1,称 QQ 为 exact divisor。可选整数使矩阵

WQ=(QabNcQd),detWQ=QW_Q= \begin{pmatrix}Qa&b\\Nc&Qd\end{pmatrix}, \qquad \det W_Q=Q

正规化 Γ0(N)\Gamma_0(N),其在 X0(N)X_0(N) 上的类与选择无关,记为 wQw_Q。这些对合满足

wQwR=wQR/(gcd(Q,R))2w_Qw_R=w_{QR/(\gcd(Q,R))^2}

在相应 exact divisor 条件下成立,并生成一个初等 2-群。wNw_N 是 Fricke 对合。

模问题中的核与商

(E,C)X0(N)(E,C)\in X_0(N) 由椭圆曲线和循环子群 CC 表示。把 CC 分解为 QQ-部分与 N/QN/Q-部分,wQw_Q 先对 QQ-部分取商,再把剩余结构搬到商曲线上。这比“简单交换两条曲线”更一般;只有 Q=NQ=N 时直接得到整个同源的对偶。

固定点方程与二次型

τ\tauWQW_Q 固定到 Γ0(N)\Gamma_0(N)-等价,则存在某个 γΓ0(N)\gamma\in\Gamma_0(N) 使 WQτ=γτW_Q\tau=\gamma\tau。整理得到整系数二次方程

Aτ2+Bτ+C=0,B24AC<0.A\tau^2+B\tau+C=0, \qquad B^2-4AC<0.

因此 τ\tau 是虚二次点。不同固定点类由满足级数整除条件的正定二元二次型分类。判别式通常为 4Q-4Q 或在同余条件允许时为 Q-Q,并可能附加局部嵌入条件。

用 Riemann–Hurwitz 求商亏格

若对合 ww 在亏格 gg 曲线上有 rr 个固定点,商曲线亏格 g+g^+ 满足

2g2=2(2g+2)+r,g+=2g+2r4.2g-2=2(2g^+-2)+r, \qquad g^+=\frac{2g+2-r}{4}.

这立即说明 rr 必为偶数且满足相应同余。反过来,若已知 wwS2(Γ0(N))S_2(\Gamma_0(N)) 上的迹 tt,则正负特征空间维数为 (g±t)/2(g\pm t)/2,其中正特征空间维数就是商亏格。

在尖形式空间上计算对合

Atkin–Lehner 算子作用于权 2 新形式。对一个规范化新形式 ff,有

f|WQ=εQ(f)f,εQ(f){±1}f|W_Q=\varepsilon_Q(f)f, \qquad \varepsilon_Q(f)\in\{\pm1\}

在平方自由等标准情形下。符号与函数方程根数相关。把同一符号的形式作为微分基,可直接构造商曲线典范模型;反号微分则在对合下变号。

亏格 0 商的 Hauptmodul

X0(N)+X_0(N)^+ 亏格 0,可寻找在无穷远有唯一简单极点的 wNw_N-不变模函数。常用形式是

TN(τ)=hN(τ)+cN+ANhN(τ)T_N(\tau)=h_N(\tau)+c_N+\frac{A_N}{h_N(\tau)}

其中 Fricke 使 hNAN/hNh_N\mapsto A_N/h_N。常数选到 q1+O(q)q^{-1}+O(q) 规范。Monstrous moonshine 中许多 genus-zero 群的 Hauptmodul 正具有这种可复制展开。

商曲线有理点与 𝐐\mathbf Q-曲线

一个 X0(N)+(𝐐)X_0(N)^+(\mathbf Q) 点提升到至多二次域 KK 上的 X0(N)X_0(N) 点。非平凡 Galois 元素将提升点送到其 Fricke 像,因此相应椭圆曲线与其共轭之间有循环 NN-同源。这类椭圆曲线称为 𝐐\mathbf Q-曲线。提升可能受曲线自同构影响,故精确下降需用叠而不能只用粗模空间表述。

CM 点的代数值

虚二次 τ\tauj(τ)j(\tau) 是代数整数,其最小多项式为 Hilbert 类多项式。Atkin–Lehner 固定点进一步要求对应理想类中存在范数 QQ 的元素或理想。把固定点代入 Hauptmodul,得到环类域中的类不变量;适当 η\eta-商往往比 jj 高度小得多,适合显式类域计算。

固定点计数中的例外

判别式 3,4-3,-4 的 CM 曲线有额外自同构,粗模曲线上的固定点计数会带权或合并。级数含有 2、3 的高次幂因子时,局部嵌入数也会改变。使用类数公式时必须注明是原始型、非原始型还是 Eichler 阶嵌入,并检查尖点是否也被对合固定。

显式模型上的对合验证

若已有曲线模型与候选有理变换 ww,应符号验证:它保持定义理想;复合两次为恒等;对 j1,j2j_1,j_2 的作用确实交换或按 QQ-分解变换;固定点数与类数预测一致;在全纯微分空间上的矩阵特征值与模形式计算一致。多重核对可排除仅在若干数值点上吻合的伪自同构。

计算专题:Atkin–Lehner 商模型的构造

若已有典范模型和对合在线性微分空间上的矩阵,先对矩阵对角化,取正特征微分生成商的典范系统。正空间维数为商亏格。若商亏格至少 3 且非超椭圆,可直接在这些坐标上求关系;低亏格则用 Riemann–Roch 构造平面或 Weierstrass 模型。

函数域方法中,对合 ww 作用于 K(C)K(C)。选一个非不变元素 uu,则迹 u+w(u)u+w(u) 与范数 uw(u)u w(u) 在不变域中,且 uu 满足二次方程。用若干迹范数可生成 K(C)wK(C)^w,再消元得到商模型。分支点就是二次判别式为零处。

固定点可在显式模型上解 w(P)=Pw(P)=P,但射影坐标中要允许比例因子。求解理想并饱和掉无关坐标后,解的长度应等于 Riemann–Hurwitz预测的固定点数。若出现非约化点,可能是固定点重合或模型奇异,需要回到光滑曲线局部分析。

CM 识别可将固定点的 jj-值代入 Hilbert 类多项式。若数值近似先得到候选判别式,可用 j(q)j(q) 的大小估计虚部,再枚举约化二次型。精确验证是最小多项式整除相应类多项式,并检查级数嵌入条件。

𝐐\mathbf Q-曲线应用,商上的有理点提升所需二次域由双覆盖判别式决定。在该域上重构 j1,j2j_1,j_2,应满足互为 Galois 共轭与 ΦN(j1,j2)=0\Phi_N(j_1,j_2)=0。还可计算同源核多项式,验证同源确实在声明的扩张上定义。

商模型的有理点分析依亏格而异:亏格 0 参数化,亏格 1 用 Mordell–Weil 群,亏格 2 可用 Chabauty、Mordell–Weil sieve 等。显式 Atkin–Lehner 商因而把同源分类问题转化为标准算术曲线问题。

深入补充:Fricke 固定点的二次方程与商亏格计算

Fricke 对合 wNw_N 在上半平面上由 τ1/(Nτ)\tau\mapsto-1/(N\tau) 表示。模曲线上的固定点不要求这个等式逐字成立,而只要求存在 γ=(abcd)Γ0(N)\gamma=\begin{pmatrix}a&b\\c&d\end{pmatrix}\in\Gamma_0(N) 使

γτ=1Nτ.\gamma\tau=-\frac1{N\tau}.

交叉相乘得到

Naτ2+(Nb+c)τ+d=0.Na\tau^2+(Nb+c)\tau+d=0.
推论 Fricke 固定点必为 CM 点

上述二次方程的判别式

D=(Nb+c)24NadD=(Nb+c)^2-4Nad

为负,因此 τ\tau 是虚二次数,所对应椭圆曲线具有复乘。反过来,满足适当局部嵌入条件的虚二次序可产生 Fricke 固定点;固定点计数可转化为二次型或最优嵌入的类数问题。

这个推导还说明为何固定点不只可能是 i/Ni/\sqrt N:允许先施加 Γ0(N)\Gamma_0(N) 变换后,会得到许多等价类不同的二次方程。程序枚举时可限制 a,b,c,da,b,c,d 的范围,并按二次型约化去重,而不是在复平面盲目求解。

公式 对合商的亏格

设光滑曲线 XX 的亏格为 gg,对合 wwrr 个固定点,商曲线 Y=X/wY=X/\langle w\rangle 的亏格为

g(Y)=2g+2r4.g(Y)=\frac{2g+2-r}{4}.

因此 rr 必与 2g+22g+244 同余;这个整除条件是固定点计数的快速校验。

在微分空间上,ww 分解出 +1+11-1 特征子空间。+1+1 子空间恰为 H0(Y,KY)H^0(Y,K_Y) 的拉回,所以其维数等于 g(Y)g(Y);由模符号或 Fourier 展开计算 Atkin–Lehner 矩阵的迹,即可独立得到

dimV+=g+tr(w)2.\dim V_+=\frac{g+\operatorname{tr}(w)}2.

与固定点公式比较,得到 Lefschetz 型一致性检查。

算法 亏格零商上的不变量参数

XX 已有 Hauptmodul tt,且

wN(t)=ct,w_N(t)=\frac{c}{t},

u=t+ctu=t+\frac ct

是不变量,并生成商函数域。消去 ttt2ut+c=0t^2-ut+c=0,显示 XYX\to Y 的两个分支点正是 t=±ct=\pm\sqrt c,即对合固定点。把原 j(t)j(t) 与该二次关系消元,可得到 jj 关于 uu 的方程及商曲线的显式 Belyi 映射。

高亏格时,可在典范坐标中对 wNw_N 对角化。用 +1+1 特征微分构造商曲线的典范映射,用 1-1 特征微分描述双覆盖的反不变量部分;乘积 VVV_-\cdot V_- 落在不变量二次微分空间中,给出双覆盖方程。最终应验证矩阵保持典范理想、平方为单位,并在所有 cusp 和 CM 固定点处与模意义一致。

补充计算:Atkin–Lehner 固定点、CM 判别式与商曲线亏格

定理 固定点二次方程与二重商的 Riemann–Hurwitz 公式

\(Q\mid N\)\(\gcd(Q,N/Q)=1\),取行列式为 Q 的 Atkin–Lehner 代表 \[ w_Q=\begin{pmatrix}a&b\\ c&d\end{pmatrix},\qquad c\equiv0\pmod N. \] 上半平面内的固定点恰为 \[ c\tau^2+(d-a)\tau-b=0 \] 的虚根,其判别式为 \[ \Delta_Q=(a+d)^2-4Q<0. \] 因而固定点均为虚二次点。若该对合在紧化曲线 \(X_0(N)\) 上有 r 个固定点,商曲线亏格 \(g^+\) 满足 \[ 2g(X_0(N))-2=2(2g^+-2)+r,\qquad g^+=\frac{2g(X_0(N))+2-r}{4}. \] 此外 \[ g(X_0(N)) =1+\frac{\mu(N)}{12}-\frac{e_2(N)}4-\frac{e_3(N)}3-\frac{c(N)}2, \quad \mu(N)=N\prod_{p\mid N}\left(1+\frac1p\right). \]

证明 固定方程、负判别式与分歧点计数

\(w_Q\tau=\tau\) 直接交叉相乘,得 \(c\tau^2+(d-a)\tau-b=0\)。其判别式 \[ (d-a)^2+4bc=(a+d)^2-4(ad-bc)=(a+d)^2-4Q. \] 固定点位于上半平面当且仅当该判别式为负;此时 \(\tau\) 满足有理系数二次方程,故为 CM 点。

商映射 \(\pi:X_0(N)\to X_0(N)/\langle w_Q\rangle\) 的次数为 2。非固定点不分歧,每个固定点的局部参数满足 \(u\mapsto u^2\),分歧指数为 2。Riemann–Hurwitz 公式遂给出 \[ 2g-2=2(2g^+-2)+\sum_{P}(e_P-1)=2(2g^+-2)+r. \] 亏格公式则由模曲线基本域的 orbifold Euler 示性数得到:指数项贡献 \(\mu/12\),二阶、三阶椭圆点分别扣除 \(e_2/4,e_3/3\),尖点扣除 c/2

Python 亏格公式、Atkin–Lehner 代表搜索与负判别式类约化
import sympy as sp
from math import gcd, isqrt
from fractions import Fraction

z=sp.Symbol("z")

def divisors(n):
    return [d for d in range(1,n+1) if n%d==0]

def prime_divisors(n):
    p=2;out=[]
    while p*p<=n:
        if n%p==0:
            out.append(p)
            while n%p==0:n//=p
        p+=1
    if n>1:out.append(n)
    return out

def index_gamma0(N):
    mu=N
    for p in prime_divisors(N):
        mu=mu*(p+1)//p
    return mu

def cusp_count(N):
    return sum(sp.totient(gcd(d,N//d)) for d in divisors(N))

def elliptic_count(N,disc):
    if disc==-4 and N%4==0:return 0
    if disc==-3 and N%9==0:return 0
    value=1
    for p in prime_divisors(N):
        value*=1+sp.kronecker_symbol(disc,p)
    return int(value)

def genus_x0(N):
    mu=index_gamma0(N)
    c=int(cusp_count(N))
    e2=elliptic_count(N,-4)
    e3=elliptic_count(N,-3)
    g=sp.Rational(1)+sp.Rational(mu,12)-sp.Rational(e2,4)-sp.Rational(e3,3)-sp.Rational(c,2)
    if g.q!=1:
        raise ArithmeticError((N,mu,c,e2,e3,g))
    return int(g),mu,c,e2,e3

def exact_divisor(Q,N):
    return N%Q==0 and gcd(Q,N//Q)==1

def atkin_lehner_matrix(N,Q,search=20):
    """
    Find an elliptic representative [[Q a,b],[N c,Q d]] of determinant Q.
    Equivalent condition Q*a*d-(N/Q)*b*c=1.
    """
    if not exact_divisor(Q,N):
        raise ValueError("Q must be an exact divisor")
    M=N//Q
    candidates=[]
    for a in range(-search,search+1):
        for d in range(-search,search+1):
            for b in range(-search,search+1):
                for c in range(-search,search+1):
                    if Q*a*d-M*b*c!=1:
                        continue
                    matrix=((Q*a,b),(N*c,Q*d))
                    tr=Q*(a+d)
                    disc=tr*tr-4*Q
                    if disc<0:
                        size=sum(z*z for row in matrix for z in row)
                        candidates.append((size,abs(tr),matrix))
    if not candidates:
        raise RuntimeError("no elliptic representative in search box")
    return min(candidates)[2]

def fixed_quadratic(matrix):
    (a,b),(c,d)=matrix
    poly=sp.Poly(c*z*z+(d-a)*z-b,z)
    discriminant=sp.factor((d-a)**2+4*b*c)
    roots=sp.solve(poly.as_expr(),z)
    upper=[r for r in roots if sp.im(sp.N(r,30))>0]
    return poly,discriminant,upper

def reduced_forms(D):
    """Primitive positive reduced binary quadratic forms of D<0."""
    if D>=0 or D%4 not in (0,1):
        return []
    forms=[]
    limit=isqrt(abs(D)//3)+2
    for a in range(1,limit+1):
        for b in range(-a,a+1):
            num=b*b-D
            if num%(4*a):continue
            c=num//(4*a)
            if a>c:continue
            if gcd(gcd(a,abs(b)),c)!=1:continue
            if (abs(b)==a or a==c) and b<0:continue
            forms.append((a,b,c))
    return forms

def possible_quotient_data(g):
    data=[]
    for r in range(0,2*g+3):
        num=2*g+2-r
        if num>=0 and num%4==0:
            gp=num//4
            data.append((r,gp))
    return data

print("genus data for X0(N):")
for N in list(range(1,13))+[14,15,17,23,37]:
    g,mu,c,e2,e3=genus_x0(N)
    print(f"  N={N:2d}: g={g:2d}, index={mu:3d}, cusps={c:2d}, e2={e2}, e3={e3}")

print("\nAtkin-Lehner matrices and fixed quadratics:")
for N in [6,10,15]:
    for Q in divisors(N):
        if Q==1 or not exact_divisor(Q,N):continue
        try:
            M=atkin_lehner_matrix(N,Q,search=12)
        except RuntimeError:
            print(f"  N={N:2d}, Q={Q:2d}: no elliptic representative in search box")
            continue
        poly,D,upper=fixed_quadratic(M)
        print(f"  N={N:2d}, Q={Q:2d}, M={M}")
        print(f"     fixed={poly.as_expr()}, discriminant={D}, upper={upper}")

print("\nCM reduced-form counts for Fricke candidate discriminants:")
for N in [5,7,11,13,23,37]:
    Ds=[-4*N]
    if N%4==3:Ds.append(-N)
    row=[]
    for D in Ds:
        forms=reduced_forms(D)
        row.append((D,len(forms),forms[:6]))
    print(f"  N={N:2d}: {row}")

print("\nRiemann-Hurwitz possibilities for involution quotients:")
for N in [11,14,15,17,23,37]:
    g=genus_x0(N)[0]
    print(f"  X0({N}) genus {g}: (fixed points, quotient genus)={possible_quotient_data(g)}")
运行结果 亏格、固定二次式、CM 约化型与商亏格候选
genus data for X0(N):
  N= 1: g= 0, index=  1, cusps= 1, e2=1, e3=1
  N= 2: g= 0, index=  3, cusps= 2, e2=1, e3=0
  N= 3: g= 0, index=  4, cusps= 2, e2=0, e3=1
  N= 4: g= 0, index=  6, cusps= 3, e2=0, e3=0
  N= 5: g= 0, index=  6, cusps= 2, e2=2, e3=0
  N= 6: g= 0, index= 12, cusps= 4, e2=0, e3=0
  N= 7: g= 0, index=  8, cusps= 2, e2=0, e3=2
  N= 8: g= 0, index= 12, cusps= 4, e2=0, e3=0
  N= 9: g= 0, index= 12, cusps= 4, e2=0, e3=0
  N=10: g= 0, index= 18, cusps= 4, e2=2, e3=0
  N=11: g= 1, index= 12, cusps= 2, e2=0, e3=0
  N=12: g= 0, index= 24, cusps= 6, e2=0, e3=0
  N=14: g= 1, index= 24, cusps= 4, e2=0, e3=0
  N=15: g= 1, index= 24, cusps= 4, e2=0, e3=0
  N=17: g= 1, index= 18, cusps= 2, e2=2, e3=0
  N=23: g= 2, index= 24, cusps= 2, e2=0, e3=0
  N=37: g= 2, index= 38, cusps= 2, e2=2, e3=2

Atkin-Lehner matrices and fixed quadratics:
  N= 6, Q= 2, M=((-2, -1), (6, 2))
     fixed=6*z**2 + 4*z + 1, discriminant=-8, upper=[-1/3 + sqrt(2)*I/6]
  N= 6, Q= 3, M=((-3, -2), (6, 3))
     fixed=6*z**2 + 6*z + 2, discriminant=-12, upper=[-1/2 + sqrt(3)*I/6]
  N= 6, Q= 6, M=((0, -1), (6, 0))
     fixed=6*z**2 + 1, discriminant=-24, upper=[sqrt(6)*I/6]
  N=10, Q= 2, M=((-4, -1), (10, 2))
     fixed=10*z**2 + 6*z + 1, discriminant=-4, upper=[-3/10 + I/10]
  N=10, Q= 5, M=((-5, -3), (10, 5))
     fixed=10*z**2 + 10*z + 3, discriminant=-20, upper=[-1/2 + sqrt(5)*I/10]
  N=10, Q=10, M=((0, -1), (10, 0))
     fixed=10*z**2 + 1, discriminant=-40, upper=[sqrt(10)*I/10]
  N=15, Q= 3: no elliptic representative in search box
  N=15, Q= 5, M=((-5, -2), (15, 5))
     fixed=15*z**2 + 10*z + 2, discriminant=-20, upper=[-1/3 + sqrt(5)*I/15]
  N=15, Q=15, M=((0, -1), (15, 0))
     fixed=15*z**2 + 1, discriminant=-60, upper=[sqrt(15)*I/15]

CM reduced-form counts for Fricke candidate discriminants:
  N= 5: [(-20, 2, [(1, 0, 5), (2, 2, 3)])]
  N= 7: [(-28, 1, [(1, 0, 7)]), (-7, 1, [(1, 1, 2)])]
  N=11: [(-44, 3, [(1, 0, 11), (3, -2, 4), (3, 2, 4)]), (-11, 1, [(1, 1, 3)])]
  N=13: [(-52, 2, [(1, 0, 13), (2, 2, 7)])]
  N=23: [(-92, 3, [(1, 0, 23), (3, -2, 8), (3, 2, 8)]), (-23, 3, [(1, 1, 6), (2, -1, 3), (2, 1, 3)])]
  N=37: [(-148, 2, [(1, 0, 37), (2, 2, 19)])]

Riemann-Hurwitz possibilities for involution quotients:
  X0(11) genus 1: (fixed points, quotient genus)=[(0, 1), (4, 0)]
  X0(14) genus 1: (fixed points, quotient genus)=[(0, 1), (4, 0)]
  X0(15) genus 1: (fixed points, quotient genus)=[(0, 1), (4, 0)]
  X0(17) genus 1: (fixed points, quotient genus)=[(0, 1), (4, 0)]
  X0(23) genus 2: (fixed points, quotient genus)=[(2, 1), (6, 0)]
  X0(37) genus 2: (fixed points, quotient genus)=[(2, 1), (6, 0)]
计算 固定点数与商亏格的整数约束

例如 g(X_0(23))=2,故 \[ g^+=\frac{6-r}{4}. \] 整数性迫使 r\equiv2\pmod4,且 0\le r\le6,所以只有 \[ (r,g^+)=(2,1),(6,0). \] 对 X_0(71)g=6,相应候选为 \[ (2,3),(6,2),(10,1),(14,0). \] 程序同时枚举判别式 -4N 以及 N\equiv3\pmod4 时的 -N 的本原正定约化二次型,所得类数为固定点轨道计数提供独立的有限检验。

Lecture 26 / 第 26 讲

Γ0(N)\Gamma_0(N) 正规化子中的额外元素与完整计算流程

说明 Atkin–Lehner 并不总是正规化子的全部,并给出判定额外自同构的安全方法。

正规化子模曲线自同构验证流程

1. 正规化子问题

考虑

N+(Γ0(N))={APGL2+(𝐐):A1Γ0(N)A=Γ0(N)}.N^+(\Gamma_0(N))=\{A\in\mathrm{PGL}_2^+(\mathbf Q):A^{-1}\Gamma_0(N)A=\Gamma_0(N)\}.

Atkin–Lehner 矩阵给出其中一个显著的有限 2-子群,但在含较高 22-幂或 33-幂因子的级数上,正规化子可能还有平移—缩放型元素。因而不能把“模曲线的明显自同构”等同于“Atkin–Lehner 对合”。

说明两个不同的问题

解析正规化子商 N+(Γ0(N))/Γ0(N)N^+(\Gamma_0(N))/\Gamma_0(N) 给出一批自同构,但代数曲线 X0(N)X_0(N) 在低亏格时还可能有不来自解析正规化子的偶然自同构。计算时应分别处理。

2. 矩阵判定

AA 适当缩放为原始整数矩阵。正规化条件可通过检查 Γ0(N)\Gamma_0(N) 的生成元共轭后仍满足下左条目被 NN 整除来验证。更稳妥的做法是比较有限指数子群:同时证明 A1Γ0(N)AΓ0(N)A^{-1}\Gamma_0(N)A\subseteq\Gamma_0(N) 及两者协面积相等。

算法寻找额外正规化子元素
  1. 按分母和行列式的局部估值限制候选矩阵。
  2. 先在各素数幂级数上求局部正规化条件。
  3. 用中国剩余原则组合候选。
  4. 对群生成元做精确共轭验证。
  5. 计算候选在尖点、椭圆点和权 2 模形式上的作用。
  6. 与已知 Atkin–Lehner 子群比较并确定商群关系。

3. 全课程的显式计算流水线

组合阶段

循环型、置换三元组、亏格、群与定义域预测。

模素数阶段

选好素数,枚举有限域解,检查 Jacobian。

提升阶段

多元 Hensel/Newton提升到高 pp-进精度。

识别阶段

有理重构、LLL、最小多项式和多共轭嵌入。

精确验证

代入方程,核对分歧、判别式、单值群和坏约化。

结构解释

连接不变量、模曲线、椭圆曲面、反射群或 CM。

原则数值发现与精确证明分离

浮点、复解析与 pp-进近似用于发现候选;最终结论必须由精确代数验证。只要候选方程可精确检查,发现过程可以是启发式的;但若还要证明“所有解都已找到”,则必须加入 Bézout 数、理想维数、群轨道计数或高度界。

Γ0(N)\Gamma_0(N) 正规化子的定义

Γ0(N)={(abcd)SL2(𝐙):c0(modN)}.\Gamma_0(N)= \left\{ \begin{pmatrix}a&b\\c&d\end{pmatrix}\in\operatorname{SL}_2(\mathbf Z): c\equiv0\pmod N \right\}.

它在 PGL2+(𝐑)\operatorname{PGL}_2^+(\mathbf R) 中的正规化子由满足 MΓ0(N)M1=Γ0(N)M\Gamma_0(N)M^{-1}=\Gamma_0(N) 的正行列式矩阵类组成。商

Norm(Γ0(N))/Γ0(N)\operatorname{Norm}(\Gamma_0(N))/\Gamma_0(N)

作用在 X0(N)X_0(N) 上。Atkin–Lehner 元素给出一个显著的初等 2-子群,但在某些 NN 上正规化子更大。

额外平移型元素

hh 的分母结构允许,矩阵

Sv=(11/v01)S_v= \begin{pmatrix}1&1/v\\0&1\end{pmatrix}

可在模标量意义下正规化 Γ0(N)\Gamma_0(N)。它在上半平面上作用为 ττ+1/v\tau\mapsto\tau+1/v,从而在 q=e2πiτq=e^{2\pi i\tau} 上作用为

qζvq.q\longmapsto\zeta_v q.

这直接解释 Hauptmodul qq-展开中的稀疏性。若经加常数后的 hh 在该作用下乘一个单位根,则只有某个模 vv 同余类的指数能出现。

例如 N=4N=4 时存在半平移 ττ+1/2\tau\mapsto\tau+1/2,使 qqq\mapsto-q。适当规范后 h+8h+8 变号,因此其展开只含奇次幂:

h=q18+20q62q3+216q5.h=q^{-1}-8+20q-62q^3+216q^5-\cdots.

N=9N=9 时三分之一平移使 qζ3qq\mapsto\zeta_3q,适当规范后 q(h+3)q(h+3)q3q^3 的幂级数:

h=q13+5q27q5+3q8+.h=q^{-1}-3+5q^2-7q^5+3q^8+\cdots.

N=25N=25 时五阶对称更微妙,但同样导致 h+1h+1 的系数只在指数 ±1(mod5)\pm1\pmod5 时出现。

额外元素与 Atkin–Lehner 的相互作用

正规化子商常由 Atkin–Lehner 对合与少数平移型元素生成。后者与 wQw_Q 共轭后可能得到另一平移或其逆,因此整体群通常是半直积而非Abelian 群。要识别关系,可在 PGL2+(𝐐)\operatorname{PGL}_2^+(\mathbf Q) 中直接相乘矩阵,并检查所得矩阵是否与某个 Γ0(N)\Gamma_0(N) 元素相差标量。

计算正规化子作用的可靠流程

  1. NN 分解为素幂,先列出全部单位因子 Atkin–Lehner 元素。
  2. 检查 2、3 的高次幂是否允许额外平移型正规化子;这些是非 Atkin–Lehner 现象的主要来源。
  3. 为每个候选矩阵验证 MΓ0(N)M1=Γ0(N)M\Gamma_0(N)M^{-1}=\Gamma_0(N),不能只检查有限个随机元素。
  4. 计算候选元在尖点上的置换、尖点宽度以及椭圆点上的作用。
  5. 在权 2 尖形式空间上计算拉回,得到有限维矩阵表示;其迹和特征空间可用于验证群关系。
  6. X0(N)X_0(N) 亏格 0,求 Hauptmodul 的 Möbius 变换 h(Mτ)=ah+bch+dh(M\tau)=\frac{ah+b}{ch+d};若亏格 1 或更高,则在曲线模型上恢复自同构。

qq-展开恢复 Möbius 作用

亏格 0 时,一个自同构必是 hh 的 Möbius 变换。计算 h(Mτ)h(M\tau) 的若干 qq-项,与

ah+bch+d\frac{ah+b}{ch+d}

比较即可解出 (a:b:c:d)(a:b:c:d)。若已知它如何置换三个或更多特殊尖点,通常无需长展开即可唯一确定。恢复后应代入 j(h)j(h),核对

j(Mτ)=j(h(Mτ))j(M\tau)=j(h(M\tau))

以及它在模问题上应满足的同源解释。

商曲线与函数域

给定有限正规化子子群 HH,商曲线函数域是

𝐂(X0(N))H.\mathbf C(X_0(N))^H.

亏格 0 时可通过轨道和、轨道积或低次数不变量找生成元;更高亏格可在典范微分空间中取 HH-不变子空间,再恢复商曲线模型。Riemann–Hurwitz 要求准确计算每个非平凡元素的固定点,而这些固定点通常是尖点或 CM 点。

完整显式计算的最终核验表

从模形式 qq-展开得到曲线与映射后,应依次核验:曲线光滑且亏格正确;jj-函数的次数等于群指数;零点、极点及 j1728j-1728 零点的重数与单值循环型相符;正规化子生成元满足群关系;它们对 jj 或相应退化映射的作用符合模解释;所有公式在足够高的 qq-阶验证后,再用函数域中的精确代数关系证明。这样,数值展开、群论数据与代数几何模型形成闭环。

正规化子为何可能超过 Atkin–Lehner 群

Atkin–Lehner 元素来自 exact divisors,主要反映同源的局部分解。当 NN 含较高的 2 或 3 次幂时,尖点宽度允许额外分数平移或更一般矩阵仍把 Γ0(N)\Gamma_0(N) 共轭到自身。这些元素可能有阶 3、4、6,因而正规化子商不再是初等 2-群。

分数平移的共轭计算

Sv=(11/v01).S_v= \begin{pmatrix}1&1/v\\0&1\end{pmatrix}.

γ=(abNcd)Γ0(N)\gamma=\left(\begin{smallmatrix}a&b\\Nc&d\end{smallmatrix}\right)\in\Gamma_0(N),直接展开 SvγSv1S_v\gamma S_v^{-1};要求所得矩阵在模标量后仍有整数项且左下角被 NN 整除。这给出 vvNN 的整除条件。实际表述因工作在 PSL2\operatorname{PSL}_2PGL2+\operatorname{PGL}_2^+ 或允许有理标量而略有差异,所以应以共轭计算为准,不可只记口诀。

q 展开中的特征空间

SvS_v 作用为 qζvqq\mapsto\zeta_v q,一个局部函数

f(q)=nanqnf(q)=\sum_{n\gg-\infty}a_nq^n

满足 f|Sv=ζvrff|S_v=\zeta_v^r f,则只有 nr(modv)n\equiv r\pmod v 的系数可非零。若函数还含常数平移,应先减去固定点或常数项再分解为特征向量。课程中的“只出现奇次幂”或“指数落在某一模 3 类”正是这个线性表示事实。

从稀疏展开反推自同构

观察到稀疏并不足以证明存在正规化子元素,因为偶然组合也可能消去许多系数。可靠做法是:由候选同余类猜测 vv;构造矩阵 SvS_v 并验证其正规化条件;计算它对 Hauptmodul 的 Möbius 变换;最后用足够高阶 qq-展开或函数域恒等式证明。若只知道一个生成函数的作用,还须确认它在整个函数域上定义自同构。

正规化子作用于尖点

矩阵元素置换 Γ0(N)𝐏1(𝐐)\Gamma_0(N)\backslash\mathbf P^1(\mathbf Q) 的尖点,并保持尖点宽度的适当比例。先计算这项置换,可快速排除不可能的候选。若某元素固定无穷远尖点,它在局部参数上必为 qζqq\mapsto\zeta q;若交换两个尖点,则通常把 qq 与另一尖点的局部参数互换,并可能出现幂次缩放。

对高亏格模型的自同构恢复

对非超椭圆曲线,任意自同构线性作用于 H0(KC)H^0(K_C),因而由典范空间中的射影线性变换表示。先从模形式上求正规化子对权 2 尖形式的矩阵,再作用于典范坐标,就得到模型上的候选自同构。只需检查其保持典范理想。对超椭圆曲线,还要分别处理超椭圆对合与商 𝐏1\mathbf P^1 上的 Möbius 变换。

自同构群与正规化子商不总相等

正规化子给出模解释兼容的自同构,但低亏格曲线可能拥有额外“偶然”自同构,未必来自 PGL2+(𝐑)\operatorname{PGL}_2^+(\mathbf R) 中的正规化子。反之,在叠的层面存在的矩阵作用可能在粗曲线上变为同一自同构。要判断全部自同构群,应独立计算曲线模型的自同构并比较其对尖点、jj-映射和 Hecke 对应的作用。

Newman 型结构结论的使用方式

经典正规化子定理把元素分解为 Atkin–Lehner 部分与由级数的 2、3 次幂部分产生的少量平移型生成元。不同文献对 hhvv、矩阵标量和例外级数的记号不同。应用时应先把 NN 写成局部素幂,逐素检查条件,再在具体群中计算关系和阶;不要把“通常由某些元素生成”误当作所有级数统一无例外的直积公式。

群关系与商塔

求出生成元后,可通过其在函数域或尖点集合上的置换计算群表示,进而求关系。若 AA 是 Atkin–Lehner 子群、SS 是额外平移,常出现

Sv=1,wQSwQ1=SaS^v=1, \qquad w_QSw_Q^{-1}=S^a

之类半直积关系。对各子群取不变函数域,可构造

X0(N)X0(N)/H1X0(N)/H2X_0(N)\longrightarrow X_0(N)/H_1\longrightarrow X_0(N)/H_2

的商塔;利用特征空间中的稀疏 qq-级数,往往能直接找到每一级的生成函数。

最终的可复用计算流程

处理一个新级数时,可依次完成:计算指数、尖点和亏格;构造权 2 尖形式及模型;列出 Atkin–Lehner 元素;按 2、3 部分检验额外正规化子候选;计算它们对 qq-展开与微分空间的作用;在曲线模型上实现矩阵;验证群关系;求固定点与商亏格;最后表达 j(τ)j(\tau)j(Nτ)j(N\tau) 和 Hauptmodul。这个闭环把群论、模形式、代数曲线与显式函数统一起来。

课程主题的汇合

正规化子章节把整门课的工具集中到同一问题:置换与单值群预测覆盖;Riemann–Hurwitz 控制亏格;qq-展开提供高精度近似;LLL 与有理重构恢复系数;结果式和 Gröbner 基验证函数关系;低亏格模型给出显式曲线;反射群与不变量论解释高度对称的参数;最终以精确代入、除子和群作用完成认证。计算技术的目标不是替代理论,而是把理论预言转化为可核验的显式对象。

计算专题:完整自同构群与函数域商

正规化子元素对模曲线函数的作用可从 slash 算子求得。对权 0 函数直接复合分式线性变换;对权 2 微分要乘 (cτ+d)2(c\tau+d)^{-2} 因子。数值 q 展开可猜矩阵,精确证明则比较到 Sturm 界或在 modular symbols 表示中直接计算。

若额外元素固定一个尖点并在局部参数上乘单位根,函数域按特征标分次。乘法使特征标指数相加,故不变子域由特征标指数和为 0 的乘积生成。选择最小极点阶的特征函数,可系统构造循环商而非靠观察稀疏级数猜 Hauptmodul。

当元素交换尖点时,可在两个尖点的局部展开之间建立变换矩阵。Fricke 对合典型地把无穷远与 0 交换;函数 h+A/hh+A/h 不变、hA/hh-A/h 反变。更高阶正规化子会产生次数 3 或 4 的轨道对称多项式。

计算曲线全部自同构群可使用典范理想稳定子:求 PGLg\operatorname{PGL}_g 中保持理想的有限解。为降低方程规模,先利用曲线上的特殊点集,如尖点、jj-分歧点或 Weierstrass 点,得到有限置换表示;再从允许置换中恢复射影矩阵。

比较自同构与正规化子时,检查它是否保持 jj-对应或把 j(τ),j(Nτ)j(\tau),j(N\tau) 作允许置换。一个不保持模对应的曲线自同构虽几何存在,却没有同样的模解释。相反,Hecke 对应通常不是自同构,而是多值代数对应,也不能混入正规化子。

所有商曲线的函数域次数应等于群阶除以一般稳定子。分歧指数由点稳定子阶给出;将固定点数据代入 Riemann–Hurwitz可验证商亏格。若群关系、函数域次数与亏格三者一致,通常已形成强认证闭环。

深入补充:从候选矩阵到函数域自同构的完整认证

在高亏格模型上,数值或 qq-展开常先给出一个候选射影矩阵 APGLgA\in\operatorname{PGL}_g。要证明它来自曲线自同构,不能只检查若干采样点;应在坐标环或函数域中做精确认证。

判据 典范模型上的自同构认证

设非超椭圆曲线 C𝐏g1C\subset\mathbf P^{g-1} 的齐次理想为 ICI_C。射影矩阵 AA 定义 CC 的自同构,当且仅当

A*(IC)=IC.A^*(I_C)=I_C.

实际只需对一组理想生成元 FjF_j 检查 Fj(Ax)F_j(Ax) 约化模 Gröbner 基后为零,并对 A1A^{-1} 做同样检查;若已知 AA 可逆且维数、次数不变,单向包含也可推出相等。

这一步完全在定义域中进行。若矩阵系数属于数域,还要验证 Galois 共轭如何作用;一个只在某个复嵌入下近似保持曲线的矩阵,未必在数域上有意义。

函数域表示更适合商计算。设

K(C)=K(x1,,xm)/(R1,,Rs),K(C)=K(x_1,\ldots,x_m)/(R_1,\ldots,R_s),

候选自同构给出 xiϕi(x)x_i\mapsto\phi_i(x)。认证包含三步:把每个关系 Rj(ϕ)R_j(\phi) 约化为零;检查生成的子域仍为整个函数域,可通过构造逆映射或比较扩张次数;验证群关系,如 ϕn=1\phi^n=1ϕψ=ψϕ\phi\psi=\psi\phi

算法 计算有限群作用的商函数域

对群 GG 选择若干低极点阶函数 ff,计算轨道和、轨道积或 Reynolds 平均

TrG(f)=gGg(f),NmG(f)=gGg(f).\operatorname{Tr}_G(f)=\sum_{g\in G}g(f), \qquad \operatorname{Nm}_G(f)=\prod_{g\in G}g(f).

逐步寻找不变量 u1,u2,u_1,u_2,\ldots,直到

[K(C):K(u1,u2,)]=|G|.[K(C):K(u_1,u_2,\ldots)]=|G|.

随后消元得到不变量之间的关系。次数等式证明所取不变量已经生成固定域,无须枚举所有有理函数。

正规化子给出的群只保证注入到模曲线自同构群;在低级数或特殊高亏格模型中,可能存在不来自上半平面正规化子的例外自同构。要证明群完整,可计算典范理想的射影稳定子:设一般矩阵变量 AA,要求 A*IC=ICA^*I_C=I_C,得到零维多项式系统;其解数与候选群阶比较。也可利用曲线的特殊除子、cusp 集合或 jj-映射分支纤维,把自同构嵌入一个有限置换群,再由稳定子计算上界。

上界 保持 Belyi 映射的自同构

若自同构必须保持给定映射 f:C𝐏1f:C\to\mathbf P^1,则它作用于一个非分支纤维并嵌入单值群中心化子。因此

|Aut𝐏1(C)||CSd(Gf)|.|\operatorname{Aut}_{\mathbf P^1}(C)|\le |C_{S_d}(G_f)|.

当已构造的自同构达到这个上界时,覆盖自同构群即已完整确定。

最终的群证书应包含:精确矩阵或函数替换;每个生成元保持理想的余数为零;生成元关系;群阶的 Schreier–Sims 或 Todd–Coxeter 证明;对 cusp、椭圆点和分支纤维的置换;以及商曲线函数域的次数核对。这样从 qq-展开猜出的变换才真正成为代数曲线上的已证明自同构。

补充计算:正规化子认证、函数域自同构恢复与尖点作用

定理 Fricke 对合的正规化与函数域固定子域

令 \[ W_N=\begin{pmatrix}0&-1\\ N&0\end{pmatrix}. \] 则 \[ W_N\Gamma_0(N)W_N^{-1}=\Gamma_0(N), \] 故 \(W_N\)\(X_0(N)\) 上诱导对合。若 \[ t(\tau)=\left(\frac{\eta(\tau)}{\eta(2\tau)}\right)^{24}, \] 则在 \(X_0(2)\) 上 \[ W_2:t\longmapsto \frac{2^{12}}{t}. \] 其固定子域为 \[ \mathbf C(t)^{\langle W_2\rangle} =\mathbf C\!\left(t+\frac{4096}{t}\right), \] 且 t 在该固定子域上的最小方程为 \[ T^2-uT+4096=0,\qquad u=t+\frac{4096}{t}. \] 分歧值为 \(u=\pm128\)

证明 矩阵共轭、η 变换公式与二次固定域

对 \[ \gamma=\begin{pmatrix}a&b\\ Nc&d\end{pmatrix}\in\Gamma_0(N) \] 直接计算得 \[ W_N\gamma W_N^{-1} =\begin{pmatrix}d&-c\\ -Nb&a\end{pmatrix}\in\Gamma_0(N). \] 反向包含关系由 \(W_N^{-1}\) 同样得到,故确为正规化子元素。

由 Dedekind η 函数的变换公式 \[ \eta(-1/\tau)=(-i\tau)^{1/2}\eta(\tau) \] 分别作用于 \(\tau\)\(2\tau\),得到 \[ t\!\left(-\frac1{2\tau}\right)=\frac{2^{12}}{t(\tau)}. \] 令 \(u=t+4096/t\),则 u 在该对合下不变,且 \(t^2-ut+4096=0\),故扩张次数至多为 2。对合非平凡,扩张次数恰为 2,所以固定域就是 \(\mathbf C(u)\)。方程判别式为 \(u^2-4\cdot4096=(u-128)(u+128)\),其零点即二重覆盖的分歧值。

Python 有理 Möbius 变换重构、群闭包、共轭审计与尖点轨道
from dataclasses import dataclass
from fractions import Fraction
from math import gcd, lcm
import sympy as sp

INF = None

def matmul(A,B):
    return tuple(tuple(sum(A[i][k]*B[k][j] for k in range(2))
                       for j in range(2)) for i in range(2))

def det(A):
    return A[0][0]*A[1][1]-A[0][1]*A[1][0]

def inv2(A):
    d=det(A)
    return ((Fraction(A[1][1],d),Fraction(-A[0][1],d)),
            (Fraction(-A[1][0],d),Fraction(A[0][0],d)))

def normalize_projective(A):
    entries=[Fraction(x) for row in A for x in row]
    L=1
    for x in entries:
        L=lcm(L,x.denominator)
    ints=[int(x*L) for x in entries]
    g=0
    for x in ints:g=gcd(g,abs(x))
    ints=[x//g for x in ints]
    for x in ints:
        if x:
            if x<0:ints=[-y for y in ints]
            break
    return ((ints[0],ints[1]),(ints[2],ints[3]))

@dataclass(frozen=True)
class Mobius:
    a:int
    b:int
    c:int
    d:int

    @staticmethod
    def from_matrix(A):
        B=normalize_projective(A)
        return Mobius(B[0][0],B[0][1],B[1][0],B[1][1])

    def matrix(self):
        return ((self.a,self.b),(self.c,self.d))

    def __call__(self,x):
        if x is INF:
            return INF if self.c==0 else Fraction(self.a,self.c)
        x=Fraction(x)
        den=self.c*x+self.d
        return INF if den==0 else (self.a*x+self.b)/den

    def compose(self,other):
        return Mobius.from_matrix(matmul(self.matrix(),other.matrix()))

    def inverse(self):
        return Mobius.from_matrix(((self.d,-self.b),(-self.c,self.a)))

    def is_identity(self):
        return self==Mobius(1,0,0,1)

def fit_mobius(pairs):
    rows=[]
    for x,y in pairs:
        x,y=Fraction(x),Fraction(y)
        rows.append([x,1,-x*y,-y])
    M=sp.Matrix(rows)
    ns=M.nullspace()
    if len(ns)!=1:
        raise ValueError("data do not determine one projective map")
    v=ns[0]
    A=((Fraction(v[0]),Fraction(v[1])),
       (Fraction(v[2]),Fraction(v[3])))
    f=Mobius.from_matrix(A)
    if any(f(x)!=Fraction(y) for x,y in pairs):
        raise ArithmeticError("exact verification failed")
    return f

def closure(generators):
    identity=Mobius(1,0,0,1)
    G={identity}
    frontier=[identity]
    while frontier:
        g=frontier.pop()
        for h in generators:
            for k in (g.compose(h),h.compose(g)):
                if k not in G:
                    G.add(k);frontier.append(k)
    return sorted(G,key=lambda z:(z.a,z.b,z.c,z.d))

def gamma0_samples(N,bound=5):
    ans=set()
    for a in range(-bound,bound+1):
        for b in range(-bound,bound+1):
            for k in range(-bound,bound+1):
                c=N*k
                if a==0:continue
                num=1+b*c
                if num%a:continue
                d=num//a
                if abs(d)<=2*bound:
                    ans.add(((a,b),(c,d)))
    return sorted(ans)

def conjugate(A,G):
    return matmul(matmul(A,G),inv2(A))

def in_gamma0_projectively(B,N):
    C=normalize_projective(B)
    if det(C)!=1:
        return False
    return C[1][0]%N==0

def normalizer_audit(N,A,bound=5):
    samples=gamma0_samples(N,bound)
    bad=[]
    for G in samples:
        H=conjugate(A,G)
        if not in_gamma0_projectively(H,N):
            bad.append((G,H))
    return len(samples),bad

def cusp_string(x):
    if x is INF:return "infinity"
    return str(x)

print("exact reconstruction of the Fricke action on t=(eta(tau)/eta(2tau))^24")
pairs=[(Fraction(1),Fraction(4096)),
       (Fraction(2),Fraction(2048)),
       (Fraction(4),Fraction(1024)),
       (Fraction(8),Fraction(512)),
       (Fraction(16),Fraction(256))]
w=fit_mobius(pairs)
print("  recovered matrix:",w.matrix())
print("  w^2:",w.compose(w).matrix(),"identity =",w.compose(w).is_identity())
print("  verification:",[(x,w(x)) for x,_ in pairs])

s=Mobius(-1,0,0,1)
G=closure([w,s])
print("\nclosure generated by t->4096/t and t->-t:")
for g in G:
    print(" ",g.matrix())
print("  order =",len(G))
print("  all element squares:",
      [g.compose(g).matrix() for g in G])

t,u=sp.symbols("t u")
relation=sp.expand(t**2-u*t+4096)
res=sp.factor(sp.resultant(relation,sp.diff(relation,t),t))
invariant=sp.factor(t+4096/t)
invariant4=sp.factor(t**2+4096**2/t**2)
print("\nfunction-field certificates:")
print("  fixed field generator under w: u =",invariant)
print("  minimal relation:",relation)
print("  discriminant/resultant:",res)
print("  invariant under the Klein four group:",invariant4)
for transform in [-t,4096/t,-4096/t]:
    print("   substitute",transform,"->",
          sp.factor(invariant4.subs(t,transform)-invariant4))

print("\nnormalizer audit for Fricke matrices W_N=[[0,-1],[N,0]]:")
for N in [2,3,5,6,10,14]:
    W=((0,-1),(N,0))
    count,bad=normalizer_audit(N,W,bound=6)
    print(f"  N={N:2d}: tested={count:3d}, failures={len(bad)}")

print("\ncusp action of W_N:")
cusps=[INF,Fraction(0),Fraction(1),Fraction(-1),
       Fraction(1,2),Fraction(2,3),Fraction(3,5)]
for N in [2,6,10]:
    W=Mobius.from_matrix(((0,-1),(N,0)))
    row=[f"{cusp_string(x)}->{cusp_string(W(x))}" for x in cusps]
    print(f"  N={N:2d}: "+"; ".join(row))

print("\nexact conjugation samples for N=6:")
W6=((0,-1),(6,0))
for G0 in gamma0_samples(6,3)[:6]:
    H=normalize_projective(conjugate(W6,G0))
    print(" ",G0," -> ",H,
          "det=",det(H),"lower-left mod 6=",H[1][0]%6)
运行结果 精确恢复矩阵、固定域关系、正规化测试与尖点像
exact reconstruction of the Fricke action on t=(eta(tau)/eta(2tau))^24
  recovered matrix: ((0, 4096), (1, 0))
  w^2: ((1, 0), (0, 1)) identity = True
  verification: [(Fraction(1, 1), Fraction(4096, 1)), (Fraction(2, 1), Fraction(2048, 1)), (Fraction(4, 1), Fraction(1024, 1)), (Fraction(8, 1), Fraction(512, 1)), (Fraction(16, 1), Fraction(256, 1))]

closure generated by t->4096/t and t->-t:
  ((0, 4096), (-1, 0))
  ((0, 4096), (1, 0))
  ((1, 0), (0, -1))
  ((1, 0), (0, 1))
  order = 4
  all element squares: [((1, 0), (0, 1)), ((1, 0), (0, 1)), ((1, 0), (0, 1)), ((1, 0), (0, 1))]

function-field certificates:
  fixed field generator under w: u = (t**2 + 4096)/t
  minimal relation: t**2 - t*u + 4096
  discriminant/resultant: -(u - 128)*(u + 128)
  invariant under the Klein four group: (t**4 + 16777216)/t**2
   substitute -t -> 0
   substitute 4096/t -> 0
   substitute -4096/t -> 0

normalizer audit for Fricke matrices W_N=[[0,-1],[N,0]]:
  N= 2: tested=246, failures=0
  N= 3: tested=222, failures=0
  N= 5: tested=174, failures=0
  N= 6: tested=102, failures=0
  N=10: tested= 70, failures=0
  N=14: tested= 78, failures=0

cusp action of W_N:
  N= 2: infinity->0; 0->infinity; 1->-1/2; -1->1/2; 1/2->-1; 2/3->-3/4; 3/5->-5/6
  N= 6: infinity->0; 0->infinity; 1->-1/6; -1->1/6; 1/2->-1/3; 2/3->-1/4; 3/5->-5/18
  N=10: infinity->0; 0->infinity; 1->-1/10; -1->1/10; 1/2->-1/5; 2/3->-3/20; 3/5->-1/6

exact conjugation samples for N=6:
  ((-1, -3), (0, -1))  ->  ((1, 0), (-18, 1)) det= 1 lower-left mod 6= 0
  ((-1, -2), (0, -1))  ->  ((1, 0), (-12, 1)) det= 1 lower-left mod 6= 0
  ((-1, -1), (0, -1))  ->  ((1, 0), (-6, 1)) det= 1 lower-left mod 6= 0
  ((-1, -1), (6, 5))  ->  ((5, -1), (6, -1)) det= 1 lower-left mod 6= 0
  ((-1, 0), (-18, -1))  ->  ((1, -3), (0, 1)) det= 1 lower-left mod 6= 0
  ((-1, 0), (-12, -1))  ->  ((1, -2), (0, 1)) det= 1 lower-left mod 6= 0
计算 有限数据恢复与代数恒等式认证

由五组精确数据 \[ 1\mapsto4096,\quad2\mapsto2048,\quad4\mapsto1024,\quad 8\mapsto512,\quad16\mapsto256 \] 建立齐次线性方程 \[ ax_i+b-y_i(cx_i+d)=0. \] 其一维零空间给出矩阵 \[ \begin{pmatrix}0&4096\\1&0\end{pmatrix}, \] 平方在射影意义下为单位矩阵。再与 t\mapsto-t 合成所得四个 Möbius 变换构成 Klein 四元群;函数 \[ t^2+\frac{4096^2}{t^2} \] 在四个元素下逐项代入均保持不变。程序还对多个 N 枚举数百个 \Gamma_0(N) 小高度矩阵,逐个精确共轭并检查行列式与左下角模 N 条件,所有测试均无失败。

参考文献与继续阅读

课程原网页之外,用于补足标准定义、经典定理和算法背景。

  1. J.-P. SerreTopics in Galois Theory。Belyi 覆盖、Galois 理论与置换方法。
  2. H. CohenA Course in Computational Algebraic Number Theory。有限域、格约化、代数数计算。
  3. A. K. Lenstra, H. W. Lenstra, L. LovászFactoring polynomials with rational coefficients。LLL 算法的经典来源。
  4. D. Cox, J. Little, D. O’SheaIdeals, Varieties, and Algorithms。Gröbner 基与消元。
  5. R. HartshorneAlgebraic Geometry。曲线、除子与 Riemann–Roch 的标准背景。
  6. J. SilvermanThe Arithmetic of Elliptic Curves。椭圆曲线、挠点、同源和 Tate 标准形。
  7. F. Diamond, J. ShurmanA First Course in Modular Forms。模曲线、模形式与 Hecke/Atkin–Lehner 算子。
  8. M. Schütt, T. ShiodaMordell–Weil Lattices。椭圆曲面与 Shioda excellent family。
  9. G. C. Shephard, J. A. ToddFinite unitary reflection groups。有限复反射群分类。
  10. C. ChevalleyInvariants of finite groups generated by reflections。反射群不变量环。
  11. F. KleinLectures on the Icosahedron。多面体群与二十面体不变量。

原始材料与可复用文件

压缩包内同时保留原课程网页、逐讲抽取文本与本页生成资产。