Atan2

atan2は、関数の一種。「2つの引数を取るarctan」という意味である。x軸の正の向きと、点 }}まで伸ばした半直線との間の、ユークリッド平面上における角度として定義される。関数はもしくはの形をとり、値はラジアンで返ってくる。

関数は、プログラミング言語のFortran において最初に登場した。元々は、角度θ}}を直交座標系の}}から極座標系の}}に変換する際に、正確で一意な値が返ってくることを意図して導入された。また、は複素数の偏角 を求める際にも利用される。

関数 は、−//π// < mvarの範囲で、

となる単一の値θ}}を返す。

なお、arctanを使って角度θ}}を求める際に注意すべきことであるが、が真であるからと言って、

であるということが常に言えるとは限らない。

これは、//x// > 0}}だった場合にのみ当てはまる。もし//x// < 0}}だった場合は、上の式から導出された角度は、正しい角度とは正反対の方向を指し示している。そして、デカルト点}}をユークリッド平面上の正しい象限に配置するには、の値をθ}}に加算または減算する必要がある。これはつまり、正しい角度を出すためにはx}}およびy}}の符号の情報がそれぞれ別個に必要とされると言うことであり、もし単にy}}をx}}で除算した場合は、その情報が失われてしまうというわけである。その点、atan2は細かいことを気にしなくてもyとxに代入すれば普通に正しい角度を返してくれるので便利である。

関数の戻り値である角度θ}}については、x}}とy}}の値を変更しないままでも角度θ}}に2pi}}}}の任意の整数倍を加算することが可能であるため、つまり区間をちゃんと設定しないと戻り値の値が曖昧になってしまうため、関数atan2はその主値として、区間を(−pi}}, pi}}]}}としたものが戻り値として返ってくるようになっている。角度θ}} は符号付き角度であり、反時計回りの角度は正、時計回りは負となる。具体的に言うと、もし//y// ≥ 0}}だった場合は0, pi}}}} の区間にあり、もし//y// < 0}}だった場合には−pi}}, 0}}の区間にある、と言う感じになるように関数の内部で場合分けをしている。

1. atan2が生み出された経緯と動機
--------------------

atan2}}関数は、元々は特定のプログラミング言語に実装された関数の一つに過ぎなかったが、現在では他の科学技術の分野でもよく使われるものとなっている。その起源は少なくとも、古のプログラミング言語であるFORTRANにまで遡ることができるが、現在においては他の現代的なプログラミング言語においても実装されている。例を挙げると、C言語のmath.h 標準Cライブラリ、JavaのMathライブラリ、.NETのSystem.Math 、Pythonのmathモジュール、RubyのMathモジュール、Goのmathパッケージ、などであるが、もちろん他にもたくさんの言語に実装されている。さらに言うと、Perlを始めとするスクリプト言語にも、C言語風のatan2関数が実装されていることが多い。

atan2関数が生み出された背景として、単一引数のみを取るアークタンジェントは正反対の方向を区別できない、と言う使い勝手の悪さがある。例えば、x}}軸とベクトル}}がなす反時計回りの角度を、arctan関数を使って「arctan}}」のような形で計算した場合、「π/4}}ラジアン」という答えが返ってくる。しかし、x}}軸とベクトル}}の間の角度を同様に、「arctan}}」のような形で計算してみると、期待される答えは「−3π/4}}ラジアン」または「5π/4}}ラジアン」であるにもかかわらず、やっぱり「π/4}}ラジアン」が返ってくる。arctan関数の使い勝手の悪さをさらに言うと、x}}軸とベクトル}}がなす角度をarctan関数で計算しようとすると、これはarctan}}の評価が必要になるわけだが、こんなことをさせるとコンピューターはゼロ除算のエラーを吐いてバグる。

atan2関数は、2つの変数 y}} と x}}から一意なアークタンジェントの値を算出するが、そのとき両変数の正負の符号が、実行結果の象限を決定するために利用される。それに基づいて、アークタンジェントで「//y/////x//}}」したときの結果の中から、求める値が出るような分岐先に飛ばしている。例を挙げると、「1=atan2 = π/4}}」 と 「1=atan2 = −3π/4}}」のどちらに分岐するのか、と言ったことを判別している。また、例えば「ゼロ除算のエラーを吐いてバグる」の代わりに「1=atan2 = π/2}}」に分岐させるときも、同様の方法で飛ばしている。

もちろん、場合によって必要な象限補正と例外処理をいちいち精査することで、上記の計算を力技で行うことは可能だが、そんなことをするよりも、常に一意な正しい結果を返してくれるような1つの関数が存在した方が便利である。そんな経緯でatan2関数が存在する。atan2}}関数は様々な応用において有用であり、例えばユークリッド空間上におけるユークリッド点に関して、1つの点から別の点へと至る方向ベクトルを調べるのに便利である。主な用途としては、コンピューターグラフィックスにおける回転において、回転行列をオイラー角に変換する際に使われる。

2. 定義と計算
--------

定義}}定義 関数 atan2}} は複素数 //x//   +   //y//i}} に偏角関数 arg}} を適用した時の主値を計算する。すなわち、atan2 =}} Pr   arg =}} Arg}} である。偏角は、2π}}の整数倍を加えたものも同じ角度になるが、atan2}} を一意に定義するために範囲 の主値を使用する。つまり、−//π// < atan2 ≤ //π//}} とする。

標準の arctan}} 関数を用いて、次のように表すことができる:

重複する4つの半平面を用いたコンパクトな式:

アイバーソンの記法を用いれば、さらにコンパクトな式が可能:

一見すると条件式のない数式:

タンジェントの半角の公式から派生した次の式で atan2}} を定義することもできる:

この式は、上記の定義よりもシンボリックな使用に適している場合がある。ただし、 の丸め誤差の影響が領域 1=//x// < 0, //y// = 0}} の近くで拡大するため、一般的な浮動小数点数の計算用途には適していない。

これらの膨らんだ丸め誤差を回避するため、先ほどの式を変形:

注意:

これにより、範囲 −π, π}} の結果が生成される。
上記のように、偏角の主値 atan2}} は、三角法によって arctan}} に関連付けることができる。 導出は次のようになる:  =}} }} のとき tan =}} //y// / }} となる。その結果、次式が成立する。 問題の領域は sqrt であることに注意。

3. 微分
-----

関数 atan2}} は2変数関数であるため、2つの偏導関数がある。これらの導関数が存在する点では、atan2}} は定数項を除いた arctan}} に等しくなる。したがって、//x// > 0}} または //y// ≠ 0}} の場合、

したがって、atan2 の勾配は次式で与えられる。

関数 atan2}} を角度関数 1=//θ// = atan2}} として省略して表すと、全微分について次の式が得られる:

関数 atan2}} は、負の x}} 軸に沿って不連続であるが、角度を連続的に定義できないという事実を反映して、この導関数は原点を除いて連続的に定義される。これは、角度の微小な//変化//が原点を除くすべての場所で定義できるという事実を反映している。この導関数をパスに沿って積分するとパス全体の角度が全体的に変化し、閉ループで積分すると回転数が得られる。

微分幾何学の言語では、この導関数は1-形式であり、閉であるが、完全ではない。実際、1点を除いた平面の1次のド・ラームコホモロジーを生成する。これはそのような形式の最も基本的な例であり、微分幾何学の基本である。

atan2}} の偏導関数には三角関数が含まれていないため、三角関数の評価にコストがかかる可能性がある多くのアプリケーションで特に役立つ。

4. 図による可視化
----------

この図は、ある半直線に沿ったatan2の値を単位円上に示している。atan2の値はラジアンであり、単位円内に記載されている。標準的な数学の方式に従い、角度は右方向の半直線をゼロとして反時計回りに増加する。ここで、２つの引数の順序が座標と比べて入れ替わっていることに注意が必要である。すなわち、関数atan2}}は座標}}に対応する角度を計算する。

この図はと、におけるの値を示している。両方の関数ともに奇関数であり、それぞれとの周期関数である。このため、の実数値における補角となることが出来る。一例としてのにおける分岐截断、およびのにおける分岐截断が明確に確認出来る。

下記の２つの図は、atan2}}およびarctan}}における//X/////Y//平面の原点から伸びる半直線が定数値なのに対し、arctan(sfracでは//X/////Y//平面の原点を通る直線が定数値である。//x// > 0}}において、２つの図は同一の値となる。



5. 加法定理
-------

の和は、下記の定理によれば一つの式にまとめることができる。

...ここで.

証明には、 または 、および かつ の二つのケースにわけて行う必要がある。 ここでは前者の または のケースのみにおいて考える。最初に、下記の考察を行う：

において または .
であり、は複素数の偏角の数値計算である。
である限り、が成り立つ。
.において、複素数の偏角の定理により、ここで 、従って となる。さらに、全ての正の実数値に対してが成り立ち、 および とすると、となる。

上記より、次の等式が成り立つ：

Corollary: もし および が２次元のベクトルであり、これらベクトル間の角度を計算するのに を用いた差分の式が頻繁に用いられているとすると、計算結果はの区間となることから、ほとんどのケースではレンジチェックは不要となる。

6. 東-反時計回り、北-時計回り および 南-時計回り等の変換
--------------------------------

関数は元々数学的に多く用いられる、原点から右の半直線から反時計回りに動く場合の変化について定義している。一方実際の実装系では、北-時計回り および 南-時計回りの変換がよく用いられる。 例えば気象学において、風向は関数を用いて、風の東および北向きの成分を引数として利用して計算されている。 同様に太陽の方位角も東および北方向の成分を引数として用いている。風向きは通常北-時計回りで定義されているためであり、太陽の方位角は北-時計回り および 南-時計回り両方を用いて広く計算されていためである。 これらの異なる変換は、下記のように位置の置換およびx/y座標の符号を下記のように変更することで実現できる：



. 例として、 で の場合、東-反時計回りの場合には、北-時計回りでは南-時計回りのようになる。

x/y成分の符号の変更と位置の転換は結果として８つのの定義が可能となる。それらは時計回り・反時計回りの４つの方角・東西南北を始点とする。

7. プログラミング言語における実装
------------------

atan2のプログラミング言語での実装は言語毎に異なる。

Microsoft Excel、OpenOffice.org Calc、LibreOffice Calc、Google Spreadsheets, iWork Numbers、およびANSI SQL:2008 standardでは、２つの引数をもつatan2関数はそのままの順序の引数で定義されている 。
MathematicaではArcTan[//x//,&hairsp;//y//]の形式が用いられ、引数が一つの場合は通常のアークタンジェントになる。MathematicaではArcTan[0,&hairsp;0]は不定となる。入れ替わった順序の引数は下記で用いられている：

C言語のatan2関数を始めとする多くのプログラミング言語では、直交座標系から極座標系への変換の手間を減らすため、引数は入れ替わったものが使われており、atan2も定義されている。実装においては−0を除外している、あるいは+0が引数に指定された場合には単純にゼロと定義している。関数は常に−π, π}}の間の値を返し、エラーやNaN を返すことはしない。
Common Lispでは引数の数は可変なので、atan関数は１つの場合と//x//座標を付加したが定義されている。
Juliaでは、Common Lisp同様にatan2関数を定義する代わりに、atanが１つまたは２つの引数を持っている。 １つの関数が複数のメソッドを行う副作用として、コンパイル時の最適化時間が多くなってしまう。
Intelアーキテクチャーのx87命令では、 atan2はFPATAN  命令で実装される。この命令は無限大を扱うことができ、結果は閉区間−π, π}}の値となる。例えば、有限の//x//に対し、atan2 = +π}}/2となる。特に両方の引数がゼロである時、FPATANは下記のようになる： atan2 = +0; atan2 = +π}}; atan2 = −0; atan2 = −π}}. この定義は-0の定義に従ったものとなる。
コード以外での学術論文などの数学的表記では、通常の arctanおよびtan−1の最初の１文字を大文字にしたArctanおよびTan−1が用いられる。用法は複素数の偏角と同様で、Atan =}} Arg}}となる。
シンボリック算術をサポートする実装系では通常、atan2}} は不定値あるいはエラーを返す。
-0、無限大やNaNをサポートする実装系