Mamy dane punkty $(x_1,y_1),\dots,(x_n,y_n)$. Szukamy wielomianu stopnia $n-1$ przechodzącego przez te punkty. $c_i$ to współczynniki wielomianu
In [116]:
var('x')
xs=[]
ys=[]
cs=[]
n_pkts = 4
for i in range(1,n_pkts+1):
xs.append(var('x%d' % i))
ys.append(var('y%d' % i))
cs.append(var('c%d' % i))
X=vector([x^i for i in range(n_pkts)] )
A=(matrix([ X.subs(x==xx) for xx in xs] ))
b=(vector(ys).column())
c=(vector(cs).column())
# table([["$A$","$\cdot$","$c$","$= b$"],[A,"$\cdot$",c,b]],header_row=True)
In [117]:
show(A)
Bierzemy konkretne punkty:
In [118]:
points=[[1,1],[2,2],[3,5]]
points
Out[118]:
In [119]:
table( [["x","y"]]+points, header_row=True)
pkt_plt=point(points,size=30)
show(pkt_plt,figsize=4)
In [ ]:
In [120]:
npoints=len(points)
print npoints
In [121]:
[[x_^i for i in range(npoints)] for x_,y_ in points]
Out[121]:
In [22]:
A = matrix( [[x_^i for i in range(npoints)] for x_,y_ in points])
show(A)
In [23]:
b = vector( [y_ for x_,y_ in points] )
b
Out[23]:
In [ ]:
Rozwiązujemy ze względu na współczynniki $c_i$:
In [24]:
c = A.solve_right(b)
c
Out[24]:
sprawdźmy:
In [25]:
A*c==b
Out[25]:
In [ ]:
In [ ]:
[["$A$","$\cdot$","$c$","$= b$"]
In [32]:
show(A,c.column(),"=",b.column())
In [33]:
## Możemy utworzyć wielomian mnożąc skalarnie wektor z elementami bazy funckji ze współczynnikami
In [34]:
var('x')
X = vector([x^i for i in range(npoints)])
In [35]:
wielomian= c.dot_product(X)
show(wielomian)
plot(wielomian,(-.5,33.5),color='red',figsize=4)+pkt_plt
print(wielomian)
In [36]:
n=12
l=[ ( 2*pi.n()/(n-1)*i , sin(2*pi.n()/(n-1)*i) ) for i in range(n)]
A = matrix( [[x_^i for i in range(n)] for x_,y_ in l])
b = vector( [y_ for x_,y_ in l] )
var('x')
X = vector([x^i for i in range(n)])
c = A.solve_right(b)
wielomian= c.dot_product(X)
pp = plot(wielomian,(x,-4,12),ymin=-2,ymax=2)
pp += plot(sin(x),(x,-4,4*pi),color='red')
pp += point(l,color='green',size=70)
pp.show()
W SageMath mamy instniejącą implementacje zagadnienia Lagrange'a.
In [115]:
var('x')
n=12
l=[ ( 2*pi.n()/(n-1)*i , sin(2*pi.n()/(n-1)*i) ) for i in range(n)]
R = PolynomialRing(RR, 'x')
L = R.lagrange_polynomial(l)
pp=L.plot(-4,12,ymin=-2,ymax=2)+plot(sin(x),(x,0,2*pi),color='red')+point(l,color='green',size=70)
pp.show()
Należy uważać na fakt, że x jest generatorem pierścienia wielomianów nie zmienną symboliczą:
In [118]:
var('y')
R.<x> = PolynomialRing(RR)
L = R.lagrange_polynomial(l)
print type(L(y))
print type(L)
print type(L(x))
print type(x)
In [121]:
var('x')
f(x)=exp(-x)*sin(x)
f(1.1)
Out[121]:
In [ ]:
var('xx')
f(xx)=sin(xx)
@interact
def sinpoly(n=slider(range(2,20),default=4),a=slider(srange(0.2,5,0.2),default=1) ) :
l=[ (a*2*pi.n()/(n-1)*i,exp(-0.2*a*2*pi.n()/(n-1)*i)*sin(a*2*pi.n()/(n-1)*i)) for i in range(n)]
R = PolynomialRing(RR, 'x')
L = R.lagrange_polynomial(l)
plt=L.plot(-4,a*2*pi+4,ymin=-1.2,ymax=1.2)+plot(exp(-0.2*x)*sin(x),(x,0,2*pi*a),color='red')+point(l,color='green',figsize=(6,3),size=70)
plt.show()
In [181]:
points = [[1,1],[2,2],[3,5]]
In [182]:
x_lst = [x_ for x_,y_ in points]
y_lst = [y_ for x_,y_ in points]
In [183]:
X = vector([x^i for i in range(npoints)])
Spróbuj na przykład:
X = vector([sin(x*i) for i in range(npoints)])
X[0] = 1
albo:
X = vector([exp(x*i) for i in range(npoints)])
In [184]:
X
Out[184]:
Zapiszmy tworzenie macierzy $A$ w sposób niezależny od tego jaką formuła będzie w wektorze X:
In [185]:
A = matrix( [X.subs({x:x_}) for x_ in x_lst] )
b = vector(y_lst)
In [186]:
A
Out[186]:
In [187]:
c = A.solve_right(b)
In [188]:
plot(X.dot_product(c),(x,-2,3)) + point(points,figsize=4,color='red')
Out[188]:
In [ ]:
Cel:
Zamiast:
$$ A x = b$$
rozwiązujemy
$$ A^T A x = A^T b.$$
Inaczej mówiąc, niech błąd:
$$ r=b-A x$$
leży w lewym jądrze A:
$$A^T r =A^T( b-Ax) = A^T b-A^TAx = 0.$$
$$ A^T A x = A^T b.$$
$$ A_{ij} \delta_{jk} (A_{il} x_l - b_i) + A_{il} \delta_{lk} (A_{ij} x_j - b_i) = $$ $$ A^TAx - A^T b + A^TAx - A^T b $$
In [179]:
var('x y t')
points=[[0,1],[2,0],[3,4],[5,7]]
In [180]:
N=len(points)
X=vector([1,x,x^2])
M=len(X)
var('x')
xs=[]
ys=[]
cs=[]
for i in range(1,N+1):
xs.append(var('x%d' % i))
ys.append(var('y%d' % i))
for i in range(1,M+1):
cs.append(var('c%d' % i))
A=(matrix([ X.subs(x==xx) for xx in xs] ))
b=(vector(ys).column())
c=(vector(cs).column())
ATA=A.transpose()*A
ATb=A.transpose()*b
#table([["$A$","$\cdot$","$c$","$= b$"],
show(A,c,"=",b)
show(ATA,c,"=",ATb)
In [187]:
pkt_plt=point(points,size=30)
show(pkt_plt,figsize=4)
In [188]:
A = matrix( [X.subs(x==x_[0]) for x_ in points] )
b = vector( [x_[1] for x_ in points] )
show(A,b.column())
In [ ]:
In [189]:
ATA=A.transpose()*A
ATb=A.transpose()*b
In [191]:
show(A,c,"=",b.column())
show(ATA,c,"=",ATb.column())
In [192]:
c=ATA\ATb
In [193]:
c
Out[193]:
In [194]:
wielomian= c.dot_product( X )
show(wielomian)
In [195]:
pkt_plt+plot(wielomian, (x,0,5),color='red',thickness=2,figsize=5)
Out[195]:
Zagadnienie Lagrange'a w Sage:
In [200]:
pts=[[1,1],[2,2],[3,4]]
R = PolynomialRing(QQ, 'x') ### x - bedzie generatorem wielomianów nad ciałem liczb wymiernych,
### R - będzie objektem reprezentującym to ciało
L = R.lagrange_polynomial(pts) ### interpolacja Lagrange'a jest zaimplementowana w R
show(L(x).expand() )
Rozważmy funkcję:
In [202]:
f(x)= 1/(1+25*x^2)
plot(f,(-1,1), figsize=4)
Out[202]:
Jej pochodne przyjmują duże wartości w $0$:
In [203]:
[ diff(1/(1+25*x^2),x,i).subs({x:0}) for i in range(1,7) ]
Out[203]:
@interact
def inter1(n_pkt=slider(range(1,20),default=7) ):
x0 = 1
f(x)= 1/(1+25*x^2)
x_bounds=(-1,1)
p = plot(f,x_bounds, thickness=2)
#n_pkt=10
xvals1=[cos(i/(n_pkt-1)*pi.n()) for i in range(n_pkt)]
xvals2=[-1+ (2*i/(n_pkt-1)).n() for i in range(n_pkt)]
#xvals3=[ 2*random()-1 for i in range(n_pkt) ]
plt=[]
for xvals in [xvals2,xvals1]:
pts=[(i,QQ(f(i))) for i in xvals]
R = PolynomialRing(QQ, 'x')
L = R.lagrange_polynomial(pts)
L_plot = plot(L(x),x_bounds, color='green', thickness=2,figsize=4)
plt.append(L_plot+p+point(pts,pointsize=40,color='red'))
print " Punkty jednorodnie położone"," Punkty Chebysheva"
map(show,plt)
In [ ]:
In [204]:
pts=[(1,1),(2,2),(3,4)]
In [205]:
R = PolynomialRing(QQ, 'x')
L = R.lagrange_polynomial(pts)
show(L)
In [206]:
DD=R.divided_difference(pts)
DD
Out[206]:
In [207]:
xlst=map(lambda y:y[0],pts)
xlst
Out[207]:
In [211]:
f=[1]
for xi in xlst[:-1]:
f.append( f[-1]*(x-xi) )
show(f)
In [213]:
show(zip(DD,f))
In [214]:
sum([dd*f_ for dd,f_ in zip(DD,f)]).expand().show()
In [215]:
DD=vector(DD)
f=vector(f)
f.dot_product(DD).expand().show()
In [92]:
Out[92]:
In [87]:
Out[87]:
In [54]:
Out[54]:
In [217]:
points
Out[217]:
In [218]:
var('a,b,c,x')
model(x) = c*x^1+b
fit = find_fit(points,model,solution_dict=True)
fit
Out[218]:
In [ ]:
In [219]:
model.subs(fit)
Out[219]:
In [220]:
point(points)+plot(model.subs(fit),(x,0,10),color='red',figsize=5)
Out[220]:
In [64]:
Out[64]:
In [214]:
s = spline(points)
show(point(points) + plot(s,1,3, hue=.8,figsize=5))
s.list()
Out[214]:
In [215]:
GSLpoints
Out[215]:
In [216]:
v = [(i + sin(i)/2, i+cos(i^2)) for i in range(10)]
s = spline(v)
show(point(v) + plot(s,0,9, hue=.8,figsize=5))
s.list()
Out[216]:
In [217]:
pts=[(0,0),(.15,.1),(0.7,1.6),(1,0)]
path = [pts]
curve = bezier_path(path, linestyle='dashed', rgbcolor='green',figsize=5)
curve+point(pts)
Out[217]:
In [66]:
Out[66]: