/******************************************************************************** * * Bayesian Regression and Adaptive Sampling with Gaussian Process Trees * Copyright (C) 2005, University of California * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Questions? Contact Robert B. Gramacy (rbgramacy@ams.ucsc.edu) * ********************************************************************************/ extern "C" { #include "matrix.h" #include "lh.h" #include "lik_post.h" #include "rand_draws.h" #include "rand_pdf.h" #include "all_draws.h" #include "gen_covar.h" #include "rhelp.h" } #include "corr.h" #include "params.h" #include "model.h" #include "mr_exp_sep.h" #include #include #include #include #include #include #include using namespace std; #define BUFFMAX 256 #define PWR 2.0 /* * MrExpSep: * * constructor function; should be the same as ExpSep, excepy * for nin calculation, and assignments of r, delta, and nugfine */ MrExpSep::MrExpSep(unsigned int col, Base_Prior *base_prior) : Corr(col, base_prior) { /* Sanity Checks */ assert(base_prior->BaseModel() == MR_GP); assert( ((MrGp_Prior*) base_prior)->CorrPrior()->CorrModel() == MREXPSEP); /* set pointer to correllation priot from the base prior */ prior = ((MrGp_Prior*) base_prior)->CorrPrior(); assert(prior); /* let the prior choose the starting nugget value */ nug = prior->Nug(); /* calculate the true input dimension of X */ nin = (int) col/2-1; /* allocate and initialize (from prior) the range params */ d = new_dup_vector(((MrExpSep_Prior*)prior)->D(), 2*nin); /* start fully in the GP model, not the LLM */ b = new_ones_ivector(2*nin, 1); pb = new_zero_vector(2*nin); /* memory allocated for effective range parameter -- deff = d*b */ d_eff = new_dup_vector(d, 2*nin); /* counter of the number of d-rejections in a row */ dreject = 0; /* get the autoregressive cofficient from the prior */ r = ((MrGp_Prior*) base_prior)->R(); /* get the fine variance discount factor, and observation nugget for thefine level proc -- both fro prior */ delta = ((MrExpSep_Prior*)prior)->Delta(); nugfine = ((MrExpSep_Prior*)prior)->Nugfine(); } /* * MrExpSep (assignment operator): * * used to assign the parameters of one correlation * function to anothers. Both correlation functions * must already have been allocated */ Corr& MrExpSep::operator=(const Corr &c) { MrExpSep *e = (MrExpSep*) &c; /* sanity check */ assert(prior == ((MrGp_Prior*) base_prior)->CorrPrior()); /* copy everything */ log_det_K = e->log_det_K; linear = e->linear; nin = e->nin; dupv(d, e->d, 2*nin); dupv(pb, e->pb, 2*nin); dupv(d_eff, e->d_eff, 2*nin); dupiv(b, e->b, 2*nin); nug = e->nug; dreject = e->dreject; /* copy the covariance matrices */ Cov(e); return *this; } /* * ~MrExpSep: * * destructor */ MrExpSep::~MrExpSep(void) { free(d); free(b); free(pb); free(d_eff); } /* * DrawNug: * * draw for the nugget; * rebuilding K, Ki, and marginal params, if necessary * return true if the correlation matrix has changed; * false otherwise */ bool MrExpSep::DrawNug(unsigned int n, double **X, double **F, double *Z, double *lambda, double **bmu, double **Vb, double tau2, void *state) { bool success = false; MrGp_Prior *gp_prior = (MrGp_Prior*) base_prior; /* allocate K_new, Ki_new, Kchol_new */ if(! linear) assert(n == this->n); /* with probability 0.5, skip drawing the nugget */ if(runi(state) > 0.5) return false; /* make the draw */ double* new_nugs = mr_nug_draw_margin(n, col, nug, nugfine, X, F, Z, K, log_det_K, *lambda, Vb, K_new, Ki_new, Kchol_new, &log_det_K_new, &lambda_new, Vb_new, bmu_new, gp_prior->get_b0(), gp_prior->get_Ti(), gp_prior->get_T(), tau2, prior->NugAlpha(), prior->NugBeta(), ((MrExpSep_Prior*) prior)->Nugf_alpha(), ((MrExpSep_Prior*) prior)->Nugf_beta(), r, delta, gp_prior->s2Alpha(), gp_prior->s2Beta(), (int) linear, state); /* did we accept the draw? */ if(new_nugs[0] != nug) { nug = new_nugs[0]; nugfine = new_nugs[1]; success = true; swap_new(Vb, bmu, lambda); } /* clean up */ free(new_nugs); return success; } /* * Update: (symmetric) * * computes the internal correlation matrix K, * (INCLUDES NUGGET) */ void MrExpSep::Update(unsigned int n, double **K, double **X) { corr_symm(K, nin, X, n, d_eff, nug, nugfine, r, delta, PWR); } /* * Update: (symmetric) * * takes in a (symmetric) distance matrix and * returns a correlation matrix (INCLUDES NUGGET) */ void MrExpSep::Update(unsigned int n, double **X) { /* no need to update internal K if we're at LLM */ if(linear) return; /* sanity check */ assert(this->n == n); /* compute K */ corr_symm(K, nin, X, n, d_eff, nug, nugfine, r, delta, PWR); } /* * Update: (non-symmetric) * * takes in a distance matrix and returns a * correlation matrix (DOES NOT INCLUDE NUGGET) */ void MrExpSep::Update(unsigned int n1, unsigned int n2, double **K, double **X, double **XX) { corr_unsymm(K, nin+1, XX, n1, X, n2, d_eff, r, delta, PWR); } /* * propose_new_d: * * propose new d and b values. Sometimes propose d's and b's for all * dimensions jointly, sometimes do just the d's with b==1, and * other times do only those with b==0. I have found that this improves * mixing */ bool MrExpSep::propose_new_d(double* d_new, int * b_new, double *pb_new, double *q_fwd, double *q_bak, void *state) { *q_bak = *q_fwd = 1.0; /* copy old values */ dupv(d_new, d, 2*nin); dupv(pb_new, pb, 2*nin); dupiv(b_new, b, 2*nin); /* 1/3 of the time -- just draw all the ds jointly */ if(runi(state) < 0.3333333333) { /* RW proposal for all d-values */ d_proposal(2*nin, NULL, d_new, d, q_fwd, q_bak, state); /* if we are allowing the LLM, then we need to draw the b_new conditional on d_new; otherwise just return */ if(prior->LLM()) { if(runi(state) < 0.5) /* sometimes skip drawing the bs */ return linear_rand_sep(b_new,pb_new,d_new,2*nin,prior->GamLin(),state); else return linear; } else return false; /* just draw the ds with bs == 1 or bs == 0, choosing one of those randomly */ } else { /* choose bs == 1 or bs == 0 */ FIND_OP find_op = NE; if(runi(state) < 0.5) find_op = EQ; /* find those ds which coincide with find_op */ unsigned int len = 0; int* zero = find(d_eff, 2*nin, find_op, 0.0, &len); /* if there are no d's which coincide with find_op, then there is nothing to propose, so just return with the current LLM setting */ if(len == 0) { free(zero); return linear; } /* otherwise, draw length(zero) new d values, only at the indices of d_new indicated by zero */ d_proposal(len, zero, d_new, d, q_fwd, q_bak, state); /* done if forcing Gp model (not allowing the LLM) */ if(! prior->LLM()) { free(zero); return false; } /* otherwise, need to draw bs (booleans) conditional on the proposed d_new -- only do this 1/2 the time */ /* sometimes skip drawing the bs */ if(runi(state) < 0.5) { /* gather the ds, bs, and pbs into the "short" vectors, as indexed by the zero-vector */ double *d_short = new_vector(len); double *pb_short = new_zero_vector(len); int *b_short = new_ones_ivector(len, 0); /* make ones give zeros */ copy_sub_vector(d_short, zero, d_new, len); /* draw new bs conditional on the new ds */ linear_rand_sep(b_short,pb_short,d_short,len,prior->GamLin(),state); /* copy the new bs and pbs into the big "new" proposals */ copy_p_vector(pb_new, zero, pb_short, len); copy_p_ivector(b_new, zero, b_short, len); /* clean up */ free(d_short); free(pb_short); free(b_short); free(zero); /* only return true if we have actiually jumpted to the LLM; i.e., only when all the b_new's are 0 */ for(unsigned int i=0; i<(2*nin); i++) if(b_new[i] == 1) return false; return true; } else { /* if we skipped drawing new b's, then clean-up and return the previous LLM setting */ free(zero); return linear; } } } /* * Draw: * * draw parameters for a new correlation matrix; * returns true if the correlation matrix (passed in) * has changed; otherwise returns false */ int MrExpSep::Draw(unsigned int n, double **F, double **X, double *Z, double *lambda, double **bmu, double **Vb, double tau2, void *state) { int success = 0; bool lin_new; double q_fwd, q_bak; /* get more accessible pointers to the priors */ MrExpSep_Prior* ep = (MrExpSep_Prior*) prior; MrGp_Prior *gp_prior = (MrGp_Prior*) base_prior; /* pointers to proposed settings of parameters */ double *d_new = NULL; int *b_new = NULL; double *pb_new = NULL; /* when the LLM is active, sometimes skip this Draw and only draw the nugget; this is done for speed, and to improve miding in the rest of the model */ if(linear && runi(state) > 0.5) { return DrawNug(n, X, F, Z, lambda, bmu, Vb, tau2, state);} /* proposals happen when we're not forcing the LLM */ if(prior->Linear()) lin_new = true; else { /* allocate new d, b, and pb */ d_new = new_zero_vector((2*nin)); b_new = new_ivector((2*nin)); pb_new = new_vector((2*nin)); /* make the RW proposal for d, and then b */ lin_new = propose_new_d(d_new, b_new, pb_new, &q_fwd, &q_bak, state); } /* calculate the effective model (d_eff = d*b), and allocate memory -- when we're not proposing the LLM */ double *d_new_eff = NULL; if(! lin_new) { d_new_eff = new_zero_vector((2*nin)); for(unsigned int i=0; i<(2*nin); i++) d_new_eff[i] = d_new[i]*b_new[i]; /* allocate K_new, Ki_new, Kchol_new */ allocate_new(n); /* sanity check */ assert(n == this->n); } /* compute the acceptance ratio, unless we're forcing the LLM in which case we do nothing just return a successful "draw" */ if(prior->Linear()) success = 1; else { /* compute prior ratio and proposal ratio */ double pRatio_log = 0.0; double qRatio = q_bak/q_fwd; pRatio_log += ep->log_DPrior_pdf(d_new); pRatio_log -= ep->log_DPrior_pdf(d); /* MH acceptance ratio for the draw */ success = d_draw(d_new_eff, n, col, F, X, Z, log_det_K,*lambda, Vb, K_new, Ki_new, Kchol_new, &log_det_K_new, &lambda_new, Vb_new, bmu_new, gp_prior->get_b0(), gp_prior->get_Ti(), gp_prior->get_T(), tau2, nug, nugfine, qRatio, pRatio_log, gp_prior->s2Alpha(), gp_prior->s2Beta(), (int) lin_new, state); /* see if the draw was acceptedl; if so, we need to copy (or swap) the contents of the new into the old */ if(success == 1) { swap_vector(&d, &d_new); /* d_eff is zero if we're in the LLM */ if(!lin_new) swap_vector(&d_eff, &d_new_eff); else zerov(d_eff, (2*nin)); linear = (bool) lin_new; /* copy b and pb */ swap_ivector(&b, &b_new); swap_vector(&pb, &pb_new); swap_new(Vb, bmu, lambda); } } /* if we're not forcing the LLM, then we have some cleaning up to do */ if(! prior->Linear()) { free(d_new); free(pb_new); free(b_new); } /* if we didn't happen to jump to the LLM, then we have more cleaning up to do */ if(!lin_new) free(d_new_eff); /* something went wrong, abort; otherwise keep track of the number of d-rejections in a row */ if(success == -1) return success; else if(success == 0) dreject++; else dreject = 0; /* abort if we have had too many rejections */ if(dreject >= REJECTMAX) return -2; /* draw nuggets */ bool changed = DrawNug(n, X, F, Z, lambda, bmu, Vb, tau2, state); bool deltasuccess = DrawDelta(n, X, F, Z, lambda, bmu, Vb, tau2, state); success = success || changed || deltasuccess; return success; } /* * Combine: * * used in tree-prune steps, chooses one of two * sets of parameters to correlation functions, * and choose one for "this" correlation function */ void MrExpSep::Combine(Corr *c1, Corr *c2, void *state) { get_delta_d((MrExpSep*)c1, (MrExpSep*)c2, state); CombineNug(c1, c2, state); } /* * Split: * * used in tree-grow steps, splits the parameters * of "this" correlation function into a parameterization * for two (new) correlation functions */ void MrExpSep::Split(Corr *c1, Corr *c2, void *state) { propose_new_d((MrExpSep*) c1, (MrExpSep*) c2, state); SplitNug(c1, c2, state); } /* * get_delta_d: * * compute d from two ds residing in c1 and c2 * and sample b conditional on the chosen d * * (used in prune) */ void MrExpSep::get_delta_d(MrExpSep* c1, MrExpSep* c2, void *state) { /* ceate pointers to the two ds */ double **dch = (double**) malloc(sizeof(double*) * 2); dch[0] = c1->d; dch[1] = c2->d; /* randomly choose one of the ds */ int ii[2]; propose_indices(ii, 0.5, state); /* and copy the chosen one */ dupv(d, dch[ii[0]], (2*nin)); /* clean up */ free(dch); /* propose b conditional on the chosen d */ linear = linear_rand_sep(b, pb, d, (2*nin), prior->GamLin(), state); /* compute d_eff = d * b for the chosen d and b */ for(unsigned int i=0; i<(2*nin); i++) d_eff[i] = d[i] * b[i]; } /* * propose_new_d: * * propose new D parameters for possible * new children partitions. */ void MrExpSep::propose_new_d(MrExpSep* c1, MrExpSep* c2, void *state) { int i[2]; double **dnew = new_matrix(2, (2*nin)); /* randomply choose which of c1 and c2 will get a copy of this->d, and which will get a random d from the prior */ propose_indices(i, 0.5, state); /* =from this->d */ dupv(dnew[i[0]], d, (2*nin)); /* from the prior */ draw_d_from_prior(dnew[i[1]], state); /* copy into c1 and c2 */ dupv(c1->d, dnew[0], (2*nin)); dupv(c2->d, dnew[1], (2*nin)); /* clean up */ delete_matrix(dnew); /* propose new b for c1 and c2, conditional on the two new d parameters */ c1->linear = (bool) linear_rand_sep(c1->b, c1->pb, c1->d, (2*nin), prior->GamLin(), state); c2->linear = (bool) linear_rand_sep(c2->b, c2->pb, c2->d, (2*nin), prior->GamLin(), state); /* compute d_eff = b*d for the two new b and d pairs */ for(unsigned int i=0; i<(2*nin); i++) { c1->d_eff[i] = c1->d[i] * c1->b[i]; c2->d_eff[i] = c2->d[i] * c2->b[i]; } } /* * d_draw: * * draws for d given the rest of the parameters except b and s2 marginalized out * * F[col][n], Kchol[n][n], K_new[n][n], Ti[col][col], T[col][col] Vb[col][col], * Vb_new[col][col], Ki_new[n][n], Kchol_new[n][n], b0[col], Z[n], dlast[col-1], * d_alpha[col-1][2], d_beta[col-1][2] * * return 1 if draw accepted, 0 if rejected, -1 if error */ int MrExpSep::d_draw(double *d, unsigned int n, unsigned int col, double **F, double **X, double *Z, double log_det_K, double lambda, double **Vb, double **K_new, double **Ki_new, double **Kchol_new, double *log_det_K_new, double *lambda_new, double **VB_new, double *bmu_new, double *b0, double **Ti, double **T, double tau2, double nug, double nugfine, double qRatio, double pRatio_log, double a0, double g0, int lin, void *state) { double pd, pdlast, alpha; unsigned int m = 0; /* Knew = dist_to_K(dist, d, nugget) compute lambda, Vb, and bmu, for the NEW d */ if(! lin) { /* regular */ corr_symm(K_new, nin+1, X, n, d, nug, nugfine, r, delta, PWR); inverse_chol(K_new, Ki_new, Kchol_new, n); *log_det_K_new = log_determinant_chol(Kchol_new, n); *lambda_new = compute_lambda(Vb_new, bmu_new, n, col, F, Z, Ki_new, Ti, tau2, b0); } else { /* linear */ *log_det_K_new = 0.0; for(unsigned int i=0; i= 1 || runi(state) < alpha) return 1; else return 0; } bool MrExpSep::DrawDelta(unsigned int n, double **X, double **F, double *Z, double *lambda, double **bmu, double **Vb, double tau2, void *state) { bool success = false; MrGp_Prior *gp_prior = (MrGp_Prior*) base_prior; MrExpSep_Prior *ep = (MrExpSep_Prior*) prior; unsigned int m = 0; double* b0 = gp_prior->get_b0(); double a0 = gp_prior->s2Alpha(); double g0 = gp_prior->s2Beta(); /* allocate K_new, Ki_new, Kchol_new */ if(! linear) assert(n == this->n); if(runi(state) > 0.5) return false; double q_fwd; double q_bak; double pdelta; double pnewdelta; /* make the draw */ double newdelta = unif_propose_pos(delta, &q_fwd, &q_bak, state); // printf("%g %g\n", delta, newdelta); /* new covariace matrix based on new nug */ if(linear) { log_det_K_new = 0.0; for(unsigned int i=0; iget_Ti(), tau2, b0, nug); } else{ corr_symm(K_new, nin+1, X, n, d, nug, nugfine, r, newdelta, PWR); inverse_chol(K_new, Ki_new, Kchol_new, n); log_det_K_new = log_determinant_chol(Kchol_new, n); lambda_new = compute_lambda(Vb_new, bmu_new, n, col, F, Z, Ki_new, gp_prior->get_Ti(), tau2, b0); } if((gp_prior->get_T())[0][0] == 0) m = col; pnewdelta = gamma_mixture_pdf(newdelta, ep->Delta_alpha(), ep->Delta_beta()); pnewdelta += post_margin(n,col,lambda_new,Vb_new,log_det_K_new,a0-m,g0); pdelta = gamma_mixture_pdf(delta, ep->Delta_alpha(), ep->Delta_beta()); pdelta += post_margin(n,col,*lambda,Vb,log_det_K,a0-m,g0); /* accept or reject */ double alpha = exp(pnewdelta - pdelta)*(q_bak/q_fwd); if(runi(state) < alpha) { success = true; delta = newdelta; swap_new(Vb, bmu, lambda); } return success; } /* * draw_d_from_prior: * * get draws of separable d parameter from * the prior distribution */ void MrExpSep::draw_d_from_prior(double *d_new, void *state) { if(prior->Linear()) dupv(d_new, d, (2*nin)); else ((MrExpSep_Prior*)prior)->DPrior_rand(d_new, state); } /* * corr_symm: * * compute a (symmetric) correllation matrix from a seperable * exponential correllation function * * X[n][m], K[n][n] */ void MrExpSep::corr_symm(double **K, unsigned int m, double **X, unsigned int n, double *d, double nug, double nugfine, double r, double delta, double pwr) { unsigned int i,j,k/*, across*/; double diff, fine; i = k = j = 0; for(i=0; ilog_Prior(d, b, pb, linear); return prob; } /* * sum_b: * * return the count of the number of linearizing * booleans set to one (the number of linear dimensions) */ unsigned int MrExpSep::sum_b(void) { unsigned int bs = 0; for(unsigned int i=0; i<(2*nin); i++) if(!b[i]) bs ++; /* sanity check */ if(bs == (2*nin)) assert(linear); return bs; } /* * ToggleLinear: * * make linear if not linear, otherwise * make not linear */ void MrExpSep::ToggleLinear(void) { if(linear) { /* force a full GP model */ linear = false; for(unsigned int i=0; i<(2*nin); i++) b[i] = 1; } else { /* force a full LLM */ linear = true; for(unsigned int i=0; i<(2*nin); i++) b[i] = 0; } /* set d_Eff = d * b */ for(unsigned int i=0; i<(2*nin); i++) d_eff[i] = d[i] * b[i]; } /* * D: * * return the vector of range parameters for the * separable exponential family of correlation function */ double* MrExpSep::D(void) { return d; } /* * R: * * return the default auto-correlation between fidelities. */ double MrExpSep::R(void) { return r; } /* * Delta: * * * return the fine fidelity discount factor, delta. */ double MrExpSep::Delta(void) { return delta; } /* * Nugfine: * * * return the fine fidelity observational error */ double MrExpSep::Nugfine(void) { return nugfine; } /* * Trace: * * return the current values of the parameters * to this correlation function */ double* MrExpSep::Trace(unsigned int* len) { *len = 0; /* FOR TADDY TO FILL IN */ return NULL; } /* * MrExpSep_Prior: * * constructor for the prior parameterization of the separable * exponential power distribution function */ MrExpSep_Prior::MrExpSep_Prior(const unsigned int col) : Corr_Prior(col) { corr_model = MREXPSEP; /* calculate effective number of input dimension */ nin = col/2-1; /* default starting values and initial parameterization */ d = ones((2*nin), 0.5); d_alpha = new_zero_matrix((2*nin), 2); d_beta = new_zero_matrix((2*nin), 2); default_d_priors(); /* set d_alpha and d_beta */ default_d_lambdas(); /* set d_alpha_lambda and d_beta_lambda */ /* defauly starting values for mr-specific parameters; these should probably be moved into a default_* function like the others */ r = 1.0; delta = 1.0; nugfine = 0.01; delta_alpha = ones(2,1.0); delta_beta = ones(2,20.0); nugf_alpha = ones(2,1.0); nugf_beta = ones(2,1.0); } /* * Dup: * * duplicate this prior for the isotropic exponential * power family */ Corr_Prior* MrExpSep_Prior::Dup(void) { return new MrExpSep_Prior(this); } /* * MrExpSep_Prior (new duplicate) * * duplicating constructor for the prior distribution for * the separable exponential correlation function */ MrExpSep_Prior::MrExpSep_Prior(Corr_Prior *c) : Corr_Prior(c) { MrExpSep_Prior *e = (MrExpSep_Prior*) c; /* sanity check */ assert(e->corr_model == MREXPSEP); /* copy all parameters of the prior */ corr_model = e->corr_model; dupv(gamlin, e->gamlin, 3); nin = e->nin; d = new_dup_vector(e->d, (2*nin)); fix_d = e->fix_d; d_alpha = new_dup_matrix(e->d_alpha, (2*nin), 2); d_beta = new_dup_matrix(e->d_beta, (2*nin), 2); dupv(d_alpha_lambda, e->d_alpha_lambda, 2); dupv(d_beta_lambda, e->d_beta_lambda, 2); r = e->r; delta = e->delta; nugfine = e->nugfine; delta_alpha = new_dup_vector(e->delta_alpha, 2); delta_beta = new_dup_vector(e->delta_beta, 2); nugf_alpha = new_dup_vector(e->nugf_alpha, 2); nugf_beta = new_dup_vector(e->nugf_beta, 2); } /* * ~MrExpSep_Prior: * * destructor for the prior parameterization of the separable * exponential power distribution function */ MrExpSep_Prior::~MrExpSep_Prior(void) { free(d); delete_matrix(d_alpha); delete_matrix(d_beta); free(delta_alpha); free(delta_beta); free(nugf_alpha); free(nugf_beta); } /* * read_double: * * read the double parameter vector giving the user-secified * prior parameterization specified in R */ void MrExpSep_Prior::read_double(double *dparams) { /* read the parameters that have to to with the nugget */ read_double_nug(dparams); /* read the starting value(s) for the range parameter(s) */ for(unsigned int i=0; i<(2*nin); i++) d[i] = dparams[1]; /*myprintf(stdout, "starting d="); printVector(d, (2*nin), stdout); */ /* reset the d parameter to after nugget and gamlin params */ dparams += 13; /* read d gamma mixture prior parameters */ double alpha[2], beta[2]; get_mix_prior_params_double(alpha, beta, dparams, "d"); for(unsigned int i=0; igetline(line, BUFFMAX); d[0] = atof(strtok(line, " \t\n#")); for(unsigned int i=1; i<(2*nin); i++) d[i] = d[0]; myprintf(stdout, "starting d=", d); printVector(d, (2*nin), stdout); /* read d and nug-hierarchical parameters (mix of gammas) */ double alpha[2], beta[2]; ctrlfile->getline(line, BUFFMAX); get_mix_prior_params(alpha, beta, line, "d"); for(unsigned int i=0; i<(2*nin); i++) { dupv(d_alpha[i], alpha, 2); dupv(d_beta[i], beta, 2); } ctrlfile->getline(line, BUFFMAX); get_mix_prior_params(alpha, beta, line, "d"); dupv(delta_alpha, alpha, 2); dupv(delta_beta, beta, 2); ctrlfile->getline(line, BUFFMAX); get_mix_prior_params(alpha, beta, line, "d"); dupv(nugf_alpha, alpha, 2); dupv(nugf_beta, beta, 2); /* d hierarchical lambda prior parameters */ ctrlfile->getline(line, BUFFMAX); strcpy(line_copy, line); if(!strcmp("fixed", strtok(line_copy, " \t\n#"))) { fix_d = true; myprintf(stdout, "fixing d prior\n"); } else { fix_d = false; get_mix_prior_params(d_alpha_lambda, d_beta_lambda, line, "d lambda"); } } /* * default_d_priors: * * set d prior parameters * to default values */ void MrExpSep_Prior::default_d_priors(void) { for(unsigned int i=0; i<(2*nin); i++) { d_alpha[i][0] = 1.0; d_beta[i][0] = 20.0; d_alpha[i][1] = 10.0; d_beta[i][1] = 10.0; } } /* * default_d_lambdas: * * set d (lambda) hierarchical prior parameters * to default values */ void MrExpSep_Prior::default_d_lambdas(void) { d_alpha_lambda[0] = 1.0; d_beta_lambda[0] = 10.0; d_alpha_lambda[1] = 1.0; d_beta_lambda[1] = 10.0; fix_d = false; } /* * D: * * return the default range parameter vector */ double* MrExpSep_Prior::D(void) { return d; } /* * R: * * return the default auto-correlation between fidelities. */ double MrExpSep_Prior::R(void) { return r; } /* * Delta: * * * return the fine fidelity discount factor, delta. */ double MrExpSep_Prior::Delta(void) { return delta; } /* * Nugfine * * * return the fine fidelity observation error. */ double MrExpSep_Prior::Nugfine(void) { return nugfine; } /* * DAlpha: * * return the default/starting alpha matrix for the range * parameter mixture gamma prior */ double** MrExpSep_Prior::DAlpha(void) { return d_alpha; } /* * DBeta: * * return the default/starting beta matrix for the range * parameter mixture gamma prior */ double** MrExpSep_Prior::DBeta(void) { return d_beta; } /* * DeltaAlpha: * * return the default/starting alpha matrix for the scaled variance * parameter mixture gamma prior */ double* MrExpSep_Prior::Delta_alpha(void) { return delta_alpha; } /* * DeltaBeta: * * return the default/starting beta matrix for the scaled variance * parameter mixture gamma prior */ double* MrExpSep_Prior::Delta_beta(void) { return delta_beta; } /* * NugfAlpha: * * return the default/starting alpha for the fine nugget * parameter mixture gamma prior */ double* MrExpSep_Prior::Nugf_alpha(void) { return nugf_alpha; } /* * NugfBeta: * * return the default/starting beta matrix for the fine nugget * parameter mixture gamma prior */ double* MrExpSep_Prior::Nugf_beta(void) { return nugf_beta; } /* * Draw: * * draws for the hierarchical priors for the MrExpSep * correlation function which are contained in the params module * * inputs are howmany number of corr modules */ void MrExpSep_Prior::Draw(Corr **corr, unsigned int howmany, void *state) { /* don't do anything if we're fixing the prior for d */ if(!fix_d) { /* for gathering the d-s of each of the corr models; repeatedly used for each dimension */ double *d = new_vector(howmany); /* for each dimension */ for(unsigned int j=0; j<(2*nin); j++) { /* gather all of the d->parameters for the jth dimension from each of the "howmany" corr modules */ for(unsigned int i=0; iD())[j]; /* use those gathered d values to make a draw for the parameters for the prior of the jth d */ mixture_priors_draw(d_alpha[j], d_beta[j], d, howmany, d_alpha_lambda, d_beta_lambda, state); } /* clean up */ free(d); } /* hierarchical prior draws for the nugget */ DrawNug(corr, howmany, state); } /* * newCorr: * * construct and return a new separable MrExponential correlation * function with this module governing its prior parameterization */ Corr* MrExpSep_Prior::newCorr(void) { return new MrExpSep(col, base_prior); } /* * log_Prior: * * compute the (log) prior for the parameters to * the correlation function (e.g. d and nug) */ double MrExpSep_Prior::log_Prior(double *d, int *b, double *pb, bool linear) { double prob = 0; /* if forcing the LLM, just return zero (i.e. prior=1, log_prior=0) */ if(gamlin[0] < 0) return prob; /* sum the log priors for each of the d-parameters */ for(unsigned int i=0; i<(2*nin); i++) prob += log_d_prior_pdf(d[i], d_alpha[i], d_beta[i]); /* if not allowing the LLM, then we're done */ if(gamlin[0] <= 0) return prob; /* otherwise, get the prob of each of the booleans */ double lin_pdf = linear_pdf_sep(pb, d, (2*nin), gamlin); /* either use the calculated lin_pdf value */ if(linear) prob += log(lin_pdf); else { /* or the sum of the individual pbs */ for(unsigned int i=0; i<(2*nin); i++) { /* probability of linear, or not linear */ if(b[i] == 0) prob += log(pb[i]); else prob += log(1.0 - pb[i]); } } return prob; } /* * log_Dprior_pdf: * * return the log prior pdf value for the vector * of range parameters d */ double MrExpSep_Prior::log_DPrior_pdf(double *d) { double p = 0; for(unsigned int i=0; i<(2*nin); i++) { p += log_d_prior_pdf(d[i], d_alpha[i], d_beta[i]); } return p; } /* * DPrior_rand: * * draw from the joint prior distribution for the * range parameter vector d */ void MrExpSep_Prior::DPrior_rand(double *d_new, void *state) { for(unsigned int j=0; j<(2*nin); j++) d_new[j] = d_prior_rand(d_alpha[j], d_beta[j], state); } /* * BasePrior: * * return the prior for the Base (eg Gp) model */ Base_Prior* MrExpSep_Prior::BasePrior(void) { return base_prior; } /* * SetBasePrior: * * set the base_prior field */ void MrExpSep_Prior::SetBasePrior(Base_Prior *base_prior) { this->base_prior = base_prior; } /* * Print: * * pretty print the correllation function parameters out * to a file */ void MrExpSep_Prior::Print(FILE *outfile) { myprintf(stdout, "corr prior: separable power\n"); /* print nugget stuff first */ PrintNug(outfile); /* range parameter */ /* myprintf(outfile, "starting d=\n"); printVector(d, (2*nin), outfile); */ /* range gamma prior, just print once */ myprintf(outfile, "d[a,b][0]=[%g,%g],[%g,%g]\n", d_alpha[0][0], d_beta[0][0], d_alpha[0][1], d_beta[0][0]); /* print many times, one for each ninension instead? */ /*for(unsigned int i=0; i<(2*nin); i++) { myprintf(outfile, "d[a,b][%d]=[%g,%g],[%g,%g]\n", i, d_alpha[i][0], d_beta[i][0], d_alpha[i][1], d_beta[i][0]); }*/ /* range gamma hyperprior */ if(fix_d) myprintf(outfile, "d prior fixed\n"); else { myprintf(stdout, "d lambda[a,b][0,1]=[%g,%g],[%g,%g]\n", d_alpha_lambda[0], d_beta_lambda[0], d_alpha_lambda[1], d_beta_lambda[1]); } } /* * log_HierPrior: * * return the log prior of the hierarchial parameters * to the correllation parameters (i.e., range and nugget) */ double MrExpSep_Prior::log_HierPrior(void) { double lpdf; lpdf = 0.0; /* mixture prior for the range parameter, d */ if(!fix_d) { for(unsigned int i=0; i