2008-10-22

3. Osnove Mathematica  jezika

3.1 Liste

Liste i elementi

Liste su važan dio Mathematica jezika. Srodne su poljima (array) iz standardnih programskih jezika (C, Fortran), ali imaju bitno više svojstava. Elementi liste mogu biti praktički bilo koji Mathematica objekti.

l1=List[1,3,5,7,9,11]
l2={Sin,Cos,Log}
l3={{},{"jedan"},%}

Vitičaste zagrade su samo skraćeni oblik funkcije List. Puni oblik se rijetko koristi.

Elementima liste se pristupa putem funkcije Part, odnosno njenog skraćenog oblika [[ ]]  koji se može ukucati i putem sekvence Esc-[-[-Esc što onda možda ljepše izgleda.

Part[l1,2]
l1[[2]]="tri"
l1[[2]]

l1[[{3,6}]]
Take[l1,{3,6}]

l1

Listama se može manipulirati na skoro svaki zamislivi način. First, Last, Take, Drop, Rest, Extract, Length, Prepend, PrependTo, Append, AppendTo, Insert, Delete, ... (vidi Help).

Važno je imati na umu da većina ovih komandi (iznimke su PrependTo i AppendTo)  ne mijenja originalnu listu

Drop[l2, -1]

l2

Dakle, ukoliko želimo mijenati listu, trebamo se služiti standardnim trikom

l2=Drop[l2,-1];
l2

Zadatak 3-1: Izbrišite u gornjoj listi l1 treći element  i dodajte na kraj još dva elementa, brojeve 13 i 15.

Elementi liste mogu biti i druge liste, pa onda imamo višedimenzionalne liste. Dvodimenzionalne liste (listu lista jednake duljine) smo već sreli kao matrice. Evo primjera trodimenzionalne liste:

l4={{{a,b},{h},{d,e}},{{f},{g,h},{i,j,k}}}

l4[[1]]
l4[[1]][[3]]
l4[[1,3]]
l4[[1,3,2]]

Depth[l4]

Često se javlja potreba za izborom elemenata liste koji zadovoljavaju neki kriterij. To se izvodi funkcijom Select.

l5={0,1,2,3,4,5,6,7,8,9,10};
Select[l5,EvenQ]

Drugi argument funkcije Select može biti bilo koji predikat. Predikat je termin iz matematičke logike koji označava funkciju koja poprima isključivo vrijednosti True ili False.

IntegerQ[3.]

Određen broj predikata je već ugrađen u Mathematicu (svima ime završava na "Q" od "Question" ili "Query" jer postavljaju neko da-ne pitanje svojim argumentima), a kasnije ćemo vidjeti kako ih možemo i sami definirati.

?*Q

NumberQ[x]
NumberQ[3.]
NumberQ[(Sqrt[2])]

Zašto (Sqrt[2]) nije "broj"? Pogledajmo točnu internu reprezentaciju tog objekta u Mathematici pomoću funkcije FullForm, koja je od neprocjenjive vrijednosti pri rješavanju problema.

(Sqrt[2])//FullForm
2 // FullForm

Dakle, (Sqrt[2]) Mathematica tretira kao neku vrstu složenog izraza, a ne kao obični broj. Vidjet ćemo u odjeljku 3.3 što to točno znači. Zasad samo recimo da testiranje da li je nešto broj u smislu "da li ima numeričku vrijednost" obavljamo pomoću NumericQ

NumericQ[(Sqrt[2])]

Prilikom programiranja u Mathematici se razmjerno često javlja potreba za smanjivanjem dimenzije liste tj. za micanjem zagrada. Funkcija Flatten bez dodatnog argumenta pretvara svaku listu u jednodimenzionalnu tj. miče sve unutarnje zagrade, dok dodatnim argumentom možemo zatražiti da to ide samo do neke razine.

Flatten[l4]
Flatten[l4,1]

Konstruiranje lista

Range[10]

Range[2,5,0.5]

Range radi samo s brojevima. Univerzalnija funkcija za konstruiranje lista je Table.

Table[((x^n)/(n!)),{n,1,5}]

tbl=Table[a[i,j],{i,1,3},{j,1,2}]

tbl //TableForm

Nekoliko Mathematica funkcija (Integrate, Sum, ...) poput Table kao argumente imaju i objekte koji se zovu iteratori i dolaze u slijedećim oblicima:

({{{n,nmin,nmax,step}, izraz se ponavlja,a n ide od nmin do nmax, uz korak step}, {{n,nmin,nmax}, izraz se ponavlja,a n ide od nmin do nmax, uz korak 1}, {{n,nmax}, izraz se ponavlja,a n ide od 1  do nmax, uz korak 1}, {{n}, izraz se ponavlja n puta}})

Ovdje gore nmin, nmax i step mogu biti i simboličke konstante. Jedini uvjet je da (nmax-nmin)/(step) mora biti broj.

Table[n,{n, a, 8a, 2 a}]

Za konstruiranje dijagonalnih matrica postoje i specijalne funkcije  DiagonalMatrix  i  IdentityMatrix

DiagonalMatrix[{1,w,2}] //MatrixForm

IdentityMatrix[2]//MatrixForm

Zadatak 3-2: Konstruirajte listu svih prim-brojeva manjih od 100. Koliko ima prim-brojeva manjih od (10^6), (10^7),(10^8), ...? Usporedite rezultat (i brzinu njegovog dobivanja, vidi funkciju Timing) s ugrađenom funkcijom PrimePi, te slijedećom aproksimacijom (koja je sadržaj slavnog teorema o prim-brojevima)

π(x)≈((∫_0)^x)(dz/(ln(z)))           x>1

Kad želimo prekinuti Mathematicu u nekom predugom računu možemo iskoristiti meni Evaluation→Interrupt/Abort Evaluation, ili možemo unaprijed ograničiti vrijeme funkcijom TimeConstrained

TimeConstrained[Timing[Length[Select[Range[(10^7)],PrimeQ]]],5]

Zadatak 3-3: Izračunajte funkciju π(x) (broj prim-brojeva manjih od x) za x=(10^(10 ))statističkom metodom: Izaberite uzorak od n slučajnih cijelih brojeva između 1 i x   i  testirajte koliko ima prim-brojeva među njima. Iz tog udjela odredite π(x). Kolika veličina uzorka vam treba da bi greška prema PrimePi[(10^10)] pala ispod 1%?

Liste kao skupovi

Liste nisu skupovi u matematičkom smislu jer u skupovima nema ponavljanja elemenata i redosljed elemenata u skupovima nije bitan. Međutim, Mathematica ima nekoliko funkcija koje rade s listama standardne operacije koje se inače rade sa skupovima (unija je Union, presjek Intersection, a razlika skupova Complement) i pritom eliminira duple elemente te uredi redosljed (tj. originalni redoslijed je nebitan).

l6={10,9,10,8,7,7,7,4}

Union[l6]

Union[l6,l1]

Intersection[l6,l1]
Complement[l6,l1]

Listabilnost funkcija

Listabilnost je atribut koje imaju neke Mathematica fukcije, a riječ je o svojstvu da se one, primijenjene na listu, distribuiraju po elementima liste.

l7={1,2,x,(x^2)};
Log[l7]

(l7^2)+1

Ispitati da li neka funkcija ima to svojstvo moguće je funkcijom Attributes.

Attributes[{Log,Length,Power,Attributes}]//MatrixForm

Primijetite da je i sama funkcija Attributes listabilna što smo ovdje odmah i upotrijebili. Atribute možemo dobiti i Help-funkcijom "??" koja i inače daje više podataka o objektu od jednostrukog "?".

??Log

Zadatak 3-4: Napišite one-liner (elegantni  program koji je cijeli sadržan u jednom redu – ponos svakog programera) koji ispisuje slijedeću tablicu (desni stupac je derivacija lijevog):

({{x, 1}, {(x^2), 2 x}, {(x^3), 3 (x^2)}, {(x^4), 4 (x^3)}, {(x^5), 5 (x^4)}})

Komanda ne smije uključivati nikave brojeve izuzev broja 5! (Jeftini trikovi poput 5/5+5/5 naravno ne dolaze u obzir.)

3.2 Funkcije

Vrste pridruživanja

Već znamo da se pridruživanje ("assignment") vrijednosti simbolu izvodi jednostrukim znakom jednakosti

m=3;
n=4;
zbroj=m+n

Ako sad promijenimo vrijednost simbolu m

m=6;
zbroj

vidimo da se zbroj nije promijenio. Takva je narav operacije pridruživanja vrijednosti znakom "=". Postoji i druga mogućnost, tzv. odgođeno pridruživanje ("delayed assignment"), koje se izvodi znakom ":=".

zbroj2:=m+n

Primijetite da Mathematica nije dala nikakav output. Dat će ga tek prilikom poziva varijable zbroj2 kad će i izvršiti njegovo izračunavanje prema trenutnim vrijednostima varijabli a i b.

zbroj2

n=w;
zbroj2

?zbroj

?zbroj2

Definiranje funkcija

Mogućnost definiranja novih funkcija je osnovna stepenica k naprednijem programiranju. Nove funkcije u Mathematici  definiramo na slijedeći način

f[x_]:=(x^2)

f[2]

f[(((2x+3))^2)]

Jasno je da je prilikom definicije funkcija potrebno upotrebljavati odgođeno pridruživanje ":=" jer želimo da se funkcija izvrijednjava tek kad je pozovemo. Nadalje, primijetite simbol "_" na lijevoj strani, tzv.  blank. Izraz "x_" je  tzv.  uzorak (pattern).

({{x, jedinstveni simbol x}, {x_, bilo koji izraz, privremeno (za vrijeme izvrijednjavanja funkcije)  zvan x}})

Da bolje uočimo razliku, pogledajmo "funkciju" definiranu bez blanka.

g[x]:=(x^2)

g[x]

g[w]

Ona djeluje samo na argument koji je upravo x i na nijedan drugi, što nikako nije željeno ponašanje za jednu funkciju.

Poželjno je sad izbrisati ovu lošu definiciju iz memorije, pomoću funkcije Clear, jer inače možemo naletiti na probleme poput ovih:

g[a_]:=3a

g[2]
g[w]
g[x]

Vidimo da sad funkcija radi dobro za sve argumente osim za x. To je zbog toga jer je još uvijek važeće gornje specifično pravilo za g[x], a Mathematica uvijek primjenjuje prvo specifična pravila, a opća tek onda ako nema primjenjivih specifičnih pravila. (Istovrsna pravila se primjenjuju po redoslijedu po kojem su definirana.)

?g

Clear[g]
g[a_]:=3a
g[x]

Sad je sve uredu.

Naravno, funkcija može biti i od više varijabli:

f[x_,a_]:=(x^a)

f[4,2]

f[Range[4],3]

Ovo radi zahvaljujući listabilnosti potenciranja. Naravno, funkcije mogu imati i složenije objekte kao argumente, poput liste u slijedećem primjeru:

g[list_,n_]:=n+Length[list]

g[{a,b,c},1]

g[2,1]

(Broj 2 nije lista, pa mu je duljina 0.)

Zapravo, bilo što može biti argument funkcije. Najmoćnija stvar, obilato korištena u funkcionalnom pristupu programiranju (odjeljak 4.2), je da i same funkcije mogu biti argumenti funkcija (kompozicija funkcija).

h[f_,x_]:=f[f[x]]

h[Sin,2]
h[Log,0.1]

intder[f_,x_]:=D[Integrate[f, x],x]

intder[x Log[Tan[x]],x] //Simplify

Moguće je i ograničiti domenu neke funkcije pomoću funkcije Condition, koja se obično zapisuje u skraćenom infiks obliku "/;" (čitaj npr.  "uz uvjet"):

p[x_/;x>0]:=(x^3)

"p(x), uz uvjet da je x veći od nula, je (x^3)."

p[3]

p[-3]

Tako možemo definirati funkciju po dijelovima

step[x_/;x≥0]:=1
step[x_]:=0   /; x<0

Za negativni dio domene smo, demonstracije radi, upotrijebili alternativnu poziciju operatora "/;". U starijim verzijama Mathematice  samo je taj način bio dozvoljen.

Plot[step[x],{x,-1,1},PlotStyle->Thickness[0.01]]

Pripazite! Takve funkcije mogu imati problematično numeričko ponašanje oko točaka gdje su nederivabilne.

delta=step'

delta[1]//N
delta[0.1]//N

Plot[delta[x],{x,-1,1},PlotStyle->Thickness[0.01]]

Ove nepostojeće oscilacije su artefakt numeričkih metoda koje Mathematica koristi prilikom crtanja.

Zadatak 3-5: Ugrađena funkcija UnitStep odgovara ovoj funkciji step. Uvjerite se da je njeno ponašanje oko nule bolje. Kojoj je (ugrađenoj) funkciji jednaka njena derivacija UnitStep'? Ta funkcija i UnitStep su dvije rijetke nederivabilne funkcije koje se relativno često koriste u fizici pa je stoga u Mathematici posvećena dodatna pažnja njihovoj kvalitetnoj definiciji koja ne pati od gornjih problema.

Rezultat izvrijednjavanja funkcije može biti i crtež

<<PlotLegends`

ReImPlot[fun_, iter_] := 
  Plot[{Re[fun], Im[fun]}, iter, 
    PlotStyle -> {{Thickness[0.006], RGBColor[1, 0, 0]}, {Thickness[0.006], 
          Dashing[{0.03, 0.02}], RGBColor[0, 0, 1]}}, 
    PlotLegend -> {"Re", "Im"}, LegendShadow -> {.005, -0.005}, 
    LegendPosition -> {0.4, -0.35}, LegendSize -> {0.3, 0.2}, LegendTextSpace -> 0.9]

ReImPlot[Log[I x],{x,-10,10}]

Zadatak 3-6: Definirajte funkciju argand[list_] koja crta kompleksnu ravninu s točkama zadanim u listi kompleksnih brojeva list = {(Subscript[z, 1]), (Subscript[z, 2]),…}. (Treba vam funkcija ListPlot.) Upotrijebite funkciju argand da nacrtate na jednom dijagramu svih devet devetih korijena od 1.

Naputak: Prvo definirajte funkciju plotpoint[z_] koja crta samo jednu točku.

Zadatak 3-7: Definirajte funkciju kettle[masa_, donjatemp_, gornjatemp_, korak_] koja crta tablicu oblika
                   ({{7 Celsius, 29.400000000000002` Joule, 2.94`*^8 Erg}, {7.3` Celsius, 30.66` Joule, 3.066`*^8 Erg}, {7.6` Celsius, 31.919999999999998` Joule, 3.192`*^8 Erg}})

gdje su prvi stupac temperature izmedju donjatemp i gornjatemp (u razmacima korak), drugi stupac su energije u SI sustavu koje trebaju da se masa vode zagrije od (0^◦)C do te temperature, a treći stupac su te iste energije, ali u CGS sustavu jedinica.

Naputak:
1. Prisjetite se da je energija potrebna da se temperatura tvari mase m i specifičnog toplinskog kapaciteta c promijeni za ΔT jednaka  E = m c ΔT. Toplinski kapacitet vode je 4200 J (kg^(-1))(K^(-1)).
2. Upoznajte se s paketom Units` i funkcijama SI, CGS koje rade konverziju između sustava jedinica.
3. Definirajte funkciju energija1 koja za zadanu masu i temperaturu daje potrebnu energiju. Neka funkcija prima argumente s fizikalnom dimenzijom, poput  energija1[0.01 Kilogram, 5.3 Celsius].
4. Definirajte funkciju energija2 koja za zadanu masu i temperaturu daje cijeli redak tablice
5. Koristeći funkciju energija2 definirajte traženu funkciju kettle.

Zadatak 3-8

Za prijelaz iz jednog sustava varijabli {(Subscript[x, 1]),(Subscript[x, 2]),⋯} u drugi {(Subscript[y, 1])((Subscript[x, 1]),(Subscript[x, 2]),⋯), (Subscript[y, 2])((Subscript[x, 1]),(Subscript[x, 2]),⋯), ⋯} često se rabi tzv. Jacobijeva matrica transformacija

J=(({{((∂(Subscript[y, 1]))/(∂(Subscript[x, 1]))), ((∂(Subscript[y, 1]))/(∂(Subscript[x, 2]))), ⋯}, {((∂(Subscript[y, 2]))/(∂(Subscript[x, 1]))), ((∂(Subscript[y, 2]))/(∂(Subscript[x, 2]))), ⋯}, {⋮, ⋮, ⋱}}))

(1) Definirajte funkciju jacobiMatrix[ylist_, xlist_]  koja izračunava Jacobijevu matricu.
(2) Izračunajte Jacobijevu matricu jac transformacija iz polarnog u kartezijev sustav x=r cos(θ), y=r sin(θ). 
(3) Odredite (ručno) inverzne transformacije iz kartezijevog u polarni sustav i izračunajte odgovarajuću Jacobijevu matricu invjac.
(4) Provjerite da je umnožak matrica iz (2) i (3) jednak jediničnoj matrici.
(5) Ako podzadatak (3) pokušate riješiti tako da pomoću Mathematice invertirate jednadžbe x=r cos(θ), y=r sin(θ) dobit ćete četiri rješenja. Izračunajte sve te četiri moguće Jacobijeve matrice invjac[n], n=1,2,3,4  i pokažite da su sve one inverzne originalnoj matrici, nakon što se obavi odgovarajuća zamjena varijabli.
Tu je za pojednostavljenje nekih izraza potrebno je Mathematici objasniti da je r>0, kako bi ona znala da je npr.(Sqrt[(r^2)])=r. Za to je korisna funkcija Assuming.

Zadatak 3-9

Formule za nerelativističku i relativističku kinetičku energiju tijela mase m koje se giba brzinom v su

(Subscript[K, nr])=(1/2)m (v^2)                         (Subscript[K, rel])=m (c^2)[(1/(Sqrt[1-((v^2)/(c^2))]))-1]

(a) Definirajte odgovarajuće funkcije knr i krel te usporedite na istom dijagramu ponašanje tih funkcija za brzine od 0 do 3×(10^8) m/s za neku vrijednost mase. Označite koordinatne osi!
(b) Odredite brzinu pri kojoj je greška nerelativističke formule  tisućinku promila.

3.3 Izrazi (expressions)

Sve su samo izrazi

Sve objekte s kojima smo se dosad sreli, poput funkcija, lista, polinoma, jednadžbi, dijagrama itd., Mathematica interno tretira kao objekte iste vrste, tzv. izraze (expressions).

FullForm[(x^2)+1==Sin[x]]
FullForm[b->g]
FullForm[Plot[x,{x,0,1},PlotPoints->5,DisplayFunction->Identity]]

Vidimo da su sva ova tri objekta izgrađena na isti način, od uglatih zagrada, zareza i objekata poput brojeva ili simbola koji se u Mathematici zovu atomi. Mogući tipovi atoma su brojevi (3, 4.1, 3+2i), simboli (x, β, Plot, wf3c) i stringovi ("dvije lipe", "če=").

Zadatak 3-10. Objasnite slijedeću poruku o grešci:

Union[{2,3},4]

Od atoma se izgrađuju objekti koji se zovu izrazi, a koji se formalno definiraju na rekurzivni način: Izrazi su ili atomi ili objekti oblika

(Subscript[i, 0])[(Subscript[i, 1]), (Subscript[i, 2]),…]

gdje su (Subscript[i, n])  izrazi. Dakle, izraz može biti npr.  fja[][w[2,b],p[wrus[r,t]]]

Da bi vidjeli interni Mathematica izraz koji odgovara nekom izrazu na ekranu, koristimo funkciju FullForm.Objekt (Subscript[i, 0]) u  gornjoj definiciji se zove glava izraza ("head"). Moguće ga je ekstrahirati funkcijom Head.

FullForm[b/;x>3]

Head[b/;x>3]

Head[(1/2)]

Mi razne tipove izraza interpretiramo na različit način, kako je prikazano u tabeli

({{Funkcija[argumenti], Log[x]}, {Komanda[argumenti], Expand[(((x+1))^2)] }, {Operacija[operandi], Plus[2,3]}})

no to različito interpretiranje je više posljedica navike. U gornjem primjeru  Log[x], Log možemo smatrati i komandom ili pak operacijom koja se vrši na jednom operandu i čiji je rezultat logaritam tog operanda.

Premda svi izrazi interno imaju oblik  glava[... argumenti ...], Mathematica često dopušta i druge načine zapisa izraza, u skladu sa standardnom matematičkom notacijom

({{f[x,y], standardni oblik}, {f @ x, prefiksni oblik}, {x//f, postfiksni oblik}, {x~f~y, infiksni oblik}})

Osnovni razlog ovakve raznolikosti je mogućnost pisanja čitljivijih programa.

Join[{a,b},{c,d,e}]

{a,b} ~Join~{c,d,e}

Pritom treba paziti na pravila o redoslijedu izvršavanja komandi.

Sin @ π+π

π+π//Sin

Ovaj primjer pokazuje da je @ po redosljedu izvršenja ispred, a // iza zbrajanja. Najbolje je, ukoliko nismo sasvim sigurni u prioritete izvršavanja, igrati na sigurno i koristiti zagrade.

Dijelovi izraza

Pojedine dijelove izraza je moguće ekstrahirati slično kao kod lista (izrazi interno i jesu objekti vrlo slični listama)

izr=(x^3)+(((1+x))^2)

Drop[izr,-1]

Take[izr,-1]

Append[izr,(w^6)]

izr2=x(1-x);
Append[izr2,(w^6)]

U prvom od zadnja dva primjera glava od izr je Plus, a u drugom glava od izr2 je Times, pa Append priključuje argument (w^6) shodno tome.

Pažnja: gore prikazane operacije ne mijenjaju originalne izraze!

izr2

Dakle, ako želimo transformacijama mijenjati izraze, to se treba raditi npr. ovako:

izr2=Append[izr2,(w^6)]

izr2

Nivoi izraza (*)

Vidimo da su izrazi "višedimenzionalni". Njihovu stabloliku strukturu je moguće i skicirati pomoću funkcije TreeForm

TreeForm[izr]

Razne operacije se mogu usredotočiti i samo na pojedine nivoe (levels) izraza.

({{n, nivoi od 1 do n}, {Infinity, svi nivoi (osim 0)}, {{n}, samo n-ti nivo}, {{n,m}, nivoi od n-tog do m-tog}})

Level[izr,{2}]

Level[izr,2]

Replace[izr, x->y,{2}]

Ovo ograničavanje na pojedine nivoe je korisno kod funkcionalnog programiranja gdje se time omogućuje fina kontrola područja djelovanja funkcija.

Sin[izr]

Map[Sin, izr,{1}]

Map[Sin,izr,{2}]

Map[Sin,izr,{3}]

Map[Sin,izr,3]

Zadatak 3-11: Objasnite riječima slijedeći izračun:

izr=(x^3)+(((1+x))^2)

Apply[Times,izr,2]

3.4 Uzorci (patterns)

Pojam uzorka (pattern) smo već upoznali u kontekstu definiranja funkcija. f[x_] je značilo da će funkcija f djelovati na bilo koji izraz. Mathematica radi sparivanje (uspoređivanje) s uzorkom (pattern matching) da bi odlučila da li da primijeni funkciju ili ne. x_ se tako sparuje s bilo kojim izrazom, ali složeniji uzorci mogu biti selektivniji.

f2[((x_)^(n_))]:=pwr[x,n]

f2[(a^2)]

f2[a]

Primijetite da se uspoređivanje s uzorkom obavlja u strukturalnom, a ne matematičkom smislu. Tako se u prethodnom primjeru ((x_)^(n_))  ne sparuje s a, premda je a matematički gledano isto oblika (x^n), uz n=1.

f3[x_,x_]:="isti"

f3[3,3]+f3[a,a]+f3[1,1.0]

Kod funkcija koje barataju elementima liste ili izraza,  željene elemente možemo specificirati i pomoću uzoraka.

lst={1,3,(5^w),a,1,(c^2),(d^w),4};

Cases[lst,x_^n_]

U ovim primjerima zapravo i nismo trebali davati imena uzorcima

DeleteCases[lst,_^_]

Jedna od mogućnosti ograničavanja domene funkcija je specificiranje uzoraka x_head koji se sparuju samo s izrazima odgovarajuće glave (head). (Primijetite da ova sintaksa znači da se podvlaka ne može koristiti kao dio imena što je česti običaj u nekim programskim jezicima.)

gg[x_Integer]:=1

gg[3.]

gg[3]

ili koji zadovoljavaju dodatne uvjete (to smo već vidjeli)

DeleteCases[lst,x_/;x<4]

3.5 Transformacijska pravila

Transformacijska pravila smo već sreli prilikom provjere rješenja jednadžbi, ali njihova je primjena univerzalna.

izr=a+b Log[(x^2)]+c x Sin[x];

izr /. {_^2->sq,x->y, c->x}

Primijetite da se pravila primjenjuju po redu kako su navedena i da u njima smijemo koristiti uzorke.

ff[a+ff[x]]+ff[a] /. ff[x_]->hh[x]

Uočavamo da je unutarnji ff[x] ostao netransformiran. To je stoga što simbol  "/." pravila primjenjuje samo jednom na svaki dio izraza. Postoji i simbol "//." koja pravila primjenjuje iterativno sve dok ima ikakvih promjena izraza.

ff[a+ff[x]]+ff[a] //. ff[x_]->hh[x]

Ako transformacijsko pravilo involvira izvrijednjavanje neke funkcije to se izvrijednjavanje odvija čim je pravilo zadano (dakle prije nego se ono primijeni na izraz s lijeve strane simbola /.)

x+ff[x]/.x->RandomInteger[100]

Postoji i alternativa, tzv. odgođeno transformacijsko pravilo  ":>" (Mathematica ga tipografski u bilježnici prikazuje kao ":>") koje se izvrijednjuje tek prilikom upotrebe pravila:

x+ff[x]/.x:>RandomInteger[100]

Vidimo da je razlika između "->" i ":>" za transformacijska pravila slična kao i razlika između "=" i ":=" za pridruživanja.

Naravno, i u transformacijskim pravilima na uzorke se mogu postavljati i dodatni uvjeti

Range[10]/.(x_/;PrimeQ[x])->0

Ukoliko na izraz primijenimo listu listi transformacijskih pravila, dobit ćemo listu transformiranih izraza. (To smo
već koristili kod provjere rezultata funkcije Solve.)

(x^2)/.{{x->1},{x->2}}

Može i

(x^2)/.x->{1,2}

Zadatak 3-12: Definirajte funkciju factors[n_, m_] koja crta tablicu oblika

         ({{15, 2}, {16, 1}, {17, "prim"}, {18, 2}})
         
gdje su lijevi stupac cijeli brojevi od n do m, a desni broj njihovih različitih faktora, odnosno string "prim" gdje treba.

Naputak:
1. Upoznajte se s funkcijom FactorInteger koja daje listu faktora s njihovim učestalostima.
2. Napravite transformacijsko pravilo koje radi pridruživanje  x → {x , <broj razl. faktora>}, tj. pretvara cijeli broj u jedan redak tražene tablice.
3. Trebate posebno pravilo za prim brojeve, koje ih pretvara u {x , "prim"}.
4. Primijenite pravila na listu brojeva Range[6,8] (za tablični ispis trebate funkciju TableForm).
5. Definirajte traženu funkciju factors.

Zadatak 3-13:   Modificirajte funkciju factors tako da u desnom stupcu ne bude broj njihovih različitih faktora, već ukupan broj faktora, dakle

                 ({{15, 2}, {16, 4}, {17, "prim"}, {18, 3}})

(*) Slijedi napredniji primjer uporabe transformacijskih pravila. Neka je zadana je lista planetarnih podataka

planeti={
{"Merkur",0.387,0.24085},
{"Venera",0.7233,0.61515},
{"Zemlja",1,1},
{"Mars",1.5237,1.8808},
{"Jupiter",5.2028,11.867},
{"Saturn",9.5388,29.461},
{"Uran",19.18,84.013},
{"Neptun",30.0611,164.793},
{"Pluton",39.44,247.7}
};

TableForm[planeti,TableHeadings->{Automatic,{"planet","R-udaljenost od Sunca [AJ]","T-period ophodnje [god]"}}]

Upotrebom transformacijskih pravila provjerit ćemo treći Keplerov zakon tj. da je (R^3)/(T^2)otprilike konstantno. Prvo kreiramo iz liste planeti dvije posebne liste s udaljenostima i periodima:

podaci={imena,udaljenosti,periodi}=Transpose[planeti]

Zatim transformiramo izraz ((R^3)/(T^2)) pomoću liste pravila te tako dobivamo listu omjera:

((R^3)/(T^2))/.{R->udaljenosti, T->periodi}

Odredit ćemo još i odgovarajuću masu Sunca putem formule

(Subscript[M, Sunca])=((4 (π^2)(R^3))/(G (T^2)))

Za konverziju jedinica (AJ) i vrijednost Newtonove konstante G koristimo pakete Units` i PhysicalConstants`.

If[$VersionNumber<6.0,
<<Miscellaneous`Units`;
<<Miscellaneous`PhysicalConstants`,
<<Units`;
<<PhysicalConstants`]

konstante={
 G->GravitationalConstant, 
god->Convert[Year,Second],
AJ->Convert[AstronomicalUnit,Meter]
}

mSun=((4 (π^2)(R^3))/(G (T^2)))/.{R->udaljenosti*AJ, T->periodi*god}/.konstante/.Newton -> Kilogram Meter/(Second^2)