2021-04-03に投稿

Python 標準ライブラリ math 数学関数

読了目安:15分

Pythonには各種数学関数にアクセスするためのライブラリmathが用意されています。

数学定数

pi 円周率 π

import math
math.pi # => 3.141592653589793

tau 円周率の2倍 2π

math.tau # => 6.283185307179586

e 自然対数の底、ネイピア数

math.e  # => 2.718281828459045

inf 無限大

math.inf # => inf

nan 非数 not a number(NaN)

math.nan # => nan

基本的な数論・数値計算の関数

ceil(x) xより大きい最小の整数

math.ceil(1.1) # => 2

comb(n, k) n個からk個選ぶ組み合わせ

math.comb(5, 2) # => 10
math.comb(5, 3) # => 10
math.comb(5, 5) # => 1
math.comb(5, 0) # => 1

copysign(x, y) 絶対値x、符号yの数値

math.copysign(5.0, -2.0) #= > -5.0
math.copysign(-5.0, -2.0) #= > -5.0
math.copysign(-5.0, 2.0) #= > 5.0
math.copysign(5.0, 2.0) #= > 5.0

fabs(x) 絶対値

math.fabs(-1.23) # => 1.23

factorial(x) 階乗

math.factorial(10) # => 3628800

floor(x) x以下の最大の整数

math.floor(5.1) # => 5

fmod(x, y) xをyで割った余り x - (xをyで割った商) * y

fmodは余りがxと同じ符号となる。%で余りを出すと絶対値が小さいほうが採用される。

math.fmod( 14,  3) # =>  2.0   14-   4*  3  ->  2.0
math.fmod( 14, -3) # =>  2.0   14-(-4)*(-3) ->  2.0
math.fmod(-14,  3) # => -2.0  -14-(-4)*  3  -> -2.0
math.fmod(-14, -3) # => -2.0  -14-   4*(-3) -> -2.0
 14 %  3 # =>  2   14 -    4*  3  ->  2
 14 % -3 # => -1   14 - (-5)*(-3) -> -1
-14 %  3 # =>  1  -14 - (-5)*  3  ->  1
-14 % -3 # => -2  -14 - (-4)*(-3) -> -2

frexp(x) 仮数と指数の組(m, e)を取得

x == m * 2**e(mは0または絶対値が0.5以上1未満)を計算する。

math.frexp(1.5) # => (0.75, 1)
1.5 == 0.75*2**1 # => True

math.frexp(1024) # => (0.5, 11)
1024 == 0.5*2**11 # => True

math.frexp(0) # => (0.0, 0)
0 == 0.0*2**0 # => True

math.frexp(1e10) # => (0.5820766091346741, 34)
1e10 == 0.5820766091346741*2**34 # => True

math.frexp(-100) # => (-0.78125, 7)
-100 == -0.78125*2**7 # => True

fsum(iterable) 浮動小数点の和

math.fsum(0.1 for x in range(10)) # => 1.0

# 組み込みsumより小数点の精度が出せる場合がある
sum(0.1 for x in range(10)) # => 0.9999999999999999

gcd(*integers) 最大公約数 greatest common divisor

math.gcd(2, 3) # => 1
math.gcd(91, 1729, 7) # => 7

isqrt(n) 2乗してnを超えない最大の整数

math.isqrt(25) #=> 5
math.isqrt(35) #=> 5
math.isqrt(36) #=> 6

lcm(*integers) 最小公倍数 least common multiple

math.lcm(2, 3, 4, 5, 6, 7, 8, 9) # => 2520

ldexp(x, i) 仮数と指数の組から値を取得

x * 2**iを計算する。

math.ldexp(0.75, 1) # => 1.5
math.ldexp(0.5, 11) # => 1024.0
math.ldexp(0, 0) # => 0.0
math.ldexp(0.5820766091346741, 34) # => 10000000000.0
math.ldexp(-0.78125, 7) # => -100.0

frexpとは逆関数の関係になっている。

math.frexp(math.ldexp(0.5820766091346741, 34)) # => (0.5820766091346741, 34)
math.ldexp(*math.frexp(10000000000.0)) # => 10000000000.0

modf(x) 小数部分と整数部分の取得

math.modf(1.25) # => (0.25, 1.0)
math.modf(1.29) # => (0.29000000000000004, 1.0)
math.modf(-1.25) # => (-0.25, -1.0)

nextafter(x, y) xからyに向かって近い浮動小数の値

math.nextafter(1.1, 1.0) # => 1.0999999999999999
math.nextafter(1.1, 1.2) # => 1.1000000000000003


math.nextafter(1.1, math.inf) # => 1.1000000000000003
math.nextafter(math.inf, math.inf) # => inf
math.nextafter(-math.inf, math.inf) # => -1.7976931348623157e+308

math.nextafter(1.1, -math.inf) # => 1.0999999999999999
math.nextafter(math.inf, -math.inf) # => 1.7976931348623157e+308

math.nextafter(1.1, 0) # => 1.0999999999999999
math.nextafter(-1.1, 0) # => -1.0999999999999999
math.nextafter(-math.inf, 0) # => -1.7976931348623157e+308
math.nextafter(math.inf,0) # => 1.7976931348623157e+308

math.copysignとの組み合わせで、0から離れる関数を定義できる。

def away_from_zero(x):
    return math.nextafter(x, math.copysign(math.inf, x))

away_from_zero(1.1) # => 1.1000000000000003
away_from_zero(-1.1) # => -1.1000000000000003
away_from_zero(0) # => 5e-324

perm(n, k=None) n個からk個選ぶ順列

math.perm(10) # => 3628800
math.perm(10, None) # => 3628800
math.perm(10, 3) # = > 720

prod(iterable, *, start=1) イテレータの積

start:積の初期値。

math.prod([1, 2, 3, 4, 5]) #= > 120
math.prod([1, 2, 3, 4, 5], start=10) #= > 1200

remainder(x, y) xをyで割った余り

商は x/yに近い整数(真ん中の場合偶数)。

math.remainder(14,  3) # => -1.0
# x/y = 14/3 = 4.666666666666667なので商qは5
# x-q*y = 14-5*3 = -1

math.remainder(13,  3) # => 1.0
# x/y = 13/3 = 4.333333333333333なので商qは4
# x-q*y = 13-4*3 = 1

math.remainder(13,  2) # => 1.0
# x/y = 13/2 = 6.5なので商qは偶数6
# x-q*y = 13-6*2 = 1

math.remainder(15,  2) # => -1.0
# x/y = 15/2 = 7.5なので商qは偶数8
# x-q*y = 15-8*2 = -1

trunc(x) 整数へ切り捨て

math.trunc(1.5) # => 1
math.trunc(-1.1) # => -1

ulp(x) 最下位ビットの浮動小数

math.ulp(1) # => 2.220446049250313e-16

数値の判定を行う関数

isfinite(x) 通常の数(無限、NaN以外)の判定

math.isfinite(1) # => True
math.isfinite(math.nan) # => False
math.isfinite(float('nan')) # => False
math.isfinite(math.inf) # => False
math.isfinite(float('inf')) # => False

isinf(x) 無限大判定

math.isinf(1) # => False
math.isinf(math.nan) # => False
math.isinf(float('nan')) # => False
math.isinf(math.inf) # => True
math.isinf(float('inf')) # => True

isnan(x) NaN (not a number、非数)判定

math.isnan(1) # => False
math.isnan(math.nan) # => True
math.isnan(float('nan')) # => True
math.isnan(math.inf) # => False
math.isnan(float('inf')) # => False

isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) aとbが近いか

rel_tol:相対許容差はaとbの差をa(b)で割った値、
abt_tol:絶対許容差はa,bの差で比較する。

a,bが小さい場合は絶対許容差で比較しやすい。

math.isclose(1.500000000, 1.499999999) #=> True
math.isclose(1.50000000, 1.49999999) #=> False

math.isclose(100.01, 100.02, rel_tol=1e-4) #=> True
math.isclose(100.01, 100.02, rel_tol=1e-5) #=> False

math.isclose(0.000101, 0.000102, rel_tol=1e-5) #=> False
math.isclose(0.000101, 0.000102, rel_tol=1e-5, abs_tol=0.0000001) #=> False
math.isclose(0.000101, 0.000102, rel_tol=1e-5, abs_tol=0.000001) #=> True

math.isclose(0.000101, 0.000102, abs_tol=0.0000001) #=> False
math.isclose(0.000101, 0.000102, abs_tol=0.000001) #=> True

ノルム・ユークリッド距離の関数

dist(p, q) 2点間のユークリッド距離

math.dist((1,),(4,)) # => 3.0
math.dist((0, 0),(3, 4)) # => 5.0
math.dist((4, 1),(1, 5)) # => 5.0
math.dist((0, 0, 0),(2, 3, 6)) # => 7.0
math.dist([2, 2, -1],[0, 5, 5]) # => 7.0

以下のような計算を行っている。

def dist_func(p, q):
    return math.sqrt(math.fsum( (x - y)*(x - y) for x, y in zip(p,q)))

dist_func((1,),(4,)) # => 3.0
dist_func((0, 0),(3, 4)) # => 5.0
dist_func([2, 2, -1],[0, 5, 5]) # => 7.0

hypot(*coordinates) 斜辺(hypotenuse)

math.hypot(3) # => 3.0
math.hypot(3, 4) # => 5.0
math.hypot(2, 3, 6) # => 7.0

以下のような計算を行っている。

def hypot_func(*coordinates):
    return math.sqrt(math.fsum( x*x for x in coordinates))

hypot_func(3) # => 3.0
hypot_func(3, 4) # => 5.0
hypot_func(2, 3, 6) # => 7.0

指数関数

pow(x, y) xのy乗

math.pow(2,10) # => 1024.0

sqrd(x) xの平方根

math.sqrt(81) # => 9
math.sqrt(2) # => 1.4142135623730951

exp(x) 自然対数eのx乗

math.exp(1) # => 2.718281828459045
math.exp(2) # => 7.38905609893065
math.exp(-1) # => 0.36787944117144233

expm1(x) 自然対数eのx乗-1

math.expm1(1) # => 1.718281828459045

対数関数

log(x[, base]) 底baseの対数

base省略時は自然対数。

math.log(7.38905609893065) # => 2.0
math.log(1024, 2) # => 10.0

log1p(x) 1+xの自然対数

math.log1p(6.38905609893065) # => 2.0

log2(x) 底2の対数

math.log2(1024) # => 10.0

log10(x) 常用対数

math.log10(1000) # => 3.0

三角関数

sin(x) 正弦(サイン)

math.sin(-math.pi/2) # => -1.0
math.sin(-math.pi/6) # => -0.49999999999999994
math.sin(0) # => 0.0
math.sin(math.pi/6) # => 0.49999999999999994
math.sin(math.pi/2) # => 1.0

cos(x) 余弦 (コサイン)

math.cos(0) # => 1.0
math.cos(math.pi/3) # => 0.5000000000000001
math.cos(math.pi/2) # => 6.123233995736766e-17
math.cos(2*math.pi/3) # => -0.4999999999999998
math.cos(math.pi) # => -1

tan(x) 正接(タンジェント)

math.tan(-math.pi/2) # => -1.633123935319537e+16
math.tan(-math.pi/4) # => -0.9999999999999999
math.tan(0) # => 0.0
math.tan(math.pi/4) # => 0.9999999999999999
math.tan(math.pi/2) # => 1.633123935319537e+16

asin(x) 逆正弦(アークサイン)

math.asin(-1) # => -1.5707963267948966
math.asin(0) # => 0
math.asin(1/math.sqrt(2)) # => 0.7853981633974482
math.asin(1) # => 1.5707963267948966

acos(x) 逆余弦 (アークコサイン)

math.acos(1) # => 0.0
math.acos(1/math.sqrt(2)) # => 0.7853981633974484
math.acos(0) # => 1.5707963267948966
math.acos(-1) # => 3.141592653589793

atan(x) 逆正接(アークタンジェント)

math.atan(-math.inf) # => -1.5707963267948966
math.atan(-1) # => -0.7853981633974483
math.atan(0) # => 0.0
math.atan(math.inf) # => 1.5707963267948966

atan2(y, x) ベクトル(x, y)と(1, 0)の成す角

atan(y/x)のラジアンを各象限に拡張した結果を取得できる。

math.atan2(0, 0) # => 0.0
math.atan2(1, 1) # => 0.7853981633974483
math.atan2(1, 0) # => 1.5707963267948966
math.atan2(1, -1) # => 2.356194490192345
math.atan2(0, -1) # => 3.141592653589793
math.atan2(-1, -1) # => -2.356194490192345
math.atan2(-1, 0) # => -1.5707963267948966
math.atan2(-1, 1) # => -0.7853981633974483

角度の変換関数

radians(x) ディグリー(度、Degree)からラジアン(弧度、Radian)に変換

math.radians(0) # => 0.0
math.radians(45) # => 0.7853981633974483
math.radians(90) # => 1.5707963267948966
math.radians(180) # => 3.141592653589793

degrees(x) ラジアン(弧度、Radian)からディグリー(度、Degree)に変換

math.degrees(0) # => 0.0
math.degrees(math.pi/6) # => 29.999999999999996
math.degrees(math.pi/4) # => 45.0
math.degrees(math.pi/3) # => 59.99999999999999
math.degrees(math.pi/2) # => 90.0
math.degrees(math.pi) # => 180.0

双曲線関数

sinh(x) 双曲線正弦

math.sinh(0) # => 0.0
math.sinh(1) # => 1.1752011936438014
math.sinh(-1) # => -1.1752011936438014

cosh(x) 双曲線余弦

math.cosh(0) # => 1.0
math.cosh(1) # => 1.5430806348152437
math.cosh(-1) # => 1.5430806348152437

tanh(x) 双曲線正接

math.tanh(0) # => 0.0
math.tanh(1) # => 0.7615941559557649
math.tanh(-1) # => -0.7615941559557649

asinh(x) 逆双曲線正弦

math.asinh(0) # => 0.0
math.asinh(1.1752011936438014) # => 1.0
math.asinh(-1.1752011936438014) # => -1.0

acosh(x) 逆双曲線余弦

math.acosh(1.0) # => 0.0
math.acosh(1.5430806348152437) # => 1.0

atanh(x) 逆双曲線正接

math.atanh(0) # => 0.0
math.atanh(0.7615941559557649) # => 0.9999999999999999
math.atanh(-0.7615941559557649) # => -0.9999999999999999

その他の関数

erf(x) 誤差関数

math.erf(0) # => 0.0
math.erf(1) # => 0.8427007929497149
math.erf(6) # => 1.0

erfc(x) 補正誤差関数 1.0 - erf(x)

math.erfc(0) # => 1.0
math.erfc(1) # => 0.1572992070502851
math.erfc(6) # => 2.1519736712498913e-17

gamma(x) ガンマ関数

math.gamma(1) # => 1.0
math.gamma(2) # => 1.0
math.gamma(3) # => 2.0
math.gamma(4) # => 6.0
math.gamma(5) # => 24.0

lgamma(x) ガンマ関数の自然対数

math.lgamma(1) # => 0.0
math.lgamma(2) # => 0.0
math.lgamma(3) # => 0.693147180559945
math.lgamma(4) # => 1.7917594692280554
Originally published at marusankakusikaku.jp
ツイッターでシェア
みんなに共有、忘れないようにメモ

maru3kaku4kaku

Pythonこつこつ学習中。よく忘れる。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント