2026年3月14日土曜日

判別式(1)


図:判別式のイメージ(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 件のコメント: