pr st2openbugsana, rclass vers 13 syntax varlist /// [ , /// Thin(integer 1) /// Grbplot /// Nbins(integer 10) /// Savegraphs /// Wdpath(string) /// Prefix(string) /// ] tempvar thinind if `thin' == 1 gen `thinind' = 1 else gen `thinind' = mod(iteration, `thin') // deviance node not implicitly included tokenize `varlist' loc nvar: word count `varlist' qui su iteration loc iter1 = r(min) loc niter = r(max) - `iter1' + 1 qui su chain loc nchains = r(max) if "`grbplot'" != "" & `nchains' == 1 di as err "Warning: the {it:grbplot} option doesn't make sense with only one chain" if "`grbplot'" != "" & `nchains' > 1 & mod(`niter', `nbins') != 0 { di as err "Warning: the {it:nupdate} argument of {bf:stopenbugs} must be a multiple of {it:nbins}; {it:nbins} is reset to its default" loc nbins = 10 } if "`wdpath'" == "" loc wdpath = "~" if "`prefix'" == "" di as err "Warning: you are using a log file whose name has no prefix; if the {it:CODA.dta} file does have one, this is probably an error" loc logfile = "`prefix'log.log" matrix pctiles = J(`nvar', 3, .) forv i = 1/`nvar' { _pctile ``i'', p(2.5 50 97.5) matrix pctiles[`i', 1] = (r(r1), r(r2), r(r3)) } mata: st2openbugsanamata("`varlist'", `nvar', `niter', `iter1', `nchains', "`grbplot'", "`nbins'", "`wdpath'", "`logfile'") // trace and density plots if "`grbplot'" != "" & `nchains' > 1 { preserve matname GRBmatplot "node" "nstart" "CSRF", c(.) e svmat GRBmatplot, names(col) ret mat GRBmatplot GRBmatplot } forv i = 1/`nvar' { loc lineplot line ``i'' iteration if chain==1 & `thinind'==1 forv chain = 2/`nchains' { loc lineplot `lineplot' || line ``i'' iteration if chain==`chain' & `thinind'==1 } loc lower = pctiles[`i', 1] loc median = pctiles[`i', 2] loc upper = pctiles[`i', 3] loc lineplot `lineplot', nodraw yti(``i'') ylab(, nogrid) yli(`lower' `median' `upper', lsty(grid)) xtitle("iteration (thinning: `thin')") leg(off) name(line``i'', replace) `lineplot' tw kdensity ``i'', xti(``i'') yti("density") nodraw name(dens``i'', replace) if "`savegraphs'" != "" { gr combine line``i'' dens``i'', cols(1) saving("`wdpath'/`prefix'``i''_trace.gph", replace) name(trace_``i'', replace) if "`grbplot'" != "" & `nchains' > 1 line CSRF nstart if node==`i', lp(solid dash) ti("``i''") xti("Starting iteration") yti("CSRF") /// leg(off) saving("`wdpath'/`prefix'``i''_GRB.gph", replace) name(GRB_``i'', replace) } else { gr combine line``i'' dens``i'', cols(1) name(trace_``i'', replace) if "`grbplot'" != "" & `nchains' > 1 line CSRF nstart if node==`i', lp(solid dash) ti("``i''") xti("Starting iteration") yti("CSRF") /// leg(off) name(GRB_``i'', replace) } } if "`grbplot'" != "" & `nchains' > 1 restore // saved results if `isDIC' { matname DIC "Dbar" "DIC" "pD", c(.) e ret mat DIC DIC } if `nchains' == 1 matname summarymat "mean" "sd" "MC_error" "2dot5%" "median" "97dot5%", c(.) e else matname summarymat "mean" "sd" "MC_error" "2dot5%" "median" "97dot5%" "CSRF", c(.) e ret mat summarymat summarymat ret sca niteration = `niter' ret sca nburnin = `iter1' - 1 ret sca nchain = `nchains' ret loc varlist `varlist' end version 13 mata: function st2openbugsanamata(varlist, nvar, niter, iter1, m, grbplot, nbin, wdpath, logfile) { // GRB saves the value of the Gelman-Rubin diagnostic computed with all the iterations if (m > 1) GRB = GelmanRubinBrooks(varlist, nvar, niter/2, niter, niter, m) pctiles = st_matrix("pctiles") summary(varlist, nvar, niter, iter1, m, pctiles, GRB, wdpath, logfile) if (grbplot != "" & m > 1) GelmanRubinBrooksplot(varlist, nvar, niter, iter1, m, strtoreal(nbin)) } function GelmanRubinBrooks(varlist, nvar, nstart, nend, niter, m) { grb = J(nvar, 1, .) indices = vec(niter :* (0..(m-1)) :+ J(1, m, nstart::nend)) n = nend - nstart + 1 X = st_data(indices, varlist) grand_mean = mean(X) chain_mean = J(m, nvar, .) matrix_chain_mean = J(m * n, nvar, .) W_chain = J(m, nvar, .) for (j = 1; j <= nvar; j++) { for (i = 1; i <= m; i++) { temp1 = X[((n * (i-1) + 1)::(n * i)), j] chain_mean[i, j] = mean(temp1) temp2 = J(n, 1, chain_mean[i, j]) matrix_chain_mean[((n*(i-1)+1)::(n*i)), j] = temp2 W_chain[i, j] = sum((temp1 :- temp2):^2) / (n-1) } } B = colsum((chain_mean :- grand_mean):^2) :* n :/ (m-1) var_B = 2 :* B:^2 :/ (m - 1) df_B = m - 1 W = mean(W_chain) var_W = colsum((W_chain :- W):^2) :/ (m-1) df_W = 2 :* W:^2 :/ var_W cov_BW = (n / m / (m -1)) :* (colsum((W_chain :- W) :* (chain_mean:^2 :- mean(chain_mean:^2))) :- 2 :* grand_mean :* colsum((W_chain :- W) :* (chain_mean :- grand_mean))) V = ((n-1) / n) :* W :+ ((m + 1) / m / n) :* B var_V = (((m + 1) / m)^2 :* var_B :+ (n - 1)^2 :* var_W :+ (2*(m + 1) / m * (n - 1)) :* cov_BW):/ n^2 df_V = 2 :* V:^2 :/ var_V R = V :/ W df_adj = (df_V :+ 3) :/ (df_V :+ 1) return(vec(sqrt(df_adj :* R))) } function summary(varlist, nvar, niter, iter1, m, pctiles, grb, wdpath, logfile) { // computations vecvarlist = tokens(varlist) if (m > 1) summarymat = J(nvar, 7, .) else summarymat = J(nvar, 6, .) sample = niter * m X = st_data(1::sample, varlist) means = mean(X) summarymat[. , 1] = means' summarymat[. , 2] = sqrt(diagonal(variance(X))) a = trunc(sqrt(niter)) means_batch = J(a * m, nvar, .) for (i = 1; i <= m; i++) { for (j = 1; j <= a; j++) { means_batch[j + a * (i - 1), .] = mean(X[((1::a) :+ a :* (j - 1)) :+ (niter * (i - 1)), 1..nvar]) } } summarymat[. , 3] = (sqrt((a / (a * m - 1) / sample) :* colsum((means_batch :- J(a * m, 1, means)):^2)))' summarymat[. , 4..6] = pctiles if (m > 1) summarymat[. , 7] = grb DIC = readDICpD(wdpath, logfile) nrowDIC = rows(DIC) if (nrowDIC == 0) st_local("isDIC", "0") else st_local("isDIC", "1") // printing printf("\n") printf("{txt}{space 1}Number of chains:\t\t\t\t\t{res}%g\n", m) printf("{txt}{space 1}Number of 'burn-in' iterations:\t\t\t{res}%g\n", iter1 - 1) printf("{txt}{space 1}Number of iterations by chain (after burn-in):\t\t{res}%g\n", niter) printf("\n") if(m == 1) { printf("{space 1}{hline 72}\n") printf("{space 7}node{space 6}mean{space 8}sd{space 2}MC error{space 6}2.5%%{space 4}median{space 5}97.5%%\n") printf("{space 1}{hline 72}\n") for (i = 1; i <= nvar; i++) { printf("{res}%11s%10.5g%10.5g%10.5g%10.5g%10.5g%10.5g\n", vecvarlist[i], summarymat[i, 1], summarymat[i, 2], summarymat[i, 3], summarymat[i, 4], summarymat[i, 5], summarymat[i, 6]) } printf("{space 1}{hline 72}\n") } else { printf("{space 1}{hline 82}\n") printf("{space 7}node{space 6}mean{space 8}sd{space 2}MC error{space 6}2.5%%{space 4}median{space 5}97.5%%{space 6}CSRF\n") printf("{space 1}{hline 82}\n") for (i = 1; i <= nvar; i++) { printf("{res}%11s%10.5g%10.5g%10.5g%10.5g%10.5g%10.5g%10.5g\n", vecvarlist[i], summarymat[i, 1], summarymat[i, 2], summarymat[i, 3], summarymat[i, 4], summarymat[i, 5], summarymat[i, 6], summarymat[i, 7]) } printf("{space 1}{hline 82}\n") } printf("\n") printf("{txt}{space 1}Deviance-related measures:\n") if (nrowDIC == 0) printf("{txt}{space 1}Not available\n") else { printf("{space 1}{hline 42}\n") printf("{res}{space 7}node{space 6}Dbar{space 6}DIC{space 8}pD{space 2}\n") printf("{space 1}{hline 42}\n") for (i = 1; i <= nrowDIC; i++) { if(i == nrowDIC) printf("{space 1}{dup 42:-}\n") printf("{res}%11s%10.5g%10.5g%10.5g\n", DIC[i, 1], strtoreal(DIC[i, 2]), strtoreal(DIC[i, 3]), strtoreal(DIC[i, 4])) } printf("{space 1}{hline 42}\n") } printf("\n") // returned to Stata st_matrix("summarymat", summarymat) rowssummarymat = J(rows(summarymat), 2, "") rowssummarymat[, 2] = vecvarlist' st_matrixrowstripe("summarymat", rowssummarymat) if (nrowDIC > 0) { st_matrix("DIC", strtoreal(DIC[., 2..4])) rowsDIC = J(rows(DIC), 2, "") rowsDIC[, 2] = DIC[., 1] st_matrixrowstripe("DIC", rowsDIC) } } function readDICpD(wdpath, logfile) { file = invtokens((wdpath, "/", logfile), "") fh = fopen(file, "r") do { line = fget(fh) } while (line != "Deviance information" & line != "can not calculate DIC for this model" ) if (line == "Deviance information") { // skip line with names skip = fget(fh) position = ftell(fh) // count number of lines with deviance information counter = 0 line = fget(fh) while (line != "CODA files written") { counter++ line = fget(fh) } fseek(fh, position, -1) result = J(counter, 4, "") for (i = 1; i <= counter; i++) { result[i, .] = (tokens(fget(fh), char(9)))[1, (1, 3, 7, 9)] } } else { result = J(0, 0, "") } fclose(fh) return(result) } function GelmanRubinBrooksplot(varlist, nvar, niter, iter1, m, nbin) { nend = (1..nbin) :* (niter/nbin) nstart = trunc(nend :/ 2) GRBmatplot = J(nvar * nbin, 3, .) GRBmatplot[., 1] = vec(J(1, nbin, 1::nvar)) GRBmatplot[., 2] = vec(J(nvar, 1, nstart :+ iter1 :- 1)) for(i = 1; i <= nbin; i++) { GRBmatplot[(1::nvar) :+ (nvar * (i-1)), 3] = GelmanRubinBrooks(varlist, nvar, nstart[i], nend[i], niter, m) } st_matrix("GRBmatplot", GRBmatplot) } end