📄 matbugs.m
字号:
function [samples, stats, structArray] = matbugs(dataStruct, bugsModel, varargin)% MATBUGS a Matlab interface for WinBugs, similar to R2WinBUGS% [samples, stats] = matbugs(dataStruct, bugsModelFileName, ...)%% This generates a file called 'script.txt' in the directory where% winbugs14.exe is kept (so you must have write access to this directory!),% then calls winbugs with this script, then reads the resulting samples from% files into matlab structs.%% INPUT:% dataStruct contains values of observed variables.% bugsModel is the name of the model file; MUST END IN .txt% % Note: variables with names 'a.b' in the bugs model file% should be called 'a_b' in the matlab data structure.%% Optional arguments passed as 'string', value pairs [default in brackets, case% insensitive]:%% 'init' - init(i).v is a struct containing initial values for variable 'v'% for chain i. Uninitialized variables are given random initial% values by WinBUGS. It is highly recommended that you specify the% initial values of all root (founder) nodes.% 'monitorParams' - cell array of field names (use 'a_b' instead of 'a.b')% [defaults to *, which currently does nothing...]% 'nChains' - number of chains [3]% 'nBurnin' - num samples for burn-in per chain [1000]% 'nSamples' - num samples to keep after burn-in [5000]% 'thin' - keep every n'th step [1]% 'blocking' - do block updating for GLMs (using IRLS proposal)?% [1 - doesn't yet work]% 'view' - set to 1 if you want to view WinBUGS output (then close the WinBUGS% window to return control to matlab)% set to 0 to close WinBUGS automatically without pausing [default 0]% 'openBugs' - set to 1 to use openBugs file format [0]% 'Bugdir' - location of winbugs executable% Default is 'C:/Program Files/WinBUGS14' if not openBugs% Default is 'C:/Program Files/OpenBUGS' if OpenBugs.% 'workingDir' - directory to store temporary data/init/coda files [pwd/tmp]%% 'DICstatus' - takes value 1 to set the DIC tool and 0 otherwise% 'refreshrate' - sets the refresh rate for the updater. Default is 100. Values% of 10 prevent the computer from hanging too much if the model% is very slow to run.%% Note that total number of iterations = nBurnin + nSamples * thin.%% OUTPUT% S contains the samples; each field may have a different shape:% S.theta(c, s) is the value of theta in sample s, chain c% (scalar variable)% S.theta(c, s, i) is the value of theta(i) in sample s, chain c% (vector variable)% S.theta(c, s, i, j) is the value of theta(i,j) in sample s, chain c% (matrix variable)%% stats contains various statistics, currently:% stats.mean, stats.std and stats.Rhat, stats.DIC (Andrew Jackson added).% Each field may have a different shape:% stats.mean.theta% stats.mean.theta(i)% stats.mean.theta(i,j)%% Rhat is the "estimated potential scale reduction" statistic due to% Gelman and Rubin.% Rhat values less than 1.1 mean the chain has probably converged for% this variable.%% DIC reads the actual DIC values generated by WinBUGS. This is different% to Andrew Gelman's R2WinBUGS which calculates these stats by monitoring% the deviance. Problem with his method is that he must estimate pD by% var(deviance)/2. This can be quite different to the winbugs value.% matbugs reads the DIC values from the winbugs log file directly. Fields% are generated for each of the variables listed including the total value.% e.g. stats.DIC.total returns the fields Dbar, Dhat, pD, DIC as per% winbugs. So stats.DIC.total.DIC returns the actual DIC value you% probably want.%% Example%% [S,stats] = matbugs(data, 'schools_model.txt', 'nSamples', 10000, ...% 'monitorParams', {'mu_theta', 'theta'}, ...% 'init', initStruct, 'nchains', 3, 'DICstatus',1)%% Written by Maryam Mahdaviani (maryam@cs.ubc.ca)% and Kevin Murphy (murphyk@cs.ubc.ca), August 2005% Modified for OpenBUGS by Tomo Eguchi 23 March 2006% Modified for DIC by Andrew Jackson (a.jackson@tcd.ie), March 2006 % Modified for winbugs filename by Sohrab Shah 28 Nov 2006% Bug fix 7 Mar 08 Woojae Kim clear valTransp[openBUGS, junk] = process_options(varargin, 'openBUGS', 0);if openBUGS Bugdir = 'C:/Program Files/OpenBUGS';else Bugdir = 'C:/Program Files/WinBUGS14';end [initStructs, Bugdir, nChains, view, workingDir, nBurnin, nSamples, ... monitorParams, thin, blocking, refreshrate, DICstatus, openBUGS, junk] = ... process_options(... varargin, ... 'init', {}, ... 'Bugdir', Bugdir, ... 'nChains', 3, ... 'view', 0, ... 'workingDir', fullfile(pwd,'tmp'), ... 'nBurnin', 1000, ... 'nSamples', 5000, ... 'monitorParams', {}, ... 'thin', 1, ... 'blocking', 1, ... 'refreshrate',100,... 'DICstatus',0, ... 'openBUGS', 0); % allow user to not specify initial valuesif 0 % length(initStructs) ~= nChains error(['init structure does not match number of chains ', ... sprintf('(%d)', nChains)]);endif ~exist(workingDir, 'dir') mkdir(pwd, 'tmp');endlog_filename = fullfileKPM(workingDir, 'log.txt');his_filename = fullfileKPM(workingDir, 'history.txt');scriptFile = [Bugdir,'\','script.txt'];%bugsModel = [pwd, '/', bugsModel];%bugsModel = fullfile(pwd, bugsModel);bugsModel = strrep(bugsModel, '\', '/'); % winBUGS wants a/b not a\bcodaFile = fullfileKPM(workingDir, 'coda');fid = fopen(scriptFile,'w');if (fid == -1) error(['Cannot open ', scriptFile]);end%display(option)fprintf(fid, 'display(''log'') \n');%check(model file)if openBUGS fprintf(fid, 'modelCheck(''%s'')\n',bugsModel); else fprintf(fid, 'check(''%s'')\n',bugsModel);endif ~isempty(dataStruct) dataFile = fullfileKPM(workingDir, 'data.txt'); dataGen(dataStruct, dataFile); if openBUGS fprintf(fid, 'modelData(''%s'')\n', dataFile); else fprintf(fid, 'data(''%s'')\n', dataFile); endend%fprintf(fid, '.txt'')\n');if openBUGS fprintf(fid, 'modelCompile(%u) \n', nChains);else fprintf(fid, 'compile(%u) \n', nChains);end initfileN = size(initStructs,2);for i=1:initfileN initFileName = fullfileKPM(workingDir, ['init_', num2str(i) '.txt']); dataGen(initStructs(i), initFileName) if openBUGS, fprintf(fid, 'modelInits(''%s'', %u)\n', initFileName, i); else fprintf(fid, 'inits (%u, ''%s'')\n', i, initFileName); endendif 0 % block fixed effects (for GLMs) % Don't know how to make this work in winbugs % Not available in openbugs fprintf(fid, 'blockfe(1)\n'); endfprintf(fid, 'refresh(%u) \n', refreshrate); % Andrew Jackson - line addedif openBUGS fprintf(fid, 'modelGenInits() \n'); fprintf(fid, 'modelUpdate(%u, TRUE)\n', nBurnin);else fprintf(fid, 'gen.inits() \n'); fprintf(fid, 'update(%u)\n', nBurnin);end%setting params to monitorif isempty(monitorParams) if openBUGS fprintf(fid, 'samplesSet ("*")\n'); else fprintf(fid, 'set (*)\n'); endelse for i=1:length(monitorParams) if openBUGS fprintf(fid, 'samplesSet (%s)\n', strrep(monitorParams{i}, '_', '.')); else fprintf(fid, 'set (%s)\n', strrep(monitorParams{i}, '_', '.')); end end %fprintf(fid, 'set (%s)\n','deviance');endif DICstatus; fprintf(fid, 'dic.set()\n'); end % Andrew Jackson - line addedif openBUGS fprintf(fid, 'samplesThin(%u)\n', thin); fprintf(fid, 'modelUpdate(%u)\n', nSamples); fprintf(fid, 'samplesCoda("*", ''%s'')\n', codaFile); fprintf(fid, 'samplesStats("*")\n'); fprintf(fid, 'samplesDensity("*")\n'); fprintf(fid, 'samplesHistory("*")\n');else fprintf(fid, 'thin.updater(%u)\n', thin); fprintf(fid, 'update(%u)\n', nSamples); fprintf(fid, 'coda(*, ''%s'')\n', codaFile); fprintf(fid, 'stats(*)\n');end% Andrew Jackson - line added, includes marker text to denote the end of% the DIC stats see belowif DICstatus; fprintf(fid, 'dic.stats()\n #endDIC'); endif openBUGS fprintf(fid, 'samplesHistory("*", ''%s'')\n', his_filename); fprintf (fid, 'modelSaveLog(''%s'')\n', log_filename);else fprintf(fid, 'history(*, ''%s'')\n', his_filename); fprintf (fid, 'save (''%s'')\n', log_filename);endif (view == 0) if openBUGS %fprintf(fid, 'modelQuit() \n'); % Bug fix by Brani Vidakovic fprintf(fid, 'modelQuit("y")\n'); else fprintf(fid, 'quit() \n'); endendfclose(fid);%calling WinBUGS and passing the script to it% File name fix by Sohrab Shah 28 Nov 2006if openBUGS f = fullfile(Bugdir, 'winbugs.exe'); %str = ['"', Bugdir, '\winbugs.exe" /PAR script.txt'];else f = fullfile(Bugdir, 'Winbugs14.exe'); %str = ['"', Bugdir, '\Winbugs14.exe" /PAR script.txt'];endstr = ['"',f,'" /PAR script.txt'];dos(str); % DOS wants a\b% passing the coda files to bugs2mat to convert files to structsif openBUGS codaIndex = [codaFile, 'CODAindex.txt'];else codaIndex = [codaFile, 'Index.txt'];endfor i=1:nChains if openBUGS codaF = [codaFile, 'CODAchain', num2str(i), '.txt']; else codaF = [codaFile, num2str(i), '.txt']; end S = bugs2mat(codaIndex, codaF); structArray(i) = S;endsamples = structsToArrays(structArray);stats = computeStats(samples);if DICstatus; DICstats = getDICstats(workingDir); stats.DIC = DICstats; endif nChains == 1 disp('EPSR not calculated (only one chain)');end%%%%%%%%%%%%%function dataGen(dataStruct, fileName)% This is a helper function to generate data or init files for winBUGS% Inputs:% fileName: name of the text file containing initial values. for each% chain we'll fileName_i where 'i' is the chain number,% dataStruct: is a Struct with name of params(consistant in the same% order with paramList) are fields and intial values are functionsif nargin<2 error(['This function needs two arguments']);endfieldNames = fieldnames(dataStruct);Nparam = size(fieldNames, 1);%fileName = [fileName, '.txt'];fid = fopen(fileName, 'w');if fid == -1 error(['Cannot open ', fileName ]);endfprintf(fid,'list(');for i=1:Nparam fn = fieldNames(i); fval = fn{1}; val = getfield(dataStruct, fval); [sfield1, sfield2]= size(val); msfield = max(sfield1, sfield2); newfval = strrep(fval, '_', '.'); if ((sfield1 == 1) && (sfield2 == 1)) % if the field is a singleton fprintf(fid, '%s=%G',newfval, val); % % One-D array: % beta = c(6, 6, ...) % % 2-D or more: % Y=structure( % .Data = c(1, 2, ...), .Dim = c(30,5)) % elseif ((length(size(val)) == 2) && ((sfield1 == 1) || (sfield2 == 1))) fprintf(fid, '%s=c(',newfval); for j=1:msfield if (isnan(val(j))) fprintf(fid,'NA'); else % format for winbugs fprintf(fid,wb_strval(val(j))); end if (j<msfield) fprintf(fid, ', '); else fprintf(fid, ')'); end end else % non-trivial 2-D or more array valsize = size(val); alldatalen = prod(valsize); %alldata = reshape(val', [1, alldatalen]); %alldata = alldata(:)'; %Truccolo-Filho, Wilson <Wilson_Truccolo@brown.edu> if length(valsize)<3 alldata = reshape(val', [1, alldatalen]); elseif length(valsize)==3 clear valTransp for j=1:valsize(3) valTransp(j,:,:)=val(:,:,j)';%need a new variable, since val might be rectangular end alldata=valTransp(:)'; else ['Error: 4D and higher dimensional arrays not accepted'] return end fprintf(fid, '%s=structure(.Data=c(', newfval); for j=1:alldatalen if (isnan(alldata(j))) fprintf(fid,'NA'); else % format for winbugs fprintf(fid,wb_strval(alldata(j))); end if (j < alldatalen) fprintf(fid,','); else fprintf(fid,'), .Dim=c(', alldata(j)); end end for j=1:length(valsize) if (j < length(valsize)) fprintf(fid, '%G,', valsize(j)); else fprintf(fid, '%G))', valsize(j)); end end end if (i<Nparam) fprintf(fid, ', '); else fprintf(fid, ')\n'); endendfclose(fid);%%%%%%%%function s = wb_strval(v)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -