ベアストウ法を実装した
以下の高次方程式の解を全て求められる。
試しに
を解いてみると
>>> solve([16, -152, 324, 162, 80, 50]) [(1.7058483573106117e-15+0.5000000000000019j), (1.7058483573106117e-15-0.5000000000000019j), 4.999999960549872, -0.5000000000000036, 5.000000039450128]
となり、複素数解や重解が求められているのがわかる。また、第二引数に精度が指定できるようになっている(デフォルトでは1e-9)。
>>> solve([16, -152, 324, 162, 80, 50], 1e-15) [(-1.5133374263982614e-17+0.5j), (-1.5133374263982614e-17-0.5j), 4.999999985745681, -0.5, 5.000000014254319]
# -*- coding: utf-8 -*- import math def cutzero(a): c = 0 while a[c] == 0: c += 1 return a[c:] def solve(a, eps=1e-9): a = cutzero(a) n = len(a) - 1 solutions = [] p0 = q0 = 0.0 while n > 2: b = [0 for i in range(n+1)] c = [0 for i in range(n+1)] d = [0 for i in range(n+1)] b[0], b[1] = a[0], a[1]-p0*a[0] for i in range(2, n+1): b[i] = a[i] - p0*b[i-1] - q0*b[i-2] c[0], c[1] = 0, -b[0] for i in range(2, n+1): c[i] = -b[i-1] - p0*c[i-1] - q0*c[i-2] for i in range(2, n+1): d[i] = -b[i-2] - p0*d[i-1] - q0*d[i-2] D = c[n-1]*d[n] - d[n-1]*(c[n]+b[n-1]) dp = (b[n]*d[n-1] - b[n-1]*d[n]) / D dq = (b[n-1]*(c[n]+b[n-1]) - b[n]*c[n-1]) / D if abs(dp) < eps and abs(dq) < eps: rt = p0*p0 - 4*q0 imag = 1 if rt < 0: imag = 1j rt = abs(rt) sa = (-p0 + math.sqrt(rt) * imag) / 2 sb = (-p0 - math.sqrt(rt) * imag) / 2 solutions.append(sa) solutions.append(sb) a = b[:n-1] n -= 2 else: p0 += dp q0 += dq if n == 2: rt = a[1]*a[1] - 4*a[0]*a[2] imag = 1 if rt < 0: imag = 1j rt = abs(rt) sa = (-a[1] + math.sqrt(rt) * imag) / (2*a[0]) sb = (-a[1] - math.sqrt(rt) * imag) / (2*a[0]) solutions.append(sa) solutions.append(sb) if n == 1: solutions.append(-a[1]/a[0]) return solutions