非数と無限大

非数と無限大

非数(nan)

 nannot a number (非数) の略で、異常な数値を表す浮動小数点数型オブジェクトであり、後述するように inf を用いた演算の結果として生成されることがあります。nan は float("nan") で生成することもできます (とはいえ、意図的にこのオブジェクトを生成しても使い道はほとんどないでしょう)。

# PYTHON_NAN-1

# 非数(nan)を生成
x = float("nan")

print(x)
nan

 nan を含む四則演算の実行結果は常に nan です。

# PYTHON_NAN-2

# nan(非数)の四則演算
print(x + 1)
print(x - 1)
print(2 * x)
print(x / 2)
nan
nan
nan
nan

 nan から nan を引いても 0 にはなりません。
 実行結果はやはり nan です。

# PYTHON_NAN-3

# 非数同士の減算
print(x - x)
nan

 

math.nan

 math モジュールをインポートすれば、math.nan で nan を呼び出せます。これは float("nan") と全く等価です。

# PYTHON_MATH_NAN_01

import math

# nanを生成
x = math.nan

print(x)
nan

 

math.isnan()

 math.isnan() は x が nan のときにのみ True を返します。それ以外は False を返します。

# PYTHON_MATH_NAN_02

import math

# ∞-∞
a = math.inf - math.inf

# xは非数?
x = math.isnan(x)

print(x)
True

 

numpy.nan

 NumPy の配列演算において、nan は 0/0 や ∞/∞ の演算結果として生成されます (Python 本体では 0/0 は ZeroDivisionError を送出します)。

# PYTHON_NUMPY_NAN_01

import numpy as np

arr = np.array([0, 1])

print(arr/0)
[nan inf]

 numpy.nan を使えば意図的に nan を呼び出すことができます。

# PYTHON_NUMPY_NAN_02

import numpy as np

# nanを生成
x = np.nan

print(x)
nan

 

numpy.isnan()

 numpy.isnan() は受け取った配列の要素が非数であるかを判定してブール値 (True または False) を返します。

# PYTHON_NUMPY_NAN_03

import numpy as np

# ∞を定義
inf = np.inf

# ∞-∞
x = np.isnan(inf - inf)

print(x)
True

無限大(inf, -inf)

 Pythonでは float() の引数に文字列 "inf" あるいは "infinity" を渡すと、inf というオブジェクトが返ります。inf は infinity の略で、正の無限大 (+∞) を意味する特殊な浮動小数点数型データです。

# PYTHON_INFINITY-1

# 正の無限大
pos_inf = float("inf")

print(pos_inf)
print(neg_inf)
# 正の無限大
pos_inf = float("inf")

# 負の無限大
neg_inf = float("-inf")

print(pos_inf)

 float() に "-inf" もしくは "-infinity" という文字列を渡すと、負の無限大を意味する -inf が返ります。

# PYTHON_INFINITY-2

# 負の無限大
neg_inf = float("-inf")
print(neg_inf)

 inf と -inf は floatクラスのオブジェクトなので、算術演算子を使って inf 同士、あるいは他の数値と演算させることが可能ですが、その戻り値には注意が必要です。たとえば、inf に整数や浮動小数点数、あるいは inf 自身を加える演算はすべて inf を返します。

# PYTHON_INFINITY-3

print(pos_inf + 1)
print(pos_inf - 1.5)
print(pos_inf + pos_inf)
inf
inf
inf
inf

 ただし、inf に複素数を加える操作は実数部だけが inf となります。

# PYTHON_INFINITY-4

# 複素数zを定義
z = 2 + 3j

print(pos_inf + z)
(inf+3j)

 inf に正の整数や浮動小数点数、あるいは inf 自身を掛けると、inf が返ります。

# PYTHON_INFINITY-5

print(2 * pos_inf)
print(1.5 * pos_inf)
print(pos_inf * pos_inf)
inf
inf
inf

 inf に負の整数や浮動小数点数、あるいは -inf を掛けると、符号が反転して -inf が返ります。 

# PYTHON_INFINITY-6

print(-2 * pos_inf)
print(neg_inf * pos_inf)
-inf
-inf

 inf から inf を引く、あるいは inf と -inf を加える演算は 0 ではなく nan (非数) を返します。

# PYTHON_INFINITY_7

print(pos_inf - pos_inf)
print(pos_inf + neg_inf)
nan
nan

 

math.inf

 math.inf は inf を呼び出します。
 float("inf") の出力と等価です。

# PYTHON_MATH_INFINITY_01

import math

a = math.inf

print(a)
inf

 

math.isinf()

 math.isinf() は引数が無限大 (inf または -inf) であるときは True, それ以外は False を返します。

# PYTHON_MATH_INFINITY_02

import math

a = math.inf

# ∞+∞がinfまたは-infであるかを判定
x = math.isinf(a + a)

print(x)
True

 

math.isfinite()

 math.isfinite()は引数が有限数のときに True、それ以外 (inf, -inf, nan など) の場合は False を返します。

# PYTHON_MATH_INFINITY_03

import math

a = math.inf

# aが有限数であるかを判定
x = math.isfinite(a)

print(x)
False

 

numpy.inf

 numpy.inf は inf を呼び出します。
 float("inf") と全く等価です。

# PYTHON_NUMPY_INFINITY_01

# infを呼び出す
x = np.inf

print(x)
inf

 

numpy.NINF

 numpy.NINF は -inf を呼び出します。
float("-inf") と全く等価です。

# PYTHON_NUMPY_INFINITY_02

# -infを呼び出す
x = np.NINF

print(x)
-inf

 

numpy.isinf()

 numpy.isinf() は引数が無限大 (inf または -inf) であれば True, 有限数であれば False を返します。

# PYTHON_NUMPY_INFINITY_03

import numpy as np

arr = np.array([np.inf, np.NINF, np.nan, 1])

x = np.isinf(arr)

print(x)
[True  True  False  False]

 

numpy.isposinf()

 numpy.isposinf() は引数が正の無限大 (inf) のときのみ True を返し、それ以外には False を返します。

# PYTHON_NUMPY_INFINITY_04

import numpy as np

arr = np.array([np.inf, np.NINF, np.nan, 1])

x = np.isposinf(arr)

print(x)
[True  False  False  False]

 

numpy.isneginf()

 numpy.isneginf() は引数が負の無限大 (-inf) のときのみ True を返し、それ以外には False を返します。

# PYTHON_NUMPY_INFINITY_05

import numpy as np

arr = np.array([np.inf, np.NINF, np.nan, 1])

x = np.isneginf(arr)

print(x)
[False  True  False  False]

 

numpy.isfinite()

 numpy.isfinite() は引数が有限数のときに True を返し、それ以外は False を返します。

# PYTHON_NUMPY_INFINITY_06

import numpy as np

arr = np.array([np.inf, np.NINF, np.nan, 1])

x = np.isfinite(arr)

print(x)
[False  False  False  True]

 

SymPy における無限大演算

 SymPy では oo という記号で無限大 (∞) を扱います。

# PYTHON_SYMPY_INFINITY

# sympyから無限大記号をインポート
from sympy import oo

# 無限大記号の演算
print("oo + 1 = {}".format(oo + 1))
print("oo - oo = {}".format(oo - oo))
print("oo / oo = {}".format(oo / oo))
oo + 1 = oo
oo - oo = nan
oo / oo = nan

 oo から oo を引いても 0 にはならず、nan という記号が返っています。
 nan は not a number (非数) を意味する記号です。
 このように、oo の演算は普通の数の演算とは異なる結果を返します。