NumPyで多項式の根をバッチリ求める!『polynomial.polynomial.polyzero』関数徹底解説


numpy.polynomial.polynomial.polyzero(c)

引数

  • c: 多項式の係数を要素とする配列。

戻り値

  • 多項式の根の集合を表す配列。

詳細

polyzero 関数は、根求めのアルゴリズムとして Durand-Kerner 法を使用します。このアルゴリズムは、効率的で安定した方法で複素数の根を見つけることができます。

以下の例では、2次方程式 x^2 - 3x + 2 = 0 の根を求めます。

import numpy as np

# 多項式の係数を設定
c = np.array([2, -3, 1])

# 根を求める
roots = np.polynomial.polynomial.polyzero(c)

# 結果を出力
print(roots)

このコードを実行すると、以下の出力が得られます。

[1. 2.]

これは、2次方程式 x^2 - 3x + 2 = 0 の根が 1 と 2 であることを示しています。

  • polyzero 関数は、数値誤差の影響を受ける可能性があります。そのため、厳密な精度が必要な場合は、別の方法を使用する必要があります。
  • 複素数の根を求める場合、結果は複素数型になります。
  • polyzero 関数は、高次方程式の根を求める場合にも使用できます。
  • numpy.polynomial.polynomial.polyint: 多項式の積分を求める関数。
  • numpy.polynomial.polynomial.polyder: 多項式の微分を求める関数。
  • numpy.polynomial.polynomial.polyval: 多項式の値を評価する関数。
  • numpy.polynomial.polynomial.polyroots: 多項式の根を求めるもう一つの関数。


例 1: 2次方程式の根を求める

この例では、2次方程式 ax^2 + bx + c = 0 の根を求めます。

import numpy as np

def quadratic_roots(a, b, c):
  """
  2次方程式 ax^2 + bx + c = 0 の根を求める関数

  Args:
    a: 係数 a の値
    b: 係数 b の値
    c: 係数 c の値

  Returns:
    2次方程式の根の組 (x1, x2)
  """
  # 根を求める
  roots = np.polynomial.polynomial.polyzero([a, b, c])

  # 2つの根を返す
  return roots[0], roots[1]

# 例: ax^2 + bx + c = 2x^2 - 5x + 3 を解く
a = 2
b = -5
c = 3

x1, x2 = quadratic_roots(a, b, c)

print("x1 =", x1)
print("x2 =", x2)
x1 = 1.0
x2 = 3.0

例 2: 高次方程式の根を求める

この例では、3次方程式 x^3 - 3x^2 + 2x = 0 の根を求めます。

import numpy as np

# 多項式の係数を設定
c = np.array([0, 2, -3, 1])

# 根を求める
roots = np.polynomial.polynomial.polyzero(c)

# 結果を出力
print(roots)
[0.  1.  2.]

これは、3次方程式 x^3 - 3x^2 + 2x = 0 の根が 0, 1, 2 であることを示しています。

例 3: 複素数係数の多項式の根を求める

この例では、複素数係数の多項式 (x - 1 + 2j)^2 = 0 の根を求めます。

import numpy as np

# 複素数係数の多項式の係数を設定
c = np.array([1, -2j, 1])

# 根を求める
roots = np.polynomial.polynomial.polyzero(c)

# 結果を出力
print(roots)
[1.00000000+2.00000000j]

これは、複素数係数の多項式 (x - 1 + 2j)^2 = 0 の根が 1 + 2j であることを示しています。



  • numpy.roots: NumPy の標準ライブラリに含まれる roots 関数を使用して、多項式の根を求めることができます。この関数は、polyzero 関数よりも高速でメモリ効率が良い場合がありますが、複素数の根を扱う際には注意が必要です。
import numpy as np

# 多項式の係数を設定
c = np.array([2, -3, 1])

# 根を求める
roots = np.roots(c)

# 結果を出力
print(roots)
  • scipy.optimize.fsolve: SciPy ライブラリに含まれる fsolve 関数を使用して、非線形方程式を解くことで、多項式の根を求めることができます。この関数は、polyzero 関数よりも汎用性が高いですが、収束に時間がかかる場合があることに注意が必要です。
from scipy.optimize import fsolve

# 多項式の係数を設定
def f(x):
  return 2 * x**2 - 3 * x + 1

# 根を求める
roots = fsolve(f, 0)

# 結果を出力
print(roots)

第三者ライブラリ

  • sympy: SymPy ライブラリは、記号計算に特化したライブラリであり、多項式の根を解析的に求めることができます。この方法は、厳密な精度が必要な場合に役立ちますが、計算量が多くなる場合があります。
import sympy as sp

# 変数を定義
x = sp.symbols('x')

# 多項式を定義
p = 2 * x**2 - 3 * x + 1

# 根を求める
roots = sp.solve(p, x)

# 結果を出力
print(roots)
  • gmpy2: gmpy2 ライブラリは、高精度な数値計算に特化したライブラリであり、多項式の根を高精度で求めることができます。この方法は、数値誤差の影響を受けやすい場合に役立ちますが、インストールと設定が必要になります。
import gmpy2

# 多項式の係数を設定
c = [2, -3, 1]

# 根を求める
roots = gmpy2.polyroots(c)

# 結果を出力
for root in roots:
  print(root)

手計算

簡単な多項式の場合は、手計算で根を求めることもできます。2次方程式や3次方程式には、解の公式と呼ばれる解析的な解法が存在します。

数値解析

数値解析的手法を用いて、多項式の根を近似的に求めることもできます。例えば、ニュートン法やバイセクション法などの方法があります。これらの方法は、比較的簡単に実装できますが、収束に時間がかかる場合があることに注意が必要です。

polynomial.polynomial.polyzero 関数は、NumPy で多項式の根を求めるための便利なツールですが、状況に応じて他の方法も検討する必要があります。最良の方法は、問題の要件と計算リソースによって異なります。

  • 厳密な精度が必要な場合は、解析的な解法や高精度な数値計算ライブラリを使用する必要があります。
  • 複素数の根を扱う場合は、注意が必要です。