{{{id=240| var('x y a b c') /// }}}
U Sageu kao znak jednakosti u jednadžbama stoji "==", jer je uobičajeni znak "=" , kako smo gore već vidjeli, rezerviran za pridjeljivanje vrijednosti simbolima odnosno pridjeljivanje imena izrazima. Rješavanje jednadžbi se izvodi funkcijom solve():
{{{id=3| sol = solve(2*x^2 - 1 == 0, x); sol /// }}}Valja primijetiti slijedeće:
1. Prilikom poziva funkcije solve() treba eksplicitno naznačiti po kojoj varijabli se traži rješavanje.
2. Pronađena su oba rješenja kvadratne jednadžbe.
3. Rezultat je ispisan u obliku liste [...] jednadžbi. To omogućuje uvrštavanje rješenja u neki drugi izraz, ili u samu originalnu jednadžbu radi provjere. (Zato smo gore toj listi rješenja odmah pridjelili ime sol).
Pristup pojedinim elementima liste ostvaruje se sintaksom lista[n] gdje je n indeks elementa i brojanje počinje s nulom tako da prvi element ima indeks 0. (O listama će biti više riječi u slijedećem poglavlju.). Uvrštavanje tj. supstitucija u izrazu izvodi se metodom subs(), čiji argument može biti i jednadžba:
{{{id=228| (x+y).subs(sol[0]) /// }}} {{{id=231| (2*x^2 - 1 == 0).subs(sol[1]) /// }}}Transformacija izraza pomoću supstitucije je vrlo korisna operacija o kojoj će više riječi biti kasnije. Zasad pokažimo samo njenu najčešću upotrebu: pridjeljivanje vrijednosti simbolima u nekom izrazu:
{{{id=232| ( (a+b-c)^4 ).expand() /// }}} {{{id=234| _.subs(b==c) /// }}} {{{id=235| _.subs(a==2) /// }}}Funkcija solve() može rješavati i sustave jednadžbi, ako se kao argumenti zadaju liste jednadžbi odnosno liste varijabli:
{{{id=4| sol2 = solve([x^2 + y^2 == 1, x - 2*y == 0], [x, y]); sol2 /// }}}Da bi dobili numeričke vrijednosti ovih rješenja ne možemo (kao u npr. Mathematici) jednostavno primijeniti funkciju n() na ovu listu rješenja, jer n() nije metoda liste (a ni jednadžbe), već samo primitivnijih objekata, pa je potrebno indeksiranjem ekstrahirati izraze s desne strane gornjih jednadžbi npr.
{{{id=416| (x.subs(sol2[0][0]).n(), y.subs(sol2[0][1]).n()) /// }}}(* do Zadatka) Koristeći nešto naprednije tehnike možemo ovo izvesti elegantnije tako da iteriramo preko liste rješenja i to tako da se n() primjenjuje samo na desne strane gornjih jednadžbi. To je lakše izvesti tako da zatražimo od solve() rješenje, ne u obliku liste jednadžbi, već u obliku liste riječnika. Vidi python tutorial: dictionary
{{{id=410| soln = solve([x^2 + y^2 == 1, x - 2*y == 0], x, y, solution_dict=True); soln /// }}}Sad primjenjujemo moćni postupak obuhvaćanja liste (list comprehension) koji omogućuje kreiranje nove liste na osnovi stare u jednom koraku (vidi kasnije poglavlje o programiranju):
{{{id=412| [s[y] for s in soln] /// }}}odnosno
{{{id=420| [s[y].n() for s in soln] /// }}}Konačno, za ljepši ispis možemo koristiti Pythonovo formatiranje stringova (slično kao u C-u)
{{{id=411| ["x = %f y = %f" % (s[x].n(), s[y].n()) for s in soln] /// }}}♦ Zadatak 2-2.1: Riješite sustav jednadžbi
$$ x^4 + a^4 =1 \;, \quad x^2 + a^2 = 1 \;, $$
Koliko ima rješenja?
Ukoliko sustav jednadžbi ima beskonačno rješenja, dobit ćemo rješenje koje uključuje slobodni parametar ili više njih:
Gore je r<broj> neki realni, a z<broj> neki cijeli broj. Ovo radi samo sa sustavom jednadžbi, a ne i s jednom jednadžbom ...
{{{id=264| solve(sin(x)==0, x) /// }}}... pa ukoliko želimo i ovo rješenje zapisano kao skup rješenja možemo iskoristiti trik da kreiramo sustav u kojem je druga jednadžba razvezana:
{{{id=259| sol3=solve([sin(x)==0,y==0], x,y); sol3 /// }}} {{{id=268| [a for a,b in sol3] # (*) /// }}} {{{id=266| show(_) /// }}}solve() daje simbolička (analitička) rješenja jednadžbi. Međutim, neka rješenja npr. jednadžbi viših stupnjeva nije moguće analitički zapisati. Npr, za slijedeću jednadžbu solve() nam daje samo jedno trivijalno realno rješenje:
{{{id=305| eq = 9*x^6 + 4*x^4 + 3*x^3 + x - 17 == 0 solve(eq, x) /// }}}No znamo da ta jednadžba, šestog stupnja, mora imati šest kompleksnih rješenja. Ostalih pet se ne da zapisati drugačije nego kao numeričke (floating point) brojeve. Da bismo dobili ta rješenja koristimo metodu roots(), gdje opcijom ring=CC tražimo rješenja u prstenu kompleksnih brojeva:
{{{id=304| eq.roots(x, multiplicities=False, ring=CC) /// }}} {{{id=307| len(_) /// }}}Daljnji je problem da je i roots() zapravo analitički rješavač jednadžbi (koristi egzaktne, a ne numeričke metode), a neke jednadžbe se ne mogu analitički egzaktno riješiti, poput onih koje uključuju transcendentalne funkcije.
{{{id=310| eq2 = 2 * arctan(x) == x^2 eq2.roots(ring=CC) /// }}}U tom slučaju moramo pribjeći pravom numeričkom rješavanju tako da definiramo funkciju čije nul-točke su ekvivalentne rješenjima jednadžbe i onda ih tražimo pomoću funkcije find_root(). Problem s find_root() je da mu se treba dati interval u kojem traži nul-točku i da će pronaći samo jednu. Nakon toga moguće treba tražiti dalje u drugačijem intervalu koji ne uključuje pronađenu nul-točku itd.
{{{id=286| f(x) = 2 * arctan(x) - x^2 # ekvivalentno eq2 find_root(f(x), 0, 10) /// }}} {{{id=291| find_root(f(x), 0.1, 10) /// }}} {{{id=292| find_root(f(x),1.4, 10) /// }}} {{{id=294| find_root(f(x), -1., 1) /// }}}Ovo zadnje rješenje je zapravo 0 jer funkcija find_root() radi numeriku s konačnom preciznošću, koja po defaultu otprilike odgovara preciznosti double precision floating point varijabli u Fortranu ili C-u, što može promijeniti pomoću opcionalnog argumenta xtol:
{{{id=295| find_root(f(x), -1., 1, xtol=1e-30) /// }}}Vidimo da se s povećanjem radne preciznosti rješenje još više približilo nuli. Možemo se uvjeriti da su ova gore dva rješenja zaista jedina, tako da skiciramo graf funkcije f(x) i vidimo da siječe apscisu na samo dva mjesta. Koristimo funkciju plot() o kojoj će kasnije biti više riječi.
{{{id=312| plot(f(x), (x, -3, 3), ymin=-4) /// }}}♦ Zadatak 2-2.2: Riješite jednadžbu
$$ \tan x - \frac{x}{10} ==0 \;. $$
♦ Zadatak 2-2.3: (*) Pronađite numeričku vrijednost nekog kompleksnog rješenja jednadžbe $\sin x = 2$ i provjerite uvrštavanjem.
♦ Zadatak 2-2.4 Riješite nejednadžbu $ x^2 +x - 12 < 0$.
♦ Zadatak 2-2.5 Pronađite pozicije lokalnog minimuma te lokalnog maksimuma gama funkcije $\Gamma(x)$ koji su najbliži točki x=0.
♦ Zadatak 2-2.6 (*) Pronađite pozicije minimuma i maksimuma Besselove funkcije $J_{1}(x)$ koji su najbliži točki $x=0$.
{{{id=421| /// }}}