https://en.wikipedia.org/wiki/Horner%27s_method
Algorytm Hornera (Horner's scheme, Horner's method) to sposób obliczania wartości wielomianu dla nadej wartości argumentu wykorzystujący minimalną liczbę mnożeń. Jest to również algorytm dzielenia wielomianu W(x) przez dwumian (x-c). Schemat ten wiązany jest z nazwiskiem Hornera, był jednak już znany Newtonowi, Ruffiniemu i matematykom chińskim w XII wieku.
Dla wielomianu stopnia n należy wykonać n mnożeń i n dodawań. Schemat Hornera jest optymalny pod względem liczby wykonywanych działań (1971 Borodin).
def horner(L, left, right, x): """Wersja iteracyjna algorytmu Hornera. W(x) = L[left] + L[left+1]*x + L[left+2]*x*x + ... """ i = right result = L[i] while i > left: i = i - 1 result = result * x + L[i] return result
Kod funkcji możemy zapisać w module horner.py, aby skorzystać z niej w innych programach.
import horner poly = [1, 2, 3, 4] y = 2 result = horner.horner(poly, 0, len(poly)-1, y)
Ciekawe informacje są na Wikipedii(en). Jest też kod w Pythonie, współczynniki muszą być podawane kolejno od najwyższego.
def horner2(x, *arguments): ""The Horner Scheme for evaluating a polynomial.""" result = 0 for coefficient in arguments: result = result * x + coefficient return result # Wywołanie. # a0 + x * (a1 + x * (a2 + x * a3)) y = 1 L = [1, 2, 3, 4] a0, a1, a2, a3 = L print(horner2(y, a3, a2, a1, a0)) print(horner2(y, *reversed(L))) # rozpakowanie listy argumentów
# Wydaje się, że zgrabniejsza będzie funkcja przyjmująca # rosnące współczynniki wielomianu. def horner3(x, *arguments): ""The Horner Scheme for evaluating a polynomial.""" result = 0 for coefficient in reversed(arguments): result = result * x + coefficient return result y = 1 L = [1, 2, 3, 4] # 1+2x+3x^2+4x^3 a0, a1, a2, a3 = L print(horner3(y, a0, a1, a2, a3)) print(horner3(y, *L)) # rozpakowanie listy argumentów
# Zastosowanie reduce(). def horner4(x, *arguments): ""The Horner Scheme for evaluating a polynomial.""" return reduce(lambda a,b: a*x+b, reversed(arguments)) y = 1 L = [1, 2, 3, 4] # 1+2x+3x^2+4x^3 print(horner4(y, *L)) # rozpakowanie listy argumentów