Predavanje 9: Glave 27, 28

FlipView[{Text[Style[" Branko Urošević, imqfbrankourosevic@gmail.com ",20,"Text",Italic]],Text[Style[" Faculty of Economics, University of Belgrade, NBS and CESIfo Munich",20,"Text", Italic]]}]

27. Iteracije i rekurzije

Pojam iteracije

Pojam iteracije je izuzetno bitan u programiranju. Ideja je da neku funkcije od jedne ili više varijabli, uzastopno primenimo više puta (dobijemo složenu funkcije). Pretpostavimo da je data funkcija f, i da želimo da je više puta uzastopno primenimo na neki element x.

Pretpostavimo da se f primeni na x. Dobijamo f[x]. Na tako dobijeni izraz primenimo opet f. Tako dobijamo f[f[x]], itd. Dakle, funkcija f se gnezdi (Nest) počevši od elementa x. NestList pravi listu uzastopnih primena funkcije na neki početni izraz. Evo liste četiri iteracije funkcije f počevši od x:

NestList[f,x,4]

Primer: Framed

Na primer, ukoliko umesto proizvoljne funkcije f koristimo funkciju Framed dobili bismo:

NestList[Framed,x,4]

Ukoliko želite da vidite samo krajnji rezultat a ne i sve korake ove procedure, koristite funkcije Nest umesto NestList.

Nest[Framed,x,5]

Primer: EdgeDetect

Evo kako možemo da više puta primenimo EdgeDetect na neku sliku. Prvo imamo originalnu sliku, pa nađemo njene ivice, pa ivice ivica, itd.

NestList[(1/(1+#))&,a,5]

NestList[(1/(1+#))&,1,5]

NestList[EdgeDetect, , 8]

Pretpostavimo da želimo da vidimo samo poslednju iteraciju. U tom slučaju

Nest[EdgeDetect, , 6]

Komentar o čistim funkcijama

Kada imamo definisanu funkciju, recimo Sin, prilikom primene te funkcije možemo da koristimo sintaksu:

Sin@(π/3)

Umesto toga, možemo da funkciju pretvorimo u čistu funkciju:

Sin[#]&@(π/3)

Na sličan način, mi možemo da primenimo funkciju Sin na listu {π/4,π/3,π/2} bilo kao

Nest[EdgeDetect, , 6]

Nest[EdgeDetect[#]&, , 6]

Sin/@{π/4,π/3,π/2}

ili kao čistu funkciju (to je potpuno ekvivalentno):

Sin[#]&/@{π/4,π/3,π/2}

Stoga, recimo, nestovanje EdgeDetect na krug možemo predstaviti kao

Nest[EdgeDetect[#]&, , 6]

U principu, vrši se uvek iteracija čiste funkcije

Pretpostavimo da želimo da radimo 6 iteracije funkcije koje se dobija superpozicijom EdgeDetect i ColorNegate. Nešto ovako ne bi radilo (bez ekplicitnog uvođenja čiste funkcije):

NestList[ColorNegate[EdgeDetect], , 6]

NestList[ColorNegate[EdgeDetect[#]] &, , 6]

Umesto toga, moramo da koristimo čistu funkciju kako bismo radili kako EdgeDetect tako i ColorNegate u svakom koraku:

NestList[ColorNegate[EdgeDetect[#]] &, , 6]

(((#[[1]])^2)-2 ((#[[2]])^2)+3 #[[1]])&@{x,y}

(((#[[1]])^2)-2 ((#[[2]])^2)+3 #[[1]])&@10

(((#[[1]])^2)-2 ((#[[2]])^2)+3 #[[1]])&@{3,2}

{x[t],y[t]}=={2 x[t-1]+y[t-1],x[t-1]-3 y[t-1]}

ListPlot[NestList[{2#[[1]]+#[[2]],#[[1]]-3#[[2]]}&,{1,2},5]]

NestList[{2#[[1]]+#[[2]],#[[1]]-3#[[2]]}&,{1,2},5]

{2#[[1]]+#[[2]],#[[1]]-3#[[2]]}&@{3,2}

{2#[[1]]+#[[2]],#[[1]]-3#[[2]]}&

NestList[(((#[[1]])^2)-2 ((#[[2]])^2)+3 #[[1]])&,{3,2},1]

Rad sa čistom funkcijom u punoj formi

Razmotrimo ponovo

ColorNegate[EdgeDetect[#]] &

Ova funkcija može se prepisati u punoj formi kao

Function[{slika},ColorNegate[EdgeDetect[slika]] ]

tako da istu stvar kao ranije možemo da uradimo i ovako

NestList[Function[{slika},ColorNegate[EdgeDetect[slika]] ], , 6]

Mešanje boja

Sada počinjemo sa crvenom bojom, pomešamo je sa žutom, i tako dobijenu boju nastavimo da mešamo sa žutom. I tako 20 puta. Mešanje neke boje sa žutom definišemo preko čiste funcije

Blend[{#,Yellow}]&

Na primer, ukoliko pomešamo crvenu sa žutom dobijamo

Blend[{#,Yellow}]&[Red]

Pretpostavimo da želimo da sada tako dobijenu boju pomešamo sa žutom. Dobijamo:

NestList[Function[{boja},Blend[{boja,Yellow}]],Red,20]

Blend[{#,Yellow}]&[]

To automatizujemo ovako:

NestList[Blend[{#,Yellow}]&,Red,20]

ili, u punoj formi:

NestList[Function[{boja},Blend[{boja,Yellow}]],Red,20]

Malo aritmetike: iterativno dodavanje jedinice

Pretpostavimo da počinjemo od broja 1, i svaki put dodamo 1 na dobijenu sumu. Drugim rečima primenimo, recimo, 15 puta iterativno funkciju

NestList[(((#+1))^2)&,a,5]

NestList[(((#+1))^2)&,0,20]

Range[0,20]

NestList[(#+1)&,0,20]

(#+1)&

Prvi naredni broj je

(#+1)&[1]

treći član niza je

(#+1)&[2]

itd

NestList[(#+1)&,1,15]

To je, razume se, isto što i

Range[16]

Poduplavanje itd

Pretpostavimo da smo počeli od broja jedan. Ako pomnožimo početni broj 1 sa 2 i to uradimo više puta dobićemo stepene broja dva.

NestList[2*#&,1,15]

Vidimo da kada množimo sa brojem 2, vrednosti ekponencijalno rastu.

To možemo da napišemo na više načina. Na primer:

NestList[Times[2,#]&,1,15]

ili, u punoj formi čiste funkcije:

NestList[Function[{n},Times[2,n]],1,15]

Pogledajmo sada šta dobijamo ako množimo sa brojem većim od 1 ali manjim od 2, recimo 1.5

NestList[(3+0.9*#)&,1,100]

NestList[0.9*#&,1,15]

NestList[1.3*#&,1,15]

NestList[1.5*#&,1,15]

Vrednosti i dalje rastu ali sporije. Najzad, ako množimo sa vrednostima manjim od 1 dobijamo:

NestList[0.8*#&,1,15]

Iterativna jednačina za cenu nekog proizvoda

Pretpostavimo da je početna cena nekog proizvoda jednaka 2, a da se cena menja sa vremenom tako da je cena sutra jednaka 90 posto od cene dana plus 0.3. Nađi kako se cena menja u prvih 20 dana. Kako će se odgovor menjati ako umesto 0.3 imamo 0.2 ili 0.15?

p[0]==2

p[t]==0.9-0.2 p[t-1]

ListLinePlot[NestList[(-0.2 # +0.9)&,2,20],PlotRange-> All]

p[t]==0.3+0.9 p[t-1]

ListLinePlot[NestList[(0.9 # +0.3)&,2,50]]

NestList[(0.9 # +0.2)&,2,20]

NestList[(0.9 # +0.15)&,2,20]

Vidimo da se u prvom slučaju cena neprestano povećava, da je u drugom konstantna i jednaka 2, dok u trećem slučaj se smanjuje (zapravo, kao što može da se proveri, konvergira ka 1.5).

Buduća vrednost jednog novčanog  c

Pretpostavimo da smo stavili na štednju sumu c u trenutku 0. Svake godine dobijamo kamatu od r na svaki uloženi euro. Naći akumulirani iznost posle 1,2, .., 10 godina.

Primetimo da se iterativni izraz može predstaviti kao čista funkcija

Times[#,1+r]&

Na primer, ukoliko smo uložili 100 evra, dobili bismo posle prve godine

Times[#,1+r]&@c

Times[#,1+r]&@100

Pošto je uloženi iznos u trenutku 0 jednak c, buduće vrednosti su:

Nest[Times[#,1+r]&,c,10]

NestList[Times[#,1+r]&,c,10]

Ako nas zanima samo vrednosti u godini 10, to dobijamo korišćenjem Nest umesto NestList

Nest[Times[#,1+r]&,c,10]

Buduća vrednost annuiteta

Razmotrimo buduću vrednost anuiteta. Anuitet su jednaki novčani tokovi iznosa, recimo c, koje dobijamo svake godine. Prvi novčani tok dobijamo u godini 1, drugi u godini 2, itd. Ovi novčani tokovi ostaju na računu, i svake godine imaju kamatu r po uloženom euru. Naći ukupnu buduću vrednost svih novčanih tokova od godine 0 do godine 5.

Primetimo da u godini 0 ne dobijamo ništa, u godini 1 dobijamo c. U godini 2 dobijamo iznos c ali se i dobija kamata na iznos c dobijen u godini 1. Počevši od druge godine, ova čista funkcija jeste količina novca koju posedujemo (taraba se odnosi na prethodno akumuliranu sumu).

c+#*(1+r)&

Stoga su buduće vrednosti anuiteta u različitim godinama od 0 do 5 jednake:

NestList[c+#*(1+r)&,0,5]

Vrlo korisna funkcija za manipulaciju algebarskih izraza je Collect. Ona nam dozvoljama da skupimo članove istog oblika.

Collect[%,(1+r)]

Vidimo da je izraz upravo onakav kakav intuitivno i treba da bude.

Nagrada za pronalazača šaha: iterativno stepenovanje

U stara vremena, persijski šah pozvao je mudraca koji je izmislio tu igru i pitao ga je kako da ga nagradi. Mudrac je odgovorio: na prvo polje stavite, gospodaru, jedno zrno pšenice za mene, na drugo, 2, na treće (2^2) i td. Šah je malo razmislio i shvatio da ne postoji mogućnost da takvom zahtevu udovolji. Zašto?

Evo kako možemo da koristimo NestList da napravimo liste pet stepena broja 2, to jest 2^2^2...^2 n puta. Pretpostavimo da nam zanima koliko zrna bi bilo na petom polju. Napišimo to na više načina:

NestList[Power[2,#]&,1,10]

NestList[(2^(#))&,1,4]

NestList[Function[{n},Power[2,n]],1,4]

Probajte da vidite šta bi bilo ako je želimo da stavimo pšenicu samo na 8 polja. Neprebrojivo....

Šta ukoliko bi mudrac smanjio zahtev sa 2 na 1.5. U tom slučaju

NestList[Power[1.5,#]&,1,10]

Rast je mnogo sporiji ali i dalje, ukoliko bi smo povećali broj članova na 20, to ne bi radilo. Najzad, ukoliko još smanjimo na 1.2

NestList[Power[1.2,#]&,1,10]

Zlatni presek

Primenimo sada sledeću funkciju 10 puta, počevši od 1.

Sqrt[1+#]&@1

Kada je prva dva puta dobijamo

{Sqrt[1+#]&[1],Sqrt[1+#]&[Sqrt[1+#]&[1]]}

i td. Primenivši je 10 puta uzastopno dobijamo niz:

Nest[Sqrt[1+#]&,1,10]//N

GoldenRatio//N

NestList[Sqrt[1+#]&,1,10]//N

U decimalnom zapisu dobijamo da ovaj niz konvergira ka takozvanom zlatnom preseku (GoldenRatio):

NestList[Sqrt[1+#]&,1.,10]

GoldenRatio//N

Zlatni presek se dobija kao limes ove sekvence brojeva.

Slučajan izbor elemenata liste putem RandomChoice i slučajna šetnja

RandomChoice slučajno bira elemente neke liste. Možemo koristiti ovu funkciju da napravmo čistu funkciju koja dodaje slučajno +1 ili -1 više puta, počevši od nule. To se zove slučajna šetnja (random walk). Sa slučajnom šetnjom ćemo se sresti puno puta kasnije.

Table[RandomChoice[{+1,-1}],10]

Sledeća čista funkcija ide na plus ili minus jedan od početne vrednost date tarabom. Na primer, ako smo trenutno u tački 5, u sledećom koraku možemo biti ili u 4, ili u 6 (sa podjednakom verovatnoćom, pošto nismo drugačije zahtevali).

#+RandomChoice[{+1,-1}]&[5]

ListLinePlot[NestList[#+RandomChoice[{+1,-1}]&,0,1000]]

Ovde vidimo listu koju dobijemo preko ovog algoritma kada ga primenimo na 500 koraka.

ListLinePlot[NestList[#+RandomChoice[{+1,-1}]&,0,2000],PlotTheme->"Web"]

Grafik liči na kretanje cene akcije na finansijskom tržištu. To nije slučajno!

Isto to preko funkcije Accumulate

Isti zadatak možemo obaviti u putem funkcije Accumulate. Evo kako ona radi:

Accumulate[{a,b,c,d}]

Koristeći tu funkciju možemo jednostavno napisati:

Accumulate[RandomChoice[{+1,-1},20]]

ili, u slučaju velikog broja koraka

ListLinePlot[Accumulate[RandomChoice[{+1,-1},2000]],PlotTheme->"Web"]

Slučajna šetnja u 2D

Kako bismo kreirali slučajne šetnju u 2D? I tom slučaju počnemo od {0,0} i onda slučajno odaberemo da idemo gore, dole, levo ili desno: {1,0}, {-1,0}, {0,1}, ili {0,-1}. U pet koraka:

RandomChoice[{{1,0},{-1,0},{0,1},{0,-1}},5]

Sada koristimo Accumulate. U 2D, evo kako radi:

Accumulate[{{a,b},{c,d},{e,f}}]

Drugim rečima, Accumulate akumulira posebno prvu komponentu, a posebno drugu. U dvadeset koraka.

Accumulate[RandomChoice[{{1,0},{-1,0},{0,1},{0,-1}},20]]

ListLinePlot[Accumulate[RandomChoice[{{1,0},{-1,0},{0,1},{0,-1}},5000]]]

Promena oblika funkcije ili rekurzija

Do sada smo nest-ovali iterativno, to jest primenjivali smo jednu istu funkciju više puta. Ovde imamo aplikaciju funkcije f više puta: (ovo je ITERACIJA):

NestList[f,x,5]

NestList[f[#]&,x,5]

Ali, struktura same funkcije može da se menja u svakom koraku (ovo je REKURZIJA, što je generalizacija iteracije):

NestList[Framed[f[#,#]]&,x,3]

Ukoliko dodamo ramove biće lakše da sagledamo šta se događa:

NestList[Framed[f[#,#]]&,x,3]

Primer rekurzije

Razmotrimo funkciju koja uzima neki izraz, onda pravi listu koja se sastoji od dva kopije toga izraza, od te liste pravi kolonu, a oko kolone crta ram. To definišemo sledećom čistom funkcijom

NestList[Framed[MatrixForm[{{#,#},{#,#}}]]&,x,3]

NestList[Framed[Column[{#,#}]]&,x,4]

Framed[Column[{#,#}]]&

Primetimo da je

Framed[Column[{#,#}]]&@x

Ukoliko sada na to što smo dobili ponovo primenimo isto čistu funkciju

Framed[Column[{#,#}]]&[Framed[Column[{#,#}]]&[x]]

Pretpostavimo da to ponovimo 4 puta

NestList[Framed[Column[{#,#}]]&,x,4]

Ovako pravimo rekurzivni grid

Razmotrimo čistu funkciju:

Framed[Grid[{{#,#},{#,#}}]]&

Ukoliko njome delujemo na element x dobijamo

Framed[Grid[{{#,#},{#,#}}]]&[x]

Sada primenimo istu čistu funkciju još jednom:

Framed[Grid[{{#,#},{#,#}}]]&[Framed[Grid[{{#,#},{#,#}}]]&[x]]

Primenimo to više puta:

NestList[Framed[Grid[{{#,#},{#,#}}]]&,x,3]

Rekurzivne strukture sa dve funkcije

Evo rekurzivne strukture sa dve funkcije f i g:

NestList[{f[#],g[#]}&,x,3]

NestList[Framed[Column[{f[#],g[#]}]]&,x,3]

Q and A

U čemu je razlika između iteracije i rekurzije?
Ako neko nešto rade jedno isto više puta to je interacija. Ako neko uzme rezultat neke operacije i primeni istu operaciju više puta to je rekurzija. To je malo konfuzno pošto su prostiji primeri rekurzije zapravo iteracije. NestList uvek radi rekurzije, ali ako u funkciji postoji samo jedan slot onda je rekurzija isto što i iteracija. Ako to nije slučaj, onda imamo opštiji slučaj rekurzije. 

Kakva je veza između fraktala, nestinga i rekurzije?
Vrlo su blisko vezani. Fraktali su geometrijske forme koje imaju neku vrstu nested ili rekurzivne strukture. 

Da li je NestGraph nešto kao web crawler?
Konceptualno da. Čovek može da misli o tome da je u pitanju analog toga da počnemo od neke web strane i da onda posećujemo linkove te strane, pa onda tih stranka koje smo posetili, itd. 

Da li postoji način da ponavljamo neku funkciju dok stvari ne prestanu da se menjaju?
Da. Koristite FixedPoint ili FixedPointList.

28. Kondicionali

Uvod u kondicionalne iskaze (uslove)

Kondicionali su logički iskazi koji se mogu proveriti. Odgovor na njih je True ili False (tačno ili netačno). Evo nekih primera.

Da li je 2+2 jednako 4? Pitajmo Wolfram Language. Primetimo da se logički iskaz “jednako” piše sa duplim znakom jednakosti, a ne samo sa jednim. Npr., a=2 znači da se izrazu a prisvaja vrednost 2 u memoriji, dok a==2 znači da je izraz a jednak 2. To su dve potpuno različite stvari i morate da ih zapamtite!

Boole[2 2==5]

Boole[2+2==4]

2+2==4

Da li je 2+2 veće od 6? Pitajmo Wolfram Language.

2*2>5

Funkcija If

Funkcija If omogućava da se izabere jedan izraz ukoliko je rezultat testa True, a drugi ukoliko je False. U prvom primeru dole, pošto je rezultat testa True, funkcija If daje prvu vrednost, to jest x:

If[2+2==4,x,y]

Ovde je rezultat test False pa će output biti druga vrednost, to jest y.

If[2+2==5,x,y]

Ukoliko je element list manji od  4, If će dati x, inače dobijamo y:

If[#≤4,((#)^2),Sin[#]]&/@{1,2,3,4,5,6,7}

If[#≤4,((#)^2),y]&/@{1,2,3,4,5,6,7}

If[#<4,x,y]&/@{1,2,3,4,5,6,7}

Po definiciji, ukoliko je uslov zadovoljen, to jest broj u listi je manji od četiri, If dodeljjuje vrednost x. U suprotnom, If dodeljuje vrednost y.

Puni oblik kondicionala

If[#≥4,#+7,((#)^4)]&/@{1,2,3,4,5,6,7}

Function[{izraz},If[izraz>=4,izraz+7,(izraz^4)]]/@{1,2,3,4,5,6,7}

Function[{izraz},If[izraz>=4,izraz+7,(izraz^4)]]/@{1,2,3,4,5,6,7}

Function[{izraz},If[izraz<4,x,y]]/@{1,2,3,4,5,6,7}

Primetimo da ovde koristimo čistu funkciju

If[#<4,x,y]&

Ona se može drugačije predstaviti u punoj formi kao

Function[{izraz},If[izraz<4,x,y]]

pa bi onda važilo da

Function[{izraz},If[izraz<4,x,y]]/@{1,2,3,4,5,6,7}

Druge mogućnosti

Možete imati i test sa ≤, što se kuca kao <=. U tom slučaju, ukoliko je element manji ili jednak 4, If će dati x; u suprotnom, dobićemo y:

If[#≤4,x,y]&/@{1,2,3,4,5,6,7}

Ovde ćemo dobiti x samo ukoliko je element jednak 4, a u svim ostalim slučajevima ćemo dobiti y:

If[#==4,x,y]&/@{1,2,3,4,5,6,7}

Mi takođe možemo da testiramo koristeći ≠, što se kuca kao !=. U tom slučaju nećemo dobiti x samo u slučaju elementa 4 iz liste:

RandomInteger[{1,10},10]

If[#≤4,"Plavo je nebo","Žuto je sunce"]&/@{9,9,5,1,9,9,4,9,7,1}

If[#≤4,"Plavo je nebo","Žuto je sunce"]&/@{1,2,3,4,5,6,7}

# ≠

If[#≠4,x,y]&/@{1,2,3,4,5,6,7}

Naravno, umesto x i y možemo imati bilo koje druge izraze. Na primer

If[#≤4,"Plavo je nebo","Žuto je sunce"]&/@{1,2,3,4,5,6,7}

Funkcija Select za izbor članova liste po nekom kriterijumu

Veoma je korisno znati u praksi kako da izaberemo elemente koji zadovoljavaju neki uslov. To se, između ostalog, može uraditi putem Select. Izabrati elemente liste koji su veći od 3:

Select[{1,2,3,4,5,6,7},#>3&]

a=RandomInteger[{-10,10},100]

Select[a,Function[{x},Abs[x]<3]]

Select[a,Abs[#]<3&]

Vidimo da u slučaju Select koristimo čiste funkcije. Odaberimo elemente liste koji su između 2 i 5:

Select[{1,2,3,4,5,6,7},2≤ #≤ 5&]

Vidimo da su uslovi u Select zadati preko čiste funkcije i pišu se, po ovoj sintaksi, posle liste. Umesto u skraćenoj formi, naravno, možemo da koristimo i punu formu čiste funkcije. Na primer, puna forma čiste funkcije 2≤ #≤ 5& je

Function[{izraz},2≤ izraz≤ 5]

to jest

Select[{1,2,3,4,5,6,7},Function[{izraz},2≤ izraz≤ 5]]

Select[a,Abs[#[[1]]+#[[2]]]>3&]

Select[a,Abs[#[[1]]]<4&]

a=RandomInteger[{-10,10},{50,2}]

Testovi sa parnim, neparnim i prostim brojevima

Pored upoređivanja tipa <, > i ==, Wolfram Language omogućava puno drugih testova. Primeri su EvenQ i OddQ (kada god se funkcija završtava na Q to dolazi od reči Question, i u pitanju je test funkcija koja proverava da li je neko svojstvo zadovoljeno). Te konkretne funkcije daju True ukoliko je element paran odnosno neparan broj. Npr 4 je paran broj:

EvenQ[4]

Selektujte parne brojeve iz liste:

Select[Range[20],EvenQ[#]&]

U ovom slučaju nisu nam potrebne eksplicitno čiste funkcije pošto je EvenQ definisana:

Select[Range[20],EvenQ]

Ovde biramo proste brojeve:

Select[Range[100],PrimeQ]

To je ekvivalentno iskazima:

Select[Range[100],PrimeQ[#]&]

Select[Range[100],Function[{n},PrimeQ[n]]]

Logičko “i” (And) koje se skraćeno označava sa &&

Nekad moramo da kombinujemo više testova. Oznaka && znači logičko “i”, || znači logičko “ili” a ! znači logičko “ne”. Select elemente sa liste koji su parni i veći od 4:

Select[a,(Sqrt[(((#[[1]])^2)+((#[[2]])^2))])≥10&]

Select[a,And[EvenQ[#[[1]]],Abs[#[[2]]]>4]&]

Select[a,And[EvenQ[#[[1]]],Abs[#[[1]]]>4]&]

Select[{1,2,3,4,5,6,7},Or[EvenQ[#],#>4]&]

Select[{1,2,3,4,5,6,7},And[EvenQ[#],#>4]&]

Select[{1,2,3,4,5,6,7},EvenQ[#]&&#>4&]

U punoj formi čistu funkciju EvenQ[#] && #> 4 & možemo napisati ovako:

Function[{izraz},EvenQ[izraz]&&izraz>4]

Proverimo kako ova funkcija radi na nekim primerima

Function[{izraz},EvenQ[izraz]&&izraz>4][17]

Function[{izraz},EvenQ[izraz]&&izraz>4][16]

Još o logičkom “i”

Puno ime za logičko “i” je And

Function[{izraz},And[EvenQ[izraz],izraz>4]]@16

Generalno, logičko And daje iskaz True ako i samo ako je svaki logički iskaz unutar And tačan. Ukoliko je bar jedan izraz pogrešan, dobijemo False.

Function[{izraz},And[EvenQ[izraz],izraz>4]][17]

Najzad, proverimo da

Select[{1,2,3,4,5,6,7},Function[{izraz},And[EvenQ[izraz],izraz>4]]]

Logičko “ili”

Select elemente sa liste koji su ili parni ili veći od 4. Primetimo da je logički iskaz Or tačan ako i samo ako je bar jedan od logičkih iskaza unutar njega tačan (ne moraju da svi budu tačni).

Select[{1,2,3,4,5,6,7},Or[EvenQ[#],#>4]&]

Select[{1,2,3,4,5,6,7},EvenQ[#]||#>4&]

U punoj formi, čista funkcija može da bude napisana ovako:

Function[{izraz},Or[EvenQ[izraz],izraz>4]][16]

Function[{izraz},Or[EvenQ[izraz],izraz>4]][13]

Function[{izraz},Or[EvenQ[izraz],izraz>4]][3]

ListLinePlot[If[Mod[#,6]==0,Sin[((#)^2)],Cos[((#)^2)]]&/@Range[-50,50]]

If[Mod[#,14]==0,Style[((#)^2),Red,28],#]&/@Range[100]

Logičko “ne” (Not)

Select elemente sa liste koji nisu parni niti veći od 4 (znak uzvika u logičkom iskazu jeste znak negacije):

Select[{1,2,3,4,5,6,7},!(EvenQ[#]||#>4)&]

Čista funkcija ovde je

!(EvenQ[#]||#>4)&

Ona se može prepisati u punoj formi ovako:

Function[{izraz},Not[Or[EvenQ[izraz],izraz>4]]][6]

U ovom izrazu, 6 je paran broj pa EvenQ daje True. Stoga i Or daje True, Not onda daje False.

Function[{izraz},Not[Or[EvenQ[izraz],izraz>4]]][4]

U ovom slučaju, 3 je neparan pa EvenQ daje False. Takođe 3 je manji od 4 pa ceo Or daje False. Stoga Not daje True.

LetterQ

Ima puno drugih “Q funkcija” pomoću kojih možemo postavljati pitanja. LetterQ proverava da li se string sastoji samo od slova. Space (prazan prostor) između slova nije slovo. Takođe “!” nije slovo:

{LetterQ["a"],LetterQ["bc"],LetterQ["a b"],LetterQ["!"],LetterQ["a!"]}

Primetimo da ova funkcija proverava svaki karakter u stringu te da daje False ukoliko za svaki karakter nije zadovoljen uslov da je u pitanju slovo (to jest, to je kao da imamo && između svih karaktera).

LetterQ[#]&/@Characters["30 is the best!"]

LetterQ["a!b"]

Ako razbijemo string na karaktere, možemo videti na kom mestu nemamo slovo:

Characters["30 is the best!"]

LetterQ/@Characters["30 is the best!"]

Izaberite karaketere iz stringa koji su slova

LetterNumber[#]&/@{"i","s","t","h","e","b","e","s","t"}

Select[Characters["30 is the best!"],LetterQ[#]&&LetterNumber[#]>10&]

Select karaktere koji su slova:

Select[Characters["30 is the best!"],LetterQ]

Select slova koja se pojavljuje u engleskoj azbuci posle rednog broja 10:

Select[Characters["30 is the best!"],LetterQ[#]&&LetterNumber[#]>10&]

MemberQ

MemberQ proverava da li je nešto element ili member neke liste.

MemberQ[#,5]&/@{{1,3,5,7},{2,3},{3,5,1}}

5 je element ove liste {1, 3, 5, 7}:

MemberQ[{1,3,5,7},5]

Korisno je znati kako MemberQ radi sa složenim listama. Na primer:

MemberQ[{{1,3,5,7},{2,3}},5]

Or[True,False]

Da bi to radilo, moramo naterati MemberQ da proverava do drugog nivoa:

MemberQ[{{1,3,5,7},{2,3}},5,2]

Select brojeve od 1 do 100 koji na nekoj od pozicija ima bar jednu cifru 2:

Select[Range[100],MemberQ[IntegerDigits[#],2]&]

Select[Range[100],And[MemberQ[IntegerDigits[#],2],PrimeQ[#]]&]

Select[Range[1000],And[MemberQ[IntegerDigits[#],2],PrimeQ[#]]&]//Length

Select[Range[1000],And[MemberQ[IntegerDigits[#],7],PrimeQ[#]]&]//Length

Clear[a]

a=5;

Which[a==1,x,a==2,b,a>2,c]

Which[#==1,x,#==2,b]&/@{1,2,3}

Which[#==1,x,#==2,b,#>2,c]&/@{1,2,3}

Q and A

Zašto treba da stavimo dva znaka jednakosti == kada proveravamo uslov a ne =?
Zato što = znači nešto sasvim drugo u Wolfram Language. To je takozvani assignment operator ili operacija prisvajanja vrednosti o čemu ćemo detaljno učiti kada želimo da dodeljujemo vrednosti nekom simbolu. Da bi izbegli konfuziju, == čitamo kao “double equals”.

Zašto “i” pišemo sa &&, a ne &?
Zato što smo već videli da & znači kraj čiste funkcije u Wolfram Language.

Kada treba da koristim zagrade kod izraza sa &&, ||, itd.?
Imamo ustaljena pravila Bulove algebre oko redosleda operacija. Tu je && analog ×, operacija || je analog +, a ! je analog −. Stoga !p&&q znači 
“(ne p) i q”; a operacija !(p&&q) znači “ne (p and q)”.

Šta je to posebno u vezi sa “Q” functijama?
One daju odgovor na pitanje to jest ili True ili False.

Koje su neke druge “Q” funkcije?
Ima ih ogroman broj. Recimo NumberQ, StringContainsQ, BusinessDayQ and ConnectedGraphQ su samo neke.