کدنویسی الگوریتمهای
- لاگرانژ
- روش تفاضلات تقسیم شدهی نیوتن
- درونیابی با نقاط متساوی الفاصله
- نکات
هر کدام از این برنامهها، ورودیهای مختص خود را دارند{بخش Input} و xi و fi معرف نقاط بکار برده شده برای درونیابی میباشند؛ و xm نقطهایست که باید مقدار آن را پس از درونیابی بدست آوریم.
در این برنامهها از ماژول Mpmath برای کنترل دقت محاسبات و ماژولهای Numpy و Matplotlib برای رسم تابع درونیابی استفاده شده است.
from mpmath import * # mpmath Option mp.dps = 5; mp.pretty = True # Attention: mpmath have more priority from other libs. from pylab import plot,show from numpy import linspace #------ Input ---------------- xi = [0, .12, .19, .32, .4, .51] fi = [1, 1.3, 1.8, 2.2, 2.8, 3.2] xm = .25 #------ Calc ---------------- def f(x): global fi,xi return fi[xi.index(x)] def L(j,x): global xi n = len(xi) lst = [ mpf(x - xi[i]) for i in range(n)] lmj = [ mpf(xi[j] - xi[i]) for i in range(n)] lst.pop(j) lmj.pop(j) return prd(lst)/prd(lmj) def prd(l): p = 1 for c in l: p *= c return p n = len(xi) px = lambda x: sum( fi[i] * L(i,x) \ for i in range(n) ) ###------ Print & Plot ----------------- print('Result {:}'.format(px(xm))) xpoints = [] ypoints = [] for x in linspace(xi[0],xi[-1],100): xpoints += [x] ypoints += [px(x)] plot(xpoints, ypoints) plot(xi,fi, "ro") show()
- خروجی
Result 1.9908
- نمودار برنامه
from mpmath import *
# mpmath Option
mp.dps = 5; mp.pretty = True # Attention: mpmath have more priority from other libs. from pylab import plot,show from numpy import linspace #------ Input ---------------- xi = [0, .12, .19, .32, .4, .51] fi = [1, 1.3, 1.8, 2.2, 2.8, 3.2] xm = .25 #------ Calc ---------------- def f(x): global fi,xi return fi[xi.index(x)] def prd(l): p = 1 for c in l: p *= c return p def fr(l): global ls if len(l) == 1 : return f(l[0]) rev = ( fr(l[1:]) - fr(l[:-1]) ) / ( l[-1] - l[0] ) ls += [mpf(rev)] return rev ls = [] fr(xi) fc = [f(xi[0])] + ls[ -(len(xi) - 1) :] n = len(fc) [print(" {:<{width}}".format(fc[i],width=16)) \ for i in range(n)] px = lambda x: sum( fc[i] * prd( [x - xi[j] for j in range(i)] ) \ for i in range(n) ) ###------ Print & Plot ----------------- print('\nResult {:}'.format(px(xm))) xpoints = [] ypoints = [] for x in linspace(xi[0],xi[-1],100): xpoints += [x] ypoints += [px(x)] plot(xpoints, ypoints) plot(xi,fi, "ro") show()
- خروجی
1 2.5 24.436 -139.89 719.3 -2804.0 Result 1.9908
- نمودار برنامه
حالت خاص: درونیابی با نقاط متساوی الفاصله
from mpmath import * # mpmath Option mp.dps = 5; mp.pretty = True # Attention: mpmath have more priority from other libs. from pylab import plot,show from numpy import linspace #------ Input ---------------- xi = [0, .1, .2, .3, .4, .5] fi = [1, 1.3, 1.8, 2.2, 2.8, 3.2] xm = .25 #------ Calc ---------------- def f(x): global fi,xi return fi[xi.index(x)] def c(s, k): s = mpf(s) if s-k < 0 and s-int(s) == 0: return 0 return fac(s) / ( fac(k) * fac(s - k) ) def fr(l): global ls if len(l) == 1 : return f(l[0]) rev = fr(l[1:]) - fr(l[:-1]) ls += [mpf(rev)] return rev ls = [] fr(xi) fc = [f(xi[0])] + ls[ -(len(xi) - 1) :] n = len(fc) h = abs(xi[1] - xi[0]) [print(" {:<{width}}".format(fc[i],width=16)) \ for i in range(n)] px = lambda x: sum( fc[i] * c((x - xi[0]) / h, i) \ for i in range(n) ) ###------ Print & Plot ----------------- print('\nResult {:}'.format(px(xm))) xpoints = [] ypoints = [] for x in linspace(xi[0],xi[-1],100): xpoints += [x] ypoints += [px(x)] plot(xpoints, ypoints) plot(xi,fi, "ro") show()
- خروجی
1 0.3 0.2 -0.3 0.6 -1.3 Result 1.9926
- نمودار برنامه
from mpmath import * # mpmath Option mp.dps = 5; mp.pretty = True # Attention: mpmath have more priority from other libs. from pylab import plot,show from numpy import linspace #------ Input ---------------- xi = [1.25, 1.26, 1.27, 1.28, 1.29] fi = [1.3914, 1.3770, 1.3478, 1.3046, 1.2477] xm = 1.265 #------ Calc ---------------- def f(x): global fi,xi return fi[xi.index(x)] def c(s, k): s = mpf(s) if s-k < 0 and s-int(s) == 0: return 0 return fac(s) / ( fac(k) * fac(s - k) ) def fr(l): global ls if len(l) == 1 : return f(l[0]) rev = -(fr(l[:-1]) - fr(l[1:])) ls += [mpf(rev)] return rev ls = [] fr(xi) fc = [f(xi[-1])] + ls[ -(len(xi) - 1) :] n = len(fc) h = abs(xi[1] - xi[0]) [print(" {:<{width}}".format(fc[i],width=16)) \ for i in range(n)] px = lambda x: sum((-1)**(i) * fc[i] * c(-(x - xi[-1]) / h, i) \ for i in range(n) ) ###------ Print & Plot ----------------- print('\nResult {:}'.format(px(xm))) xpoints = [] ypoints = [] for x in linspace(xi[0],xi[-1],100): xpoints += [x] ypoints += [px(x)] plot(xpoints, ypoints) plot(xi,fi, "ro") show()
- خروجی
1.2477 -0.0569 -0.0137 0.0003 -0.0005 Result 1.3642
- نمودار برنامه
- همانطور که مشاهده میشود؛ الگوریتم لاگرانژ از سادگی نسبتاً خوبی برخوردار است اما این سادگی با پیچیدگی زمانی بالایی همراه است. ضمناً دادههای ورودی روش لاگرانژ و تفاضلات تقسیم شده یکی است؛ خروجی آنها نیز یکی است.
- الگوریتمهای پیشرو و پسرو در خطوط ۲۶ ، ۳۲ و ۳۹ تفاوت دارند!
- الگوریتمهای تقسیم شده و پیشرو در خطوط نقرهای رنگ با یکدیگر تفاوت دارند!
- در هر سه الگوریتم تابع fr به صورت بازگشتی عمل میکند
- ارزش ریاضی خط ۲۶ در کدها تفاضل پیشرو و پسرو یکسان است. و این جابجایی صرفاً به دلیل ایجاد ترتیب معکوس در فراخوانی بازگشتی انجام شده است تا در نهایت در خط ۳۲ دستور «
ls[ -(len(xi) - 1) :]
» دادههای مطلوب روش را فراهم کند.
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.