import platform
platform.platform()
platform.python_version()
import numpy as np
np.__version__
from pylab import *
S polinomima jedne varijable unutar numpy modula najjednostavnije je raditi preko poly1d klase koja olakšava rad s polinomima što se tiče pisanja koda.
$f(x)=x^5-3x^3-5x,\quad g(x)=x^2-x+1$
f=np.poly1d([1,0,-3,0,-5,0])
g=np.poly1d([1,-1,1])
print(f)
print(g)
Ako želimo neku drugu varijablu kod ispisa, onda to navedemo kod definiranja polinoma.
g1=np.poly1d([1,-1,1],variable='u')
print(g1)
f.c
g.c
f[k] je koeficijent uz potenciju $x^k$
f[3]
f[2]
g[0]
f.o
g.o
f(3)
g(3)
g(3.21)
f.deriv()
print(f.deriv())
g.deriv()
print(g.deriv())
f.deriv(2)
print(f.deriv(2))
f.deriv(3)
print(f.deriv(3))
f.integ()
print(f.integ())
g.integ()
print(g.integ())
f+g
print(f+g)
(f+g)(3)
f-g
print(f-g)
f*g
print(f*g)
f**3
print(f**3)
H=f**3*g+2*f
H
print(H)
suma koeficijenata polinoma $f^3g+2f$
H(1)
kvocijent, ostatak = f/g
kvocijent
print(kvocijent)
ostatak
print(ostatak)
f/g
f.r
g.r
nul_real = np.extract(f.r.imag == 0, f.r)
nul_real
Ljepši zapis bez člana 0.j
only_real = lambda x: x.real
vector_real = np.vectorize(only_real)
vector_real(nul_real)
Zadane su točke $(-2,0),(-1,1),(1,2),(2,3.89)$. Odredite polinom najmanjeg stupnja čiji graf prolazi kroz zadane točke.
import scipy.interpolate as scip
xkor=[-2,-1,1,2]
ykor=[0,1,2,3.89]
pol=scip.lagrange(xkor,ykor)
pol
Pazite, u print ispisu neki koeficijenti mogu biti ispisani s manjom preciznošću.
print(pol)
pol.c
xp=np.arange(-2.5,2.5,0.01)
yp=pol(xp)
figure(figsize=(6,5))
grid(True)
plot(xp,yp,'b-',xkor,ykor,'ro',markersize=8,linewidth=2);
Odredite sve nultočke polinoma $p(x)=-2x^7+3x^6+4x^5-5x^4+x^3+2x^2+8x+12.$
p=np.poly1d([-2,3,4,-5,1,2,8,12])
p.r
nul_real=np.extract(p.r.imag==0, p.r)
nul_real
ljepši zapis bez člana 0.j
only_real = lambda x: x.real
vector_real = np.vectorize(only_real)
nul_real=vector_real(nul_real)
nul_real
najveća realna nultočka
max(nul_real)
najmanja realna nultočka
min(nul_real)
x1=np.arange(-1.5,2.2,0.04)
y1=p(x1)
figure(figsize=(7,6))
grid(True)
xlim(-1.6,2.3)
ylim(-15,45)
hlines(0,-1.6,2.3)
vlines(0,-15,45)
plot(x1,y1,'b-',linewidth=2)
plot(nul_real,[0,0,0],c='yellow',marker='h',ls='',ms=7,markeredgecolor='k');
Razvijte polinom $p(x)=-2x^7+3x^6+4x^5-5x^4+x^3+2x^2+8x+12$ po potencijama od $x+5.$
import math
p=np.poly1d([-2,3,4,-5,1,2,8,12])
S obzirom da imamo dostupnu naredbu za traženje derivacija polinoma, možemo brzo dobiti koeficijente u razvoju koristeći formulu $c_k=\frac{p(k)(a)}{k!}$ pri čemu je $c_k$ koeficijent uz potenciju $(x-a)^k$.
razvoj=[p.deriv(k)(-5)/math.factorial(k) for k in range(p.o+1)]
razvoj
Element s indeksom $k$ u dobivenoj listi daje koeficijent $c_k$.
razvoj[3]
razvoj[0]
Također možemo koristiti i Hornerov algoritam
kv=p
lin=np.poly1d([1,5])
raz=[]
for k in range(p.o+1):
kv,ost=kv/lin
raz.append(ost[0])
raz
Funkcije se nalaze u datoteci MMZI.py
Hornerov algoritam je brži od algoritma preko derivacija.
import sys
sys.path.append("..")
import MMZI
%time
MMZI.razvoj_der(p,-5)
%time
MMZI.razvoj_horner(p,-5)
Odredite Ferrarijevu rezolventu algebarske jednadžbe 4. reda $-5x^4+2x^3-7x^2+4x-2=0.$
Implementirana funkcija se nalazi u datoteci MMZI.py
rez=MMZI.Ferrari_rezolventa([-5,2,-7,4,-2])
rez
print(rez)
U ovom slučaju rezolventa ima sva rješenja realna.
rez.r
x2=np.arange(-1,1.1,0.02)
y2=rez(x2)
q=np.poly1d([-5,2,-7,4,-2])
x3=np.arange(-1,1.5,0.02)
y3=q(x3)
Promatrani polinom 4. stupnja nema niti jednu realnu nultočku.
q.r
figure(figsize=(14,6))
subplot(1,2,1)
title('Ferrarijeva rezolventa')
grid(True)
xlim(-1.1,1.1)
ylim(-2.3,10)
hlines(0,-1.1,1.1)
vlines(0,-2.3,10)
plot(x2,y2,'b-',linewidth=2)
plot(rez.r,[0,0,0],c='yellow',marker='h',ls='',ms=7,markeredgecolor='k')
subplot(1,2,2)
title('$f(x)=-5x^4+2x^3-7x^2+4x-2$')
grid(True)
xlim(-1.1,1.4)
ylim(-20,2)
hlines(0,-1.1,1.4)
vlines(0,-20,2)
plot(x3,y3,'b-',linewidth=2);
import sympy as sp
sp.__version__
sp.init_printing()
import matplotlib.pyplot as plt
Unutar sympy modula možemo raditi s polinomima kao simboličkim izrazima ili preko klase Poly prilagođene za rad s polinomima. Ovdje navodimo samo nekoliko osnovnih stvari koristeći klasu Poly.
x=sp.Symbol('x')
f=sp.Poly(x**5-3*x**3-5*x)
g=sp.Poly(x**2-x+1)
f
g
f.as_expr()
g.as_expr()
f.all_coeffs()
g.all_coeffs()
na poziciji s indeksom $-(k+1)$ je koeficijent uz potenciju $x^k$
f.all_coeffs()[-4]
f.all_coeffs()[-3]
g.all_coeffs()[-1]
f.degree()
g.degree()
f(3)
g(3)
g(3.21)
f.diff(x)
f.diff(x).as_expr()
g.diff(x)
g.diff(x).as_expr()
f.diff((x,2))
f.diff((x,2)).as_expr()
f.diff((x,3))
f.diff((x,3)).as_expr()
f.integrate(x)
f.integrate(x).as_expr()
g.integrate(x)
g.integrate(x).as_expr()
f+g
(f+g).as_expr()
(f+g)(3)
f-g
(f-g).as_expr()
f*g
(f*g).as_expr()
f**3
(f**3).as_expr()
H=f**3*g+2*f
H
H.as_expr()
suma koeficijenata polinoma $f^3g+2f$
H(1)
sp.div(f,g)
kvocijent,ostatak=sp.div(f,g)
kvocijent.as_expr()
ostatak.as_expr()
S obzirom da za polinome s koeficijentima iz nekog prstena ne vrijedi općenito teorem o dijeljenju, sympy po potrebi polinome s cjelobrojnim koeficijentima gleda kao na polinome s racionalnim koeficijentima prilikom dijeljenja.
h=sp.Poly(3*x**2-x+5)
h.as_expr()
sp.div(f,h)
Možemo prisiliti sympy da dijeljenje obavi nad prstenom cijelih brojeva, međutim vidimo da onda ne vrijedi teorem o dijeljenju polinoma, tj. stupanj ostatka nije strogo manji od stupnja polinoma s kojim se dijelilo.
sp.div(f,h,domain='ZZ')
Egzaktno općenito nije moguće uvijek pronaći sve nultočke.
f.all_roots()
Numeričkim putem možemo pronaći sve nultočke polinoma.
f.nroots()
Samo realne nultočke
list(filter(lambda x: sp.im(x)==0, f.nroots()))
Pomoću solve naredbe moguće je egzaktno riješiti algebarsku jednadžbu 4. reda i u ovom slučaju egzaktno pronaći sve nultočke polinoma $f$.
sp.solve(f.as_expr(),x)
Ako želimo samo realne nultočke
y=sp.Symbol('y',real=True)
sp.solve(f.as_expr(y),y)
f=x**4+x**3+2*x**2+x+1
g=x**3-2*x**2+x-2
f=f.as_poly()
g=g.as_poly()
f.as_expr()
g.as_expr()
$M(f,g)=x^2+1$
sp.gcd(f,g)
sp.gcd(f,g).as_expr()
Prošireni Euklidov algoritam
$f(x)\cdot f_1(x)+g(x)\cdot g_1(x)=M(f,g)$
sp.gcdex(f,g)
f1,g1,mjera=sp.gcdex(f,g)
f1.as_expr()
g1.as_expr()
mjera.as_expr()
Zadane su točke $(-2,0),(-1,1),(1,2),(2,3.89)$. Odredite polinom najmanjeg stupnja čiji graf prolazi kroz zadane točke.
Prikazani su različiti načini unosa za dobivanje željenog rezultata.
sp.interpolate([(-2,0),(-1,1),(1,2),(2,3.89)],x)
sp.interpolate([(-2,0),(-1,1),(1,2),(2,sp.Rational(389,100))],x)
sp.interpolate({-2:0,-1:1,1:2,2:3.89},x)
sp.interpolate({-2:0,-1:1,1:2,2:sp.Rational(389,100)},x)
Sympy modul nudi plot funkciju pomoću koje možemo brzo nacrtati graf neke funkcije. Na slici je prikazan graf interpolacijskog polinoma. Ako želimo dodati na sliku i početne točke, tada je bolje da koristimo matplotlib modul direktno kako je ranije pokazano.
f=sp.interpolate([(-2,0),(-1,1),(1,2),(2,3.89)],x)
sp.plot(f,(x,-2.5,2.5));
Odredite sve nultočke polinoma $p(x)=-2x^7+3x^6+4x^5-5x^4+x^3+2x^2+8x+12.$
p=-2*x**7+3*x**6+4*x**5-5*x**4+x**3+2*x**2+8*x+12
p=p.as_poly()
p.nroots()
samo_realne=list(filter(lambda x: sp.im(x)==0, p.nroots()))
samo_realne
najveća realna nultočka
max(samo_realne)
najmanja realna nultočka
min(samo_realne)
plt.rcParams['figure.figsize'] = 10,7
sp.plot(p.as_expr(),(x,-1.5,2.2),adaptive=False,nb_of_points=150);
Razvijte polinom $p(x)=-2x^7+3x^6+4x^5-5x^4+x^3+2x^2+8x+12$ po potencijama od $x+5.$
p=-2*x**7+3*x**6+4*x**5-5*x**4+x**3+2*x**2+8*x+12
razvoj=p.series(x,-5,8)
razvoj
U gornjem zapisu je nezgodno što nije posebno izdvojen član $x+5$. Možemo tome doskočiti jednostavnim trikom sa supstitucijom.
u=sp.Symbol('u')
raz=razvoj.subs({x:u-5})
raz
Član uz $(x+5)^1$
raz.coeff(u,1)
Član uz $(x+5)^0$
raz.coeff(u,0)
Član uz $(x+5)^4$
raz.coeff(u,4)
Odredite $a,b\in\mathbb{R}$ tako da $-2$ bude dvostruka nultočka polinoma $f(x)=x^4+2x^3+ax^2+(a+b)x+2.$
a,b=sp.symbols('a b')
f=x**4+2*x**3+a*x**2+(a+b)*x+2
f=f.as_poly()
f1=f.diff(x)
f1.as_expr()
$f(-2)=0,\ f'(-2)=0$
eq1=f(-2).as_expr()
eq2=f1(-2).as_expr()
eq1,eq2
$a=-\frac{7}{2},\ b=-\frac{5}{2}$
sp.linsolve([eq1,eq2],[a,b])
f_rj=f.subs({a:sp.Rational(-7,2),b:sp.Rational(-5,2)})
f_rj.as_expr()
sp.plot(f_rj.as_expr(),(x,-3,2.5));
nultočke
f_rj.nroots()