Pythonエンジニアのための多項式マスター講座:NumPyのPolynomialクラス徹底解説


NumPy の numpy.polynomial.polynomial モジュールは、多項式を扱うための便利なクラスと関数を提供しています。その中で、Polynomial() クラスは、多項式の係数、評価、導関数などの操作をサポートする基本的なクラスです。

Polynomial() クラスの使い方

Polynomial() クラスは、以下の方法でインスタンス化できます。

from numpy.polynomial import Polynomial

# 係数リストを渡して多項式を作成
coefs = [1, 2, 3]
poly = Polynomial(coefs)

# 文字列表現を渡して多項式を作成
poly_str = "1 + 2*x + 3*x**2"
poly = Polynomial(poly_str)

作成された Polynomial オブジェクトは、以下の操作に使用できます。

  • 文字列表現: str(poly) で、多項式の文字列表現を取得できます。
  • 比較: poly1 == poly2poly1 != poly2 などの比較演算子を使用できます。
  • 余り: poly1 % poly2 で、2つの多項式の余りを求めることができます。
  • : poly1 / poly2 で、2つの多項式の商を求めることができます。
  • : poly1 * poly2 で、2つの多項式の積を求めることができます。
  • 導関数: poly.deriv() で、多項式の導関数を求めることができます。
  • 評価: poly(x) で、 x の値における多項式の値を計算できます。

以下の例では、Polynomial() クラスを使用して、2次多項式 f(x) = x^2 + 2x + 1 を操作します。

from numpy.polynomial import Polynomial

# 多項式を作成
coefs = [1, 2, 1]
poly = Polynomial(coefs)

# 評価
x = 3
y = poly(x)
print(f"f({x}) = {y}")  # 出力: f(3) = 10

# 導関数
poly_deriv = poly.deriv()
print("f'(x) =", poly_deriv)  # 出力: f'(x) = 2 + 2*x

# 積
poly2 = Polynomial([3, 4])
poly_prod = poly * poly2
print("f(x) * g(x) =", poly_prod)  # 出力: f(x) * g(x) = 3*x**2 + 10*x + 4

# 商
poly_quot = poly / poly2
print("f(x) / g(x) =", poly_quot)  # 出力: f(x) / g(x) = x/3 + 2/3

# 余り
poly_rem = poly % poly2
print("f(x) % g(x) =", poly_rem)  # 出力: f(x) % g(x) = 1
  • Polynomial() クラスは、多項式のフィッティングやルーツの計算などの高度な操作にも使用できます。
  • Polynomial() クラスの操作は、ベクトル化されており、要素ごとの操作が効率的に実行されます。
  • Polynomial() クラスは、多項式を係数リストまたは文字列表現で表すことができます。


例 1: 多項式の作成と評価

この例では、2次多項式 f(x) = x^2 + 2x + 1 を作成し、その値を x = 3 で評価します。

import numpy as np
from numpy.polynomial import Polynomial

# 多項式を作成
coefs = [1, 2, 1]
poly = Polynomial(coefs)

# 評価
x = 3
y = poly(x)
print(f"f({x}) = {y}")

例 2: 多項式の導関数

この例では、2次多項式 f(x) = x^2 + 2x + 1 の導関数を求めます。

import numpy as np
from numpy.polynomial import Polynomial

# 多項式を作成
coefs = [1, 2, 1]
poly = Polynomial(coefs)

# 導関数
poly_deriv = poly.deriv()
print("f'(x) =", poly_deriv)

例 3: 2つの多項式の積

この例では、2つの多項式 f(x) = x^2 + 2x + 1g(x) = 3x + 4 の積を求めます。

import numpy as np
from numpy.polynomial import Polynomial

# 多項式を作成
coefs1 = [1, 2, 1]
coefs2 = [3, 4]
poly1 = Polynomial(coefs1)
poly2 = Polynomial(coefs2)

# 積
poly_prod = poly1 * poly2
print("f(x) * g(x) =", poly_prod)

例 4: 2つの多項式の商

import numpy as np
from numpy.polynomial import Polynomial

# 多項式を作成
coefs1 = [1, 2, 1]
coefs2 = [3, 4]
poly1 = Polynomial(coefs1)
poly2 = Polynomial(coefs2)

# 商
poly_quot = poly1 / poly2
print("f(x) / g(x) =", poly_quot)

例 5: 2つの多項式の余り

import numpy as np
from numpy.polynomial import Polynomial

# 多項式を作成
coefs1 = [1, 2, 1]
coefs2 = [3, 4]
poly1 = Polynomial(coefs1)
poly2 = Polynomial(coefs2)

# 余り
poly_rem = poly1 % poly2
print("f(x) % g(x) =", poly_rem)

例 6: 多項式の根の計算

この例では、3次多項式 f(x) = x^3 - 3x^2 + 2x の根を計算します。

import numpy as np
from numpy.polynomial import Polynomial

# 多項式を作成
coefs = [1, -3, 2, 0]
poly = Polynomial(coefs)

# 根を計算
roots = poly.roots()
print("f(x) の根:", roots)

例 7: 多項式のフィッティング

この例では、データ点 (x, y) に基づいて、2次多項式をフィッティングします。

import numpy as np
from numpy.polynomial import Polynomial

# データ点を作成
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 5, 10, 17, 26])

# 多項式をフィッティング
deg = 2
poly_fit = Polynomial.fit(x, y, deg)

# フィッティング結果を出力
print("フィッティング結果:", poly_fit)


手動計算

簡単な多項式の場合は、手動で計算するのが最速で最も簡単な方法になる場合があります。例えば、2次多項式 f(x) = ax^2 + bx + c の値を計算するには、以下の式を使用できます。

def f(x, a, b, c):
  return a * x**2 + b * x + c

# 例
a = 1
b = 2
c = 3
x = 4
y = f(x, a, b, c)
print(f"f({x}) = {y}")

利点:

  • 必要なライブラリをインストールする必要がない
  • シンプルで理解しやすい

欠点:

  • エラーが発生しやすい
  • コードが冗長になる可能性がある
  • 複雑な多項式の場合は、計算が煩雑になる

NumPy以外にも、多項式を扱うためのライブラリはいくつかあります。例えば、以下のようなライブラリがあります。

  • Mathematica/Wolfram Language: 商用ソフトウェアですが、強力な数学機能を搭載しており、多項式の可視化やアニメーションなどにも利用できます。
  • SciPy: 科学計算全般に広く使用されているライブラリであり、多項式のルーツの計算やフィッティングなどの機能を提供しています。
  • SymPy: シンボリック計算に特化したライブラリであり、多項式の式操作や微分積分などに強みがあります。

利点:

  • 特定のタスクに特化したライブラリを選択できる
  • NumPyよりも高度な機能を提供している場合がある

欠点:

  • ライブラリのインストールが必要になる場合がある
  • NumPyよりも習得が難しい場合がある

カスタムクラスの作成

独自のニーズに合わせた多項式クラスを作成することもできます。これは、特定の操作を頻繁に行う場合や、NumPyの標準クラスでは提供されていない機能が必要な場合に有効です。

利点:

  • コードをより効率的に記述できる
  • 独自のニーズに完全に適合したクラスを作成できる

欠点:

  • テストとデバッグが必要
  • 時間と労力が必要

どの代替方法を選択するかは、状況によって異なります。

  • 独自のニーズに完全に適合したクラスが必要な場合は、カスタムクラスを作成してください。
  • より高度な機能が必要な場合は、他のライブラリを検討してください。
  • シンプルで高速な方法が必要な場合は、手動計算が適切です。

以下、各代替方法の例です。

手動計算

def polyval(coeffs, x):
  """
  多項式の値を計算します。

  Args:
    coeffs: 係数のリスト
    x: 評価点

  Returns:
    多項式の値
  """
  y = 0
  for i, c in enumerate(coeffs):
    y += c * x**i
  return y

# 例
coeffs = [1, 2, 3]
x = 4
y = polyval(coeffs, x)
print(f"f({x}) = {y}")

SymPy

import sympy as sp

x = sp.symbols('x')
poly = sp.Poly(x**2 + 2*x + 1)

# 評価
y = poly.subs(x, 3)
print(f"f({3}) = {y}")

# 導関数
deriv = poly.diff(x)
print("f'(x) =", deriv)

SciPy

import numpy as np
from scipy.optimize import root_poly

# データ点を作成
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 5, 10, 17, 26])

# 多項式をフィッティング
deg = 2
coefs, r = root_poly(y, deg)

# フィッティング結果を出力
print("フィッティング結果:", coeffs)
(* Mathematica/Wolfram Language code *)
f[x_] := x^2 + 2 x + 1;

(*