あなただけの浮動小数点演算の効果を見ています。 (numpy配列の代わりにPythonリストを使用した場合も同じことが成り立ちます)
numpyで浮動小数点の「近い」比較を行う組み込み関数が実際には驚いています... 2つのnumpy配列を比較するのにnumpy.allclose
がありますが、ブール値配列ではなくTrue
またはFalse
が返されます。
これを実行するのは、実際には少し難しいことです。 inf
は偽陽性と偽陰性でスローされます。さらに、警告を上げるので、我々は、一般的にそれを行う避けたいだろうそれらでinf
またはnan
で二つの配列を差し引く...
import numpy as np
def close(a, b, rtol=1.e-5, atol=1.e-8, check_invalid=True):
"""Similar to numpy.allclose, but returns a boolean array.
See numpy.allclose for an explanation of *rtol* and *atol*."""
def within_tol(x, y, atol, rtol):
return np.less_equal(np.abs(x-y), atol + rtol * np.abs(y))
x = np.array(a, copy=False)
y = np.array(b, copy=False)
if not check_invalid:
return within_tol(x, y, atol, rtol)
xfin = np.isfinite(x)
yfin = np.isfinite(y)
if np.all(xfin) and np.all(yfin):
return within_tol(x, y, atol, rtol)
else:
# Avoid subtraction with infinite/nan values...
cond = np.zeros(np.broadcast(x, y).shape, dtype=np.bool)
mask = xfin & yfin
cond[mask] = within_tol(x[mask], y[mask], atol, rtol)
# Inf and -Inf equality...
cond[~mask] = (x[~mask] == y[~mask])
# NaN equality...
cond[np.isnan(x) & np.isnan(y)] = True
return cond
# A few quick tests...
assert np.any(close(0.300001, np.array([0.1, 0.2, 0.3, 0.4])))
x = np.array([0.1, np.nan, np.inf, -np.inf])
y = np.array([0.1000001, np.nan, np.inf, -np.inf])
assert np.all(close(x, y))
x = np.array([0.1, 0.2, np.inf])
y = np.array([0.101, np.nan, 0.2])
assert not np.all(close(x, y))
を何が価値があるため、これは浮動小数点演算との生活の一般的な事実です。これは、numpy配列の場合と比べて、Pythonリストには違いはありません。基本的には、 '=='を使って浮動小数点の等価性をテストしないでください。 –
Bの値の合計でBのバイナリ検索を行い、Bの値の差の絶対値をAの合計と比較します。Bの2つの値をチェックする必要があります。 Bで少し上または下にある可能性があります。 –
FYI:https://github.com/numpy/numpy/commit/b9f0f1f8b54d0e4cf74ea5e7d80893d66585c4a1 '1.7'に' numpy.isclose() '関数があります。 –