math – 数学に関する関数

目的:数学に関する演算に特化した機能を提供する
利用できるバージョン:1.4

math モジュールは、浮動小数点数、対数、三角法の演算を含む複雑な数学の演算のために、C 言語のネイティブライブラリで標準的に提供されている多くの IEEE 関数を実装します。

特別な定数

多くの数学の演算は、特別な定数に依存します。 math は π (パイ) や e の値を提供します。

import math

print 'π: %.30f' % math.pi
print 'e: %.30f' % math.e

両方の定数の値の精度は、プラットフォームの浮動小数点数の C 言語ライブラリにのみ制限されます。

$ python math_constants.py
π: 3.141592653589793115997963468544
e: 2.718281828459045090795598298428

例外値のテスト

浮動小数点数の計算は、2つの例外値を導くことがあります。 INF (“無限大”) は、 浮動小数点数の double 型のある値から巨大な絶対値をもつ値にオーバーフローするときに現れます。

import math

print '{:^3}  {:6}  {:6}  {:6}'.format('e', 'x', 'x**2', 'isinf')
print '{:-^3}  {:-^6}  {:-^6}  {:-^6}'.format('', '', '', '')

for e in range(0, 201, 20):
    x = 10.0 ** e
    y = x*x
    print '{:3d}  {!s:6}  {!s:6}  {!s:6}'.format(e, x, y, math.isinf(y))

このサンプルの指数は、 x の2乗が double 型の範囲内に収まらないほど巨大な値になると、その値は無限大として記録されます。

$ python math_isinf.py
 e   x       x**2    isinf
---  ------  ------  ------
  0  1.0     1.0     False
 20  1e+20   1e+40   False
 40  1e+40   1e+80   False
 60  1e+60   1e+120  False
 80  1e+80   1e+160  False
100  1e+100  1e+200  False
120  1e+120  1e+240  False
140  1e+140  1e+280  False
160  1e+160  inf     True
180  1e+180  inf     True
200  1e+200  inf     True

しかし、全ての浮動小数点数の値がオーバーフローすると INF の値になるというわけではありません。特に浮動小数点数の指数計算を行うと INF を保持するのではなく OverflowError を発生させます。

x = 10.0 ** 200

print 'x    =', x
print 'x*x  =', x*x
try:
    print 'x**2 =', x**2
except OverflowError, err:
    print err

この不一致は、CPython が使用するライブラリの実装の違いが原因です。

$ python math_overflow.py
x    = 1e+200
x*x  = inf
x**2 = (34, 'Result too large')

無限大の値を使用する除算は未定義です。ある数を無限大で割ると NaN (“数字ではない”) になります。

import math

x = (10.0 ** 200) * (10.0 ** 200)
y = x/x

print 'x =', x
print 'isnan(x) =', math.isnan(x)
print 'y = x / x =', x/x
print 'y == nan =', y == float('nan')
print 'isnan(y) =', math.isnan(y)

NaN は、自分自身との比較も含め、どんな値と比較しても等しくないので、 NaN を調べるには isnan() を使用しなければなりません。

$ python math_isnan.py
x = inf
isnan(x) = False
y = x / x = nan
y == nan = False
isnan(y) = True

整数への変換

math モジュールは、浮動小数点数の値から整数に変換する3つの関数を提供します。それぞれが別のアプローチを取り、様々な状況で役に立ちます。

最も簡単なのは trunc() で、ある値の整数部分の桁のみを残して、その小数部分の桁を切り捨てます。 floor() は入力値以下の最も大きな整数に変換し、 ceil() (天井値) は入力値以上の最も大きな整数を生成します。

import math

print '{:^5}  {:^5}  {:^5}  {:^5}  {:^5}'.format('i', 'int', 'trunk', 'floor', 'ceil')
print '{:-^5}  {:-^5}  {:-^5}  {:-^5}  {:-^5}'.format('', '', '', '', '')

fmt = '  '.join(['{:5.1f}'] * 5)

for i in [ -1.5, -0.8, -0.5, -0.2, 0, 0.2, 0.5, 0.8, 1 ]:
    print fmt.format(i, int(i), math.trunc(i), math.floor(i), math.ceil(i))
    

trunc() は、直接 int に変換するのと等価です。

$ python math_integers.py
  i     int   trunk  floor  ceil
-----  -----  -----  -----  -----
 -1.5   -1.0   -1.0   -2.0   -1.0
 -0.8    0.0    0.0   -1.0   -0.0
 -0.5    0.0    0.0   -1.0   -0.0
 -0.2    0.0    0.0   -1.0   -0.0
  0.0    0.0    0.0    0.0    0.0
  0.2    0.0    0.0    0.0    1.0
  0.5    0.0    0.0    0.0    1.0
  0.8    0.0    0.0    0.0    1.0
  1.0    1.0    1.0    1.0    1.0

代替の表現

modf() は、1つの浮動小数点数を受け取り、その入力値から小数部と整数部に分けたタプルを返します。

import math

for i in range(6):
    print '{}/2 = {}'.format(i, math.modf(i/2.0))

返り値のタプルに含まれる両方の値は float 型です。

$ python math_modf.py
0/2 = (0.0, 0.0)
1/2 = (0.5, 0.0)
2/2 = (0.0, 1.0)
3/2 = (0.5, 1.0)
4/2 = (0.0, 2.0)
5/2 = (0.5, 2.0)

frexp() は、浮動小数点数の仮数と指数を返し、引数の値のより移植性の高い表現を作成するのに使用されます。

import math

print '{:^7}  {:^7}  {:^7}'.format('x', 'm', 'e')
print '{:-^7}  {:-^7}  {:-^7}'.format('', '', '')

for x in [ 0.1, 0.5, 4.0 ]:
    m, e = math.frexp(x)
    print '{:7.2f}  {:7.2f}  {:7d}'.format(x, m, e)

frexp() は、数式 x = m * 2**e を導く me の値を返します。

$ python math_frexp.py
   x        m        e
-------  -------  -------
   0.10     0.80       -3
   0.50     0.50        0
   4.00     0.50        3

ldexp()frexp() の逆の計算をします。

import math

print '{:^7}  {:^7}  {:^7}'.format('m', 'e', 'x')
print '{:-^7}  {:-^7}  {:-^7}'.format('', '', '')

for m, e in [ (0.8, -3),
              (0.5,  0),
              (0.5,  3),
              ]:
    x = math.ldexp(m, e)
    print '{:7.2f}  {:7d}  {:7.2f}'.format(m, e, x)

frexp() と同じ数式を用いて、 ldexp() は、仮数と指数の値を引数として受け取り、浮動小数点数の値を返します。

$ python math_ldexp.py
   m        e        x
-------  -------  -------
   0.80       -3     0.10
   0.50        0     0.50
   0.50        3     4.00

正負の符号

数値の絶対値は符号をもたない値です。浮動小数点数の絶対値を計算するには fabs() を使用してください。

import math

print math.fabs(-1.1)
print math.fabs(-0.0)
print math.fabs(0.0)
print math.fabs(1.1)

実際には float 型の絶対値は正の値として表現されます。

$ python math_fabs.py
1.1
0.0
0.0
1.1

ある値の符号を決めるには、与えられた値セットが同じ符号をもつ、またはシンプルに比較する目的であるなら、既知の値から符号をセットするために copysign() を使用してください。

import math

print
print '{:^5}  {:^5}  {:^5}  {:^5}  {:^5}'.format('f', 's', '< 0', '> 0', '= 0')
print '{:-^5}  {:-^5}  {:-^5}  {:-^5}  {:-^5}'.format('', '', '', '', '')

for f in [ -1.0,
            0.0,
            1.0,
            float('-inf'),
            float('inf'),
            float('-nan'),
            float('nan'),
            ]:
    s = int(math.copysign(1, f))
    print '{:5.1f}  {:5d}  {!s:5}  {!s:5}  {!s:5}'.format(f, s, f < 0, f > 0, f==0)

copysign() のような拡張関数は、NaN と -NaN を他の値と直接的に比較すると正しく処理されないので必要です。

$ python math_copysign.py

  f      s     < 0    > 0    = 0
-----  -----  -----  -----  -----
 -1.0     -1  True   False  False
  0.0      1  False  False  True
  1.0      1  False  True   False
 -inf     -1  True   False  False
  inf      1  False  True   False
  nan     -1  False  False  False
  nan      1  False  False  False

一般的によく使う計算

バイナリの浮動小数点数メモリに正確な値を表現することが挑戦されています。いくつかの値は、正確に表現することはできません。そして、繰り返しの計算を通して多くの値が操作され、表現エラーが発生する可能性が高くなります。 math は、そういったエラーを最小限に抑えるように効率化されたアルゴリズムを使用して、一連の浮動小数点数の和を計算する関数を提供します。

import math

values = [ 0.1 ] * 10

print 'Input values:', values

print 'sum()       : {:.20f}'.format(sum(values))

s = 0.0
for i in values:
    s += i
print 'for-loop    : {:.20f}'.format(s)
    
print 'math.fsum() : {:.20f}'.format(math.fsum(values))

あるシーケンスの10個の値がそれぞれ 0.1 のとき、そのシーケンスの合計値は 1.0 になると予想されます。 0.1 は浮動小数点数の値として正確な表現ではないので、 fsum() で計算しない限り、その和はエラーになります。

$ python math_fsum.py
Input values: [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
sum()       : 0.99999999999999988898
for-loop    : 0.99999999999999988898
math.fsum() : 1.00000000000000000000

factorial() は、一般的に一連のオブジェクトの順列や組み合わせの数を計算するのに使用されます。正の整数 n の階乗は、 n! で表され、 (n-1)! * n として再帰的に定義されて 0! == 1 で止まります。

import math

for i in [ 0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.1 ]:
    try:
        print '{:2.0f}  {:6.0f}'.format(i, math.factorial(i))
    except ValueError, err:
        print 'Error computing factorial(%s):' % i, err

factorial() は整数でのみ動作しますが、値を失わずに整数に変換されるのであれば float の引数を受け取ります。

$ python math_factorial.py
 0       1
 1       1
 2       2
 3       6
 4      24
 5     120
Error computing factorial(6.1): factorial() only accepts integral values

gamma() も実数で動作する点を除けば、 factorial() と同じように動作しますが、その値は1つシフトダウンされます (ガンマは (n - 1)! と等価です) 。

import math

for i in [ 0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 ]:
    try:
        print '{:2.1f}  {:6.2f}'.format(i, math.gamma(i))
    except ValueError, err:
        print 'Error computing gamma(%s):' % i, err

ゼロは初期値が負の値から始まるので計算できません。

$ python math_gamma.py
Error computing gamma(0): math domain error
1.1    0.95
2.2    1.10
3.3    2.68
4.4   10.14
5.5   52.34
6.6  344.70

lgamma() は、入力値のためにガンマの絶対値の自然対数を返します。

import math

for i in [ 0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 ]:
    try:
        print '{:2.1f}  {:.20f}  {:.20f}'.format(i, math.lgamma(i), math.log(math.gamma(i)))
    except ValueError, err:
        print 'Error computing lgamma(%s):' % i, err

lgamma() を使用した方が、 gamma() の結果を使用して別々にその対数を計算するよりも高い精度を保持します。

$ python math_lgamma.py
Error computing lgamma(0): math domain error
1.1  -0.04987244125984036103  -0.04987244125983997245
2.2  0.09694746679063825923  0.09694746679063866168
3.3  0.98709857789473387513  0.98709857789473409717
4.4  2.31610349142485727469  2.31610349142485727469
5.5  3.95781396761871651080  3.95781396761871606671
6.6  5.84268005527463252236  5.84268005527463252236

モジュロ演算子 (%) は、除算の余りを計算します (例えば 5 % 2 = 1 ) 。この演算子は整数でうまく計算するように言語内に組み込まれていますが、その他の多くの浮動小数点数の計算と同様に、中間の計算で結果的にデータを失ってしまう表現の問題を引き起こします。 fmod() は、浮動小数点数のためにより正確な計算の実装を提供します。

import math

print '{:^4}  {:^4}  {:^5}  {:^5}'.format('x', 'y', '%', 'fmod')
print '----  ----  -----  -----'

for x, y in [ (5, 2),
              (5, -2),
              (-5, 2),
              ]:
    print '{:4.1f}  {:4.1f}  {:5.2f}  {:5.2f}'.format(x, y, x % y, math.fmod(x, y))

潜在的によく混乱するのは、モジュロ演算のために fmod が使用するアルゴリズムが % が使用するのと違っているという事実です。そのため、その結果の符号は違います。符号が混在した入力値を与えます。

$ python math_fmod.py
 x     y      %    fmod
----  ----  -----  -----
 5.0   2.0   1.00   1.00
 5.0  -2.0  -1.00   1.00
-5.0   2.0   1.00  -1.00

指数と対数

指数関数的な曲線は、経済学、物理学、その他の科学の分野においても見られます。Python は組み込みのべき乗演算子 (“**“) がありますが、呼び出し可能な関数に引数として渡す必要があるときは pow() が便利です。

import math

for x, y in [
    # 典型的な使用例
    (2, 3),
    (2.1, 3.2),

    # 必ず 1 になる
    (1.0, 5),
    (2.0, 0),

    # 数字ではない
    (2, float('nan')),

    # ルート
    (9.0, 0.5),
    (27.0, 1.0/3),
    ]:
    print '{:5.1f} ** {:5.3f} = {:6.3f}'.format(x, y, math.pow(x, y))

任意の数を 0.0 乗するのと同様に、 1 を任意の数でべき乗しても 1.0 を返します。数字ではない値 nan について、ほとんどの演算は nan を返します。 1 よりも小さい指数なら pow() はルート(√)を計算します。

$ python math_pow.py
  2.0 ** 3.000 =  8.000
  2.1 ** 3.200 = 10.742
  1.0 ** 5.000 =  1.000
  2.0 ** 0.000 =  1.000
  2.0 **   nan =    nan
  9.0 ** 0.500 =  3.000
 27.0 ** 0.333 =  3.000

よく使う平方根 (1/2 の指数) を計算するには別の関数があります。

import math

print math.sqrt(9.0)
print math.sqrt(3)
try:
    print math.sqrt(-1)
except ValueError, err:
    print 'Cannot compute sqrt(-1):', err
    

負の数の平方根を計算するには、 math では処理できない 複素数 を必要とします。負の数の平方根を計算しようとすると ValueError が発生します。

$ python math_sqrt.py
3.0
1.73205080757
Cannot compute sqrt(-1): math domain error

対数関数は x = b ** y という式の y を導きます。デフォルトでは、 log() は自然対数 (底は e) を計算します。第2引数が指定された場合、その値は底として利用されます。

import math

print math.log(8)
print math.log(8, 2)
print math.log(0.5, 2)

x が1より小さい対数は、負の数を導きます。

$ python math_log.py
2.07944154168
3.0
-1.0

log() には2つの関数があります。浮動小数点表現と丸め誤差の値を log(x, b) に渡して生成された値は、特に底の精度が制限されます。 log10() は、 log() より正確なアルゴリズムを用いて log(x, 10) を計算します。

import math

print '{:2}  {:^12}  {:^20}  {:^20}  {:8}'.format('i', 'x', 'accurate', 'inaccurate', 'mismatch')
print '{:-^2}  {:-^12}  {:-^20}  {:-^20}  {:-^8}'.format('', '', '', '', '')

for i in range(0, 10):
    x = math.pow(10, i)
    accurate = math.log10(x)
    inaccurate = math.log(x, 10)
    match = '' if int(inaccurate) == i else '*'
    print '{:2d}  {:12.1f}  {:20.18f}  {:20.18f}  {:^5}'.format(i, x, accurate, inaccurate, match)

* が最後に付けられた出力結果の行は間違った値です。

$ python math_log10.py
i        x              accurate             inaccurate       mismatch
--  ------------  --------------------  --------------------  --------
 0           1.0  0.000000000000000000  0.000000000000000000
 1          10.0  1.000000000000000000  1.000000000000000000
 2         100.0  2.000000000000000000  2.000000000000000000
 3        1000.0  3.000000000000000000  2.999999999999999556    *
 4       10000.0  4.000000000000000000  4.000000000000000000
 5      100000.0  5.000000000000000000  5.000000000000000000
 6     1000000.0  6.000000000000000000  5.999999999999999112    *
 7    10000000.0  7.000000000000000000  7.000000000000000000
 8   100000000.0  8.000000000000000000  8.000000000000000000
 9  1000000000.0  9.000000000000000000  8.999999999999998224    *

log1p() は、ニュートンメルカトル級数 (1+x の自然対数) を計算します。

import math

x = 0.0000000000000000000000001
print 'x       :', x
print '1 + x   :', 1+x
print 'log(1+x):', math.log(1+x)
print 'log1p(x):', math.log1p(x)

log1p() は、ゼロにとても近い x の、より正確な値を計算します。それは初期値からの丸め誤差を補償するアルゴリズムを使用するからです。

$ python math_log1p.py
x       : 1e-25
1 + x   : 1.0
log(1+x): 0.0
log1p(x): 1e-25

exp() は指数関数を計算します (e**x) 。

import math

x = 2

fmt = '%.20f'
print fmt % (math.e ** 2)
print fmt % math.pow(math.e, 2)
print fmt % math.exp(2)

その他の特殊な関数と同様に、汎用目的で等価な math.pow(math.e, x) よりも正確な値を計算するアルゴリズムを使用します。

$ python math_exp.py
7.38905609893064951876
7.38905609893064951876
7.38905609893065040694

expm1()log1p() の逆にあたる e**x - 1 を計算します。

import math

x = 0.0000000000000000000000001

print x
print math.exp(x) - 1
print math.expm1(x)

log1p() と同様に x の小さな値は、その引き算が別々に計算されるときに精度が失われます。

$ python math_expm1.py
1e-25
0.0
1e-25

角度

日常の議論では、度の方が角度よりも一般的に使用されますが、ラジアンは科学と数学の世界で角度を測定する標準単位です。ラジアンは、円周上の半径と同じ長さをもつ範囲において円の中心で交差する2つの線で作成された角度です。

円周は 2πr として計算されるので、ラジアンとパイ (π) は関連があり、それは三角法の計算でよく示される値です。その関連はもっと小さな公式になるので三角法と計算で使用されるラジアンを導きます。

度からラジアンへ変換するには radians() を使用してください。

import math

print '{:^7}  {:^7}  {:^7}'.format('Degrees', 'Radians', 'Expected')
print '{:-^7}  {:-^7}  {:-^7}'.format('', '', '')

for deg, expected in [ (  0,  0),
                       ( 30,  math.pi/6),
                       ( 45,  math.pi/4),
                       ( 60,  math.pi/3),
                       ( 90,  math.pi/2),
                       (180,  math.pi),
                       (270,  3/2.0 * math.pi),
                       (360,  2 * math.pi),
                       ]:
    print '{:7d}  {:7.2f}  {:7.2f}'.format(deg, math.radians(deg), expected)

変換の公式は rad = deg * π / 180 です。

$ python math_radians.py
Degrees  Radians  Expected
-------  -------  -------
      0     0.00     0.00
     30     0.52     0.52
     45     0.79     0.79
     60     1.05     1.05
     90     1.57     1.57
    180     3.14     3.14
    270     4.71     4.71
    360     6.28     6.28

ラジアンから度へ変換するには degrees() を使用してください。

import math

print '{:^8}  {:^8}  {:^8}'.format('Radians', 'Degrees', 'Expected')
print '{:-^8}  {:-^8}  {:-^8}'.format('', '', '')
for rad, expected in [ (0,                  0),
                       (math.pi/6,         30),
                       (math.pi/4,         45),
                       (math.pi/3,         60),
                       (math.pi/2,         90),
                       (math.pi,          180),
                       (3 * math.pi / 2,  270),
                       (2 * math.pi,      360),
                       ]:
    print '{:8.2f}  {:8.2f}  {:8.2f}'.format(rad, math.degrees(rad), expected)

公式は deg = rad * 180 / π です。

$ python math_degrees.py
Radians   Degrees   Expected
--------  --------  --------
    0.00      0.00      0.00
    0.52     30.00     30.00
    0.79     45.00     45.00
    1.05     60.00     60.00
    1.57     90.00     90.00
    3.14    180.00    180.00
    4.71    270.00    270.00
    6.28    360.00    360.00

三角法

三角関数は、その辺の長さに対する三角形の角度に関連しています。調和や円運動か、角度を扱うときといった周期的性質をもつ公式で示されます。

Note

標準ライブラリの全ての三角関数は、ラジアンで表される角度を受け取ります。

直角三角形のある角度が与えられたとき、 正弦 (sine) は、斜辺に対する角の辺の長さの比です (sin A = opposite/hypotenuse) 。 余弦 (cosine) は、斜辺に隣接する辺の長さの比です (cos A = adjacent/hypotenuse) 。そして 正接 (tangent) は、隣接する辺の反対側の辺の比です (tan A = opposite/adjacent) 。

import math

print 'Degrees  Radians  Sine     Cosine    Tangent'
print '-------  -------  -------  --------  -------'

fmt = '  '.join(['%7.2f'] * 5)

for deg in range(0, 361, 30):
    rad = math.radians(deg)
    if deg in (90, 270):
        t = float('inf')
    else:
        t = math.tan(rad)
    print fmt % (deg, rad, math.sin(rad), math.cos(rad), t)

正接 (tangent) は、その余弦 (cosine) に対する角の正弦 (sine) としても定義されます。そして、余弦 (cosine) は、π/2 や 3π/2 ラジアンに対して 0 なので、正接 (tangent) は無限大です。

$ python math_trig.py
Degrees  Radians  Sine     Cosine    Tangent
-------  -------  -------  --------  -------
   0.00     0.00     0.00     1.00     0.00
  30.00     0.52     0.50     0.87     0.58
  60.00     1.05     0.87     0.50     1.73
  90.00     1.57     1.00     0.00      inf
 120.00     2.09     0.87    -0.50    -1.73
 150.00     2.62     0.50    -0.87    -0.58
 180.00     3.14     0.00    -1.00    -0.00
 210.00     3.67    -0.50    -0.87     0.58
 240.00     4.19    -0.87    -0.50     1.73
 270.00     4.71    -1.00    -0.00      inf
 300.00     5.24    -0.87     0.50    -1.73
 330.00     5.76    -0.50     0.87    -0.58
 360.00     6.28    -0.00     1.00    -0.00

座標 (x, y) が与えられたとき、[(0, 0), (x, 0), (x, y)] の座標間にある三角形の斜辺の長さは、 (x**2 + y**2) ** 1/2 です。これは hypot() でも計算できます。

import math

print '{:^7}  {:^7}  {:^10}'.format('X', 'Y', 'Hypotenuse')
print '{:-^7}  {:-^7}  {:-^10}'.format('', '', '')

for x, y in [ # simple points
              (1, 1),
              (-1, -1),
              (math.sqrt(2), math.sqrt(2)),
              (3, 4), # 3-4-5 triangle
              # on the circle
              (math.sqrt(2)/2, math.sqrt(2)/2), # pi/4 rads
              (0.5, math.sqrt(3)/2), # pi/3 rads
              ]:
    h = math.hypot(x, y)
    print '{:7.2f}  {:7.2f}  {:7.2f}'.format(x, y, h)

円になるのは、必ず hypotenuse == 1 になります。

$ python math_hypot.py
   X        Y     Hypotenuse
-------  -------  ----------
   1.00     1.00     1.41
  -1.00    -1.00     1.41
   1.41     1.41     2.00
   3.00     4.00     5.00
   0.71     0.71     1.00
   0.50     0.87     1.00

2つの座標間の距離を調べるために同じ関数が使用できます。

import math

print '{:^8}  {:^8}  {:^8}  {:^8}  {:^8}'.format('X1', 'Y1', 'X2', 'Y2', 'Distance')
print '{:-^8}  {:-^8}  {:-^8}  {:-^8}  {:-^8}'.format('', '', '', '', '')


for (x1, y1), (x2, y2) in [ ((5, 5), (6, 6)),
                            ((-6, -6), (-5, -5)),
                            ((0, 0), (3, 4)), # 3-4-5 triangle
                            ((-1, -1), (2, 3)), # 3-4-5 triangle
                            ]:
    x = x1 - x2
    y = y1 - y2
    h = math.hypot(x, y)
    print '{:8.2f}  {:8.2f}  {:8.2f}  {:8.2f}  {:8.2f}'.format(x1, y1, x2, y2, h)

原点から端点へ移動する xy の距離を計算してから hypot() へその結果を渡してください。

$ python math_distance_2_points.py
   X1        Y1        X2        Y2     Distance
--------  --------  --------  --------  --------
    5.00      5.00      6.00      6.00      1.41
   -6.00     -6.00     -5.00     -5.00      1.41
    0.00      0.00      3.00      4.00      5.00
   -1.00     -1.00      2.00      3.00      5.00

さらに math は逆三角関数も定義します。

import math

for r in [ 0, 0.5, 1 ]:
    print 'arcsine(%.1f)    = %5.2f' % (r, math.asin(r))
    print 'arccosine(%.1f)  = %5.2f' % (r, math.acos(r))
    print 'arctangent(%.1f) = %5.2f' % (r, math.atan(r))
    print

1.57 は、およそ π/2 または90度です。それは正弦 (sine) が 1 且つ余弦 (cosine) が 0 の角度です。

$ python math_inverse_trig.py
arcsine(0.0)    =  0.00
arccosine(0.0)  =  1.57
arctangent(0.0) =  0.00

arcsine(0.5)    =  0.52
arccosine(0.5)  =  1.05
arctangent(0.5) =  0.46

arcsine(1.0)    =  1.57
arccosine(1.0)  =  0.00
arctangent(1.0) =  0.79

双曲線関数

線形微分方程式に見られる双曲線関数は、電磁界、流体力学、特殊相対性理論、その他の高度な物理学と数学の世界で使用されます。

import math

print '{:^6}  {:^6}  {:^6}  {:^6}'.format('X', 'sinh', 'cosh', 'tanh')
print '{:-^6}  {:-^6}  {:-^6}  {:-^6}'.format('', '', '', '')

fmt = '  '.join(['{:6.4f}'] * 4)

for i in range(0, 11, 2):
    x = i/10.0
    print fmt.format(x, math.sinh(x), math.cosh(x), math.tanh(x))
    

余弦 (cosine) と正弦 (sine) の関数は円を描くのに対して、双曲線余弦と双曲線正弦フォームは双曲線の半分です。

$ python math_hyperbolic.py
  X      sinh    cosh    tanh
------  ------  ------  ------
0.0000  0.0000  1.0000  0.0000
0.2000  0.2013  1.0201  0.1974
0.4000  0.4108  1.0811  0.3799
0.6000  0.6367  1.1855  0.5370
0.8000  0.8881  1.3374  0.6640
1.0000  1.1752  1.5431  0.7616

逆双曲線関数 acosh(), asinh(), atanh() も利用できます。

特殊関数

統計では、ガウスエラー関数が使用されます。

import math

print '{:^5}  {:7}'.format('x', 'erf(x)')
print '{:-^5}  {:-^7}'.format('', '')

for x in [ -3, -2, -1, -0.5, -0.25, 0, 0.25, 0.5, 1, 2, 3 ]:
    print '{:5.2f}  {:7.4f}'.format(x, math.erf(x))
    

erf(-x) == -erf(x) であることに注意してください。

$ python math_erf.py
  x    erf(x)
-----  -------
-3.00  -1.0000
-2.00  -0.9953
-1.00  -0.8427
-0.50  -0.5205
-0.25  -0.2763
 0.00   0.0000
 0.25   0.2763
 0.50   0.5205
 1.00   0.8427
 2.00   0.9953
 3.00   1.0000

補足のエラー関数は 1 - erf(x) です。

import math

print '{:^5}  {:7}'.format('x', 'erfc(x)')
print '{:-^5}  {:-^7}'.format('', '')

for x in [ -3, -2, -1, -0.5, -0.25, 0, 0.25, 0.5, 1, 2, 3 ]:
    print '{:5.2f}  {:7.4f}'.format(x, math.erfc(x))
    
$ python math_erfc.py
  x    erfc(x)
-----  -------
-3.00   2.0000
-2.00   1.9953
-1.00   1.8427
-0.50   1.5205
-0.25   1.2763
 0.00   1.0000
 0.25   0.7237
 0.50   0.4795
 1.00   0.1573
 2.00   0.0047
 3.00   0.0000

See also

math
本モジュールの標準ライブラリドキュメント
IEEE floating point arithmetic in Python
John Cook による Python で数学をするときに特殊な値の発生とその対処方法について書かれたブログの記事
SciPy
Python で科学技術計算や数学のためのオープンソースライブラリ
Bookmark and Share