3-2-Funkcije-S
system:sage


<p>Mogućnost definiranja novih funkcija je osnovna stepenica k naprednijem programiranju. U Sageu postoji nekoliko vrsta funkcija (za detalje vidi <a href="http://sagemath.org/doc/tutorial/tour_functions.html">ovdje</a>), a mi ćemo trebati i razlikovati dvije osnovne vrste:</p>
<ol>
<li>Simboličke funkcije</li>
<li>Python funkcije</li>
</ol>
<p>Ugrubo, simbolička funkcija dopu&scaron;ta vi&scaron;e simboličkih manipulacija (poput integracije ili deriviranja), ali ne može sadržavati kompleksne algoritme već samo jednostavne izraze. Python funkcija može biti proizvoljno kompleksna, ali ne može se uvijek npr. simbolički integrirati.</p>
<p><strong>Simboličke funkcije</strong> se definiraju na slijedeći prirodan način:</p>

{{{id=45|
f(x) = x^2
f
///
}}}

<p>S njima se mogu raditi sve uobičajene operacije:</p>

{{{id=2|
print f(2)
print f((2*x+3)^2)
diff(f(x), x)
///
}}}

<p>(*) Formalno, simboličke funkcije nisu po svom tipu "funkcije", već "simbolički izrazi koji se mogu pozivati" ("<em>callable symbolic expression</em>"):</p>

{{{id=42|
print type(sin)
type(f)
///
}}}

<p>Naravno, funkcija može biti i funkcija od vi&scaron;e variabli:</p>

{{{id=41|
g(x, a) = x^a
g(4, 2)
///
}}}

<p><strong>Python funkcije</strong> se definiraju kori&scaron;tenjem ključnih riječi <em>def</em> i <em>return</em>, te blokova k&ocirc;da koji su konzistentno uvučeni (npr. za 4 mjesta; Sage automatski radi to uvlačenje):</p>

{{{id=54|
def h(x):
    "Kvadriraj broj x."
    return x^2
///
}}}

{{{id=58|
print h(3)
///
}}}

<p>Kao prvi red tijela funkcije može se, kao gore, staviti dokumentacijski string (tzv. <em>docstring</em>) kojem se kasnije može pristupiti standardnim metodama pristupa dokumentaciji:</p>

{{{id=57|
h?
///
}}}

<p>Funkciju definiranu po dijelovima možemo dobiti na slijedeći način:</p>

{{{id=72|
def fpw(x):
    if x<-1:
        return -x
    elif x>1:
        return x
    else:
        return x^2
///
}}}

<p>(Ovdje smo upotrijebili if-then-else grananje. Sintaksa je očita.)</p>

{{{id=74|
plot(fpw, -2, 2)
///
}}}

<p>Kako je već spomenuto, python funkcije ne možemo općenito npr. simbolički integrirati. Posebno je opasno to &scaron;to, ukoliko poku&scaron;amo, možemo dobiti pogre&scaron;an odgovor:</p>

{{{id=66|
integral(fpw(x), x, 1, 2)
///
}}}

<p>No, uvijek možemo pribjeći numeričkoj integraciji koja u ovom slučaju daje točan rezultat 3/2:</p>

{{{id=69|
numerical_integral(fpw, 1, 2)[0]
///
}}}

<p>(*) Pri gornjem poku&scaron;aju simboličke integracije, prvo je izvrijednjen sam integrand fpw(x). Kako u tom trenutku x nema nikakvu vrijednost, on ne zadovoljava ni jedan od dva uvjeta (x&gt;1 ili x&lt;1) pa funkcija vraća simbolički izraz x^2&nbsp; ("else" blok), koji je onda integriran u granicama od 1 do 2.</p>

{{{id=79|
fpw(x)
///
}}}

<p>Iz istog razloga je prilikom crtanja gore bilo potrebno kao prvi argument staviti samu funkciju fpw, a ne izraz fpw(x) koji bi dao krivi crtež:</p>

{{{id=81|
plot(fpw(x), x, -2, 2)
///
}}}

<p>Funkcija može imati i opcionalne argumente s defaultnom vrijedno&scaron;ću:</p>

{{{id=61|
def fun(x, n=1, b=0):
    return x^n + b
///
}}}

{{{id=63|
print fun(3, 4, 5)
print fun(3, b=5, n=4)
fun(3)
///
}}}

<p>(Uočite da kad smo eksplicitno imenovali argumente nismo morali paziti na njihov poredak.)</p>

<p>Bilo &scaron;to može biti argument funkcije. Najmoćnija stvar, obilato kori&scaron;tena u funkcionalnom pristupu programiranju (vidi kasnije), je da i same funkcije mogu biti argumenti funkcija:</p>

{{{id=9|
def gun(f, x):
    "Komponiraj dvaput funkciju sa samom sobom"
    return f(f(x))
///
}}}

{{{id=51|
print gun(sin, 2)
gun(log, 0.1)
///
}}}

<p>Ukoliko znamo da python funkcija uvijek korektno vraća simbolički izraz, smijemo je integrirati i diferencirati:</p>

{{{id=71|
diff(gun(sin, x), x)
///
}}}

<p>Rezultat izvrijednjavanja funkcije, dakle ono &scaron;to slijedi ključnu riječ <em>return</em>, može biti bilo kakav objekt. Čak i crtež:</p>

{{{id=19|
def plotfun(fun, min, max):
    "Nacrtaj realni i imaginarni dio funkcije fun."
    
    Pre = plot(real(fun(x)), min, max, color='red', label="R")
    Pim = plot(imag(fun(x)), min, max, color='blue', linestyle='--', label="I")
    return Pre+Pim
///
}}}

{{{id=84|
def imlog(x):
    return log(I*x)
///
}}}

{{{id=85|
plotfun(imlog, -10, 10)
///
}}}

<p>Može i ovo, ali nije poželjno:</p>

{{{id=86|
plotfun(imlog(x), -10, 10)
///
}}}

<p><span id="cell_outer_29"><span id="cell_outer_10"><span id="cell_outer_5">&diams; </span></span><strong>Zadatak 3.2.1: </strong></span>Definirajte funkciju plotpoint(z) koja crta kompleksnu ravninu sa točkom koja odgovara kompleksnom broju z. Dakle x=Re(z), y=Im(z)</p>


<p><span id="cell_outer_29"><span id="cell_outer_10"><span id="cell_outer_5">&diams; </span></span><strong>Zadatak 3.2.2: </strong></span>Definirajte funkciju argand(lista) koja crta kompleksnu ravninu s točkama zadanim u listi kompleksnih brojeva lista = [$z_1, z_2, \ldots$]. Upotrijebite funkciju argand da nacrtate na jednom dijagramu svih devet devetih korijena od 1.</p>



<p><span id="cell_outer_21"><span id="cell_outer_29"><span id="cell_outer_10"><span id="cell_outer_5">&diams; </span></span><strong>Zadatak 3.2.3: </strong></span></span>Formule za nerelativističku i relativističku kinetičku energiju tijela mase m koje se giba brzinom v su</p>
<p>$$</p>
<p>K_{\rm nr} = \frac{1}{2} m v^2 \;, \qquad&nbsp; K_{\rm rel} = m c^2 \left( \frac{1}{\sqrt{1-v^2/c^2}}-1\right) \;.</p>
<p>$$</p>
<p>(a) Definirajte odgovarajuće funkcije <em>knr() </em>i <em>krel()</em> te usporedite na istom dijagramu pona&scaron;anje tih funkcija za brzine od 0 do $3\cdot 10^8$ m/s za neku vrijednost mase m=1 kg. Označite veličine i njihove jedinice na koordinatnim osima!</p>
<p><br />(b) Odredite brzinu pri kojoj je gre&scaron;ka nerelativističke formule&nbsp; tisućinku promila.</p>
<p>(c) Ako ste definirali funkcije kao python funkcije, ponovite zadatak sa simboličkim funkcijama i obratno.</p>

{{{id=87|

///
}}}