桁落ちを回避できない複素数係数二次方程式

方程式の数値解を有効数字の限られたコンピュータで求める際,どうしても誤差はつきものです。

今回この記事では,複素数係数の二次方程式  a x^2 + b x + c = 0\ (a \neq 0) の数値解を解の公式を用いて求める際に,桁落ちを簡単に回避できない場合があるという話をします。

解の公式

まず,0でない複素数  z に対し, \sqrt{z}

 {
    w^2 = z
}

を満たすような複素数  w(一般に2つ存在する)のうち

 {
    \displaystyle -\frac{\pi}{2} < \arg w \le \frac{\pi}{2}
}

を満たすものとして定義します。*1

すなわち, z = r e^{i \theta}\ (-\pi < \theta \le \pi) に対して  \sqrt{z} := \sqrt{r} e^{i \theta / 2} とします。
また, \sqrt{0} = 0 とします。

 a, b, c がすべて実数の場合

中学校や高校で習うように,実数  a, b, c に対して上記の二次方程式の解は

 {
    \displaystyle x = \frac{- b \pm \sqrt{b^2 - 4 a c}}{2 a}
}

と表されます。解の1つ

 {
    \displaystyle x_1 = \frac{- b + \sqrt{b^2 - 4 a c}}{2 a}
}

をコンピュータで数値的に求めることを考えると,もし  b > 0 かつ  4ac \approx 0 であれば,近い値の引き算となるため桁落ちが発生してしまいます。このときは分子を有理化した形

 {
    \displaystyle x_1 = \frac{2 c}{- b - \sqrt{b^2 - 4 a c}}
}
を計算することで桁落ちを回避できます。もう1つの解も同様です。

 a, b, c の少なくとも一つが虚数の場合

 a, b, c虚数が含まれる場合も,解は

 {
    \displaystyle x = \frac{- b \pm \sqrt{b^2 - 4 a c}}{2 a}
}

と表すことができます。しかし,この場合は後述するように桁落ちが簡単に回避できない場合があるのです。

複素数係数二次方程式の桁落ち

二次方程式  x^2 - (2 + i) x + (-0.0014571 + 1.9995 i) = 0 を解くことを考えます。

この二次方程式の厳密な数値解  x_1,\ x_2 を求めると

 {
    \begin{align}
        \displaystyle
        x_1 &= (2.0004829381256217...) + (0.00049123182823248...) i,  \\
        x_2 &= (-0.0004829381256217...) + (0.9995087681717675...) i
    \end{align}
}

となります。なお, x_1 \displaystyle \frac{- b + \sqrt{b^2 - 4 a c}}{2 a} で表される解, x_2 \displaystyle \frac{- b - \sqrt{b^2 - 4 a c}}{2 a} で表される解です。

 x_1 を有効数字5桁の10進数で計算してみます。有効数字5桁で最も真の解に近い値は

 x_1 = 2.0005 + 0.00049123 i

です。以下に計算過程を連ねます。


  a = 1.0000,\ \ b = -2.0000 - 1.0000 i,\ \ c = -0.0014571 + 1.9995 i
  b^2 = 3.0000 + 4.0000 i,\ \ \ 4ac = -0.0058284 + 7.9980 i
  b^2 - 4ac = 3.0058 - 3.9980 i,\ \ \ \sqrt{b^2 - 4ac} = 2.0010 - 0.99902 i

分子に根号がある形:

 {\displaystyle 
    \begin{align}
        x_1 = \frac{- b + \sqrt{b^2 - 4 a c}}{2 a} &= \frac{(2.0000 + 2.0010) + (1.0000 - 0.99902) i}{2.0000} \\
        &= \frac{4.0010 + 0.00098000 i}{2.0000} \\
        &= 2.0005 + 0.00049\underline{000} i
    \end{align}
}

分母に根号がある形:

 {\displaystyle 
    \begin{align}
        x_1 = \frac{2 c}{- b - \sqrt{b^2 - 4 a c}} &= \frac{-0.0029142 + 3.9990 i}{(2.0000 - 2.0010) + (1.0000 + 0.99902) i} \\
        &= \frac{-0.0029142 + 3.9990 i}{-0.0010000 + 1.9990 i} \\
        &= 2.0005 + 0.0004\underline{5708} i
    \end{align}
}


分子に根号がある形では, - b + \sqrt{b^2 - 4 a c} の虚部の計算で桁落ちが発生し,分母に根号がある形では, - b - \sqrt{b^2 - 4 a c} の実部の計算で桁落ちが発生しています。
その結果,どちらの形で計算しても下線を引いた部分に大きな誤差が発生してしまいました。なお,もう一方の解  x_2 を計算するときも同様に桁落ちによる誤差が発生してしまいます。

誤差は簡単に回避できないと書きましたが,では簡単でない何らかの手段があるのかというと,残念ながらそれは今のところ思いついていません。何か思いついたら追記します。



*1:解の公式には根号の前に  \pm がついているので,ここでは多価関数として扱わなくても問題ないでしょう。