高校国語788336 views
いろは3010814 views
高校化学2924392 views
英語613639 views
ヒストリア290598 views
中学英語811710 views
数学講師2886227 views
LaTeX962153 views
教育149510 views
中学理科1630641 views
Help
Tools
NewsSpreadsheetCalendarBookkeepingSlidesTier ListPen ToolIllustrationCrayonWatercolorPixel ArtASCII ArtPerspectiveEndless StairsGraphMind MapER DiagramFamily TreeMemeCurved TextImage EditorMosaicRetro FilterPencil SketchSwirl EffectOCR/HighlighterMakeup EditorFaviconVideo TrimmerScrolling VideoVideo TitleColor PickerColor ExtractorBonfireFireworksWater RippleWater SplashBreaking GlassWood GrainMarble TextureCSS ButtonIcon MakerBar ChartGrouped Bar ChartStacked Bar ChartPie ChartLine ChartArea ChartStacked Area ChartScatter Plot3D Bar Chart3D Pie ChartBar Chart RaceBubble ChartPopulation PyramidPictogramEarningsCandlestick ChartInvestment RiskMortgage SimulatorCalculatorMatrix CalculatorFunction GraphPolynomial ExpansionVenn DiagramField VisualizerRubik's Cube Group TheoryTraveling SalesmanVoronoi and DelaunayFractalColumn ArithmeticDraw Math FiguresArithmetic AnimationArithmetic Word ProblemsCounting with Tree DiagramsCube NetsRolling DiceCross SectionsMotion PathMechanicsWavesElectromagnetic WavesLight and LensesThermodynamicsHow Semiconductors WorkMolecular StructuresAtomic OrbitalsElectrochemical CellsChemical EquilibriumCrystal LatticesBuffer pHPeriodic TableComplex IonsDNA Double HelixCell DivisionMembrane ChannelsNerve ImpulseMuscle ContractionHormones and HomeostasisRock ClassificationWeatherConstellationsSolar and Lunar Eclipses3D ModelingFloor PlanSeismic StructuresIntersection TurnMaglevCooking AnimationOrigamiLive Viewer CountGeoJSON MapRailway MapPopulation MapCrime MapLand Price MapSchool MapShrine and Castle MapHouse of Representatives MapWord MapSolitaireReversiHakoiri MusumeChessHamburgerRippleSlide Puzzle MakerNeon PinballNovel MakerJapanese Typing PracticePiano Score EditorMusic TheoryShogi StrategyPiano Rhythm Game

English

ガンマ関数と対数ガンマ(math.gamma, math.lgamma)|Python

ガンマ関数は階乗を実数・複素数に拡張した関数であり、確率論・統計学・物理学など幅広い分野で登場する。Python では math.gamma()math.lgamma() で計算できる。

階乗とガンマ関数の関係

階乗 は非負整数に対してのみ定義される。ガンマ関数 はこれを実数全体(一部を除く)に拡張したもので、次の関係が成り立つ。

つまり、 となる。引数が 1 ずれている点に注意。

import math

# Γ(5) = 4! = 24
print(math.gamma(5))  # 24.0

# Γ(1) = 0! = 1
print(math.gamma(1))  # 1.0

# Γ(6) = 5! = 120
print(math.gamma(6))  # 120.0

非整数への拡張

ガンマ関数の真価は、非整数でも計算できることにある。

import math

# Γ(1.5) ≈ 0.886(√π / 2)
print(math.gamma(1.5))  # 0.8862269254527579

# Γ(0.5) = √π ≈ 1.772
print(math.gamma(0.5))  # 1.7724538509055159
print(math.sqrt(math.pi))  # 1.7724538509055159(一致)

という有名な結果がある。これはガウス積分から導かれる。

ガンマ関数の定義

ガンマ関数は積分で定義される。

この積分は で収束する。また、次の漸化式が成り立つ。

これは階乗の性質 の一般化だ。

import math

x = 3.5
print(math.gamma(x + 1))  # 11.631728396567448
print(x * math.gamma(x))  # 11.631728396567448(一致)

負の値と特異点

ガンマ関数は で発散する(特異点)。

import math

# 負の非整数では計算可能
print(math.gamma(-0.5))  # -3.5449077018110318

# 0 や負の整数では ValueError
# math.gamma(0)   # ValueError
# math.gamma(-1)  # ValueError

負の実数でも、整数でなければ計算できる。

対数ガンマ関数 lgamma

は急激に大きくなるため、大きな引数ではオーバーフローを起こす。

import math

print(math.gamma(170))  # 7.257415615307994e+306
print(math.gamma(171))  # inf(オーバーフロー)

このような場合、対数ガンマ関数 を使う。math.lgamma() を返す。

import math

# gamma(171) はオーバーフローするが lgamma なら計算可能
print(math.lgamma(171))  # 706.5730622457873
print(math.lgamma(1000))  # 5905.220423209181

# 元の値が必要なら指数を取る(オーバーフローしない範囲で)
print(math.exp(math.lgamma(10)))  # 362880.0(= 9!)

確率計算では対数を使うことが多いため、lgamma は非常に実用的だ。

math.gamma(x)

を直接計算。小さな引数向き。大きな値ではオーバーフローする。

math.lgamma(x)

を計算。大きな引数でもオーバーフローしない。確率計算に便利。

応用例:二項係数の計算

二項係数 はガンマ関数で表現できる。

対数を使えば、大きな数でもオーバーフローせずに計算できる。

import math

def log_binomial(n, k):
    """対数二項係数を計算"""
    return math.lgamma(n + 1) - math.lgamma(k + 1) - math.lgamma(n - k + 1)

def binomial(n, k):
    """二項係数を計算(大きな値にも対応)"""
    return round(math.exp(log_binomial(n, k)))

# 通常の計算
print(math.comb(100, 50))  # 100891344545564193334812497256

# lgamma を使った計算
print(binomial(100, 50))  # 100891344545564193334812497256

応用例:ベータ関数との関係

ベータ関数 はガンマ関数で表現される。

import math

def beta(a, b):
    """ベータ関数を計算"""
    return math.gamma(a) * math.gamma(b) / math.gamma(a + b)

print(beta(2, 3))  # 0.08333333333333333(= 1/12)
print(beta(0.5, 0.5))  # 3.141592653589793(= π)

という美しい結果も確認できる。ガンマ関数は数学の様々な場所に顔を出す、重要な特殊関数である。