[viesti Survo-keskustelupalstalla (2001-2013)]
| Kirjoittaja: | Petri Palmu |
|---|---|
| Sähköposti: | - |
| Päiväys: | 11.12.2007 0:13 |
Moi,
Olen toisinaan törmännyt tilanteisiin, jossa
esim. aineiston käsittely, kuva tai statistiikka on vaatinut
jos jonkinmoista luuppaamista. Olen näissä
tilanteissa päätynyt joko sukroon, FILE LOAD + FORMAT tietynlaiseen
käyttöön tai sitten esim. R tai Python ohjelman tarjoamiin
mahdollisuuksiin. Osan luuppauksista voi myös kiertää kikkailemalla
esim. VAR-operaatiossa.
Halusin kokeilla, josko onnistuisi tekemään jonkilaisen yleiskäyttöisen
luupitussukron. Ja mielellään sillä olisi (visuaalista) vastaavuutta
ohjelmointikielien for/while-rakenteille. Ohessa oleva REP-sukro on
tulos siitä, mitä olen alustavasti ehtinyt pakertaa homman kanssa.
Kaikki Survon ominaisuudet ovat mukana, tavallaan tämän voi
ajatella yleistettynä ACTIVATE-sukrona, joka vain toistaa aktivoitavia
komentorivejä n-kertaa. Erikoistapauksessa n=1 sukro on
olennaisesti ACTIVATE (jos ei tuota vuorovaikutteisuutta lasketa).
Luuppi-indeksimuuttujilla (tavallisesti i,j,k) on usein oma
tärkeä käyttö, mm. rajata aineistoja IND=X,i ja kirjoittaa tiedostonimiä
tyyliin file_i.txt (i=1,2,...n). Tämä ominaisuus täytyy siis myös
olla mukana (ks. sukrossa TXTCONV). Lisäksi esim. iterointityyppiset
tilanteet saattavat vaatia jonkinlaisen break option (hyppää pois
silmukasta) tai ehkä muuttaa luuppi-indeksimuuttujan arvoa pienemmäksi
tai suuremmaksi. Sinänsä toimituskentässä voi hypellä tuttuun
Survo-sirkka tyyliin... Koska luuppeja joutuu monesti sisäkkäistämään,
/REPiä on mahdollista käyttää 7 kertaa sisäkkäin. Se riittänee
useimpiin sovelluksiin ;)
/REP sukrossa annetaan parametrit:
komentoriviargumentit:
<luupissa aktivoitava merkki kontrollisarakessa>,
<aloitusrivi>, (tämä on oikeastaan tarpeeton)
<merkki kontrollisarakessa, johon aktivointi päättyy>
täsmennykset:
NREP = <toistojen lkm>
FORI = luuppi-indeksointimuuttujan nimi luuppikaaviossa ($i, $j,...)
(huom. nimi oltava sellainen, ettei se esiinny toimituskentässä
edes osana muita merkkijonoja)
LEVEL = <1,2,..> (oletus = 1)
Sitten varsinaisen suoritusosan sisällä voi käyttää
(luupin mahdollinen lopetus)
BREAK = {tyhjä,1}
(luuppi-indeksimuuttujan arvon muuttaminen)
MOVEI = {kokonaisluku tai tyhjä}
Sukroa pitää vielä kehittää. Varmaan kehitystarpeet huomaa parhaiten,
kun sitä koklaa käytännössä erilaisissa tilanteissa.
Mikäli tulee mieleen ajatuksia homman kehittämiseen tai muuten vaan
kommentteja, niin :)
t. Petri
Pari simppeliä esimerkkiä (nämä pitää olla eri toimituskentässä
kontrollimerkkien samuuden vuoksi).
*.......................
* ESIM 1:
* 3-tasoisen ryhmittelyn indeksointi
*
* eka taso (uloin):
*/REP A,CUR+1,B / NREP=1 FORI=$i LEVEL=1 { sulku kuriositeettina :)
*
*.............................
* toka taso:
A /REP C,CUR+1,D / NREP=2 FORI=$j LEVEL=2 {
*
*.................
* kolmas taso (sisin):
C /REP E,CUR+1,F / NREP=6 FORI=$k LEVEL=3 {
*
*................
ESAVEP CUR+1,CUr+1,_tmp1
* X$i.$j.$k
ELOADP _tmp1,END+1
*...............
*
* Jos ao. BREAKilla olisi joku arvo, niin luuppi hyppäisi
* ulos kolmannelta tasolta.
*
*MOVEI=1 / 3-tason luuppissa joka toinen k:n arvo
*BREAK=
E
*....................
F --- k --- }
D --- j --- }
B --- i --- }
*.................
*
*
*........................
*
*Tulos:
* X1.1.1
* X1.1.3
* X1.1.5
* X1.2.1
* X1.2.3
* X1.2.5
*
*
*
*
*.......................
* ESIM2: Gibbs-sampler, kaksiulotteinen normaalijakauma N(0,S)
* (kopsattu Gelman: Bayesian Data Analysis)
*
* Full conditionals (theta1 and theta2)
* [Theta1 | Theta2 = theta2] ~ N( , )
* [Theta2 | Theta1 = theta1] ~ N( , )
* N( , ) sisällä ao. ehdollisen jakauman parametrit
*
*
* Kokeillaan 3 eri theta1 ja theta2 korrelaatioiden r
* välistä vaikutusta yhteisjakauman simulointiin Gibbs-samplerilla
* Kaksitasoinen luuppi, jossa sisempi muodostuu
* varsinaisesta Gibbs-samplerista ja ulompi
* korrelaatioparametritasosta.
*
* Vain tämä komento aktivoidaan
* (mutta talleta eka toimkentän matriisit alla)
*/REP A,CUR+1,B / NREP=3 FORI=$i LEVEL=1
*
*.....................
* Vain 10 havainnon otos (sisempi luuppi)
A/REP C,CUR+1,D / NREP=10 FORI=$j LEVEL=2
*
*MATRIX M / Means
*/// M
*T1 0
*T2 0
*
*MATRIX SD / Standard deviations
*/// SD
*T1 1
*T2 1
*
*MATRIX R / Correlations of Theta1 and Theta2
*/// R
*1 -.5
*2 0
*3 .99
*
*Siis yo. tiedot tunnetaan
*
* Talleta tämä kaikki ensin (F2+Esc) ennen /REP komentoa
*MAT SAVE M TO M
*MAT SAVE SD TO SD
*MAT SAVE R TO R
*MAT S(1,1)=SD(1,1)^2
*MAT S(2,2)=SD(2,1)^2
*MAT S(1,2)=R(1,1)*SD(1,1)*SD(2,1)
*MAT S(2,1)=S(1,2)
*MAT OUT=ZER(Ki,2) / Ki=NREP+1
*MAT CLABELS X TO OUT
*MAT APU2=ZER(2,1)
*MAT APU=ZER(1,1) / initialize theta2
*MAT #TRANSFORM APU BY N.G(0,10^2,rnd(0)) / ~ from normal
*MAT OUT(1,2)=APU / voisi koklata suoraan jotain arvoa esim -8
*
*..............................
*
* j=$j
*
* Draw theta1 given current value of theta2
CMAT APU2(1,1)=M(1,1)+R($i,1)*SD(1,1)*INV(SD(2,1))*OUT(j,2)
CMAT APU2(2,1)=(1-R($i,1)^2)*SD(1,1)^2
CMAT #TRANSFORM APU BY probit(rnd(0)) / ~ N(0,1)
CMAT APU=APU2(1,1)+APU2(2,1)*APU
CMAT OUT(j,1)=APU / update theta1
* Draw theta2 given current value of theta1
CMAT APU2(1,1)=M(2,1)+R($i,1)*SD(2,1)*INV(SD(1,1))*OUT(j,1)
CMAT APU2(2,1)=(1-R($i,1)^2)*SD(2,1)^2
CMAT #TRANSFORM APU BY probit(rnd(0)) /
CMAT APU=APU2(1,1)+APU2(2,1)*APU
CMAT OUT(j+1,2)=APU / update theta2
*
D --- end j level ---
*
*.......................
* Tiedostojen talletus eri korrelaatiotasoilla
*
AMAT CLABELS X TO OUT
AFILE DEL OUT$i
AFILE SAVE MAT OUT TO OUT$i
AVAR SIMORD:2=ORDER TO OUT$i
*...................
ASAVEP CUr+1,CUR+1,_plot
*GPLOT OUT$i,X1,X2 / TREND=0 IND=ORDER,1,10 POINT=[Times(12)],SIMORD
ALOADP _plot,END+1
*.........................
B --- end i level ---
*.................................
*
*FILE SHOW OUT1
*FILE SHOW OUT3
*.......................
* Tulos:
* Tsekataan eri korrelaatiotason vaikutuksia simulointiin
*PEN=[Times(10)][BLACK][line_type(0)][line_width(1)][rot(0)][move(0,0)]
* XSCALE=-10,10 YSCALE=-10,10
*MODE=PS LINE=1
*GPLOT OUT1,X1,X2 / TREND=0 IND=ORDER,1,10 POINT=[Times(12)],SIMORD
*GPLOT OUT2,X1,X2 / TREND=0 IND=ORDER,1,10 POINT=[Times(12)],SIMORD
*GPLOT OUT3,X1,X2 / TREND=0 IND=ORDER,1,10 POINT=[Times(12)],SIMORD
*
*
.......................
Ja sitten itse sukro...
*TUTSAVE REP / REPeat
/ 2007-12-09 / PP
/
/ Vastaa for($i in 1:n) {...} luuppirakennetta
/
/ /REP sukrossa annetaan parametrit:
/ argumentit:
/ <luupissa aktivoitava merkki kontrollisarakessa>,
/ <aloitusrivi>, (tämä on oikeastaan tarpeeton)
/ <merkki kontrollisarakessa, johon aktivointi päättyy>
/ täsmennykset:
/ NREP = <toistojen lkm>
/ FORI = luuppi-indeksointimuuttujan nimi luuppikaaviossa ($i, $j,...)
/ (huom. nimi oltava sellainen, ettei se esiinny toimituskentässä
/ edes osana muita merkkijonoja)
/ LEVEL = <1,2,..> (oletus = 1)
/
/ Sitten varsinaisen suoritusosan sisällä voi käyttää
/ (luupin mahdollinen lopetus)
/ BREAK = {tyhjä,1}
/ (luuppi-indeksimuuttujan arvon muuttaminen)
/ MOVEI = {kokonaisluku tai tyhjä}
/
/ *********************************************************
/
/ def Wact=W1 Wcur1=W2 Wend=W3
/ def Wact=W10 Wnrep=W11 Wr1=W12 Wc1=W13 Wfori=W14 Wlevel=W15
/ def Wi=W20 Wc=W21 Wbreak=W22 Wmovei=W23
/ def Wrcmd=W30 Wccmd=W31 Wrtxtc=W32 Wctxtc=W33
/
/ *********************************************************
*{init}{tempo -1}
/ Täsmennykset
*{save spec NREP Wnrep}
*{save spec LEVEL Wlevel}
*{save spec FORI Wfori}
/
+ Checks1:
- if Wlevel '=' {} then goto Level else goto LevelOk
+ Level: {Wlevel=1}
+ LevelOk:
/ mahdollisia täsmennyksiä joilla luuppaamista voidaan ohjata
/ esim hypätään silmukasta ulos kesken (esim. konvergenssikrit täyt)
*{Wmovei=0}
*{Wbreak=}
/{R}{print Wlevel}{goto End}
/ Talletetaan sukrokomennon paikka toimkentässä
*{save cursor Wrcmd,Wccmd}
/
+ Edit1:
*{jump cur+1,cur+1,1}{u5}{d5}
*{save cursor Wr1,Wc1}{u}{ins line}
*{ins line}{ins line}{ins line}{ins line}{u4}
/ Mahdollista luuppausindeksimuuttujaa varten
+ ReplFormat:
*SAVEP CUR+5,{print Wend},_tmploop{print Wact}{act}
*{line start}{erase}
*LOADP _tmploop{print Wact}2,CUR+5{R}
/
*TXTCONV _tmploop{print Wact},_tmploop{print Wact}2{R}
*CONVERSIONS:{R}
*T "{print Wfori}" "{save cursor Wrtxtc,Wctxtc}{R}
*END
/
/ Then Activate all the commands with specified control char ACT
/ and repeat it nrep times
/
*{jump Wr1,Wr1,1}{u5}{d5}
*{Wi=0}
/ Luuppi alkaa
+ Loop: {Wi=Wi+1}{Wi=Wi+Wmovei}
- if Wi > Wnrep then goto E
/ Korvataan luuppi-indeksimuuttuja asianmukaisella arvolla 1,2,..
+ Txtconv: {jump Wrtxtc,Wrtxtc,Wctxtc}
*{erase}{print Wi}"{u2}{line start}{act}
*{u}{act}{d5}
/ Etsitään kontrollisarakkeesta merkkiä
+ Activate: {}
*{pre}Lc
*{line start}{l4}{save char Wc}{r}
*{save spec BREAK Wbreak}
- if Wbreak '<>' {} then goto E
+ CtrlCheck:
- if Wc '=' Wend then goto Loop
- if Wc '=' Wact then goto Act else goto NewRow
+ Act:
/ Siirretäänkö luuppi-indeksiä johonkin?
*{save spec MOVEI Wmovei}
- if Wmovei '=' {} then goto Move0 else goto Switch
+ Move0: {Wmovei=0}
+ Switch:
/ Talleta sukromuisti tiedostoksi luupin tason mukaan
- switch Wlevel
- case 1: goto R1
- case 2: goto R2
- case 3: goto R3
- case 4: goto R4
- case 5: goto R5
- case 6: goto R6
- case 7: goto R7
- case 8: goto R8
- default: goto E
/
+ R1: {save stack SUR_REP1}{act}{load stack SUR_REP1}{R}{goto Activate}
+ R2: {save stack SUR_REP2}{act}{load stack SUR_REP2}{R}{goto Activate}
+ R3: {save stack SUR_REP3}{act}{load stack SUR_REP3}{R}{goto Activate}
+ R4: {save stack SUR_REP4}{act}{load stack SUR_REP4}{R}{goto Activate}
+ R5: {save stack SUR_REP5}{act}{load stack SUR_REP5}{R}{goto Activate}
+ R6: {save stack SUR_REP6}{act}{load stack SUR_REP6}{R}{goto Activate}
+ R7: {save stack SUR_REP7}{act}{load stack SUR_REP7}{R}{goto Activate}
+ R8: {save stack SUR_REP8}{act}{load stack SUR_REP8}{R}{goto Activate}
/ Ja jollei aktivoida niin uusi rivi ja paluu Activateen
+ NewRow: {R}{goto Activate}
/ Viimeistelyt
+ E: {jump Wrcmd,Wrcmd,Wccmd}{d2}
*{del line}{del line}{del line}{del line}
*{u}{line start}{erase}
*LOADP _tmploop{print Wact},CUR+1{act}{del line}
*{jump Wrcmd,Wrcmd,Wccmd}{u2}{d2}
+ End: {end}
*
*.........................
| Vastaukset: |
|---|
Survo-keskustelupalstan (2001-2013) viestit arkistoitiin aika ajoin sukrolla, joka automaattisesti rakensi viesteistä (yli 1600 kpl) HTML-muotoisen sivukokonaisuuden. Vuoden 2013 alusta Survo-keskustelua on jatkettu entistäkin aktiivisemmin osoitteessa forum.survo.fi. Tervetuloa mukaan!