Pythonで積分計算を完全攻略!SymPyとSciPyを使った積分の実践ガイド

フリーランスボード

20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード

ITプロパートナーズ

週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ

Midworks 10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks

積分は微分と並んで微積分学の核心的な概念であり、面積計算、物理現象のモデリング、確率分布の計算など幅広い分野で活用されます。Pythonでは記号積分(SymPy)と数値積分(SciPy)の両方を効率的に実行できます。この記事では、Pythonを使った様々な積分計算の手法を実例とともに詳しく解説します。

必要なライブラリのインストール

pip install sympy numpy scipy matplotlib
import sympy as sp
import numpy as np
import scipy.integrate as integrate
import matplotlib.pyplot as plt

SymPyによる記号積分

基本的な不定積分

# 変数の定義
x = sp.Symbol('x')

# 基本的な関数の積分
f1 = x**2
integral1 = sp.integrate(f1, x)
print(f"∫x²dx = {integral1}")

f2 = sp.sin(x)
integral2 = sp.integrate(f2, x)
print(f"∫sin(x)dx = {integral2}")

f3 = sp.exp(x)
integral3 = sp.integrate(f3, x)
print(f"∫e^x dx = {integral3}")

定積分の計算

# 定積分
f = x**2
definite_integral = sp.integrate(f, (x, 0, 2))
print(f"∫₀² x²dx = {definite_integral}")

# 三角関数の定積分
f_trig = sp.sin(x)
trig_integral = sp.integrate(f_trig, (x, 0, sp.pi))
print(f"∫₀^π sin(x)dx = {trig_integral}")

多重積分

# 二重積分
x, y = sp.symbols('x y')
f = x * y
double_integral = sp.integrate(f, (x, 0, 1), (y, 0, 2))
print(f"∫₀¹∫₀² xy dy dx = {double_integral}")

# 三重積分
z = sp.Symbol('z')
f_triple = x + y + z
triple_integral = sp.integrate(f_triple, (x, 0, 1), (y, 0, 1), (z, 0, 1))
print(f"三重積分の結果: {triple_integral}")

部分積分と置換積分

部分積分

# 部分積分の例: ∫x*e^x dx
x = sp.Symbol('x')
f = x * sp.exp(x)
integral = sp.integrate(f, x)
print(f"∫x*e^x dx = {integral}")

# 検証(微分して元の関数に戻る)
verification = sp.diff(integral, x)
print(f"検証: d/dx({integral}) = {verification}")

置換積分

# 置換積分の例: ∫2x*(x²+1)^5 dx
f = 2*x * (x**2 + 1)**5
integral = sp.integrate(f, x)
print(f"∫2x*(x²+1)⁵ dx = {integral}")

SciPyによる数値積分

一次元数値積分

# quad関数による数値積分
def integrand(x):
    return x**2

# 定積分の数値計算
result, error = integrate.quad(integrand, 0, 2)
print(f"∫₀² x²dx ≈ {result:.6f} (誤差: {error:.2e})")

# 理論値との比較
theoretical = 8/3
print(f"理論値: {theoretical:.6f}")
print(f"差: {abs(result - theoretical):.2e}")

# 特殊関数の積分
def gaussian(x):
    return np.exp(-x**2)

gaussian_integral, _ = integrate.quad(gaussian, -np.inf, np.inf)
print(f"∫₋∞^∞ e^(-x²)dx ≈ {gaussian_integral:.6f}")
print(f"理論値: √π ≈ {np.sqrt(np.pi):.6f}")

複雑な関数の数値積分

# 振動する関数の積分
def oscillatory(x):
    return np.sin(100*x) / x

result, error = integrate.quad(oscillatory, 0.1, 10)
print(f"振動関数の積分: {result:.6f} (誤差: {error:.2e})")

# 特異点を持つ関数
def singular(x):
    return 1 / np.sqrt(x)

result, error = integrate.quad(singular, 0, 1)
print(f"特異点を持つ関数の積分: {result:.6f}")
print(f"理論値: 2")

多次元数値積分

二重積分

# dblquad関数による二重積分
def integrand_2d(y, x):
    return x * y

# ∫₀¹∫₀² xy dy dx
result, error = integrate.dblquad(integrand_2d, 0, 1, 0, 2)
print(f"二重積分: {result:.6f} (誤差: {error:.2e})")

# 変数の積分領域
def integrand_region(y, x):
    return x + y

# 三角領域での積分: 0 ≤ y ≤ x, 0 ≤ x ≤ 1
result, error = integrate.dblquad(integrand_region, 0, 1, 0, lambda x: x)
print(f"三角領域での積分: {result:.6f}")

三重積分

# tplquad関数による三重積分
def integrand_3d(z, y, x):
    return x + y + z

result, error = integrate.tplquad(integrand_3d, 0, 1, 0, 1, 0, 1)
print(f"三重積分: {result:.6f}")

モンテカルロ積分

def monte_carlo_integration(func, a, b, n_samples=100000):
    """モンテカルロ法による積分"""
    x = np.random.uniform(a, b, n_samples)
    y = func(x)
    integral = (b - a) * np.mean(y)
    error = (b - a) * np.std(y) / np.sqrt(n_samples)
    return integral, error

# 例:∫₀^π sin(x)dx
def sin_func(x):
    return np.sin(x)

mc_result, mc_error = monte_carlo_integration(sin_func, 0, np.pi)
print(f"モンテカルロ積分: {mc_result:.6f} ± {mc_error:.6f}")
print(f"理論値: {2:.6f}")

積分方程式の解法

フレドホルム積分方程式

# 簡単なフレドホルム積分方程式の数値解法
def kernel(x, t):
    return x * t

def known_function(x):
    return x**2

def solve_fredholm(n_points=100):
    """フレドホルム積分方程式の数値解法"""
    x = np.linspace(0, 1, n_points)
    A = np.zeros((n_points, n_points))
    b = known_function(x)
    
    # 積分方程式の行列形成
    dx = 1.0 / (n_points - 1)
    for i in range(n_points):
        for j in range(n_points):
            A[i, j] = kernel(x[i], x[j]) * dx
        A[i, i] -= 1  # (I - K)φ = f の形
    
    # 線形システムの解法
    phi = np.linalg.solve(-A, b)
    return x, phi

x_sol, phi_sol = solve_fredholm()
print(f"積分方程式の解の最初の5点: {phi_sol[:5]}")

微分方程式の積分による解法

オイラー法による1階微分方程式

def euler_method(f, y0, x0, xf, h):
    """オイラー法によるODEの数値解法"""
    n = int((xf - x0) / h)
    x = np.linspace(x0, xf, n+1)
    y = np.zeros(n+1)
    y[0] = y0
    
    for i in range(n):
        y[i+1] = y[i] + h * f(x[i], y[i])
    
    return x, y

# 例:dy/dx = -y, y(0) = 1
def ode_func(x, y):
    return -y

x_euler, y_euler = euler_method(ode_func, 1, 0, 2, 0.1)
y_analytical = np.exp(-x_euler)  # 解析解

print("数値解と解析解の比較(最初の5点):")
for i in range(5):
    print(f"x={x_euler[i]:.1f}: 数値解={y_euler[i]:.6f}, 解析解={y_analytical[i]:.6f}")

特殊関数の積分

ガンマ関数

# ガンマ関数の積分表現
def gamma_integrand(t, z):
    return t**(z-1) * np.exp(-t)

# Γ(3) = 2! = 2
z_val = 3
gamma_3, _ = integrate.quad(gamma_integrand, 0, np.inf, args=(z_val,))
print(f"Γ(3) ≈ {gamma_3:.6f}")
print(f"理論値: {2:.6f}")

# SciPyの特殊関数と比較
from scipy.special import gamma
print(f"scipy.special.gamma(3) = {gamma(3):.6f}")

ベッセル関数の積分表現

from scipy.special import jv

# ベッセル関数の積分表現
def bessel_integrand(theta, n, x):
    return np.cos(n * theta - x * np.sin(theta))

# J₀(1)の計算
n, x = 0, 1
bessel_integral, _ = integrate.quad(bessel_integrand, 0, np.pi, args=(n, x))
bessel_result = bessel_integral / np.pi

print(f"J₀(1) (積分表現) ≈ {bessel_result:.6f}")
print(f"J₀(1) (SciPy) = {jv(0, 1):.6f}")

面積と体積の計算

曲線下の面積

# パラメトリック曲線の面積
t = sp.Symbol('t')
x_param = sp.cos(t)
y_param = sp.sin(t)

# 半円の面積 (0 ≤ t ≤ π)
area_expr = y_param * sp.diff(x_param, t)
area = sp.integrate(area_expr, (t, 0, sp.pi))
print(f"半円の面積: {area}")
print(f"理論値: π/2 ≈ {np.pi/2:.6f}")

回転体の体積

# 回転体の体積計算
x = sp.Symbol('x')
f = x**2

# x軸周りの回転体の体積 (0 ≤ x ≤ 1)
volume_expr = sp.pi * f**2
volume = sp.integrate(volume_expr, (x, 0, 1))
print(f"回転体の体積: {volume}")
print(f"数値: {float(volume):.6f}")

確率密度関数の積分

正規分布

def normal_pdf(x, mu=0, sigma=1):
    """正規分布の確率密度関数"""
    return (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-0.5 * ((x - mu) / sigma)**2)

# P(-1 ≤ X ≤ 1) の計算
prob, _ = integrate.quad(normal_pdf, -1, 1)
print(f"P(-1 ≤ X ≤ 1) ≈ {prob:.6f}")

# 標準正規分布の累積分布関数
from scipy.stats import norm
theoretical_prob = norm.cdf(1) - norm.cdf(-1)
print(f"理論値: {theoretical_prob:.6f}")

数値積分の可視化

def plot_integration_example():
    """積分の可視化"""
    x = np.linspace(0, 2, 1000)
    y = x**2
    
    # 積分区間
    x_fill = np.linspace(0, 1.5, 100)
    y_fill = x_fill**2
    
    plt.figure(figsize=(10, 6))
    plt.plot(x, y, 'b-', linewidth=2, label='f(x) = x²')
    plt.fill_between(x_fill, y_fill, alpha=0.3, color='blue', label='積分領域')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.title('定積分の可視化')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.show()

# 関数を呼び出して可視化
plot_integration_example()

積分の数値計算精度の比較

def compare_integration_methods():
    """異なる積分法の精度比較"""
    def test_func(x):
        return np.exp(-x**2)
    
    # 理論値(ガウス積分の半分)
    theoretical = np.sqrt(np.pi) / 2
    
    # 異なる分割数での台形公式
    n_values = [10, 50, 100, 500]
    print("台形公式による積分:")
    for n in n_values:
        x = np.linspace(0, 3, n)
        y = test_func(x)
        result = integrate.trapz(y, x)
        error = abs(result - theoretical)
        print(f"n={n:3d}: {result:.8f} (誤差: {error:.2e})")
    
    # SciPyのquad関数
    quad_result, quad_error = integrate.quad(test_func, 0, np.inf)
    print(f"\nSciPy quad: {quad_result:.8f} (推定誤差: {quad_error:.2e})")
    print(f"理論値:     {theoretical:.8f}")

compare_integration_methods()

まとめ

Pythonでの積分計算は、SymPyによる記号積分とSciPyによる数値積分の2つのアプローチがあります。記号積分は正確な解析解を提供し、数値積分は複雑な関数や多次元積分にも対応できます。

これらの技術は物理学、工学、統計学、機械学習など様々な分野で活用されており、面積・体積計算、確率計算、微分方程式の解法などに不可欠です。積分の概念を理解し、Pythonで効率的に計算できるようになることで、より高度な数値解析や科学計算が可能になります。

「らくらくPython塾」が切り開く「呪文コーディング」とは?

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座

フリーランスボード

20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード

ITプロパートナーズ

週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ

Midworks 10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks