前記事での「退職後は素人数学者」さんからの報告により、方程式 \(x^{3}-2=0\) については「退職後は素人数学者」さんのプログラムと jurupapa さんのプログラムでは結果が異なり、
「退職後は素人数学者」さんは解が出たが、それは不適な解も含んだものになった
jurupapa さんは計算の途中で \(0\) による割り算が発生し、エラーで手続きが停止する
ということになっています。
不可解なのは、同じアルゴリズムに従っているはずの2つのプログラムの動作がなぜか異なっていたことでしたが、おおよその事情がわかってきたので報告します。これまでの検討から、\(x^{3}-2=0\) を解く際の一連の異常には
べき根の選び方の不定性によって、\(0\) になる可能性も、ならない可能性もあるような式
が深く関わっていることがわかってきました(ここで、「べき根の選び方の不定性」というのは、\(1\) の原始 \(p\) 乗根の具体的な表式に含まれるべき根に関するものも含んでおり、\(1\) の原始 \(p\) 乗根の \(p-1\) 通りの不定性も包含したものとする)。実は、「退職後は素人数学者」さんの元記事「可解な代数方程式のガロア理論に基づいた解法」の第11節の、拡大体での商の計算(「分母の有理化」)のアルゴリズム(以下、アルゴリズム A とします)は、このような「べき根の不定性によって、\(0\) になる可能性がある式」が分母にある時はうまく行かない時があることがわかりました。おそらくこれが一連の問題の根っこにあります。
以下説明します。なお、「退職後は素人数学者」さん・jurupapa さんともに、途中で現れるべき根を表す記号として「\(\alpha\)」を使っていますが、私の一連の記事では \(\alpha\) は「元の方程式の解」を表す記号に使ってきたので、今さらながら、本記事ではべき根の記号には \(r\) を使います。すみません。
\(x^{3}-2=0\) を解く過程で現れる \(-3\) の平方根を \(r\)、\(1\) の原始立方根を \(\omega\) とします。
\begin{align}
\label{eq:galois-sol6-1}
r^{2}+3 &=0 \\
\label{eq:galois-sol6-2}
\omega^{2}+\omega+1 &=0
\end{align}
このとき、\(2\omega+1+r\) と \(2\omega+1-r\) は一方が \(0\) になり、もう一方は非 \(0\) になります。どちらが \(0\) になるかは、条件\eqref{eq:galois-sol6-1}, \eqref{eq:galois-sol6-2}が与えられただけでは決定しません。\eqref{eq:galois-sol6-1}, \eqref{eq:galois-sol6-2}をみたす \(r\) の選び方、\(\omega\) の選び方はどちらも \(2\) 通りずつあり(べき根の不定性)、その選び方に応じてどちらが \(0\) になるかが決まります。
今、そのうち一方を分母とする式
\begin{equation}
\label{eq:galois-sol6-4}
\dfrac{1}{2\omega+1+r}
\end{equation}
を考えます。べき根の選び方によっては、これは \(\text{分母}=0\) になる不正な式ですが、別の選び方に対してはちゃんとまともな値を持つ式です。
\eqref{eq:galois-sol6-4}に対してアルゴリズム A を適用してみると、興味深い現象が起こります。まず、\eqref{eq:galois-sol6-2}を使って分母から \(\omega\) を追い出します——つまり、\(\omega\) の有理式を \(\omega\) の多項式に直します。
\begin{equation}
\label{eq:galois-sol6-3}
\frac{1}{2\omega+1+r} = a\omega + b
\end{equation}
とおき(\(a\), \(b\) は未知数)、分母を払うと
\begin{align*}
1 &= (2\omega+1+r)(a\omega+b) \\
&= 2a\omega^{2} + (2b+(1+r)a)\omega + (1+r)b \\
&= -2a(\omega+1) + (2b+(1+r)a)\omega + (1+r)b \quad (\because
\eqref{eq:galois-sol6-2}) \\
&= (2b+(r-1)a)\omega -2a + (r+1)b
\end{align*}
です。両辺を \(\omega\) の多項式と見なして係数比較を行うと
\begin{gather}
\begin{cases}
(r-1)a+2b &= 0 \\
-2a+(r+1)b &= 1
\end{cases} \notag\\
\label{eq:galois-sol6-5}
\therefore
\begin{pmatrix}
r-1 & 2 \\
-2 & r+1
\end{pmatrix}
\begin{pmatrix}
a \\ b
\end{pmatrix}
=
\begin{pmatrix}
0 \\ 1
\end{pmatrix}
\end{gather}
となります。これを \(a\), \(b\) の連立方程式として解きたいわけですが、左辺の係数行列の行列式は
\[ \det \begin{pmatrix}
r-1 & 2 \\
-2 & r+1
\end{pmatrix}
= (r-1)(r+1)-2\cdot(-2) = r^{2}+3 \]
で、\eqref{eq:galois-sol6-1}によってこれは \(0\) になります。つまりこの連立1次方程式は解けません。詳しい計算は省略しますが、\eqref{eq:galois-sol6-1}のもとでは\eqref{eq:galois-sol6-5}は解なしです。
もちろん、もともとの式\eqref{eq:galois-sol6-4}の分母が \(0\) になるような \(r\), \(\omega\) の選び方に対してこういった破綻が起きることは問題ありません。もともと不正な式が、あたかもまともな値を持つかのように \eqref{eq:galois-sol6-3}と置いて式変形を行ったのですから、結果として矛盾が現れるのはまったく不思議ではありません。しかし、この結果が \(r\), \(\omega\) の選び方によらなかった点に注目してください。\(\text{分母}=0\) にならないような、正当な \(r\), \(\omega\) に対してさえ、上の計算は頓挫してしまったのです。
わかったことをまとめます。
べき根の選び方の不定性によって \(0\) になる可能性がある分母を持つ式に対して、アルゴリズム A は分母が \(0\) にならない場合まで破綻する(そのような例が、少なくとも1つあることがわかった)。
これが、jurupapa さんのプログラムが \(0\) 割りで中断してしまう原因だと私は見ています。数式処理ソフトになったつもりになって、\eqref{eq:galois-sol6-5}以降の計算を続行し、\(0\) による割り算が発生する所まで追ってみましょう。
まず、\eqref{eq:galois-sol6-5}の段階では数式処理ソフトはまだ\eqref{eq:galois-sol6-1}のことは「知らない」わけですから、\(r\) は単なる文字(不定元)に過ぎず、この連立1次方程式を「分母が \(r^{2}+3\) という文字式であるような式」を使って解いてしまうはずです。
\begin{align*}
\begin{pmatrix}
a \\ b
\end{pmatrix}
&=
\begin{pmatrix}
r-1 & 2 \\
-2 & r+1
\end{pmatrix}^{-1}
\begin{pmatrix}
0 \\ 1
\end{pmatrix} \\
&= \frac{1}{r^{2}+3}
\begin{pmatrix}
r+1 & -2 \\
2 & r-1
\end{pmatrix}
\begin{pmatrix}
0 \\ 1
\end{pmatrix} = \frac{1}{r^{2}+3}
\begin{pmatrix}
-2 \\ r-1
\end{pmatrix}
\end{align*}
よって、\eqref{eq:galois-sol6-3}から
\[ \frac{1}{2\omega+1+r} = \frac{-2\omega+r-1}{r^{2}+3} \]
となります。
続いて数式処理ソフトがやることは、\eqref{eq:galois-sol6-1}を使ってこの \(r\) の有理式を \(r\) の多項式に直すことです。
\[ \frac{-2\omega+r-1}{r^{2}+3} = cr +d \]
(\(c\), \(d\) は未知数)と置いて分母を払うと
\[ -2\omega + r -1 = (r^{2}+3)(cr+d) \]
となり、ここで\eqref{eq:galois-sol6-1}を使って \(r\) の次数を下げると……右辺は当然 \(0\)、すなわち
\[ -2\omega + r -1 = 0cr + 0d \]
です。両辺を \(r\) の \(1\) 次式と見なして係数比較をすると
\[
\begin{cases}
0c &= 1 \\
0d &= -2\omega -1
\end{cases}
\]
となって、ここで \(c\), \(d\) を求めようとすると \(0\) による割り算をするしかなくなり、お手上げという事態に陥ります。
なお、実際に jurupapa さんのプログラムを見てみると、\(0\) 割りのエラーを発しているのは少し手前の段階のようです。ファイル ExtendedField.mac
中の関数 ef_divide(P,Q,C)
中に
while ef_polynomial_reduction(Q,[CT])=0 do ( if ef_polynomial_reduction(P,[CT])=0 then ( exp:ratsimp(P/Q), [P,Q]:[num(exp),denom(exp)],return()) else ( error("ef_divide:Division by zero 2: P=",ef_polynomial_reduction(P,[CT]),"Q=",Q,"CT=",CT))),
という個所があり、\(\dfrac{-2\omega+r-1}{r^{2}+3}\) という分数形が得られた段階で、分母・分子をそれぞれ\eqref{eq:galois-sol6-1}で簡約化し、分母が \(0\) になるのに分子が \(0\) にならない、ということを検知してエラーを出しているのだと思います。
さて、これで \(0\) 割りで行き詰まる事情は見当がつきましたが、それではなぜ「退職後は素人数学者」さんのプログラムはそういう困難に出くわさずに解を出すことに成功しているのでしょうか。また、その際不適な解が排除できずに紛れ込んでしまうのはどうしてなのでしょうか。
それを探るために、アルゴリズム A の手計算をもう1例見てみます。今度は、同じ分母の
\begin{equation}
\label{eq:galois-sol6-6}
\frac{r(2\omega+1)-3}{2\omega+1+r}
\end{equation}
という式を考えます。この分子は、よく見ると分母に \(r\) をかけただけのものです。したがって、正しく処理できれば、最終的には
\begin{equation}
\label{eq:galois-sol6-7}
\frac{r(2\omega+1)-3}{2\omega+1+r} =
\begin{cases}
r & (\text{\(2\omega+1+r \ne 0\) のとき}) \\
\text{求値不可(\(\frac{0}{0}\)型)} & (\text{\(2\omega+1+r=0\) のとき})
\end{cases}
\end{equation}
という結果が出なければいけません。
では、アルゴリズム A を実行してみましょう。まず\eqref{eq:galois-sol6-2}を使って \(\omega\) の有理式を \(\omega\) の多項式に変形するため、
\[ \frac{r(2\omega+1)-3}{2\omega+1+r} = a\omega +b \]
と置きます。分母を払い、先ほどの計算を参照すると
\begin{align*}
r(2\omega+1)-3 &= (2\omega+1+r)(a\omega+b) \\
\therefore 2r\omega + r-3 &= (2b+(r-1)a)\omega -2a + (r+1)b
\end{align*}
となります。したがって、今度は \(a\), \(b\) に対する方程式は
\begin{gather}
\begin{cases}
(r-1)a+2b &= 2r \\
-2a+(r+1)b &= r-3
\end{cases} \notag\\
\label{eq:galois-sol6-8}
\therefore
\begin{pmatrix}
r-1 & 2 \\
-2 & r+1
\end{pmatrix}
\begin{pmatrix}
a \\ b
\end{pmatrix}
=
\begin{pmatrix}
2r \\ r-3
\end{pmatrix}
\end{gather}
となります。
この左辺の係数行列は\eqref{eq:galois-sol6-5}と同じなので、行列式は今度も \(r^{2}+3=0\) となって解けません。(ただし、\eqref{eq:galois-sol6-5}が\eqref{eq:galois-sol6-1}のもとでは解なしだったのに対し、\eqref{eq:galois-sol6-8}は\eqref{eq:galois-sol6-1}のもとで任意パラメータを含む不定解を持ちます。実はそれを使うとちゃんと\eqref{eq:galois-sol6-7}が再現されるのですが、それはここでの本題からずれてしまうので詳細は省略します)
ここで、やはり数式処理ソフトになったつもりで\eqref{eq:galois-sol6-8}以降の処理を強引に進めてみると、またも興味深い現象が起こります。
\begin{equation}
\label{eq:galois-sol6-10}
\begin{pmatrix}
a \\ b
\end{pmatrix}
= \frac{1}{r^{2}+3}
\begin{pmatrix}
r+1 & -2 \\
2 & r-1
\end{pmatrix}
\begin{pmatrix}
2r \\ r-3
\end{pmatrix}
= \frac{1}{r^{2}+3}
\begin{pmatrix}
2(r^{2}+3) \\ r^{2}+3
\end{pmatrix}
\end{equation}
数式処理ソフトならば、\eqref{eq:galois-sol6-1}を知らない段階でこの式に出会ったら、\(r^{2}+3\) を約分してこういう結論を出すでしょう。
\begin{equation}
\label{eq:galois-sol6-11}
\begin{pmatrix}
a \\b
\end{pmatrix} =
\begin{pmatrix}
2 \\ 1
\end{pmatrix}
\end{equation}
つまり、数式処理ソフトが出力する\eqref{eq:galois-sol6-6}の値はこうです。
\begin{equation}
\label{eq:galois-sol6-9}
\frac{r(2\omega+1)-3}{2\omega+1+r} = 2\omega + 1
\end{equation}
これは、\(2\omega+1+r \ne 0\) の場合は確かに正しい結果\eqref{eq:galois-sol6-7}と一致します(\(2\omega+1 \pm r\) は、一方が \(0\) でもう一方が \(\ne 0\) だから、\(2\omega+1+r \ne 0\) だったら必然的に \(2\omega+1 -r =0\) なので)。
というわけで、本来ならば\eqref{eq:galois-sol6-7}のように場合分けが必要な\eqref{eq:galois-sol6-6}が、数式処理ソフトの手にかかるとあたかも確定した値を持つかのように\eqref{eq:galois-sol6-9}と出力されてしまうわけです。
結果をまとめます。
べき根の選び方の不定性によって \(0\) になる可能性がある分母を持つ式に対して、数式処理ソフトでアルゴリズム A を実行すると、\(\text{分母}=0\) の場合まで \(\text{分母} \ne 0\) の場合と同一の値を出力してしまう(そのような例が、少なくとも1つあることがわかった)。
これが、「退職後は素人数学者」さんのプログラムで起こっている現象だと私は推測しています。jurupapa さんのプログラムと、「退職後は素人数学者」さんのプログラムから、関連する部分を抜粋します。
jurupapa さん:
ファイル Stage3.mac
中の関数 Stage(nsg1,nsg2,gv,vncond,C,AC)
temp:ratexpand(ef_polynomial_reduction(remainder(temp^p1,gv),C)), A[i]:coeff(temp,x,hipow(temp,x)), ... if temp-A[i]=0 then [Q[i],q[i]]:[1,1] else ( Q[i]:ratexpand(ef_mult(temp,ef_divide(1,A[i],C),C))
「退職後は素人数学者」さん:
修正後のプログラム
bi=FracToPoly[ReductionOfAlpha[PolynomialRemainder[ Expand[al^(p-i)*ai],gx/.x->v,v]]/A1];
jurupapa さんは、temp
(\((\theta_{i}(x))^{p}\)) を A[i]
(\((\theta_{i}(x))^{p}\) の最高次係数)で割る際に、いったん ef_devide
で A[i]
の逆数を求めてから、ef_mult
でそれと temp
の積を取るという手順に分割しています。前半の「逆数を求める」計算が \(\dfrac{1}{2\omega+1+r}\) の計算に相当しているのでしょう。つまり、ここで \(0\) 割りのエラーで処理が中断します。
一方、「退職後は素人数学者」さんはそのように計算手順を分割することなく、直接 \(\dfrac{{a_{1}}^{p-i} a_{i}}{A_{1}}\) を計算しています。これが、\(\dfrac{r(2\omega+1)-3}{2\omega+1+r}\) の計算に相当するのでしょう。つまり、何ごともなかったかのように計算が進行し、「\(\text{分母} \ne 0\) の場合の値」が求まっている。ただし、本来なら除外しなければならなかった \(\text{分母} = 0\) の場合が排除できていないため、不適な解を内包する結果が出てきてしまっている。
なお、以上の観測からは、jurupapa さんのプログラムでも計算手順を分割せず、直接割り算を実行すれば \(0\) 割りのエラーは回避されそうな気がしますが、そこはちょっと複雑な事情になっているようです。上記抜粋部の最後を
Q[i]:ratexpand(ef_divide(temp,A[i],C)),
に変更しただけでは、\(0\) 割りのエラーは消えませんでした。その変更に加え、ファイル ExtendedField.mac
中の関数 ef_divide(P,Q,C)
を、コメントアウトされているバージョン(「退職後は素人数学者」さんのプログラムにより処理を近づけたもの)に入れ替えるとエラーは出なくなり、\(x^{3}-2=0\) を解いた結果が「退職後は素人数学者」さんのものと一致しました(gal_phi(xlist)
も変更して、\(x_{1}\), \(x_{2}\), \(x_{3}\) の係数は \(1\), \(2\), \(3\) にしてあります)。この場合、数値計算による \(x_{1}\), \(x_{2}\), \(x_{3}\) の値が \(0\), \(0\), \(0\) となり、不適な解を含んでしまっている所も(当然ながら)一致しています。※ 今気づきましたが、関数 ef_divide(P,Q,C)
については、丸ごと入れ替えるのではなく、元の関数のままで
while ef_polynomial_reduction(Q,[CT])=0 do ( if ef_polynomial_reduction(P,[CT])=0 then ( exp:ratsimp(P/Q), [P,Q]:[num(exp),denom(exp)],return()) else ( error("ef_divide:Division by zero 2: P=",ef_polynomial_reduction(P,[CT]),"Q=",Q,"CT=",CT))),
の部分をコメントアウトするだけでも同じ結果になりました。「分母が \(0\) になっちゃうが分子が形式上 \(0\) にならない」ことを気にせず計算を続行する、という雑なことをすると、結果としてもっともらしい値が出てくるようです。
逆に、「退職後は素人数学者」さんのプログラムでも、 \(\dfrac{{a_{1}}^{p-i} a_{i}}{A_{1}}\) を計算する際に「まず \(A_{1}\) の逆数を求め、それと \({a_{1}}^{p-i} a_{i}\) の積を求める」という手順に分割すると、前半の逆数計算で \(0\) 割りによるエラーで計算が中断すると推測します(私は Mathematica は持っていないので未検証です)。
注意すべき点があります。\eqref{eq:galois-sol6-9}で「\(\text{分母} \ne 0\) の場合の値」が正しく出ているのは、私には「幸運な偶然」としか言えません。\eqref{eq:galois-sol6-10}で \(\dfrac{0}{0}\) の不定形になってしまっているため、これを\eqref{eq:galois-sol6-11}のように変形することには、数学的な正当性はないからです。ですから、そのような変形によって得られた値が「\(\text{分母} \ne 0\) の場合の値」になっていると信じられる根拠がありません。さらに、そもそも同様な場合にいつでも「分母と分子が文字式として約分され、\(\dfrac{0}{0}\) 型不定形が解消される」という保証もありません。「分母は \(0\) だが分子は \(0\) でない」という結果になったとしても、数学的には文句が言えない状況です。したがって、修正後の「退職後は素人数学者」さんのプログラムでも、出てきた解を全面的に信用するのは今のところ危険と言わざるを得ません。
…ですが、恐らく似たような現象が起こっているであろう \(x^{5}-3=0\) や「(3)他の計算例での確認」での(例2)〜(例4)で、数値解との一致が見られた、とのことですから、実はうまく数学的に正当化されるのではないか…と期待してもいます。残念ながら今のところ「単なる希望的観測」の域を出ない話ではありますが。どなたか代数に強い方が証明してくださいませんかね…。
不適な解の排除
プログラムから得られた \(x^{3}-2=0\) の解
\begin{align}
\label{eq:galois-sol6-12}
&\alpha_{1} =-\frac{r_{2}}{2}-\frac{r_{1}r_{2}}{36},\quad
\alpha_{2}=\frac{r_{2}}{2}-\frac{r_{1}r_{2}}{36},\quad
\alpha_{3}=\frac{r_{1}r_{2}}{18} \\
\label{eq:galois-sol6-13}
&{r_{1}}^{2}+108=0 \\
\label{eq:galois-sol6-14}
&{\zeta_{3}}^{2}+\zeta_{3}+1=0 \\
\label{eq:galois-sol6-15}
&{r_{2}}^{3}-\frac{r_{1}}{2}+6\zeta_{3}+3=0
\end{align}
が、べき根の選択によっては不適な解を出す、ということは、「複素数 \(r_{1}\), \(r_{2}\), \(\zeta_{3}\) が\eqref{eq:galois-sol6-13}, \eqref{eq:galois-sol6-14},\eqref{eq:galois-sol6-15}をみたす、というだけでは、\eqref{eq:galois-sol6-12}は求める解にならない(なる保証がない)」ということで、言い換えると「\eqref{eq:galois-sol6-13},\eqref{eq:galois-sol6-14}, \eqref{eq:galois-sol6-15}だけでは条件が不足している」ということです。これを、「条件を追加すれば正しい解を表せる」と肯定的にとらえてみます。
どんな条件を追加すればいいかは、「(4)計算結果の検証」に書かれています。
\[ (x-\alpha_{1})(x-\alpha_{2})(x-\alpha_{3}) =
x^{3}-1-\frac{r_{1}(1+2\zeta_{3})}{18} \]
となった、ということは、「これが \(x^{3}-2\) になる」ことが追加すべき条件、つまり
\begin{equation}
\label{eq:galois-sol6-16}
\frac{r_{1}(1+2\zeta_{3})}{18} = 1 \iff r_{1}(1+2\zeta_{3})= 18
\end{equation}
を\eqref{eq:galois-sol6-13}, \eqref{eq:galois-sol6-14}, \eqref{eq:galois-sol6-15}に追加すれば、\eqref{eq:galois-sol6-12}が \(x^{3}-2=0\) の正しい解を与える式になるわけです。
この「条件の追加」法は、前節で触れた「幸運な偶然」「希望的観測」が「実際に信用できる結果を出す」と証明された後なら、正当化されます。
また、以下の通り、「条件の追加」は、最終的な解\eqref{eq:galois-sol6-12}が出るのを待たず、体の拡大過程の各ステップ毎に分割して実行できるはずです。
まず、我々の手順では \(g_{k-1}(x)\) から \(g_{k}(x)\) を求めるに当たって、\(h_{0}(x), h_{1}(x), \dots, h_{p-1}(x)\) を定め、\(h_{0}(x)\) を求めてそれを \(g_{k}(x)\) としていますが、この \(h_{0}(x), \dots, h_{p-1}(x)\) は実際にはすべて互いに対等であって、どれも \(g_{k}(x)\) として適しています。特に、これらの積は \(g_{k-1}(x)\) と一致します。
\begin{equation}
\label{eq:galois-sol6-17}
g_{k-1}(x) = h_{0}(x)h_{1}(x) \dotsm h_{p-1}(x)
\end{equation}
「条件の追加」は、この\eqref{eq:galois-sol6-17}が成立するかどうかをチェックすればよいはずです。我々の立場としては、\(g(x)=g_{0}(x)\) が正しく \(1\) 次式まで因数分解されさえすればいいので、各ステップごとの因数分解\eqref{eq:galois-sol6-17}が正しいことがひとつひとつ確認さえできれば、元の方程式が正しく解けたことになりますから。
つまり、各 \(\theta_{i}(x)\) がべき根を用いて求まった後、
\[ h_{0}(x) = \theta_{0}(x) + \theta_{1}(x) + \dots + \theta_{p-1}(x) \]
だけでなく、\(h_{1}(x), \dots, h_{p-1}(x)\) も求めます:
\begin{align*}
h_{1}(x) &= \theta_{0}(x) + \zeta^{-1}\theta_{1}(x) + \zeta^{-2}
\theta_{2}(x) + \dots + \zeta^{-(p-1)} \theta_{p-1}(x) \\
h_{2}(x) &= \theta_{0}(x) + \zeta^{-2}\theta_{1}(x) +
(\zeta^{2})^{-2} \theta_{2}(x) + \dots +(\zeta^{p-1})^{-2}
\theta_{p-1}(x) \\
&\vdots \\
h_{p-1}(x) &= \theta_{0}(x) + \zeta^{-(p-1)}\theta_{1}(x) +
(\zeta^{2})^{-(p-1)}\theta_{2}(x) + \dots +
(\zeta^{p-1})^{-(p-1)} \theta_{p-1}(x)
\end{align*}
(\(\zeta_{p}\) を \(\zeta\) と略記しました)。そしてこれらの積を取り、\eqref{eq:galois-sol6-17}がなりたつかどうかをチェックするのです。両辺が一致しなければ、そこから「追加すべき条件」が得られます。
今後の課題
ひとつは、アルゴリズム A の堅牢性の向上です。上で指摘したアルゴリズム A の問題点は、次のように要約されます。
べき根の選び方によって \(0\) になったりならなかったりする分母の式に対して、アルゴリズム A は、特に数式処理ソフトで実装した場合、信頼できない結果を出す。
これを克服して、\eqref{eq:galois-sol6-6}に対して正しく\eqref{eq:galois-sol6-7}という結果を出すようなアルゴリズム B が開発されれば、この記事で述べてきたような問題は自ずと解消されます。
そのためには、まず分母として与えられた式が「べき根の選び方によって \(0\) になったりならなかったりする」かどうかが判定できなければいけませんが、それは次のようにすれば可能だと思います。
まず、与えられた式は、そのステップで利用する \(1\) の原始 \(p\) 乗根 \(\zeta_{p}\)(やはり \(\zeta\) と略記します)の多項式になっています。これを \(\phi(\zeta)\) としましょう。\(p=2\) の場合は \(\zeta=-1\) で、これに「べき根の不定性」はありませんから、考える必要があるのは \(p\geqq 3\) の場合のみです。よって \(\zeta\) は
\begin{equation}
\label{eq:galois-sol6-18}
1+\zeta+\zeta^{2}+ \dots +\zeta^{p-1} = 0
\end{equation}
をみたす文字(不定元)として扱われます。
続いて、\(\phi(\zeta)\) の \(\zeta\) を \(\zeta^{2}, \zeta^{3}, \dots, \zeta^{p-1}\) で置きかえた式を考えます。
\[ \phi(\zeta), \phi(\zeta^{2}), \phi(\zeta^{3}), \dots, \phi(\zeta^{p-1}) \]
「べき根の選び方によって \(0\) になったりならなかったりする」場合には、これらの値のうちのどれかが \(0\) になりますが、どれが \(0\) になるかは\eqref{eq:galois-sol6-18}だけでは決まりません。しかし、これらの積が \(0\) になることは確定します。
\begin{equation}
\label{eq:galois-sol6-19}
\phi(\zeta)\phi(\zeta^{2}) \dotsm \phi(\zeta^{p-1}) = 0
\end{equation}
つまり、\eqref{eq:galois-sol6-18}をみたすどんな \(\zeta\) に対しても\eqref{eq:galois-sol6-19}がなりたちます。そして、\eqref{eq:galois-sol6-19}の左辺は、\eqref{eq:galois-sol6-18}を使って次数下げをすると \(\zeta\) が消えて定数になる形をしています。
つまり、\(\phi(\zeta)\) が「べき根の選び方によって \(0\) になったりならなかったりする」式かどうかは、積 \(\phi(\zeta) \dotsm \phi(\zeta^{p-1})\) を作って \(1+\zeta+\zeta^{2}+ \dots +\zeta^{p-1}\) による剰余をとった結果(\(\zeta\) によらない定数)が \(0\) になるかどうかで判定可能です。
なお、\(\theta_{1}(x), \theta_{2}(x), \dots, \theta_{p-1}(x)\) が「べき根の選び方によって \(0\) 多項式になったりならなかったりする」かどうかも、同様にこれらの積をとって判定可能です。(我々にとって興味があるのは「\(0\) 多項式になるかどうか」だけなので、実際に積を取るのは \(\theta_{i}(x)\) 自身ではなく、「\(\theta_{i}(x)\) の(見かけの)最高次係数」だけでも構いません【追記】と書きましたが、これだと不十分ですね。(見かけの)最高次係数の積が \(\ne 0\) だった場合は \(\theta_{i}(x)\) も \(\ne 0\) とわかりますが、その裏が成立するとは限りませんでした)
それから、いま問題となっている「見かけは \(0\) ではないが、真の値は \(0\)」という現象は、「べき根の選び方の不定性」以外の原因で発生する心配はないのでしょうか。もし、我々が見逃しているだけで、そういうケースが存在するようだと厄介なことになります。そういう観点からも、アルゴリズム A の改善が望まれます。
さらに、「見かけは \(0\) ではないが真の値は \(0\)」の場合ばかりが話題に上っていますが、私は「見かけからしてモロに \(0\)」の可能性も気にかかっています。つまり、\(\theta_{1}(x)\) を \(h_{i}(x)\) と \(\zeta_{p}\) から定めた段階で、「見かけは \(0\) でないが…」みたいなケチなことは言わず、ずばり \(0\) 多項式になっていると、現行のプログラムではやはり「最高次の係数で割ってモニック多項式を出す」所で \(0\) 割りのエラーが発生します(………と思いましたが、jurupapa さんのプログラムだと、定数多項式の場合は特殊処理を入れてあってそれは回避しているのかな。ただ、後の方で結局「最高次係数で割る」処理が入るはずなので、タイミングが早いか遅いかの違いしかないのではないかと思います)。これが第二の課題です。
それを避けるために、先日の私の策を採ろうとした場合、今度は「残りの \(\theta_{2}(x), \dots, \theta_{p-1}(x)\) の中から \(0\) 多項式でないものを選び出す」必要がありますが、それらが「見かけからして \(0\) 多項式」と「べき根の選び方によって \(0\) 多項式になったりならなかったりする」ものばかりだったりすると、これまた厄介なことになります。
あと、優先順位は低いですが、今後の課題としては「与えられた置換群の最大の正規真部分群を正しく求めるアルゴリズムの開発」も、あると言えばあります。もっとも、これが実際に問題を引き起こす例は、元の方程式の次数がある程度高くないと作れない(おそらく \((x^{2}-2)(x^{2}-3)(x^{2}-5)=0\) が最も簡単な例なので、最低でも \(6\) 次方程式)ため、現実的な計算量で処理できる方程式に対しては、現行のアルゴリズムのままで問題はなさそうではありますが…。
コメントを残す