verzija: SageMath 9.4
load('MMZI.sage')
%display latex
Odredite polinom trećeg stupnja koji prolazi točkama $(1,3),\, (2,16),\, (-1,1)$ i $(3,45)$.
R.<x>=QQ[]
f=R.lagrange_polynomial([(1,3),(2,16),(-1,1),(3,45)])
f
grafički prikaz dobivenog polinoma i zadanih točaka
plot(f,-2,3.5)+point(((1,3),(2,16),(-1,1),(3,45)),rgbcolor=(1,0,0),pointsize=30,markeredgecolor='black',faceted=True)
plot(f,-2,3.5)+point(((1,3),(2,16),(-1,1),(3,45)),rgbcolor=(0,0,1),pointsize=30)
ili možemo koristiti moćan python modul matplotlib
import pylab
import numpy
x=numpy.arange(-2.0,3.5,0.01)
y=list(map(f,x))
tocke_x = [1,2,-1,3]
tocke_y = [3,16,1,45]
%display plain
pylab.figure(figsize=(8,6))
pylab.axis([-2,4, -10, 70])
pylab.grid(True)
pylab.plot(x,y,'b-',tocke_x,tocke_y,'ro',markersize=8,linewidth=2);
#pylab.savefig('lagrange.png')
Uočite na grafu funkcije $y=3^x$ točke $\big(\!-\!1,\frac{1}{3}\big),\, (0,1)$ i $(1,3)$. Nađite polinom najmanjeg stupnja koji prolazi tim točkama i pomoću njega približno odredite $\sqrt[4]{3}$.
%display latex
R.<x>=QQ[]
g=R.lagrange_polynomial([(-1,1/3),(0,1),(1,3)])
g
grafički prikaz zadane funkcije (crvena boja) i pronađenog polinoma (plava boja) sa istaknutim zadanim točkama
show(plot(lambda x: 3**x,(-1,1),rgbcolor=(1,0,0))+plot(g,-1,1)+
point(((-1,1/3),(0,1),(1,3)),rgbcolor=(0,1,0),faceted=True,pointsize=30,markeredgecolor='black'),
frame=True,gridlines=True,axes=False,ymin=-0.5,ymax=3.5,
ticks=[[-1+0.25*i for i in range(0,9)],[-0.5+0.5*i for i in range(0,9)]])
aproksimacija broja $\sqrt[4]{3}$ pomoću dobivenog polinoma
vrijednost=n(3**(1/4),digits=50); vrijednost
aproksimacija=n(g(1/4),digits=50); aproksimacija
greška aproksimacije
vrijednost-aproksimacija
Odredite kvocijent i ostatak pri dijeljenju polinoma $f(x)=x^5-3x^3-5x$ s polinomom $g(x)=x^2-x+1$.
R.<x>=QQ[]
f=x^5-3*x^3-5*x
g=x^2-x+1
kvocijent
f//g
ostatak
f%g
Koliki je ostatak pri dijeljenju polinoma $f(x)=x^{1987}-2x+5$ s polinomom $g(x)=x-1$?
Već smo ranije s R.<x>=QQ[ ] definirali prsten $R$ polinoma u varijabli $x$ nad poljem racionalnih brojeva pa ne trebamo to svaki puta ispočetka ponovo definirati.
f=x^1987-2*x+5
g=x-1
ostatak
f%g
Kod ručnog dijeljenja polinoma $f$ i $g$ predugo bi trajalo određivanje kvocijenta tih dvaju polinoma, no u SAGE-u je to gotovo za manje od jedne sekunde
%display plain
time f//g
%display latex
Odredite ostatak pri dijeljenju polinoma $f(x)=x^{77}+x^{55}+x^{33}+x^{11}+1$ s polinomom $g(x)=x^2-1$.
f=x^77+x^55+x^33+x^11+1
g=x^2-1
ostatak
f%g
nije problem odrediti i kvocijent
f//g
Izračunajte vrijednost polinoma $f(x)=4x^4+2x^2+1$ u točki $2$.
f=4*x^4+2*x^2+1
f(2)
Možemo koristiti funkciju iz datoteke MMZI.sage. Funkcija rucni_Horner(p,x0) računa vrijednost polinoma $p$ u točki $x_0$ i na izlazu vraća tablicu koju dobivamo ručnim izvođenjem Hornerovog algoritma. Pazite, varijabla p mora biti tipa "SAGE polinom".
rucni_Horner(f,2)
Polinom $P(x)=x^4-8x^3+5x^2+2x-7$ razvijte po potencijama od $x+2$.
x=var('x')
P=x^4-8*x^3+5*x^2+2*x-7
P.series(x==-2,5)
Možemo koristiti funkciju iz datoteke MMZI.sage. Funkcija razvoj_Horner(p,x0) daje razvoj polinoma $p$ po potencijama od $x-x_0$, tj. daje nam tablicu koju dobivamo ručnim rješavanjem zadatka. Pazite, varijabla p mora biti tipa "SAGE polinom".
R.<x>=QQ[]
razvoj_Horner(x^4-8*x^3+5*x^2+2*x-7,-2)
Za polinome $A(x)=x^4+6x^3+17x^2+24x+12$ i $B(x)=x^3-2x^2-13x-10$ odredite polinome $P$ i $Q$ tako da vrijedi $AP+BQ=M(A,B)$.
R.<x>=QQ[]
A=x^4+6*x^3+17*x^2+24*x+12
B=x^3-2*x^2-13*x-10
ako nas zanima samo najveća zajednička mjera
A.gcd(B)
gcd(A,B)
ako nas zanima sve: $M(A,B),\, P,\ Q$
A.xgcd(B)
xgcd(A,B)
Možemo koristiti funkciju iz datoteke MMZI.sage. Funkcija polinomi_gcd(f,g) daje svaki korak Euklidovog algoritma prilikom određivanja najveće zajedničke mjere polinoma f i g, tj. u svakom koraku daje kvocijent i ostatak koji se dobiju dijeljenjem odgovarajućih polinoma, baš onako kako dobivamo ručnim određivanjem najveće zajedničke mjere dva polinoma. Pazite, varijable f i g moraju biti tipa "SAGE polinom".
polinomi_gcd(A,B)
Za polinome $A(x)=4x^5-x^4-4x^3+13x^2-3x$ i $B(x)=3x^4-x^3-3x^2+10x-3$ odredite polinome $P$ i $Q$ tako da vrijedi $AP+BQ=M(A,B)$.
A=4*x^5-x^4-4*x^3+13*x^2-3*x
B=3*x^4-x^3-3*x^2+10*x-3
najveća zajednička mjera
gcd(A,B)
ako nas sve zanima: $M(A,B),\, P,\, Q$
xgcd(A,B)
pojedini koraci Euklidovog algoritma
polinomi_gcd(A,B)
Dokažite da se razlomak $\dfrac{x^4+x^3+1}{x^5+x+1}$ ne može više skratiti.
Razlomak se ne može više skratiti zato jer je najveća zajednička mjera brojnika i nazivnika jednaka 1.
gcd(x^5+x+1,x^4+x^3+1)
pojedini koraci Euklidovog algoritma
polinomi_gcd(x^5+x+1,x^4+x^3+1)
Riješite jednadžbu $5x^3-9x^2-x-2=0$.
f=5*x^3-9*x^2-x-2
Možemo dobiti listu intervala unutar kojih se nalaze realne nultočke. Konkretno ovdje, naš polinom ima samo jednu realnu nultočku unutar intervala $\big\langle\frac{3}{2},\frac{11}{4}\big\rangle$.
f.real_root_intervals()
Sa slike bismo mogli očitati da bi ta realna nultočka bila $x=2$, što i direktnim provjeravanjem zaista jest.
plot(f,-1,3)
Daje samo racionalne nultočke polinoma $f$ jer je polinom $f$ definiran kao polinom s racionalnim koeficijentima. Sjetimo se da smo ranije definirali R.<x>=QQ[ ]. $x=2$ je jednostruka nultočka.
f.roots()
Daje sve realne nultočke od $f$. Uočavamo da $f$ ima samo jednu realnu jednostruku nultočku.
f.roots(RR)
f.roots(RealField(200))
Daje sve kompleksne nultočke
f.roots(CC)
f.roots(ComplexField(200))
možemo koristiti i naredbu solve
u=var('u')
solve(5*u^3-9*u^2-u-2,u)
ili
solve([5*u^3-9*u^2-u-2==0],u)
Napomena. Ako promatramo polinom $g(x)=x^2-2$, tada je dolje polinom $g$ definiran kao polinom s racionalnim koeficijentima jer smo već ranije definirali R.<x>=QQ[ ].
g=x^2-2
polinom $g$ nema racionalnih nultočaka
g.roots()
g.roots(QQ)
polinom $g$ ima dvije jednostruke realne nultočke
g.roots(RR)
g.roots(RealField(300))
Riješite jednadžbu $2x^4+13x^3+25x^2+15x+9=0$.
f=2*x^4+13*x^3+25*x^2+15*x+9
Pogledajmo intervale u kojima se nalaze realne nultočke
f.real_root_intervals()
f.real_root_intervals()[0][0]
pogledajmo numerički koji je to zapravo interval
[n(i,digits=50) for i in f.real_root_intervals()[0][0]]
Dakle, unutar gornjeg intervala imamo dvije realne nultočke, a kako je taj interval jako mali već predosjećamo da bi $x=-3$ mogla biti dvostruka nultočka (naravno, to je samo naša slutnja, što ne znači da mora biti i istinita). Pogledajmo i graf koji će nas još više u to uvjeriti (uočite kako graf "dodiruje" u točki $(-3,0)$ $x$-os, što zapravo znači da je $-3$ dvostruka nultočka).
plot(f,-5,1)
potvrdimo konačno naše slutnje
f.roots(RR)
f.roots(CC)
solve(2*u^4+13*u^3+25*u^2+15*u+9,u)
faktorizacija polinoma $f$
factor(f)
Riješite jednadžbu $x^3+3x^2-9x-20=0$.
f=x^3+3*x^2-9*x-20
Idemo se opet malo igrati. Pogledajmo prvo intervale u kojima se nalaze realne nultočke.
f.real_root_intervals()
Dakle, naš polinom ima tri realne nultočke, što možemo vidjeti i sa grafa.
plot(f,-5,4)
sve realne nultočke
f.roots(RR)
solve(u^3+3*u^2-9*u-20,u)
Riješite jednadžbu $x^4-4x^3+11x^2-14x+10=0$.
f=x^4-4*x^3+11*x^2-14*x+10
$f$ nema realnih nultočaka
f.real_root_intervals()
plot(f,-2,4)
f.roots(CC)
solve(u^4-4*u^3+11*u^2-14*u+10,u)
Izračunajte $\big(i-\sqrt{3}\big)^{13}$.
expand((I-sqrt(3))^13)
Riješite jednadžbu $8x^5-4x^4+2x^3-7x^2+5x-1=0$.
f=8*x^5-4*x^4+2*x^3-7*x^2+5*x-1
postoje tri realne nultočke
f.real_root_intervals()
[n(k,digits=50) for k in f.real_root_intervals()[0][0]]
naslućujemo da bi $\frac{1}{2}$ mogla biti trostruka nultočka
plot(f,-1,1.8)
sve nultočke
f.roots(CC)
solve(8*u^5-4*u^4+2*u^3-7*u^2+5*u-1,u)
solve(8*u^5-4*u^4+2*u^3-7*u^2+5*u-1,u,multiplicities=True)
faktorizacija polinoma $f$
factor(f)
Riješite jednadžbu $x^3-3x^2+3=0$.
S naredbom solve nećemo baš nešto pametno dobiti.
solve(u^3-3*u^2+3,u)
Preko metode roots dobivamo numerička rješenja i uočavamo da zadana jednadžba ima tri različita realna rješenja.
f=x^3-3*x^2+3
f.roots(CC)
Riješite jednadžbu $z^3+i=0$.
U ovom slučaju solve i roots ne daju ono što bismo željeli.
solve(u^3+I,u)
R1.<c>=CC[]
f=c^3+I
f.roots()
Međutim, SAGE ima naredbu complex_roots koja će obaviti posao kako treba
from sage.rings.polynomial.complex_roots import *
R.<x>=QQ[]
K.<i>=NumberField(x^2+1)
complex_roots(x^3+i)
ili možemo koristiti metodu nth_root za vađenje $n$-tog korijena iz kompleksnog broja. Ovdje zapravo treba izračunati $\sqrt[3]{-i}$.
a = CC(-I)
a.nth_root(3,all=True)
Možemo koristiti funkciju iz datoteke MMZI.sage. Funkcija kompleksni_korijen(z,n,sredi=False) daje sve $n$-te korijene kompleksnog broja $z$. Varijabla sredi po defaultu je stavljena na False, što znači da se neće sređivati kosinusi i sinusi "lijepih" kutova. Ako želimo da se srede kosinusi i sinusi "lijepih" kutova, tada treba staviti sredi=True.
primjena funkcije kompleksni_korijen na računanje $\sqrt[3]{-i}$
kompleksni_korijen(-I,3)
kompleksni_korijen(-I,3,sredi=True)
$\sqrt[5]{9}$
kompleksni_korijen(9,5)
kompleksni_korijen(9,5,sredi=True)
$\sqrt[3]{-\frac{1}{2}+\frac{\sqrt{3}}{2}i}$
kompleksni_korijen(-1/2+sqrt(3)/2*I,3)
kompleksni_korijen(-1/2+sqrt(3)/2*I,3,sredi=True)
$\sqrt[7]{-2-2i}$
kompleksni_korijen(-2-2*I,7)
$\sqrt[4]{1-5i}$
kompleksni_korijen(1-5*I,4)
Riješite jednadžbu $(1+i)x^4-(1-i)x=0$.
complex_roots((1+i)*x^4-(1-i)*x)
solve((1+I)*u^4-(1-I)*u,u)
Možemo primijeniti funkciju kompleksni_korijen. Naime, jedno rješenje jednadžbe je $x=0$ pa ostaje još riješiti jednadžbu $x^3=\frac{1-i}{1+i}$, tj. treba izračunati $\sqrt[3]{\frac{1-i}{1+i}}$.
solve((1+I)*u^3-(1-I),u^3)
kompleksni_korijen(-I,3,sredi=True)
Riješite jednadžbu $x^6-16x^4-30x^3-16x^2+1=0$.
solve(u^6-16*u^4-30*u^3-16*u^2+1,u)
solve(u^6-16*u^4-30*u^3-16*u^2+1,u,multiplicities=True)
f=x^6-16*x^4-30*x^3-16*x^2+1
$-1$ je dvostruko rješenje
f.roots()
f.roots(CC)
Riješite jednadžbu $x^4+3x^2+2x+3=0$.
solve(u^4+3*u^2+2*u+3,u)
Riješite jednadžbu $x^8+3x^4+2x^2+3=0$.
SAGE nema automatiziran postupak korjenovanja kompleksnih brojeva, što se dolje vidi iz danih rješenja na izlazu.
var('x')
jednadzba=x^8+3*x^4+2*x^2+3==0
solve(jednadzba,x)
Stoga ćemo uvesti najprije supstituciju $x^2=t$ i riješiti dobivenu jednadžbu za $t$. Nakon toga ćemo pomoću naše funkcije kompleksni_korijen izvaditi kvadratne korijene iz dobivenih $t$-ova.
var('t')
nova=jednadzba.substitute(x=sqrt(t)); nova
rj=solve(nova,t); rj
rj=list(map(lambda y:y.rhs(),rj)); rj
Primijenimo sada kompleksni_korijen na dobivene $t$-ove kako bismo dobili rješenja za $x$-ove. Naime, $x=\sqrt{t}$. Radi preglednosti primjenjivat ćemo funkciju kompleksni_korijen korak po korak, zasebno za svaki dobiveni $t$.
kompleksni_korijen(rj[0],2,sredi=True)
kompleksni_korijen(rj[1],2,sredi=True)
kompleksni_korijen(rj[2],2,sredi=True)
kompleksni_korijen(rj[3],2,sredi=True)
Možemo odjedanput primijeniti funkciju kompleksni_korijen na cijelu listu rj. Usput možemo primijeniti i funkciju flatten kako bismo izbacili sve unutarnje zagrade (koje stvara funkcija kompleksni_korijen) u listi rješenja za $x$-ove.
flatten(list(map(lambda y: kompleksni_korijen(y,2,sredi=True),rj)))
Naravno, mogli smo zadanu jednadžbu riješiti numerički pomoću roots metode.
R.<x>=QQ[]
f=x^8+3*x^4+2*x^2+3
f.roots(CC)
Želimo li veću preciznost, moramo to posebno naglasiti.
f.roots(ComplexField(200))
Kod ručnog rješavanja jednadžbe $a_4x^4+a_3x^3+a_2x^2+a_1x+a_0=0$ Ferrarijevom metodom, najprije treba pronaći Ferrarijevu rezolventu. Ovdje je implementirana funkcija Ferrari_rezolventa koja obavlja taj posao. Pazite, varijabla p mora biti tipa "SAGE polinom" i naravno mora biti polinom 4. stupnja. Na izlazu se vraća Ferrarijeva rezolventa u varijabli $y$.
Evo i nekoliko konkretnih primjera korištenja funkcije Ferrari_rezolventa.
Pronađite Ferrarijevu rezolventu jednadžbe $x^4+3x^2+2x+3=0$.
R.<x>=QQ[]
Ferrari_rezolventa(x^4+3*x^2+2*x+3)
možemo i dodatno pomnožiti rezolventu nekim brojem ukoliko želimo manje brojeve u jednadžbi
1/gcd([8,12,24,32])*Ferrari_rezolventa(x^4+3*x^2+2*x+3)
Pronađite Ferrarijevu rezolventu jednadžbe $x^4+x^3+x^2+x+1=0$.
Ferrari_rezolventa(x^4+x^3+x^2+x+1)
1/gcd([8,4,6,2])*Ferrari_rezolventa(x^4+x^3+x^2+x+1)
Pronađite Ferrarijevu rezolventu jednadžbe $x^4-x^3+8x^2-12x+15=0$.
Ferrari_rezolventa(x^4-x^3+8*x^2-12*x+15)
1/gcd([8,32,96,321])*Ferrari_rezolventa(x^4-x^3+8*x^2-12*x+15)
Pronađite Ferrarijevu rezolventu jednadžbe $-3x^4+5x+2=0$.
Ferrari_rezolventa(-3*x^4+5*x+2)
-9*Ferrari_rezolventa(-3*x^4+5*x+2)
U ovom dijelu implementirana je funkcija Cardan(p,q) koja daje egzaktna rješenja jednadžbe $x^3+px+q=0$ koristeći Cardanovu formulu.
Evo i nekoliko konkretnih primjera korištenja funkcije Cardan.
Pomoću Cardanove formule riješite jednadžbu $x^3+15x+124=0$.
Cardan(15,124)
U ovom slučaju i funkcija solve daje rješenja
var('x')
solve(x^3+15*x+124==0,x)
Pomoću Cardanove formule riješite jednadžbu $x^3-2x-2=0$.
Cardan(-2,-2)
Funkcija solve također daje rješenja
solve(x^3-2*x-2==0,x)
Kako egzaktna rješenja nisu previše "lijepa", uvijek možemo jednadžbu riješiti i numerički pomoću metode roots.
R.<x>=QQ[]
f=x^3-2*x-2
f.roots(CC)
Pomoću Cardanove formule riješite jednadžbu $x^3-3x+1=0$.
Cardan(-3,1)
Ovaj put se funkcija solve nije proslavila. Uočite da ona ne zna računati korijene iz kompleksnih brojeva, dok naša funkcija Cardan to zna.
var('x')
solve(x^3-3*x+1==0,x)
Pomoću Cardanove formule riješite jednadžbu $x^3+6x-2=0$.
Cardan(6,-2)
Funkcija solve daje također rješenja jer u ovom slučaju nije bilo potrebno vaditi korijen iz kompleksnog broja.
solve(x^3+6*x-2==0,x)
Pomoću Cardanove formule riješite jednadžbu $x^3-12x-8=0$.
Cardan(-12,-8)
U ovom slučaju funkcija solve ima problema s vađenjem korijena iz kompleksnog broja.
solve(x^3-12*x-8==0,x)
Pomoću Cardanove formule riješite jednadžbu $x^3-2x^2-x+2=0$.
Ova jednadžba ima sva rješenja cjelobrojna.
var('x y')
solve(x^3-2*x^2-x+2==0,x)
Međutim, Cardanova formula će dati vrlo komplicirane zapise tih rješenja. Da bismo mogli primijeniti Cardanovu formulu, moramo se prvo riješiti kvadratnog člana. U jednadžbi $x^3+ax^2+bx+c=0$ kvadratnog člana se rješavamo pomoću supstitucije $x=y-\frac{a}{3}$.
jed=x^3-2*x^2-x+2==0
jed.substitute(x=y+2/3)
expand(jed.substitute(x=y+2/3))
Sada rješavamo jednadžbu $y^3-\frac{7}{3}y+\frac{20}{27}=0$ pomoću Cardanove formule.
rj=Cardan(-7/3,20/27); rj
Sva rješenja početne jednadžbe su
rj2=list(map(lambda h:h+2/3,rj)); rj2
Dakle, užasno komplicirani zapisi rješenja početne jednadžbe, a znamo da su ta rješenja jako lijepa i cjelobrojna kao što smo i na početku vidjeli. No, možemo se numerički uvjeriti da su ovi komplicirani zapisi zaista jednaki $2,\, 1$ i $-1$.
list(map(lambda h:n(h,digits=20),rj2))
list(map(lambda h:n(h,digits=80),rj2))
Možemo zaključiti da nije pametno odmah koristiti Cardanovu formulu kod algebarske jednadžbe trećeg stupnja. Najbolje je prvo probati jednadžbu riješiti nekim drugim metodama, a tek kad nam potonu sve lađe, onda krenemo koristiti Cardanovu formulu i probamo pomoću nje doznati da li se egzaktna rješenja mogu napisati u nekom lijepom obliku. Jasno, u praksi se koriste razne numeričke metode za rješavanje jednadžbi, a ovdje smo pokazali metodu roots koja numerički traži nultočke polinoma i može ih dati na unaprijed zadanu preciznost.