''' mbinary ######################################################################### # File : interplotion.py # Author: mbinary # Mail: zhuheqin1@gmail.com # Blog: https://mbinary.xyz # Github: https://github.com/mbinary # Created Time: 2018-10-02 21:14 # Description: ######################################################################### ''' ######################################################################### # File : interplotion.py # Author: mbinary # Mail: zhuheqin1@gmail.com # Blog: https://mbinary.xyz # Github: https://github.com/mbinary # Created Time: 2018-05-18 09:29 # Description: 插值计算,有牛顿插值,拉格朗日插值,以及通过插值得到的多项式估计新的函数值 ######################################################################### import sympy from collections import namedtuple from functools import reduce from operator import mul X = sympy.Symbol('x') point = namedtuple('point', ['x', 'y']) class interplotion: def __init__(self, points): self.points = [point(x, y) for x, y in points] self.xs = [i for i, j in points] self.poly, self.rem = self.newton(self.points, 0, len(self.points)-1) def newton(self, li, a, b): '''li:[(x,f(x))...]''' qs = [li[0].y] def quoDiff(begin, end): if begin == end: return li[begin].y q = (quoDiff(begin+1, end)-quoDiff(begin, end-1)) / \ (li[end].x-li[begin].x) if begin == a: qs.append(q) return q quoDiff(a, b) poly, base = 0, 1 for i, q in enumerate(qs): poly += q*base base *= X-li[i].x return poly, base*qs[-1] def lagrange(self, points=None): xs = None if points is None: xs = self.xs points = self.points else: xs = [x for x, y in points] product = reduce(mul, [X-x for x in xs], 1) poly = 0 for x, y in points: tmp = product/(X-x) coef = y/(tmp.subs(X, x)) poly += coef * tmp return poly def predict(self, val, poly=None): if poly is None: poly = self.poly return poly.subs(X, val) # note the func subs if __name__ == '__main__': f = interplotion([(81, 9), (100, 10), (121, 11)]) p = f.lagrange() print(p.subs(X, 105)) print(p) intor = interplotion([(0, 11), (0.02, 9), (0.04, 7), (0.06, 10)]) p = intor.lagrange() print(p) res = intor.predict(0.08) print(res)