%% CONTROL CODE FOR FULLY BAYESIAN SPATIO-TEMPORAL TEMPERATURE RECONSTRUCTION %EVERYTHING IS MODULAR TO ALLOW FOR EASY DEBUGGING AND ADAPTATION % _vNewModel_Oct08: change the formalism to reflect new model (Beta_1 now % normal). Allows for multiple proxies clear all; close all; %SET MATLAB'S CURRENT DIRECTORY TO HERE. % set the priors and the inital values for the MCMC sampler Prior_pars_vNewModel Initial_par_vals_vNewModel %% Set the seed of the random number generators randn('state', sum((1000+600)*clock)) rand('state', sum((1000+800)*clock)) %% load the data cd TestData load BARCAST_INPUT_vNewMeth1 %break it apart Locs=BARCAST_INPUT.Master_Locs; N_Locs=length(Locs(:,1)); %Number of locations: timeline=[BARCAST_INPUT.Data_timeline(1)-1, BARCAST_INPUT.Data_timeline]; N_Times=length(timeline)-1; %Number of DATA times loc_areas=BARCAST_INPUT.Areas; Inds_GridLocs_Central=BARCAST_INPUT.Inds_Central; %get the number of proxy types: N_PT=length(fieldnames(BARCAST_INPUT))-5; %stack the three data matrices, one on top of the other %the first N_Locs ROWS are the Inst, the next N_Locs ROWS the first proxy %type, the next the third. . . . .. Each column a year. The first %corresponds to the SECOND entry in timeline. Data_ALL=BARCAST_INPUT.Inst_Data; for kk=1:1:N_PT tp=eval(['BARCAST_INPUT.Prox_Data', num2str(kk)]); Data_ALL=[Data_ALL; tp]; end % % % % All_locs_wInd=BARCAST_INPUT.All_locs_wInd; % % % % lon_lat_area=BARCAST_INPUT.lon_lat_area; % % % % DATA_Mat=BARCAST_INPUT.DATA_Mat; % % % % DATA_Mat_locs=BARCAST_INPUT.DATA_Mat_locs; % % % % Inds_GridLocs_Central=BARCAST_INPUT.Inds_GridLocs_Central; % % % % timeline=BARCAST_INPUT.timeline; % % % % clear BARCAST_INPUT %Priors and MH jumping parameters, from Prior_pars_vNewModel load PRIORS_vNewMeth1 load MHpars_vNewMeth1 %Initial values from Initial_par_vals_vNewModel load INITIAL_VALS_vNewMeth1 %The Order of THE SCALAR parameters WILL ALWAYS thus: %1 = alpha, the AR(1) coefficient %2 = mu, the constant par in the linear mean of the AR(1) process %3 = sigma2, the partial sill in the spatial covariance matrix %4 = phi, the range parameter in the spatial covariance matrix %5 = tau2_I, the Inst measurement error %6 = tau2_P, the measurement error, first PROX type %7 = Beta_1, the scaling par in the first P observation equation %8 = Beta_0, the additive par in the first P observation equation %and, if there is second proxy type %9 = tau2_P_2, the measurement error, second PROX type %10 = Beta_1, the scaling par in the second P observation equation %11 = Beta_0, the additive par in the second P observation equation %and, if there is third proxy type . . . . %A NOTE ON GAMMA NOTATION. WE USE THE NOTATION OF Gelman et al, "Bayesian %Data Analysis", WHERE GAMMA PARAMETERS ALPHA, BETA)==(SHAPE, INVERSE SCALE). %THE RANDRAW.M CODE USES (A,B)==(SHAPE, SCALE), AND THE CALL IS RANDRAW('GAMMA', [M,B,A], SAMPLESIZE), %WHERE M IS THE LOCATION (NOT NEEDED). SO IN THE NOTATION OF GELMAN ET AT, THE CALL IS %RANDRAW('GAMMA', [0,1/BETA,ALPHA], SAMPLESIZE). %For example, %RANDRAW('GAMMA', [0,1/PRIORS.sigma2(2),PRIORS.sigma2(1)], 1), AND ETC. %switch back tot he main directory cd .. %% SET a few parameters %Number of iterations of the complete sampler Sampler_Its=2000; %Number of times to update only the temperature array before beginning to %update the other parameters pre_Sampler_Its=500; %% Areal weights vector for averaging the temperatures at each year %note that some of the elments of the temeprature are given 0 weight - %outside the prediction bounds. This is based on an input of the area of %each gridbox SpaceWeight=loc_areas/sum(loc_areas); %and for the central region/region of interest Areas_Central=zeros(1,N_Locs); Areas_Central(Inds_GridLocs_Central)=loc_areas(Inds_GridLocs_Central); SpaceWeight_Central=Areas_Central/sum(Areas_Central); %(In some applications, the goal might be to estimate the block average %over a subset of the locations in the reconstruction. For example, the %goal might be to reconstruct temperatures in Maine, but proxy records from %NH are incldued in the analysis, as they help to constrain temperatures in %Maine. SO some of the weights are, in this case, set to zero). %% CALCULATE FIXED QUANTITIES (DO NOT DEPEND ON UNKOWN PARAMETERS) %The matrix of distances between every possible pair of points, (I,P,R) All_DistMat=EarthDistances(Locs); %The H(t) selection matrix. %Basically, H(t) tells us which Inst and prox %locations have measurements for a given year. So: define H(t) for each %year as an indicator vector, and thus HH a matrix such that each column is %the indicator vector for that year. In other words, this is the complete %indicator matrix for the presence of data:: %1=YES Measurement; %0=NO Measurement %Simply a ZERO wherever there is a NaN in Data_ALL, and a ONE whereever %this is a value HH_SelectMat=ones(size(Data_ALL))-isnan(Data_ALL); %The total number of Inst/Prox Observations are needed for several %conditional posteriors, and can be calculated from the HH_SelectMat: M_InstProx=NaN(1+N_PT,1); %vectot: first the total number of inst obsm then the total number of each %prox type, in order. %Inst: M_InstProx(1)=sum(sum(HH_SelectMat(1:1:N_Locs, :))); %Prox: for kk=1:1:N_PT M_InstProx(kk+1)=sum(sum(HH_SelectMat(kk*N_Locs+1:1:(kk+1)*N_Locs, :))); end %% Set the initial values of the Field matrix and Current Parameter Vector % These will be updated and then saved at each iteration of the sampler. % They are initially filled with the values from INITIAL_VALS. % Paramter/field values at each step of the gibbs sampler are taken from % these objects, and new draws override the current entries. This ensures % that each step of the Gibbs sampler is ALWAYS using the most recent set of ALL % parameters, without having to deal with +/-1 indices. %Array of the estimated true temperature values, set to the initial values: Temperature_MCMC_Sampler=INITIAL_VALS.Temperature; %Order: All I, P with locs common to I, Rest of the P, R. %In other words, ordered the same as InstProx_locs, then with Rand_locs %added on %note that %[Inst_locs; Prox_locs] = InstProx_locs([Inst_inds,Prox_inds],:) %SO: Temperature_MCMC_Sampler([Inst_inds,Prox_inds], KK) extracts the %elements that can be compared to the corresponding time of DATA_Mat % Current values of the scalar parameters INITIAL_SCALAR_VALS=rmfield(INITIAL_VALS, 'Temperature'); CURRENT_PARS=cell2mat(struct2cell(INITIAL_SCALAR_VALS)); % OR LOAD TRUE VALUES - FOR TESTING % load TestData\Pars_TRUE % CURRENT_PARS=Pars_TRUE'; % % load TestData\TrueTemps_v1 % Temperature_MCMC_Sampler=Temperature_Matrix; %% DEFINE EMPTY MATRICES that will be filled with the sampler %DEFINE the empty parameter matrix: N_Pars=length(CURRENT_PARS); Paramters_MCMC_Samples=NaN(N_Pars, Sampler_Its); %The empty matrix of the samples of the blockaverage timeseries: BlockAve_MCMC_Samples=NaN(N_Times+1, pre_Sampler_Its+Sampler_Its); %and the central/target portion BlockAve_Central_MCMC_Samples=NaN(N_Times+1, pre_Sampler_Its+Sampler_Its); %NOTE the initial values of the parameters, field, and block averages will %NOT be saved. So the first item in all matrices/arrays are the results %after the first iteration of the sampler %IN this case, as the amount of data is small, we are able to deal %with the whole array of space time draws. In applications with larger %data, this is not possible (memory overflow). Temperature_ARRAY=NaN(N_Locs, N_Times+1, pre_Sampler_Its+Sampler_Its); %% CALCULATE PARAMETER DEPENDENT QUANTITIES %that are used several times in the sampler % %The idea: calculate the quantities with the initial parameter values, then %update as soon as possible, leaving the variablle name the same % %calculate the initial spatial correlation matrix, and its inverse %these are needed several times. %AS SOON as phi is updated, this is updated, ensuring that the %correlation matrix and its inverse are always up to date, regardless of %the order of the sampling below. CURRENT_spatial_corr_mat=exp(-CURRENT_PARS(4)*All_DistMat); CURRENT_inv_spatial_corr_mat=inv(CURRENT_spatial_corr_mat); %% To speed up the code %1. Find the UNIQUE missing data patterns, number them. %2. Index each year by the missing data pattern. %3. For each missing data pattern, calculate the inverse and square root of %the conditional posterior covariance of a T_k, and stack them %4. Rewrite the T_k_Updater to simply call these matrices. %This reduces the number of matrix inversions for each FULL iteration of %the sampler to the number of UNIQUE data patterns, and reduces the number %for the pre iterations to 2. U_Patterns=unique(HH_SelectMat', 'rows'); %create an index vector that gices, for each year, the number of the %corresponding pattern in U_Patterns %Basically - HH_SelectMat can be represented by U_Patterns and this index vector: Pattern_by_Year=NaN(N_Times,1); for kk=1:1:length(U_Patterns(:,1)); dummy=ismember(HH_SelectMat', U_Patterns(kk,:), 'rows'); Pattern_by_Year(find(dummy==1))=kk; end %Input the CURRENT_PARS vector and etc into Covariance_Patterns, which returns two 3d %arrays: the covariance amtrix for each missing data patter (for %the mean calculation) and the squre root of the covariance matrix (to make %the draw). [CURRENT_COV_ARRAY, CURRENT_SQRT_COV_ARRAY]=Covariance_Patterns(U_Patterns, CURRENT_PARS, CURRENT_inv_spatial_corr_mat, N_Locs, N_PT); %% In an attempt to speed convergence of the variance paramters % we will uptate only the true temperature array for a number of % iterations, and then add the updating of the other parameters. This is to % prevent the model from requiring large variances to fit the observations % to the data. %timertimer=NaN; for samples=1:1:pre_Sampler_Its tic; %% SAMPLE T(0): True temperature the year before the first measurement. Temperature_MCMC_Sampler(:,1)=T_0_Updater_vNM(PRIORS.T_0, Temperature_MCMC_Sampler(:,2), CURRENT_PARS, CURRENT_inv_spatial_corr_mat); %% SAMPLE T(1), . . ., T(last-1). Recall that the T matrix starts at time=0, while the W matrix starts at time=1 for Tm=2:1:N_Times Temperature_MCMC_Sampler(:,Tm)=T_k_Updater_vFAST(Temperature_MCMC_Sampler(:, Tm-1), Temperature_MCMC_Sampler(:,Tm+1), Data_ALL(:,Tm-1), CURRENT_PARS, U_Patterns(Pattern_by_Year(Tm-1),:),CURRENT_COV_ARRAY(:,:,Pattern_by_Year(Tm-1)),CURRENT_SQRT_COV_ARRAY(:,:,Pattern_by_Year(Tm-1)),CURRENT_inv_spatial_corr_mat, N_Locs, N_PT); end %This is a SLOW step, because it is actually N_Times-1 steps. . . %% SAMPLE T(last) Temperature_MCMC_Sampler(:,N_Times+1)=T_last_Updater_vNM(Temperature_MCMC_Sampler(:, N_Times), Data_ALL(:,N_Times), HH_SelectMat(:, N_Times), CURRENT_PARS, CURRENT_inv_spatial_corr_mat, N_Locs, N_PT); %% Fill in the next iteration of the BlockAve_MCMC_Samples matrix: BlockAve_MCMC_Samples(:,samples)=(SpaceWeight*Temperature_MCMC_Sampler)'; BlockAve_Central_MCMC_Samples(:, samples)=(SpaceWeight_Central*Temperature_MCMC_Sampler)'; %Fill in the next slice of the space-time field draw array Temperature_ARRAY(:,:,samples)=Temperature_MCMC_Sampler; %save the current draw of the space-time temp matrix %save(['TestData\FieldDraws\Temp_MCMC_vNM_Test_PreStep' num2str(samples)],'Temperature_MCMC_Sampler'); timertimer=toc; disp(['Working on pre-MCMC iteration ', num2str(samples), ' of ', num2str(pre_Sampler_Its), '. Last iteration took ', num2str(timertimer), ' seconds.']) end timertimer=NaN; %% RUN THE SAMPLER for samples=1:1:Sampler_Its tic %% SAMPLE T(0): True temperature the year before the first measurement. Temperature_MCMC_Sampler(:,1)=T_0_Updater_vNM(PRIORS.T_0, Temperature_MCMC_Sampler(:,2), CURRENT_PARS, CURRENT_inv_spatial_corr_mat); %% SAMPLE T(1), . . ., T(last-1). Recall that the T matrix starts at time=0, while the W matrix starts at time=1 for Tm=2:1:N_Times Temperature_MCMC_Sampler(:,Tm)=T_k_Updater_vFAST(Temperature_MCMC_Sampler(:, Tm-1), Temperature_MCMC_Sampler(:,Tm+1), Data_ALL(:,Tm-1), CURRENT_PARS, U_Patterns(Pattern_by_Year(Tm-1),:),CURRENT_COV_ARRAY(:,:,Pattern_by_Year(Tm-1)),CURRENT_SQRT_COV_ARRAY(:,:,Pattern_by_Year(Tm-1)),CURRENT_inv_spatial_corr_mat, N_Locs, N_PT); end %This is a SLOW step, because it is actually N_Times-1 steps. . . %% SAMPLE T(last) Temperature_MCMC_Sampler(:,N_Times+1)=T_last_Updater_vNM(Temperature_MCMC_Sampler(:, N_Times), Data_ALL(:,N_Times), HH_SelectMat(:, N_Times), CURRENT_PARS, CURRENT_inv_spatial_corr_mat, N_Locs, N_PT); %% SAMPLE AR(1) coefficient New_Alpha=Alpha_Updater_vNM(PRIORS.alpha, Temperature_MCMC_Sampler, CURRENT_PARS, CURRENT_inv_spatial_corr_mat); CURRENT_PARS(1)=New_Alpha; clear New_Alpha %% SAMPLE AR(1) mean constant parameter, mu: New_mu=Mu_Updater_vNM(PRIORS.mu, Temperature_MCMC_Sampler, CURRENT_PARS, CURRENT_inv_spatial_corr_mat); CURRENT_PARS(2)=New_mu; clear New_AR_mean_mu %% SAMPLE Partial Sill of the spatial covaraince martrix New_sigma2=Sigma2_Updater_vNM(PRIORS.sigma2, Temperature_MCMC_Sampler, CURRENT_PARS, CURRENT_inv_spatial_corr_mat); %ARTIFICIALLY put a cieling at, say, 5. %CHECK a posterior that, one the algorithm has converged, ALL draws are %lower than this. CURRENT_PARS(3)=min(5, New_sigma2); clear New_sigma2 %% SAMPLE Range Parameter of the spatial covaraince martrix (METROPOLIS) % This also updates the spatial corelation matrix and its inverse [New_phi, New_scm, New_iscm]=Phi_Updater_vNM(PRIORS.phi, Temperature_MCMC_Sampler, CURRENT_PARS, CURRENT_spatial_corr_mat, CURRENT_inv_spatial_corr_mat, All_DistMat, MHpars.log_phi); CURRENT_PARS(4)=New_phi; CURRENT_spatial_corr_mat=New_scm; CURRENT_inv_spatial_corr_mat=New_iscm; clear New_phi New_iscm New_scm %% SAMPLE Instrumental measurement error New_tau2_I=tau2_I_Updater_vNM(PRIORS.tau2_I, Temperature_MCMC_Sampler, Data_ALL, N_Locs, M_InstProx(1)); %ARTIFICIALLY put a cieling at, say, 5. %CHECK a posterior that, one the algorithm has converged, ALL draws are %lower than this. CURRENT_PARS(5)=min(5, New_tau2_I); clear New_tau2_I %% NEED TO LOOP THE SAMPLING OF THESE THREE PARAMETERS for Pnum=1:1:N_PT %curtail the CURRENT_PARS vector to only include the pars for one %proxy type at a time: CURRENT_PARS_Brief=[CURRENT_PARS(1:1:5); CURRENT_PARS([6:1:8]+(Pnum-1)*3)]; %Similarily exract each type of proxy data: Prox_Data_Brief=eval(['BARCAST_INPUT.Prox_Data', num2str(Pnum)]); %% SAMPLE Proxy measurement error New_tau2_P=tau2_P_Updater_vNM(eval(['PRIORS.tau2_P_', num2str(Pnum)]), Temperature_MCMC_Sampler, Prox_Data_Brief, CURRENT_PARS_Brief, M_InstProx(Pnum+1)); %ARTIFICIALLY put a cieling at, say, 50. %CHECK a posterior that, one the algorithm has converged, ALL draws are %lower than this. CURRENT_PARS_Brief(6)=min(10, New_tau2_P); clear New_tau2_P %% SAMPLE Scaling constant in the proxy observation equation New_beta_1=Beta_1_Updater_vNM(eval(['PRIORS.Beta_1_', num2str(Pnum)]), Temperature_MCMC_Sampler, Prox_Data_Brief, CURRENT_PARS_Brief); CURRENT_PARS_Brief(7)=New_beta_1; clear New_beta_1 %% SAMPLE Additive constant in the proxy observation equation New_Beta_0=Beta_0_Updater_vNM(eval(['PRIORS.Beta_0_', num2str(Pnum)]), Temperature_MCMC_Sampler, Prox_Data_Brief, CURRENT_PARS_Brief, M_InstProx(Pnum+1)); CURRENT_PARS_Brief(8)=New_Beta_0; clear New_Beta_0 CURRENT_PARS([6:1:8]+(Pnum-1)*3)=CURRENT_PARS_Brief(6:1:8); end %% UPDATE the covariance arrays used in the T_k_Updater step [CURRENT_COV_ARRAY, CURRENT_SQRT_COV_ARRAY]=Covariance_Patterns(U_Patterns, CURRENT_PARS, CURRENT_inv_spatial_corr_mat, N_Locs, N_PT); %% UPDATE THE VARIOUS MATRICES, SAVE CURRENT TEMPERTAURE MATRIX %update the Paramters_MCMC_Samples matrix: Paramters_MCMC_Samples(:, samples)=CURRENT_PARS; %CURRENT_PARS is not cleared: it is, after all, the current parameter %vector. %Fill in the next iteration of the BlockAve_MCMC_Samples matrix: BlockAve_MCMC_Samples(:, pre_Sampler_Its+samples)=(SpaceWeight*Temperature_MCMC_Sampler)'; BlockAve_Central_MCMC_Samples(:, pre_Sampler_Its+samples)=(SpaceWeight_Central*Temperature_MCMC_Sampler)'; %add the new draw of the space-time temp matrix Temperature_ARRAY(:,:,pre_Sampler_Its+samples)=Temperature_MCMC_Sampler; %save the current draw of the space-time temp matrix %save(['TestData\FieldDraws\Temp_MCMC_vNM_Test_Step' num2str(samples)],'Temperature_MCMC_Sampler'); %SAVE the matrix of parameter vector draws and the matrix of block %average vectors. (This way, even if the code is stopped prematurely, %we get something) %cd TestData %cd FieldDraws %save TestData\FieldDraws\Paramters_MCMC_Samples_vNM Paramters_MCMC_Samples %save TestData\FieldDraws\Temperature_ARRAY_vNM Temperature_ARRAY %save TestData\FieldDraws\BlockAve_MCMC_Samples_vNM BlockAve_MCMC_Samples %save TestData\FieldDraws\BlockAve_Central_MCMC_Samples_vNM BlockAve_Central_MCMC_Samples %and back %cd .. %cd .. timertimer=toc; disp(['Finished MCMC iteration ', num2str(samples), ' of ', num2str(Sampler_Its), '. Last iteration took ', num2str(timertimer), ' seconds.']) end %% SAVE the matrix of parameter vector draws and the matrix of block %average vectors. cd TestData cd FieldDraws save Paramters_MCMC_Samples_vNM Paramters_MCMC_Samples save Temperature_ARRAY_vNM Temperature_ARRAY save BlockAve_MCMC_Samples_vNM BlockAve_MCMC_Samples save BlockAve_Central_MCMC_Samples_vNM BlockAve_Central_MCMC_Samples %and back cd .. cd ..