2017-01-23 3 views
0

私はpython2.7でいくつかのベクトルの間の角度を計算しようとしています。 私は以下のアイデンティティーを使って角度を見つけています。は、有界のドメインを持つ関数にfloatを渡します。

シータ= ACOS(w/vで| V || W |)

特定のインスタンスのために私のコードは次のとおりです。

v = numpy.array([1.0, 1.0, 1.0]) 
w = numpy.array([1.0, 1.0, 1.0]) 
a = numpy.dot(v, w)/(numpy.linalg.norm(v) * numpy.linalg.norm(w)) 
theta = math.acos(a) 

私はこれを実行すると、私はエラーにValueError: math domain error

を取得

これは、acosはドメイン[-1,1]上でのみ定義されており、私の値 'a'は1に非常に近いが実際は少し大きいfloatであるためです。私はこれをprint Decimal(a)と確認でき、1.00000000000002220446 ...

この問題を回避する最も良い方法は何ですか?

私は、 'a'の値が1より大きい(または-1より小さい)かどうかをチェックし、正確に1に丸めると考えることができます。この問題を解決するために、従来の/もっと一般的な方法がありますか?あなたは数学に

を再整理し、acos1 + epsトラブルを避けるために、私のtheta = atan2(b,a)製剤で修飾し、あなたのコードで使用することができれば

答えて

0

numpy.clip:Angles between two n-dimensional vectors in Python

numpy.nan_to_num:に使用されたのも良いパッチのように見えます(これは私の第1回目のパスでした:b = np.nan_to_num(np.sqrt(1 - a ** 2))

しかし、私は普遍的なドット製品の普遍的使用に関しては、ベクトルの問題との間の角度のため、特に我々はnp.cross製品を有する2および3 D

でIはatan2に非正規化a「余弦」という用語は、私b両方を通る、外積をb「サイン」という用語を形成する好みます: - とにかく

atan2はノルム引数を必要としません

import numpy as np 
v = np.array([1.0, 1.0, 1.0]) 
w = np.array([1.0, 1.0, 1.0]) 

a = np.dot(v, w) 
c = np.cross(v, w) 
b = np.sqrt(np.dot(c,c)) 

theta = np.arctan2(b,a) 

あなたはノルム引数を使用する場合atan2(b, a)製剤はlinalg.norm浮動小数点公差から1 + epsフロートエラーと例外をスローしません。(のビット:私はそれは外積で全体のちょうどacos

編集でa内積「コサイン」という用語で情報を使用するよりも優れた精度を与えるb用語とatan2より数値的に堅牢であると考えてい

数学、について説明、MathJaxはこのフォーラム上で有効にしていないようですので、上記のコードのように、多少のテキストで入力したベクトル数学を混合Cない同じA、B、)

* B = | a || b | COS(ワット)=

CXB = | || B |罪(ワットc_unit_vector

のsqrt(CC * )= | || B | c_unit_vector * c_unit_vector以来の罪(ワット = 1

ので、ATAN(で終わる| || B |罪(ワット)、| || B | COS(ワット))と| a || b | atanの内部の比率計算でキャンセルする

+0

私はこのtanソリューションを実装しました。それはうまくいく(ありがとう)が、どのように機能するのですか?あるベクトルのもう一方のベクトルへの投影と直交する間の角度をとるように見えます。 – Jemma

関連する問題