Path: blob/master/material/LagrangePolynomial.py
934 views
"""1From: https://gist.github.com/folkertdev/084c53887c49a62488392A sympy-based Lagrange polynomial constructor.34Implementation of Lagrangian interpolating polynomial.5See:67def lagrangePolynomial(xs, ys):89Given two 1-D arrays `xs` and `ys,` returns the Lagrange interpolating10polynomial through the points ``(xs, ys)``111213Given a set 1-D arrays of inputs and outputs, the lagrangePolynomial function14will construct an expression that for every input gives the corresponding output.15For intermediate values, the polynomial interpolates (giving varying results16based on the shape of your input).1718The Lagrangian polynomials can be obtained explicitly with (see below):1920def polyL(xs,j):2122as sympy polynomial, and2324def L(xs,j):2526as Python functions.272829This is useful when the result needs to be used outside of Python, because the30expression can easily be copied. To convert the expression to a python function31object, use sympy.lambdify.32"""33from sympy import symbols, expand, lambdify, solve_poly_system34#Python library for arithmetic with arbitrary precision35from mpmath import tan, e3637import math3839from operator import mul40from functools import reduce, lru_cache41from itertools import chain4243# sympy symbols44x = symbols('x')4546# convenience functions47product = lambda *args: reduce(mul, *(list(args) + [1]))4849# test data50labels = [(-3/2), (-3/4), 0, 3/4, 3/2]51points = [math.tan(v) for v in labels]5253# this product may be reusable (when creating many functions on the same domain)54# therefore, cache the result55@lru_cache(16)56def l(labels, j):57def gen(labels, j):58k = len(labels)59current = labels[j]60for m in labels:61if m == current:62continue63yield (x - m) / (current - m)64return expand(product(gen(labels, j)))6566def polyL(xs,j):67'''68Lagrange polynomials as sympy polynomial69xs: the n+1 nodes of the intepolation polynomial in the Lagrange Form70j: Is the j-th Lagrange polinomial for the specific xs.71'''72xs=tuple(xs)73return l(xs,j)7475def L(xs,j):76'''77Lagrange polynomials as python function78xs: the n+1 nodes of the intepolation polynomial in the Lagrange Form79j: Is the j-th Lagrange polinomial for the specific xs.80'''81return lambdify(x, polyL(xs,j) )8283def lagrangePolynomial(xs, ys):84'''85Given two 1-D arrays `x` and `w,` returns the Lagrange interpolating86polynomial through the points ``(x, w)``.8788'''89# based on https://en.wikipedia.org/wiki/Lagrange_polynomial#Example_190k = len(xs)91total = 09293# use tuple, needs to be hashable to cache94xs = tuple(xs)9596for j, current in enumerate(ys):97t = current * l(xs, j)98total += t99100return total101102103104105def x_intersections(function, *args):106"Finds all x for which function(x) = 0"107# solve_poly_system seems more efficient than solve for larger expressions108return [var for var in chain.from_iterable(solve_poly_system([function], *args)) if (var.is_real)]109110def x_scale(function, factor):111"Scale function on the x-axis"112return functions.subs(x, x / factor)113114if __name__ == '__main__':115func = lagrangePolynomial(labels, points)116117pyfunc = lambdify(x, func)118119for a, b in zip(labels, points):120assert(pyfunc(a) - b < 1e-6)121122123