図:判別式のイメージ(ChatGPTによる)
判別式といえば,2次方程式の$ D = b^2 - 4 a c $ がすぐに思い浮かぶ。ところが,福井大学の木村欣司さんが,16次方程式とか17次方程式の判別式の計算について議論していた。判別式とは,方程式に重解が存在する条件(D=0)を与えるものだった。
調べてみると,$x$の$n$次方程式,$f(x) = a_n x^n + a_{n-1} x^{n-1} \cdots + a_0 = 0\ $の判別式は,$\displaystyle D_n = a_n^{2n -2} \ \prod_{i<j } (\alpha_i - \alpha_j)^2$ で定義される。ここで,$\alpha_i ( 1 \le i \le n )$ はこの$n$次方程式の解である。例えば,$D_2 = a_1^2- 4 a_0 a_2 = b^2 - 4 a c $である。
この判別式は,$f(x)$と $g(x)=f'(x)$ からつくるシルベスター行列の終結式になっているらしい。ま,そこのところはそんなものかということでスルーして,木村さんがスパコン計算で工夫した膨大な項数の判別式(n=17で,219億項,427GB)の一端を感じるために,Juliaのコードを作ってもらった。
ChatGPTとGeminiとClaudeを駆使したバイブコーディングの結果,途中でコードが膨らんで発散しそうになったが,リスタートを繰り返して,なんとか最終結果はマイルドなものになった。「プログラミング=エラーメッセージのコピペ作業」という新しい(しょうもない)パラダイムが展開している。彼らは,ポピュラーなPythonは得意だけれど,マイナーなJuliaはやや苦手なのかも知れない。
using Nemo
using Printf
# 判別式 Disc(f) を返す(a0..an の多項式)
function discriminant_poly(n::Int)
# 係数環 R = QQ[a0,...,an]
R, a = polynomial_ring(QQ, ["a$i" for i in 0:n])
# f は R[x]
S, x = polynomial_ring(R, "x")
f = zero(S)
@inbounds for i in 0:n
f += a[i+1] * x^i
end
g = derivative(f)
# res = Res_x(f, f')
t = @elapsed res = resultant(f, g)
# Disc(f) = (-1)^{n(n-1)/2} * Res(f,f') / a_n
an = a[n+1]
sgn = isodd(div(n*(n-1), 2)) ? -1 : 1
disc = (sgn * res) ÷ an # ここで割り切れる(理論上必ず)
return disc, res, t
end
for n in 2:10
disc, res, t = discriminant_poly(n)
nt = length(terms(disc))
@printf "n=%d : 判別式の項数=%d, 時間=%.4f秒\n" n nt t
# 画面に全部出すと巨大になるので、まずは n<=4 だけ表示などが安全
if n <= 4
println("Disc(f) = ")
println(disc)
println()
end
end
n=2 : 判別式の項数=2, 時間=0.0000秒
Disc(f) =
-4*a0*a2 + a1^2
n=3 : 判別式の項数=5, 時間=0.0000秒
Disc(f) =
-27*a0^2*a3^2 + 18*a0*a1*a2*a3 - 4*a0*a2^3 - 4*a1^3*a3 + a1^2*a2^2
n=4 : 判別式の項数=16, 時間=0.0000秒
Disc(f) =
256*a0^3*a4^3 - 192*a0^2*a1*a3*a4^2 - 128*a0^2*a2^2*a4^2 + 144*a0^2*a2*a3^2*a4 - 27*a0^2*a3^4 + 144*a0*a1^2*a2*a4^2 - 6*a0*a1^2*a3^2*a4 - 80*a0*a1*a2^2*a3*a4 + 18*a0*a1*a2*a3^3 + 16*a0*a2^4*a4 - 4*a0*a2^3*a3^2 - 27*a1^4*a4^2 + 18*a1^3*a2*a3*a4 - 4*a1^3*a3^3 - 4*a1^2*a2^3*a4 + a1^2*a2^2*a3^2
n=5 : 判別式の項数=59, 時間=0.0002秒
n=6 : 判別式の項数=246, 時間=0.0014秒
n=7 : 判別式の項数=1103, 時間=0.0200秒
n=8 : 判別式の項数=5247, 時間=0.5292秒
n=9 : 判別式の項数=26059, 時間=11.6190秒
n=10 : 判別式の項数=133881, 時間=340.8076秒
P. S. 最初のコードだと,n=6で108秒を越えていたのです。
P. P. S. $D_2, D_3$では,その正負で,実数解か虚数解を判定することができるが,$D_n (n \ge 4)$ではそこまではいえない。
0 件のコメント:
コメントを投稿