Ex - Intersection 2 Editorial by MMNMM

実数(浮動小数点数)の計算・出力の誤差について

この問題の解法の正当性を誤差の観点から確認します。 解法は公式解説のものと変わらないので、公式解説を既に読了していることを前提とします。

この提出の実装をもとに解説を行います。 解説・実装を読む上で出現する非自明な実装の特徴として次のようなものがあります。

  • 整数を表す型には long 、実数を表す型には double を使っています。
  • 係数を定数倍することで \(C\leq0\) としています。
  • 原点を中心とした半径 \(\sqrt{r^2}\) の円と直線 \(Ax+By+C=0\ (C\leq0)\) の交点の偏角を \(\tan^{-1}\dfrac{B}{A}\pm\cos^{-1}\sqrt{\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) で計算しています(円周を適当な点からいずれかの向きで回るときの順序が定まればよいので、偏角の定数倍や定数の差は無視してよいです)。
    • \(\tan^{-1},\cos^{-1}\) を \(\sin^{-1}\) で計算しています。適宜 \(\dfrac{\pi}{2}\) 程度の回転や反転をしたものを考えることで、\(\sin^{-1}\) の引数を \(0\leq\theta\leq\dfrac{1}{\sqrt{2}}\) を満たすようにしています。
  • 答えの \(2\) 乗で二分探索をしています。
  • 二分探索でははじめに \(1\) について判定をしています。

それらを選んだ理由

  • 前者は実装を楽にするためです。後者は誤差の評価を楽にするためです。
  • 実装を簡単にするためです。これを行うと、原点からその直線へ下ろした垂線(存在すれば)の足が \((kA,kB)\ (k>0)\) の形になり、その偏角を \(\tan^{-1}\dfrac{B}{A}\) などで計算できます.
  • 実装を簡単にし、誤差の評価を楽にするためです。円と直線の交点を出してそれらを偏角ソートする場合、同様の三角関数の計算を使ったり、円と直線の交点を二次方程式を解いたりしますが、誤差を抑えるのが面倒な計算を経ることになると考えたためです。この方針でなくても根気よく計算することで本ユーザ解説とおおよそ同じ程度のオーダーの誤差評価ができると思います。
    • 誤差の評価を楽にするためでしたが、楽になったかは不明です。同様にこの方針でなくてもがんばって計算することで本ユーザ解説とおおよそ同じ程度のオーダーの誤差評価ができると思います。
  • 誤差の評価を楽にするためです。\(r^2\) の真の値が double で正確に表現できるようにしておくことで、円と直線が共有点を持つかを正確に判定することができます。そうでないと、円と直線の位置関係を間違えて判定してしまう場合があり場合分けが増えて困ると考えたためです。この方針でなくても本ユーザ解説とおおよそ同じ程度のオーダーの誤差評価ができると思いますが、どう議論をすればいいのかあまりわかりません。
  • 定数倍高速化のためです。解の絶対値が \(1\) 以下であれば絶対誤差を、\(1\) 以上であれば相対誤差を小さくするように動くことで少ない回数の反復で所望の誤差の範囲の値を得ることができます。


以下の文章では、真の値を表す式を \(2y\) のように、プログラムで計算される誤差を含む値を表す式を 2 * y のように書きます。

読解には浮動小数点数のおおまかな表現(符号部、指数部、仮数部があってうんぬんなど)をそれなりに納得できている必要があると思います。 コードテストの環境で std::numeric_limits<double>::is_iec559true なので、AtCoder の実行環境で常に true であると仮定しています。 文中で断りなく出現する、浮動小数点数の演算に関する非自明な事実として「四則演算と sqrtfma (fused multiply-add) は計算を無限精度で行った場合の結果を現在の丸めモードで丸めた結果と等しいものを返す」というものがあります。

途中式や論証を折りたたみにしましたが、余談を除いてすべて読むことが想定されています。 読まなくても話の流れが追えるようにはなっていると思います。


この解説は次の3つの節からなります。

  1. 判定に失敗するような範囲の評価
  2. 探索区間の長さの評価
  3. 得られる出力と真の値との差の評価

1 節では二分探索の判定に失敗しうる(\(=\) 半径 \(r\) の円内にある交点の数を間違えて計算する)ような \(r\) の範囲を評価します。2 節では二分探索を \(n\) 回繰り返した時の探索区間の長さを評価します。3 節では 1,2 節の内容をあわせて上の提出で出力される値と真の値との誤差について評価します。

以下では、問題の真の解を \(d_{\operatorname{truth}}\) と書くことにします。\(d_{\operatorname{truth}}\) と出力される値との誤差を評価するのが目標です。

1. 判定に失敗するような範囲の評価

半径 \(\sqrt{r^2}\ (r^2>0)\) の円内にある交点の数を間違えて計算するとき、偏角ソートで失敗しています。つまり、円と直線の交点のうちある \(2\) 点について、計算された偏角の大小関係が真の偏角の大小関係と異なってしまっています。

他の部分でこわれない理由

直線が円と交点を持つかは、\(\dfrac{|C|}{\sqrt{A^2+B^2}}\leq \sqrt{r^2}\iff0\leq-C^2+r^2\left(A^2+B^2\right)\) で求められます。 \(C^2,A^2+B^2\) はいずれも double で正確に表すことができる整数です。 r_sq に \(r^2\) の正確な値が入っているなら、\(0\leq-C^2+r^2\left(A^2+B^2\right)\) が成り立つとき、かつそのときに限りfma(r_sq, A * A + B * B, -C * C) の符号が \(+\) になります。 よって、直線が円の内部にあるかの判定に失敗することはありません。

偏角ソートに成功すると、それ以降は円と直線の交点の偏角の大小関係のみで数え上げの結果が決まります。 これはすべて整数の範囲で計算を行うことができるため、誤差によって計算結果が変わることはありません。


よって、偏角ソートに失敗する条件について考えます。

偏角は \(\tan^{-1}\dfrac{B}{A}\pm\cos^{-1}\sqrt{\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) で計算されています。これの誤差範囲が重なるような \(2\) つの偏角が存在するとき、偏角ソートに失敗する可能性があります。

\(\tan^{-1}\dfrac{B}{A}\) は以下のように計算されています。

評価

        const auto d{sqrt(A * A + B * B)};
        if(B > 0){
            if(-B < A && A < B){
                const auto cos_theta{A / d};
                theta = pi_half - asin(cos_theta);
            }else{
                const auto sin_theta{B / d};
                theta = A > 0 ? asin(sin_theta) : pi - asin(sin_theta);
            }
        }else{
            if(B < A && A < -B){
                const auto cos_theta{A / d};
                theta = pi_triple_half + asin(cos_theta);
            }else{
                const auto sin_theta{B / d};
                theta = A > 0 ? pi_2 + asin(sin_theta) : pi - asin(sin_theta);
            }
        }

if 文および条件演算子の条件はすべて整数の比較なので、誤差はありません。

d は、double で正確に表せる値 \(A^2+B^2\) の平方根を double に丸めたものなので、たかだか \(0.5\operatorname{ulp}\) の誤差があります。よって、d は \(\left[\sqrt{A^2+B^2}\left(1-2^{-53}\right),\sqrt{A^2+B^2}\left(1+2^{-53}\right)\right]\) に存在します。

cos_thetadouble で正確に表せる値 \(A\) を d で割った正確な値を double に丸めたものです。 この計算において、割り算の丸めでたかだか \(0.5\operatorname{ulp}\) の誤差が生じます。 \(A=0\) のとき、cos_theta も \(0\) になります。 \(A\neq0\) のとき、\(|\cos_{\operatorname{theta}}|>\dfrac{1}{\sqrt{10^6+1}}\) です。 なので、割り算の丸めではたかだか \(2^{-53}\) の相対誤差が生じます。 よって、cos_theta の \(\cos_{\operatorname{theta}}\) との相対誤差はたかだか \(\dfrac{2}{2^{53}-1}\) です。

sin_theta はまったく同様にして真の値からの相対誤差が高々 \(\dfrac{2}{2^{53}-1}\) であることが言えます。

if 文の条件から、\(-\dfrac{1}{\sqrt{2}}\leq\operatorname{sin_{theta}},\operatorname{cos_{theta}}\leq\dfrac{1}{\sqrt{2}}\) であって、これらを \(\sin^{-1}\) した結果の真の値は \(\left[-\dfrac{\pi}{4},\dfrac{\pi}{4}\right]\) にあることがわかります。また、\(x\in[-1,1]\) に対して \(|x|\leq|\sin^{-1}x|\) であるので、\(|\sin^{-1}\operatorname{sin_{theta}}|,|\sin^{-1}\operatorname{cos_{theta}}|\) は \(0\) でなければ \(\dfrac{1}{\sqrt{10^6+1}}\) 以上です。

これらから、asin(cos_theta) および asin(sin_theta) の値と真の値との絶対誤差は高々 \(\dfrac{1}{2^{51}}\) 以下であることが言えます。

評価の詳細

こちらを参照すると、asin の計算結果と真の値との誤差は多くの計算機でたかだか \(1\operatorname{ulp}\) です。つまり、たかだか \(2^{-52}\) の相対誤差を含みます。

\(\sin^{-1}(x+\varepsilon)\ (|x|\leq\dfrac{1}{\sqrt{2}},|x+\varepsilon|\leq\dfrac{4}{5})\) について、\(\varepsilon\leq0\)なら \(\sin^{-1}x+\dfrac{5\varepsilon}{3}\leq\sin^{-1}(x+\varepsilon)\) が、\(\varepsilon\geq0\) なら \(\sin^{-1}x+\dfrac{5\varepsilon}{3}\geq\sin^{-1}(x+\varepsilon)\) が成り立つ、つまり \(0\lt\varepsilon,|x|\leq\dfrac{1}{\sqrt{2}},|x+\varepsilon|\leq\dfrac{4}{5}\) について \(\left[\sin^{-1}(x-\varepsilon),\sin^{-1}(x+\varepsilon)\right]\subseteq\left[\sin^{-1}x-\dfrac{5\varepsilon}{3},\sin^{-1}x+\dfrac{5\varepsilon}{3}\right]\) が成り立つことに注意します。 sin_theta, cos_theta の相対誤差はたかだか \(\dfrac{2}{2^{53}-1}\) であったので、上の式における \(\varepsilon\) は \(|\varepsilon|\leq\dfrac{\sqrt{2}}{2^{53}-1}\) を満たすといえます。

よって、計算結果と真の値との誤差は \(\dfrac{5}{3}\times\dfrac{\sqrt{2}}{2^{53}-1}+\dfrac{\pi}{4}\times2^{-52}\leq\dfrac{1}{2^{51}}\) で絶対値を上から抑えることができ、所望の評価が得られました。


pi_half,pi,pi_triple_half,pi_2 はいずれも定数を double に丸めたもので、それぞれ高々 \(\dfrac{5}{2^{56}},\dfrac{5}{2^{55}},\dfrac{15}{2^{56}},\dfrac{5}{2^{54}}\) の絶対誤差を含みます。

\(0\lt B\lt A\) のとき、\(\theta=\sin^{-1}\operatorname{sin_{theta}}\) です。 これは上で求めた通り、絶対誤差は高々 \(\dfrac{1}{2^{51}}\) 以下です。
そうでないとき、\(\theta=\dfrac{k}{2}\pi\pm\sin^{-1}\alpha\ (k=1,2,3\wedge\alpha=\operatorname{sin_{theta}},\operatorname{cos_{theta}})\) と表されます。 加減算でたかだか \(1\) 回丸めが行われ、たかだか \(0.5\operatorname{ulp}\) の誤差が発生します。 \(0.5\operatorname{ulp}\) は、pi_2 などと asin(sin_theta) などとの和の真の値が \(2\pi+\dfrac{13}{2^{54}}\) 以下であるため、たかだか \(\dfrac{1}{2^{51}}\) です。 よって、計算結果の \(\theta\) との絶対誤差はたかだか \(\dfrac{21}{2^{54}}\) です。


以上より、\(\theta=\tan^{-1}\dfrac{B}{A}\) の計算における絶対誤差は高々 \(\dfrac{21}{2^{54}}\) です。

余談(読まなくても以下の読解に問題はありません)|実際の誤差の値

この部分は \(4\times10^6\) 通り程度の入力しかないので、全探索を用いて評価を行うことができます。 実際に計算を行うと、最悪の場合 \(16.59\times2^{-54}\) 程度の絶対誤差が生じていることが確認できます。(誤差が最大になるときは \((A,B)=(786,-767)\) のとき、真の値 \(5.51002091848314726693722961\ldots\) に対し、計算結果は \(5.51002091848314634603411832\ldots\) です。)


\(\cos^{-1}\sqrt{\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) の計算結果 phi に生じる絶対誤差の大きさを、真の値 \(\varphi\) の関数 \(e_\varphi(\varphi)\) で上から抑えることを考えます。

\(\varphi=\cos^{-1}\sqrt{\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) は以下のように計算されています。

評価

            const real phi{0 <= copysign(1, fma(r_sq, A * A + B * B, -2 * C * C)) ? pi_half - asin(sqrt(C * C / r_sq / (A * A + B * B))) : asin(sqrt(1 - C * C / r_sq / (A * A + B * B)))};

if 文で書き直すと以下のようになります。

            real phi;
            if(0 <= copysign(1, fma(r_sq, A * A + B * B, -2 * C * C))){
                phi = pi_half - asin(sqrt(C * C / r_sq / (A * A + B * B)));
            }else{
                phi = asin(sqrt(1 - C * C / r_sq / (A * A + B * B)));
            }

条件分岐では \(\dfrac{|C|}{\sqrt{A^2+B^2}}\leq\dfrac{\sqrt{r^2}}{\sqrt{2}}\) であるか(\(\iff\dfrac{\pi}{4}\leq\varphi\leq\dfrac{\pi}{2}\) であるか)を正確に判定しています。

処理全体でこわれないことの確認

\(r^2>0\) および \((A,B)\neq(0,0)\) より、\(0\) での除算は行われません。

前者の場合、\(0\leq\dfrac{C^2}{r^2\left(A^2+B^2\right)}\leq\dfrac{1}{2}\) です。 C * C / r_sq / (A * A + B * B) のいかなる部分でも結果が負になることはないため、sqrt の定義域の中の値が渡されます。 \(\dfrac{A^2+B^2}{2}\) は double で正確に表現できる値なので、C * C / r_sq は \(\dfrac{A^2+B^2}{2}\) 以下です。 よって同様に、C * C / r_sq / (A * A + B * B) は \(\dfrac{1}{2}\) 以下です。 \(\left[0,\dfrac{1}{2}\right]\) の値の sqrt なので特に \(1\) 以下であり、asin の定義域の外の値が渡されることはありません。

後者の場合、\(\dfrac{1}{2}\leq\dfrac{C^2}{r^2\left(A^2+B^2\right)}\leq1\) です。 上と同様に、C * C / r_sq / (A * A + B * B) も \(\dfrac{1}{2}\) 以上 \(1\) 以下、1 - C * C / r_sq / (A * A + B * B) が \(0\) 以上 \(\dfrac{1}{2}\) 以下であることが言えます。 よって、sqrtasin の定義域の外の値が渡されることはありません。


誤差について考えます。

\(\dfrac{\pi}{4}\leq\varphi\leq\dfrac{\pi}{2}\) のとき、 \(\tan^{-1}\dfrac{B}{A}\) の評価と同様にして \(e_\varphi(\varphi)=\dfrac{41}{2^{56}}\) とできることが示せます。

\(\varphi=0\) のとき、phi も \(0\) です。よって、\(e_\varphi(0)=0\) です。

\(0<\varphi<\dfrac{\pi}{4}\) のとき、\(\varphi=\sin^{-1}\sqrt{1-\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) を用いて phi を計算しています。 このとき、 \(\dfrac{C^2}{r^2\left(A^2+B^2\right)}=1-\sin^2\varphi\) です。 C * C / r_sq は条件より \(\dfrac{A^2+B^2}{2}\) 以上 \(A^2+B^2\) 以下で、double で正確に表せる値 \(C^2\) と \(r^2\) の商を double に丸めたものです。 よって、C * C / r_sq にはたかだか \(2^{-53}\) の相対誤差があります。 C * C / r_sq / (A * A + B * B) はこれを double で正確に表せる値 \(A^2+B^2\) で割ったものを double に丸めたもので、\(\dfrac{1}{2}\) 以上 \(1\) 以下です。 よってこの丸めでもたかだか \(2^{-53}\) の相対誤差が生じるため、C * C / r_sq / (A * A + B * B) は \(\left[\left(1-\sin^2\varphi\right)\left(1-2^{-52}+2^{-106}\right),\left(1-\sin^2\varphi\right)\left(1+2^{-52}+2^{-106}\right)\right]\cap\left[\dfrac{1}{2},1\right]\) に存在します。

1 - C * C / r_sq / (A * A + B * B) は、\(\left[0,\dfrac{1}{2}\right]\) に存在します。 なので計算結果の丸め誤差は生じず、この計算結果は \(\left[1-\left(1-\sin^2\varphi\right)\left(1+2^{-52}+2^{-106}\right),1-\left(1-\sin^2\varphi\right)\left(1-2^{-52}+2^{-106}\right)\right]\cap\left[0,\dfrac{1}{2}\right]\) に存在します。

これを整理します。\[\begin{aligned}1-\left(1-\sin^2\varphi\right)\left(1+2^{-52}+2^{-106}\right)&=\sin^2\varphi\left(1+2^{-52}+2^{-106}-\dfrac{2^{-52}+2^{-106}}{\sin^2\varphi}\right)\\&\geq\sin^2\varphi\left(1-\dfrac{2^{-52}+2^{-106}}{\sin^2\varphi}\right)\end{aligned}\] が成り立ちます(\(0\lt\varphi\lt\dfrac{\pi}{4}\) より \(\sin^2\varphi\gt0\) です)。同様に \(1-\left(1-\sin^2\varphi\right)\left(1-2^{-52}+2^{-106}\right)\geq\sin^2\varphi\left(1+\dfrac{2^{-52}-2^{-106}}{\sin^2\varphi}\right)\) が成り立つので、1 - C * C / r_sq / (A * A + B * B) の計算結果は \[\left[\sin^2\varphi\left(1-\dfrac{2^{-52}+2^{-106}}{\sin^2\varphi}\right),\sin^2\varphi\left(1+\dfrac{2^{-52}-2^{-106}}{\sin^2\varphi}\right)\right]\cap\left[0,\dfrac{1}{2}\right]\] に存在します。

この区間に含まれる値の平方根を含むような区間について考えます。 \(\left[\sqrt{1-x},\sqrt{1+x}\right]\subseteq\left[1-x,1+\dfrac{x}{2}\right]\ (0\leq x\leq1)\) と \(\left[\sqrt{a-b},\sqrt{a+b}\right]\subseteq\left[\sqrt{\vphantom{h}a}-\sqrt{b},\sqrt{\vphantom{h}a}+\sqrt{b}\right]\ (0\leq b\leq a)\) を用いると、 \[\begin{aligned}&\left[\sin\varphi\left(1-\dfrac{2^{-52}+2^{-106}}{\sin^2\varphi}\right),\sin\varphi\left(1+\dfrac{2^{-53}-2^{-107}}{\sin^2\varphi}\right)\right]\cap\left[\sin\varphi-\sqrt{2^{-52}+2^{-106}},\sin\varphi+\sqrt{2^{-52}-2^{-106}}\right]\cap\left[0,\dfrac1{\sqrt2}\right]\\ \subseteq&\left[\sin\varphi\left(1-\dfrac{2^{-52}+2^{-106}}{\sin^2\varphi}\right),\sin\varphi\left(1+\dfrac{2^{-53}-2^{-107}}{\sin^2\varphi}\right)\right]\cap\left[\sin\varphi-2^{-26}-2^{-81},\sin\varphi+2^{-26}-2^{-81}\right]\cap\left[0,\dfrac1{\sqrt2}\right]\end{aligned}\] はそのような区間であることがわかります。 平方根の計算において、丸めによる絶対誤差はたかだか \(2^{-54}\) なので、sqrt(1 - C * C / r_sq / (A * A + B * B)) は \[\begin{aligned}&\left[\sin\varphi\left(1-\dfrac{2^{-52}+2^{-106}}{\sin^2\varphi}\right)-2^{-54},\sin\varphi\left(1+\dfrac{2^{-53}-2^{-107}}{\sin^2\varphi}\right)+2^{-54}\right]\cap\left[\sin\varphi-2^{-26}-2^{-54}-2^{-81},\sin\varphi+2^{-26}+2^{-54}-2^{-81}\right]\cap\left[0,\dfrac1{\sqrt2}+2^{-54}\right]\\ \subseteq&\left[\sin\varphi-\dfrac{2^{-52}+2^{-54.5}+2^{-106}}{\sin\varphi},\sin\varphi+\dfrac{2^{-53}+2^{-54.5}-2^{-107}}{\sin\varphi}\right]\cap\left[\sin\varphi-2^{-26}-2^{-54}-2^{-81},\sin\varphi+2^{-26}+2^{-54}-2^{-81}\right]\cap\left[0,\dfrac1{\sqrt2}+2^{-54}\right]\\ =&\left[\sin\varphi-\delta_0,\sin\varphi+\delta_1\right]\cap\left[\sin\varphi-\delta_2,\sin\varphi+\delta_3\right]\cap\left[0,\dfrac1{\sqrt2}+2^{-54}\right]\eqqcolon I\end{aligned}\] に存在することがわかります(\(\dfrac{1}{\sqrt{2}}\) は double で正確に表せない値なので、\(\dfrac{1}{\sqrt{2}}\) 以下の値は double で表せる \(\dfrac{1}{\sqrt{2}}\) に最も近い値 \(\dfrac{6369051672525773}{2^{53}}\) 以下へ丸められ、これは \(\dfrac{1}{\sqrt{2}}+2^{-54}\) 以下です)。

\(0\leq\varepsilon,|x|\leq\dfrac{1}{\sqrt2},|x+\varepsilon|\leq\dfrac{4}{5}\) において \[\left[\sin^{-1}(x-\varepsilon),\sin^{-1}x\right]\subseteq\left[\sin^{-1}x-\dfrac{5}{3}\varepsilon,\sin^{-1}x\right],\left[\sin^{-1}x,\sin^{-1}(x+\varepsilon)\right]\subseteq\left[\sin^{-1}x,\sin^{-1}x+\dfrac{5}{3}\varepsilon\right]\] が成立することを用います。 \(J\coloneqq\left\{\sin^{-1}x\middle|x\in I\right\}\) を評価します。

\(I\subseteq\left[0,\dfrac{1}{\sqrt{2}}+2^{-54}\right]\) と \(\sin^{-1}\) が単調増加関数であることからただちに \(J\subseteq\left[0,\sin^{-1}\left(\dfrac{1}{\sqrt{2}}+2^{-54}\right)\right]\) が言えます。
\(I\) を \(\left[\sin\varphi-\varepsilon_0,\sin\varphi+\varepsilon_1\right]\ (\varepsilon_0,\varepsilon_1\geq0)\) と表すとき、\(I\subseteq\left[0,\dfrac{1}{\sqrt{2}}+2^{-54}\right]\) なので \(\varepsilon_0\leq\sin\varphi,\varepsilon_1\leq\dfrac{1}{\sqrt{2}}+2^{-54}-\sin\varphi\) です。 よって、上の条件 \(0\leq\varepsilon,|x|\leq\dfrac{1}{\sqrt2},|x+\varepsilon|\leq\dfrac{4}{5}\) を満たすので \(J\subseteq\left[\varphi-\dfrac{5}{3}\varepsilon_0,\varphi+\dfrac{5}{3}\varepsilon_1\right]\) です。 また、\(I\subseteq\left[\sin\varphi-\delta_0,\sin\varphi+\delta_1\right]\) が成り立つので、\(\varepsilon_0\leq\delta_0,\varepsilon_1\leq\delta_1\) です。 よって、\(J\subseteq\left[\varphi-\dfrac{5}{3}\varepsilon_0,\varphi+\dfrac{5}{3}\varepsilon_1\right]\subseteq\left[\varphi-\dfrac{5}{3}\delta_0,\varphi+\dfrac{5}{3}\delta_1\right]\) です。まったく同様にして \(J\subseteq\left[\varphi-\dfrac{5}{3}\delta_2,\varphi+\dfrac{5}{3}\delta_3\right]\) です。
よって、\(J\subseteq\left[\varphi-\dfrac{5}{3}\delta_0,\varphi+\dfrac{5}{3}\delta_1\right]\cap\left[\varphi-\dfrac{5}{3}\delta_2,\varphi+\dfrac{5}{3}\delta_3\right]\cap\left[0,\sin^{-1}\left(\dfrac{1}{\sqrt{2}}+2^{-54}\right)\right]\) です。

\(J\) の要素は大きくても \(\sin^{-1}\left(\dfrac{1}{\sqrt{2}}+2^{-54}\right)\simeq\dfrac{\pi}{4}+2^{-54}\sqrt{2}\lt1\) であるため、 asin の計算にかかる誤差がたかだか \(1\operatorname{ulp}\) であるとすると、計算結果とその真の値との絶対誤差はたかだか \(2^{-53}\) です。

また、 double で表現可能な \(\dfrac{1}{\sqrt2}\) 以上の最小の値 \(\dfrac{6369051672525773}{2^{53}}\) を逆正接関数に与えたもの以上の double で表現可能な最小の数 \(\dfrac{7074237752028441}{2^{53}}\)が \(\dfrac{\pi}{4}+2^{-53}\) 以下であることから、phi は \(\left[0,\dfrac{\pi}{4}+2^{-53}\right]\) に存在します。

よって、phi は \(\left[\varphi-\dfrac{5}{3}\delta_0-2^{-53},\varphi+\dfrac{5}{3}\delta_1+2^{-53}\right]\cap\left[\varphi-\dfrac{5}{3}\delta_2-2^{-53},\varphi+\dfrac{5}{3}\delta_3+2^{-53}\right]\cap\left[0,\dfrac{\pi}{4}+2^{-53}\right]\) に存在します。

\(\dfrac53\delta_0+2^{-53},\dfrac53\delta_1+2^{-53},\dfrac53\delta_2+2^{-53},\dfrac53\delta_3+2^{-53}\) を上から評価します。\(\sin\varphi\in\left[0,\dfrac1{\sqrt2}\right]\) なので、 \[\begin{aligned} \dfrac53\delta_0+2^{-53}&=\dfrac53\dfrac{2^{-52}+2^{-54.5}+2^{-106}}{\sin\varphi}+2^{-53}&\qquad&\\ &=\dfrac1{\sin\varphi}\left(\dfrac532^{-52}+\dfrac532^{-54.5}+\dfrac532^{-106}\right)+\sqrt{2}\times2^{-53.5}&\qquad&\\ &\leq\dfrac1{\sin\varphi}\left(\dfrac532^{-52}+\dfrac532^{-54.5}+\dfrac532^{-106}\right)+\dfrac1{\sin\varphi}\times2^{-53.5}&&(\sin\varphi\leq\dfrac{1}{\sqrt{2}}\text{ より})\\ &\leq\dfrac{5}{\sin\varphi}\times2^{-53} \end{aligned}\] が成り立ちます。同様の計算を行うことで、\(\dfrac53\delta_1+2^{-53}\leq\dfrac3{\sin\varphi}\times2^{-53}\) が得られます。

また、\(\dfrac53\delta_3+2^{-53}=\dfrac53\left(2^{-26}+2^{-54}+2^{-81}\right)+2^{-53}\leq2^{-25},\dfrac53\delta_4+2^{-53}=\dfrac53\left(2^{-26}+2^{-54}-2^{-81}\right)+2^{-53}\leq2^{-25}\) が成り立ちます。

よって、\(0\lt\varphi\lt\dfrac\pi4\) において、\(e_\varphi(\varphi)=\min\left\{\dfrac{5}{\sin\varphi}\times2^{-53},2^{-25}\right\}\) とすることができます。


以上より、\(\varphi=\cos^{-1}\sqrt{\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) の計算における絶対誤差は \(\varphi\) の関数として高々 \[e_\varphi(\varphi)=\left\{\begin{matrix}0&&(\varphi=0)\\\min\left\{\dfrac{5}{\sin\varphi}\times2^{-53},2^{-25}\right\}&&\left(0\lt\varphi\lt\dfrac\pi4\right)\\\dfrac{41}{2^{56}}&&\left(\dfrac\pi4\leq\varphi\leq\dfrac\pi2\right)\end{matrix}\right.\] です。また、phi は特に \(\left[0,\dfrac{\pi}{2}\right]\) に存在します。

偏角の一方は theta + phipi_2 以上のとき theta + phi - pi_2 、そうでないとき theta + phi で計算されています。 theta + phi はたかだか \(\dfrac{5\pi}2+21\times2^{-54}\) なので、これを丸めることによる絶対誤差は高々 \(2^{-51}\) です。 よって、theta + phi の \(\theta+\varphi\) に対する絶対誤差はたかだか \(e_\varphi(\varphi)+29\times2^{-54}\) です。 theta + phipi_2 以上のとき、pi_2 を減ずるため pi_2 に含まれる誤差が加えられ、theta + phi - pi_2 の \(\theta+\varphi\) に対する絶対誤差は(\(2\pi\) の整数倍の差を無視して)たかだか \(e_\varphi(\varphi)+17\times2^{-53}\) です。

もう一方は theta - phi が \(0\) 以上のとき theta - phi 、そうでないとき theta - phi + pi_2 で計算されています。 theta - phi の絶対値はたかだか \(2\pi+21\times2^{-54}\) なので、これを丸めることによる絶対誤差は高々 \(2^{-51}\) です。 よって、theta - phi の \(\theta+\varphi\) に対する絶対誤差はたかだか \(e_\varphi(\varphi)+29\times2^{-54}\) です。 theta + phi が \(0\) 未満のとき pi_2 を加えるため pi_2 に含まれる誤差が加えられ、たかだか \(2^{-51}\) の誤差を含む丸めが行われます。 よって、theta + phi - pi_2 の \(\theta+\varphi\) に対する絶対誤差は(\(2\pi\) の整数倍の差を無視して)たかだか \(e_\varphi(\varphi)+21\times2^{-53}\) です。

以上より、偏角 \(\tan^{-1}\dfrac BA\pm\cos^{-1}\sqrt{\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) の計算で生じる絶対誤差は \(\varphi=\cos^{-1}\sqrt{\dfrac{C^2}{r^2\left(A^2+B^2\right)}}\) の関数 \(e(\varphi)\) としてたかだか \[e(\varphi)=\left\{\begin{matrix}\dfrac{21}{2^{53}}&&(\varphi=0)\\\min\left\{\dfrac{5}{\sin\varphi}\times2^{-51},2^{-25}+\dfrac{21}{2^{53}}\right\}&&\left(0\lt\varphi\lt\dfrac\pi4\right)\\\dfrac{209}{2^{56}}&&\left(\dfrac\pi4\leq\varphi\leq\dfrac\pi2\right)\end{matrix}\right.\] です。これは \(0\lt\varphi\leq\dfrac\pi2\) において単調に減少する関数です。

いま、半径 \(\sqrt{r^2}\) の円に対して判定を行ったところ \(2\) 直線 \((\theta_0,\varphi_0),(\theta_1,\varphi_1)\) の偏角ソートに失敗した(つまり、計算された \(4\) つの共有点の偏角の順序が真の順序と異なった)とします。 このとき、この \(2\) 直線の交点の原点からの距離の \(2\) 乗と \(r^2\) との比を評価します。

評価

得られている誤差の評価は回転によって不変であるので、適当に全体を回転させることで \(\theta_0=0\) としてよいです。 対称性から、\(\varphi_0\geq\varphi_1\) として一般性を失いません。 対称性から、\(|(\theta_0+\varphi_0)-(\theta_1+\varphi_1)|\leq e(\varphi_0)+e(\varphi_1)\) もしくは \(|(\theta_0+\varphi_0)-(\theta_1-\varphi_1)|\leq e(\varphi_0)+e(\varphi_1)\) が成り立つとしてよいです。

今回の問題設定において、\(2\) 直線がなす角度は最小で \(\alpha=\tan^{-1}\dfrac1{1996002}\) です(\(\dfrac1{1996002}=\dfrac{999\times999-1000\times998}{1000\times999+999\times998}\))。

よって、\(\varphi_0,\varphi_1\) を固定したとき、\(\theta_1\) が満たすべき条件は次のようになります。

  • \(\alpha\leq\theta_1\leq\pi-\alpha\;\vee\;\pi+\alpha\leq\theta_1\leq2\pi-\alpha\)
  • \(-e(\varphi_0)-e(\varphi_1)+\varphi_0-\varphi_1\leq\theta_1\leq e(\varphi_0)+e(\varphi_1)+\varphi_0-\varphi_1\;\vee\;-e(\varphi_0)-e(\varphi_1)+\varphi_0+\varphi_1\leq\theta_1\leq e(\varphi_0)+e(\varphi_1)+\varphi_0+\varphi_1\)

\(2\) つめの条件が満たされているとき、\(-\alpha\lt-2^{-24}-\dfrac{21}{2^{52}}\leq\theta_1\leq\pi+\dfrac{209}{2^{55}}\lt\pi+\alpha\) なので、\(1\) つめの条件は単に \(\alpha\leq\theta_1\leq\pi-\alpha\) となります。 また、\(2\) つめの条件の区間の長さはいずれもたかだか \(2^{-23}+\dfrac{21}{2^{51}}\) であるため、\(\theta_1\) が動ける範囲は \[\begin{aligned}S&=\left[a_0,a_1\right]\cup\left[a_2,a_3\right]\\&=\left[\max\{\alpha,-e(\varphi_0)-e(\varphi_1)+\varphi_0-\varphi_1\},e(\varphi_0)+e(\varphi_1)+\varphi_0-\varphi_1\right]\cup\left[-e(\varphi_0)-e(\varphi_1)+\varphi_0+\varphi_1,\min\{\pi-\alpha,e(\varphi_0)+e(\varphi_1)+\varphi_0+\varphi_1\}\right]\end{aligned}\] と書けます(便宜上 \(a>b\) のとき \(\left[a,b\right]=\varnothing\) とします)。

\(\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\in S\) なら、\(2\) 直線の交点が原点と最も近いときは \(\theta_1=\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\) のとき、その距離は \(\sqrt{r^2}\cos\varphi_1\) です。 \(\varphi_0-\varphi_1\leq\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\leq\varphi_0\) なので、\(\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\in S\iff\alpha\leq\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\leq e(\varphi_0)+e(\varphi_1)+\varphi_0-\varphi_1\) です。

\(\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\notin S\) なら、\(2\) 直線の交点の原点からの距離は \(\theta_1=a_0,a_1,a_2,a_3\) のいずれかにおいて最小・最大をとります。

それぞれ評価します。

\(\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\in S\) のとき

\((\theta_1=\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1},\varphi_1)\) の直線がつくる弦の中点を \((\theta_0=0,\varphi_0)\) が通っています。 条件を満たす \(\varphi_0\) が存在するような \(\varphi_1\) の必要条件を考えます。

\(\varphi_1>\sin^{-1}\dfrac{20}{268435477}\) のとき、条件を満たす \(\varphi_0\) が存在しないことを示します。 このとき、\(e(\varphi_0),e(\varphi_1)\lt2^{-25}+\dfrac{21}{2^{53}}\) です。

半径 \(1\) の円 \(\mathrm{O}\) の円周上に点 \(\mathrm{A}\) をとり、\(\angle\mathrm{AOB}=\varphi_1\) かつ \(\angle\mathrm{OBA}=\dfrac\pi2\) なる点 \(\mathrm{B}\) をとります。 円 \(\mathrm{O}\) 上に、直線 \(\mathrm{AB}\) に対して \(\mathrm{O}\) と反対側にあり \(\angle\mathrm{ABC}=\alpha\) なる点 \(\mathrm{C}\) をとり、\(\mathrm{A}\) における円 \(\mathrm{O}\) の接線と直線 \(\mathrm{BC}\) の交点を \(\mathrm{D}\) とします。

\(\varphi_1\lt\dfrac\pi4\) のとき(\(\varphi_1\leq\dfrac\pi2-\alpha\) なので)、\(\mathrm{AD}\leq\mathrm{AC}\leq(\)弧 \(\mathrm{AC}\) の長さ\()\) です。 \((\)弧 \(\mathrm{AC}\) の長さ\()\leq e(\varphi_0)+e(\varphi_1)\) のとき、かつそのときに限り \(\varphi_1\) に対して条件を満たす \(\varphi_0\) が存在します。

\(\angle\mathrm{BAD}=\varphi_1\) です。 \(\triangle\mathrm{ABD}\) に関する正弦定理から、\(\mathrm{AD}=\dfrac1{\cot\alpha+\cot\varphi_1}\) が成り立ちます(\(\dfrac{\mathrm{AD}}{\sin\alpha}=\dfrac{\sin\varphi_1}{\sin(\pi-\varphi_1-\alpha)}\) を変形することで得られます)。

\(\mathrm{AD}\) と \(e(\varphi_0)+e(\varphi_1)\) の大小関係について考えます。\(\sin^{-1}\dfrac{20}{268435477}\lt\varphi_1\lt\dfrac\pi4\) なので、\(e(\varphi_1)=\dfrac5{\sin\varphi_1}\times2^{-51}\) です。 \(\dfrac{20}{268435477}\lt\sin\varphi_1\lt\dfrac1{\sqrt2}\) であることに注意します。

関数 \(f(x)=\dfrac{x^2}{1996002x+\sqrt{1-x^2}}\ (\dfrac{20}{268435477}\leq x\lt\dfrac1{\sqrt2})\) について考えます。 \[\begin{aligned} f^\prime(x)&=\dfrac{2x\left(1996002x+\sqrt{1-x^2}\right)-x^2\left(1996002-\dfrac{x}{\sqrt{1-x^2}}\right)}{\left(1996002x+\sqrt{1-x^2}\right)^2}&\quad&\\ &=\dfrac{x\left(2+x\left(1996002\sqrt{1-x^2}-x\right)\right)}{\sqrt{1-x^2}\left(1996002x+\sqrt{1-x^2}\right)^2}\gt0&&(\sqrt{1-x^2}\gt\dfrac1{\sqrt2}\text{ かつ }0\lt x\lt\dfrac1{\sqrt2}\text{ より}) \end{aligned}\] より、\(f(x)\) は単調に増加する関数です。 また、\(f\left(\dfrac{20}{268435477}\right)=\dfrac{400}{10715954979259080+268435477\sqrt{72057605312217129}}\gt\dfrac5{2^{50}}\) が成り立ちます。 よって、\(f(x)\gt\dfrac5{2^{50}}\ (\dfrac{20}{268435477}\leq x\lt\dfrac1{\sqrt2})\) が成り立ちます。

よって、 \[\begin{aligned} &\quad&f(\sin\varphi_1)=\dfrac{\sin^2\varphi_1}{1996002\sin\varphi_1+\cos\varphi_1}=\dfrac{\sin\varphi_1}{\cot\alpha+\cot\varphi_1}&\gt\dfrac5{2^{50}}\\ \iff&&\mathrm{AD}=\dfrac1{\cot\alpha+\cot\varphi_1}&\gt\dfrac5{\sin\varphi_1}\times2^{-50}=2e(\varphi_1)\geq e(\varphi_0)+e(\varphi_1) \end{aligned}\] がいえます。以上より、\(\sin^{-1}\dfrac{20}{268435477}\leq\varphi_1\lt\dfrac\pi4\) のとき、条件を満たすような \(\varphi_0\) は存在しません。

\(\dfrac\pi4\leq\varphi_1\leq\dfrac\pi2\) のとき、\(e(\varphi_0),e(\varphi_1)=\dfrac{209}{2^{56}}\) です。 \((\mathrm{C}\) の \(x\) 座標\()-(\mathrm{A}\) の \(x\) 座標\()\leq(\)弧 \(\mathrm{AC}\) の長さ\()\) を用います。 \((\mathrm{C}\) の \(x\) 座標\()-(\mathrm{A}\) の \(x\) 座標\()=\dfrac1{1996002}\times(\mathrm{C}\) の \(y\) 座標\()\) です。 \(\dfrac\pi4\leq\varphi_1\leq\dfrac\pi2\) のとき \(\mathrm{C}\) の \(y\) 座標は \(\dfrac1{2\sqrt2}\) 以上なので、\((\)弧 \(\mathrm{AC}\) の長さ\()\geq\dfrac1{3992004\sqrt2}\gt\dfrac{209}{2^{55}}\) となり、条件を満たすような \(\varphi_0\) は存在しません。

以上より、\(\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\in S\) なる \(\varphi_0\) が存在するような \(\varphi_1\) は \(0\leq\varphi_1\leq\sin^{-1}\dfrac{20}{268435477}\) に限られます。 また、このときの交点の原点からの距離の \(2\) 乗の最小値 \(r^2\cos^2\varphi_1\) は \(\left[r^2\left(1-\dfrac{25}{2^{52}}\right),r^2\right]\) に含まれます。


\(\cos^{-1}\dfrac{\cos\varphi_0}{\cos\varphi_1}\notin S\) のとき

端点になりうる \(6\) 点 \(\theta_1=\alpha,\pi-\alpha,\pm(e(\varphi_0)+e(\varphi_1))+\varphi_0\pm\varphi_1\) について考えます。 \(e\coloneqq e(\varphi_0)+e(\varphi_1)\) と書くことにします。

まず、\(\pi-\alpha\in[\varphi_0+\varphi_1-e,\varphi_0+\varphi_1+e]\) となるような条件を考えます。 \(\varphi_1\leq\dfrac\pi4\) ならば \(\varphi_0+\varphi_1+e\leq\dfrac{3\pi}4+2^{-25}+\dfrac{377}{2^{56}}\lt\pi-\alpha\) なので、\(\varphi_1\gt\dfrac\pi4\) が必要です。 このとき \(e=\dfrac{209}{2^{55}}\) です。 \(\varphi_0=\dfrac\pi2-\rho_0,\varphi_1=\dfrac\pi2-\rho_1\ (0\leq\rho_0\leq\rho_1\lt\dfrac\pi4)\) なる \(\rho_0,\rho_1\) をとると、 \[\begin{aligned}\alpha&\in\left[\rho_0+\rho_1-\dfrac{209}{2^{55}},\rho_0+\rho_1+\dfrac{209}{2^{55}}\right]\\\iff\rho_0+\rho_1&\in\left[\alpha-\dfrac{209}{2^{55}},\alpha+\dfrac{209}{2^{55}}\right]\end{aligned}\] です。 逆に、\(\rho_0+\rho_1\gt\alpha+\dfrac{209}{2^{55}}\) のとき、\([\varphi_0+\varphi_1-e,\varphi_0+\varphi_1+e]\subseteq[\alpha,\pi-\alpha]\) です。 \(\rho_0+\rho_1\lt\alpha-\dfrac{209}{2^{55}}\) のとき、\([\varphi_0+\varphi_1-e,\varphi_0+\varphi_1+e]\cap[\alpha,\pi-\alpha]=\varnothing\) で、このとき \([\varphi_0-\varphi_1-e,\varphi_0-\varphi_1+e]\cap[\alpha,\pi-\alpha]=\varnothing\) でもあります。

\(\rho_0+\rho_1\in\left[\alpha-\dfrac{209}{2^{55}},\alpha+\dfrac{209}{2^{55}}\right]\) なるときの \(\theta_1=\pi-\alpha\) での交点の原点からの距離を考えます。 これは、\(\rho_0=\rho_1=\dfrac\alpha2+\dfrac{209}{2^{56}}\) のときに最大となり、たかだか \(r^2\left(1+\dfrac{25}{2^{30}}\right)\) です。

次に、\(\alpha\in[\varphi_0-\varphi_1-e,\varphi_0-\varphi_1+e]\) となるようなときを考えます。 これは \(\varphi_0\in[\alpha+\varphi_1-e,\alpha+\varphi_1+e]\) と同値です。 \(\varphi_1\gt0\) ならば \(e\leq2e(\varphi_1)\) であることを用いると、\(\varphi_0\leq\alpha+\varphi_1+2e(\varphi_1)\) です。 \(2\) 直線の交点の原点からの距離は \(\varphi_1\leq\varphi_0\leq\dfrac\pi2\) において \(\varphi_0\) について単調に増加します。 よって、\(\theta_1=\alpha\) なるときの交点の原点からの距離は \(\varphi_0=\alpha+\varphi_1+2e(\varphi_1)\) で上からおさえられ、これは \(\varphi_1=\dfrac\pi2-\alpha-2e\left(\dfrac\pi2\right)\) のとき最大になります。 原点からの距離はたかだか \(r^2\left(1+\dfrac{25}{2^{30}}\right)\) です。

以下、\([\varphi_0+\varphi_1-e,\varphi_0+\varphi_1+e],[\varphi_0-\varphi_1-e,\varphi_0-\varphi_1+e]\subseteq(\alpha,\pi-\alpha)\) のときを考えます。

半径 \(1\) に拡大縮小したときの交点の \(y\) 座標を求めると、これは \[\begin{aligned}y&=\dfrac1{\sin\theta_1}\left(-\cos\theta_1\cos\varphi_0+\cos\varphi_1\right)\\ &=\dfrac1{\sin\theta_1}\left(\sin\theta_1\sin\varphi_0-\cos(\theta_1-\varphi_0)+\cos\varphi_1\right)\\ &=\sin\varphi_0+\dfrac2{\sin\theta_1}\sin\dfrac{\varphi_0-\varphi_1-\theta_1}2\sin\dfrac{\varphi_0+\varphi_1-\theta_1}2\end{aligned}\] です。

\(\theta_1=-e+\varphi_0-\varphi_1,e+\varphi_0+\varphi_1\) のとき \(y=\sin\varphi_0+\dfrac2{\sin\theta_1}\sin\left(\varphi_1+\dfrac e2\right)\sin\dfrac e2\) で、\(y=e+\varphi_0-\varphi_1,-e+\varphi_0+\varphi_1\) のとき \(y=\sin\varphi_0-\dfrac2{\sin\theta_1}\sin\left(\varphi_1-\dfrac e2\right)\sin\dfrac e2\) です。 \(\sin\theta_1\) を下から、\(\sin\left(\varphi_1\pm\dfrac e2\right)\sin\dfrac e2\) を上から評価します。 \(\theta_1\in[\alpha,\pi-\alpha]\) より、\(\sin\theta_1\geq\sin\alpha\) です。 \[\begin{aligned} \sin\left(\varphi_1\pm\dfrac e2\right)\sin\dfrac e2&\leq\left(\sin\varphi_1\pm\dfrac e2\cos\varphi_1\right)\sin\dfrac e2&&(x,x+y\in[0,\pi]\implies\sin(x+y)\leq\sin x+y\cos x)\\ &\leq\left(\sin\varphi_1\pm e(\varphi_1)\cos\varphi_1\right)\sin e(\varphi_1)&\quad\\ &\leq\left(\sin\varphi_1\pm e(\varphi_1)\cos\varphi_1\right)e(\varphi_1)\\ &\leq\dfrac5{2^{51}}\pm e(\varphi_1)^2\cos\varphi_1\\ &\leq\dfrac5{2^{51}}+e(\varphi_1)^2\leq2^{-48} \end{aligned}\] とできます。

よって、交点の \(y\) 座標は \(\left[\sin\varphi_0-\dfrac{2^{-47}}{\sin\alpha},\sin\varphi_0+\dfrac{2^{-47}}{\sin\alpha}\right]\) に含まれます。 原点からの距離の \(2\) 乗は \(\cos^2\varphi_0+\left(\sin\varphi_0\pm\dfrac{2^{-47}}{\sin\alpha}\right)^2=1\pm\dfrac{2^{-46}}{\sin\alpha}\sin\varphi_0+\dfrac{2^{-94}}{\sin^2\alpha}\) です。 \(0\leq\sin\varphi_0\leq1\) より、\(|\dfrac{2^{-46}}{\sin\alpha}\sin\varphi_0\pm\dfrac{2^{-94}}{\sin^2\alpha}|\leq\dfrac{2^{-46}}{\sin\alpha}+\dfrac{2^{-94}}{\sin^2\alpha}\leq2^{-25}\) となります。

よって、これらをあわせて交点の原点からの距離の \(2\) 乗は \(\left[r^2(1-2^{-25}),r^2(1+2^{-25})\right]\) に含まれます。



偏角ソートに失敗するような \(2\) 直線について、その交点の原点からの距離の \(2\) 乗は \(\left[r^2(1-2^{-25}),r^2(1+2^{-25})\right]\) に含まれることが示されました。

次に、数え上げた交点の数と \(K\) との大小関係の判定に失敗するときの \(d_{\operatorname{truth}}\) と \(r^2\) の関係について考えます。 このアルゴリズムでは偏角でソートされた区間のうち条件を満たしたものどうしを交点として検出しているため、交点の個数が \(x\) と計算されたとき数え上げられた交点を具体的に \(x\) 個とってくることができます。

\(x\) と \(K\) との大小関係を考えます。

\(x\geq K\) で判定に失敗しているとき、\(r^2\lt d_{\operatorname{truth}}^2\) です。 このとき、数え上げられた \(x\) 個の交点のうち最も原点から遠いもの \(P_{\operatorname{far}}=(x_{\operatorname{far}},y_{\operatorname{far}})\) は \(d_{\operatorname{truth}}^2\leq x_{\operatorname{far}}^2+y_{\operatorname{far}}^2\) を満たします。 この交点をつくる \(2\) 直線について偏角ソートが失敗している必要があるので、\(x_{\operatorname{far}}^2+y_{\operatorname{far}}^2\leq r^2(1+2^{-25})\) です。 よって、このとき \(r^2\lt d_{\operatorname{truth}}^2\leq r^2(1+2^{-25})\) です。

\(x\lt K\) で判定に失敗しているとき、\(r^2\geq d_{\operatorname{truth}}^2\) です。 このとき、数え上げらなかった \(\dfrac{N(N-1)}2-x\) 個の交点のうち最も原点に近いもの \(P_{\operatorname{far}}=(x_{\operatorname{far}},y_{\operatorname{far}})\) は \(d_{\operatorname{truth}}^2\geq x_{\operatorname{far}}^2+y_{\operatorname{far}}^2\) を満たします。 この交点をつくる \(2\) 直線について偏角ソートが失敗している必要があるので、\(x_{\operatorname{far}}^2+y_{\operatorname{far}}^2\geq r^2(1-2^{-25})\) です。 よって、このとき \(r^2\geq d_{\operatorname{truth}}^2\geq r^2(1-2^{-25})\) です。

以上より、判定に失敗するとき \(r^2(1-2^{-25})\leq d_{\operatorname{truth}}^2\leq r^2(1+2^{-25})\) が成り立ちます。

余談(読まなくても以下の読解に問題はありません)|誤差なしで判定

判定部分は誤差なしで計算を行うことができます。

与えられた \(2\) 直線 \(l_0:A_0x+B_0y+C_0=0,l_1:A_1x+B_1y+C_1=0\ (C_0,C_1\leq0)\) に対して、半径 \(\sqrt{r^2}\) の円との交点 \(p_{00},p_{01},p_{10},p_{11}\) の位置関係が高速に得られればよいです。 ただし、\(l_0\) と円との交点を \(p_{00},p_{01}\)、\(l_1\) と円との交点を \(p_{10},p_{11}\) とし、\(l_0,l_1\) へ原点から下ろした垂線の足 \(h_0,h_1\) について \(p_{00},h_0,p_{01}\) および \(p_{10},h_1,p_{11}\) がこの順に時計回りにあるとします。

\(h_0:\left(-\dfrac{A_0C_0}{A_0^2+B_0^2},-\dfrac{B_0C_0}{A_0^2+B_0^2}\right),h_1:\left(-\dfrac{A_1C_1}{A_1^2+B_1^2},-\dfrac{B_1C_1}{A_1^2+B_1^2}\right)\) は偏角がこの順であるとして一般性を失いません。この確認は整数の範囲で可能です。

円内に交点があるかは、\(\dfrac{(A_0C_1-A_1C_0)^2+(B_0C_1-B_1C_0)^2}{(A_0B_1-A_1B_0)^2}\leq r^2\) かを判定すればよいです。 \((A_0B_1-A_1B_0)^2\) は \(2^{42}\) 以下、\((A_0C_1-A_1C_0)^2+(B_0C_1-B_1C_0)^2\) は \(2^{43}\) 以下の整数なので double で正確に表現できます。 よって、\(0\leq(A_0B_1-A_1B_0)^2\times r^2-\left((A_0C_1-A_1C_0)^2+(B_0C_1-B_1C_0)^2\right)\) かを判定すればよく、これは正確に判定できます。

そうでないとき、\(2\) 直線は円内に交点を持ちません。 このとき、直線どうしの位置関係は整数の範囲の計算のみで決定できます。

円周上の適当な点からはじめた順序にするため、弦がその点をまたぐか判定する必要がありますが、同様に double で正確に判定できます。

詳細はこの提出を確認してください。


2. 探索区間の長さの評価

この問題は二分探索で解くことができる問題です。探索を \(n\) 回反復したときの探索区間の長さが \(n\) についてどのように表されるかについて考えます。

今回のアルゴリズムでは、はじめに \(r^2=1\) で判定を行ったあと、答えが \(1\) より大ならば幾何平均で、そうでないならば算術平均で二分探索の中間点を更新するようにする方法を採っています。

2-1. 答えが \(1\) より大と判定された場合

\(n\) 回目の探索では解が存在する区間 \(\left[L_{n-1}^2,R_{n-1}^2\right]\) に対して、\(M_n=\sqrt{L_{n-1}^2R_{n-1}^2}\) で判定を行います。

\(M_n\) は sqrt(L_sq * R_sq) で計算されています。 L_sq * R_sq は \(L_{n-1}^2R_{n-1}^2\) の正確な結果を丸めたものなので、たかだか \(2^{-53}\) の相対誤差があります。 sqrt(L_sq * R_sq)L_sq * R_sq の正の平方根の正確な値を丸めたものなので、同様にたかだか \(2^{-53}\) の相対誤差があります。 よって、M = sqrt(L_sq * R_sq) は \(\left[M_n\left(1-2^{-53}\right)^{3 /2},M_n\left(1+2^{-53}\right)^{3 /2}\right]\) に存在します。

対数をとった区間について考えます。 \(\left[\log L_{n-1}^2,\log R_{n-1}^2\right]\) に対して \(1\) 回判定を行った結果結果得られる区間 \(\left[\log L_n^2,\log R_n^2\right]\) は \(\left[\log L_{n-1}^2,\dfrac12\left(\log L_{n-1}^2+\log R_{n-1}^2\right)+\dfrac32\log(1+2^{-53})\right]\) もしくは \(\left[\dfrac12\left(\log L_{n-1}^2+\log R_{n-1}^2\right)+\dfrac32\log(1-2^{-53}),\log R_{n-1}^2\right]\) のどちらかに含まれます。

\(0\leq\dfrac32\log(1+2^{-53})\leq3\times2^{-54}\) および \(-2^{-52}\leq\dfrac32\log(1-2^{-53})\leq0\) なので、\(A_n\coloneqq\log R_n^2-\log L_n^2\) について \(A_n\leq\dfrac{1}{2}A_{n-1}+2^{-52}\) が成り立ちます。 よって、 \[A_n\leq\dfrac1{2^n}A_0+2^{-51}(1-\dfrac{1}{2^n})\] です。また、\(A_0=\log7984010000000=29.708\ldots\leq30\) です。

2-2. 答えが \(1\) 以下と判定された場合

\(n\) 回目の探索では解が存在する区間 \(\left[L_{n-1}^2,R_{n-1}^2\right]\) に対して、\(M_n=\left(\dfrac{\sqrt{L_{n-1}^2}+\sqrt{R_{n-1}^2}}2\right)^2\) で判定を行います。

\(M_n\) は (L_sq + R_sq + 2 * sqrt(L_sq) * sqrt(R_sq)) / 4 で計算されています。 sqrt(L_sq) および sqrt(R_sq) は \(L_{n-1}^2,R_{n-1}^2\) の正の平方根の正確な値を丸めたもので、\(L_{n-1}^2,R_{n-1}^2\leq1\) なのでたかだか \(2^{-53}\) の絶対誤差があります。 sqrt(L_sq) * sqrt(R_sq)sqrt(L_sq)sqrt(R_sq) の積の正確な値を丸めたものなので、同様にたかだか \(2^{-53}\) の絶対誤差が生じます。 よって、sqrt(L_sq) * sqrt(R_sq) は \[\left[\sqrt{L_{n-1}^2R_{n-1}^2}-2^{-52}-2^{-53}+2^{-106},\sqrt{L_{n-1}^2R_{n-1}^2}+2^{-52}+2^{-53}+2^{-106}\right]\] に存在します。 \(2\) 倍することで誤差は生じません。 \(2\) 回の和ではそれぞれ結果がたかだか \(2,4\) である足し算を行います。それぞれたかだか \(2^{-52},2^{-51}\) の絶対誤差が生じます。 \(R_{n-1}^2\) が最小の正規化数の \(4\) 倍以上なら、L_sq + R_sq + 2 * sqrt(L_sq) * sqrt(R_sq) の計算結果も最小の正規化数の \(4\) 倍以上なので、\(4\) で割ることで誤差は生じません。 よって、\(R_{n-1}^2\) が最小の正規化数の \(4\) 倍以上なら M = (L_sq + R_sq + 2 * sqrt(L_sq) * sqrt(R_sq)) / 4 は \[\left[M_n-2^{-49},M_n+2^{-49}\right]\] に存在します。

\(\left[\sqrt{L_{n-1}^2},\sqrt{R_{n-1}^2}\right]\) に対して \(1\) 回判定を行った結果結果得られる区間 \(\left[\sqrt{L_n^2},\sqrt{R_n^2}\right]\) は \(\left[\sqrt{L_{n-1}^2},\dfrac12\left(\sqrt{L_{n-1}^2}+\sqrt{R_{n-1}^2}\right)+2^{-49}\right]\) もしくは \(\left[\dfrac12\left(\sqrt{L_{n-1}^2}+\sqrt{R_{n-1}^2}\right)-2^{-49},\sqrt{R_{n-1}^2}\right]\) のどちらかに含まれます。

よって、\(R_{n-1}^2\) が最小の正規化数の \(4\) 倍以上であるかぎり、\(B_n\coloneqq\sqrt{R_n^2}-\sqrt{L_n^2}\) について \(B_n\leq\dfrac{1}{2}B_{n-1}+2^{-49}\) が成り立ちます。 よって、 \[B_n\leq\dfrac1{2^n}B_0+2^{-48}(1-\dfrac{1}{2^n})\] です。また、\(B_0=1\) です。

また、逆に \(B_n\geq\dfrac1{2^n}B_0-2^{-48}(1-\dfrac{1}{2^n})\) も成り立ちます。 ここから、\(n\lt20\) において \(R_n^2\) が最小の正規化数の \(4\) 倍以上であることがいえます。 よって、上の式は \(n\lt20\) において成立します。

3. 得られる出力と真の値との誤差

今回の実装では、はじめに \(1\) で判定するのに加えて判定を \(18\) 回行っています。

二分探索の性質から、出力時の L_sq の値は、\(0\) か、一度真の値より小さいと判定されたものです。 同様に、R_sq の値は \(7984010000000\) か、一度真の値以上であると判定されたものです。

L_sq が \(0\) のとき、\(d_{\operatorname{truth}}^2\leq r^2=2^{-36}\) と判定されています。 1 節での結果からこのとき \(d_{\operatorname{truth}}^2\leq2^{-36}(1+2^{-25})\) なので、 \( d_{\operatorname{truth}}\leq2^{-18}\sqrt{1+2^{-25}}\leq2^{-18}+2^{-44}\) です。 このとき出力される値は 0 なので、真の値との絶対誤差はたかだか \(2^{-18}+2^{-44}\lt10^{-4}\) です。

R_sq が \(7984010000000\) のとき L_sq は \(\dfrac{2043674939670817}{2^8}\) で、\(L^2\lt d_{\operatorname{truth}}^2\) と判定されています。 1 節での結果からこのとき \(d_{\operatorname{truth}}^2\geq L^2(1-2^{-25})\) なので、 \( d_{\operatorname{truth}}\geq\sqrt{L^2}\sqrt{1-2^{-25}}\) です。 問題の条件から \(d_{\operatorname{truth}}\leq\sqrt{7984010000000}\) です。 このとき出力される値は 2825438.945206413045526 なので、真の値との相対誤差は \(d_{\operatorname{truth}}=\sqrt{7984010000000}\) のときに最大になりたかだか \(0.567\times10^{-4}\lt10^{-4}\) です。

L_sq が \(0\) でも R_sq が \(7984010000000\) でもないとき、1 節での結果から \(L^2(1-2^{-25})\leq d_{\operatorname{truth}}^2\) および \(d_{\operatorname{truth}}^2\leq R^2(1+2^{-25})\) です。

L_sq と \(1\) との大小関係で場合分けを行います。

L_sq が \(1\) 未満なら、2 節での結果から \(\sqrt{L^2}\leq\sqrt{R^2}\leq\sqrt{L^2}+\dfrac1{2^{18}}+2^{-48}(1-\dfrac1{2^{18}})\) です。 よって、 \[\begin{aligned} \sqrt{L^2}\sqrt{1-2^{-25}}&\leq d_{\operatorname{truth}}\leq\left(\sqrt{L^2}+\dfrac1{2^{18}}+2^{-48}(1-\dfrac1{2^{18}})\right)(1+2^{-25})\\ \implies\qquad\sqrt{L^2}-2^{-25}&\leq d_{\operatorname{truth}}\leq\sqrt{L^2}+2^{-18}+2^{-24} \end{aligned}\] が成り立ちます。 sqrt(L_sq) の計算ではたかだか \(2^{-53}\) の絶対誤差が生じ、出力ではたかだか \(\dfrac{1}{2}\times10^{-15}\) の絶対誤差を伴う丸めが行われるので、出力される値と真の値の絶対誤差はたかだか \(0.388\times10^{-5}\lt10^{-4}\) です。

L_sq が \(1\) 以上なら、2 節での結果から \(\log L^2\leq\log R^2\leq\log L^2+\dfrac{15}{2^{17}}+2^{-51}(1-\dfrac1{2^{18}})\leq\log L^2+2^{-13}\) です。 ここから \(\sqrt{L^2}\leq\sqrt{R^2}\leq\sqrt{L^2}e^{2^{-14}}\) が得られます。 よって、 \[\begin{aligned} \sqrt{L^2}\sqrt{1-2^{-25}}&\leq d_{\operatorname{truth}}\leq\sqrt{L^2}e^{2^{-14}}(1+2^{-25})\\ \implies\qquad\sqrt{L^2}(1-2^{-25})&\leq d_{\operatorname{truth}}\leq\sqrt{L^2}(1+0.6107\times10^{-4}) \end{aligned}\] が成り立ちます。 sqrt(L_sq) の計算ではたかだか \(2^{-53}\) の相対誤差が生じ、出力ではたかだか \(\dfrac{1}{2}\times10^{-15}\) の相対誤差を伴う丸めが行われるので、出力される値と真の値の相対誤差はたかだか \(0.611\times10^{-4}\lt10^{-4}\) です。

よって、出力される値と真の値の相対誤差もしくは絶対誤差は \(0.611\times10^{-4}\lt10^{-4}\) で上からおさえられます。

4. まとめ

本ユーザ解説ではこの提出をもとに出力される値と真の値との誤差を評価してきました。

1 節では二分探索の判定に失敗するような \(r^2\) が \(r^2(1-2^{-25})\leq d_{\operatorname{truth}}^2\leq r^2(1+2^{-25})\) を満たすことを示しました。
2 節では二分探索の区間の長さを探索回数 \(n\) に対して上から評価しました。
3 節ではこれらをあわせて「今回の実装はすべての入力に対して、真の値との相対誤差もしくは絶対誤差が \(10^{-4}\) より小さい出力をする」ことを示しました。

ただし、この問題では想定解答からの誤差によって正答が保証されるため、出力と真の値との間の誤差が \(10^{-4}\) 以下であることは今回のコードがACすることを必ずしも意味しないことに注意してください。

posted:
last update: