NumPyで三角関数のアイデンティティを評価するときの驚くほど大きな違い


8

Wolfram AlphaとSageコンピュータ代数システムによれば、次のアイデンティティが成り立つ:

cos(arctan(l1l2d))=11+(l1l2)2d2

しかし、NumPyの任意の例を使用してそれを検証しようとすると、偶発性の両側で計算された実際の値にかなり大きな違いがあることに気付きました。私は次のコードを使用しました:

    l1 = 10; l2 = 8; d = 17
    from numpy import arctan2, cos, sin, sqrt

    alpha = arctan2((l1-l2),d)
    left = cos(alpha)

    right = sqrt(1 + ((l1-l2)**2)/(d**2))

結果を評価するleftright、次の結果が得られました。

    left = 0.99315060432287616
    right = 1.0

これを単なる数値エラーとして書き留めるのは魅力的ですが、私は数値エラーがどれほど大きくなるかについての経験がほとんどないため、確信が持てません。これは可能ですか、それとも何かが欠けていますか?


2
あなたrightが間違って入力されています。それはする必要がありますright = 1/sqrt() ...私は私のTi-89に数式を入力すると、私は0.99315で12桁に試合を出す
Godricシーア

ええ、平方根の式が正しく評価されていたら、彼はそれをキャッチしたと思います。
Michael Grant

ええ、彼の表現を入力すると、1.007が表示されました。
Godric Seer 2013

1
まあ、本当に。それは恥ずかしいです。お気づきありがとうございます。
Daniel Eberts

自分の前でこの間違いをしました。
マイケル・グラント

回答:


10

あなたの右側のPython式が浮動小数点除算ではなく整数除算を行っているのではないかと疑っています。その結果、((l1-l2)**2)/(d**2)はゼロとして評価され、平方根内の項は1になります。

実際、右手の式にも逆数を忘れてしまいましたが、それが最初の問題ではありません...

MATLABの場合:

>> l1 = 10; l2 = 8; d = 17;
>> alpha = atan2((l1-l2),d)
alpha =
    0.1171
>> left = cos(alpha)
left =
    0.9932
>> right = 1/sqrt(1 + ((l1-l2)^2)/(d^2))
right =
    0.9932

6
私はfrom __future__ import division、この目的のためにすべてのpythonスクリプトの一番上で使用する習慣に慣れてきました。
ジェフリーアーヴィング

@GeoffreyIrving、それを答えに変えれば、私はあなたがそのための深刻な担当者を得るに違いない。いいアドバイス。
Michael Grant

7

Michael C. Grantが指摘したように、問題は除算演算が浮動小数点除算ではなく整数除算であることです。3より前のバージョンのPythonでは/、整数に切り捨てて2つの整数を除算していました。この動作は、

from __future__ import division

スクリプトの上部。この宣言/は、現在のファイルの動作のみを変更することに注意してください。たまに元の動作が必要な場合は、//(ダブルスラッシュ)を使用します。これについては、ここで詳しく説明します。

PEP 238-除算演算子の変更

Cを含むほとんどの言語の除算のセマンティクスは似ていますが、整数は通常、関数に渡されたときに浮動小数点に昇格されないため、Pythonではセマンティクスがより混乱します。したがって、あたかも浮動小数点で動作しているかのように書かれた関数は、実際には整数で動作している可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.