『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

非数と無限大

非数(nan)

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

# PYTHON_NAN

# In[1]

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

print(x)
# nan

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

# In[2]

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

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

# PYTHON_NAN-3

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

math.nan

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

# PYTHON_MATH_NAN

# In[1]

import math

# nanを生成
x = math.nan

print(x)
# nan

math.isnan()

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

# PYTHON_MATH_ISNAN

# In[1]

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 を送出します)。

# NUMPY_NAN

# In[1]

import numpy as np

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

print(arr/0)
# [nan inf]

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

# In[2]

import numpy as np

# nanを生成
x = np.nan

print(x)
# nan

numpy.isnan()

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

# NUMPY_ISNAN

# In[1]

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)
# inf

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

# In[2]

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

print(neg_inf)
# -inf

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

# In[3]

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

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

# In[4]

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

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

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

# In[5]

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

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

# In[6]

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

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

# In[7]

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

math.inf

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

# PYTHON_MATH_INFINITY

# In[1]

import math

a = math.inf

print(a)
# inf

math.isinf()

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

# PYTHON_MATH_INF

# In[1]

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_ISFINITE

# In[1]

import math

a = math.inf

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

print(x)
# False

numpy.inf

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

# NUMPY_INF

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

print(x)
# inf

numpy.NINF

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

# NUMPY_NINF

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

print(x)
# -inf

numpy.isinf()

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

# NUMPY_ISINF

# In[1]

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 を返します。

# NUMPY_ISPOSINF

# In[1]

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 を返します。

# NUMPY_ISNEGINF

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_ISFINITE

# In[1]

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 という記号で無限大 (∞) を扱います。

# SYMPY_INFINITY

# In[1]

# 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 の演算は普通の数の演算とは異なる結果を返します。

コメント