void EEMS::propose_birthdeath_qVoronoi(Proposal &proposal) { int newqtiles = nowqtiles,r; double u = draw.runif(); double pBirth = 0.5; double pDeath = 0.5; boost::math::normal pnorm(0.0,sqrt(nowqrateS2)); proposal.newqEffcts = nowqEffcts; proposal.newqSeeds = nowqSeeds; // If there is exactly one tile, rule out a death proposal if ((nowqtiles==1) || (u<0.5)) { // Propose birth if (nowqtiles==1) { pBirth = 1.0; } newqtiles++; MatrixXd newqSeed = MatrixXd::Zero(1,2); randpoint_in_habitat(newqSeed); pairwise_distance(nowqSeeds,newqSeed).col(0).minCoeff(&r); // The new tile is assigned a rate by perturbing the current rate at the new seed double nowqEffct = nowqEffcts(r); double newqEffct = draw.rtrnorm(nowqEffct,params.qEffctProposalS2,params.qEffctHalfInterval); insertRow(proposal.newqSeeds,newqSeed.row(0)); insertElem(proposal.newqEffcts,newqEffct); // Compute log(proposal ratio) and log(prior ratio) proposal.newratioln = log(pDeath/pBirth) - dtrnormln(newqEffct,nowqEffct,params.qEffctProposalS2,params.qEffctHalfInterval) - log(cdf(pnorm,params.qEffctHalfInterval) - cdf(pnorm,-params.qEffctHalfInterval)); proposal.newpi = nowpi + log((nowqtiles+params.negBiSize)/(newqtiles/params.negBiProb)) - 0.5 * log(nowqrateS2) - 0.5 * newqEffct*newqEffct/nowqrateS2; } else { // Propose death if (nowqtiles==2) { pBirth = 1.0; } newqtiles--; int qtileToRemove = draw.runif_int(0,newqtiles); MatrixXd oldqSeed = nowqSeeds.row(qtileToRemove); removeRow(proposal.newqSeeds,qtileToRemove); removeElem(proposal.newqEffcts,qtileToRemove); pairwise_distance(proposal.newqSeeds,oldqSeed).col(0).minCoeff(&r); double nowqEffct = proposal.newqEffcts(r); double oldqEffct = nowqEffcts(qtileToRemove); // Compute log(prior ratio) and log(proposal ratio) proposal.newratioln = log(pBirth/pDeath) + dtrnormln(oldqEffct,nowqEffct,params.qEffctProposalS2,params.qEffctHalfInterval) + log(cdf(pnorm,params.qEffctHalfInterval) - cdf(pnorm,-params.qEffctHalfInterval)); proposal.newpi = nowpi + log((nowqtiles/params.negBiProb)/(newqtiles+params.negBiSize)) + 0.5 * log(nowqrateS2) + 0.5 * oldqEffct*oldqEffct/nowqrateS2; } proposal.move = Q_VORONOI_BIRTH_DEATH; proposal.newqtiles = newqtiles; proposal.newll = eval_birthdeath_qVoronoi(proposal); }
// solve vp problem using Permutation Pack or Choose Pack vp_solution_t solve_hvp_problem_MinCD(vp_problem_t vp_prob, int args[], qsort_cmp_func *cmp_item_idxs, qsort_cmp_func *cmp_bin_idxs) { int i, j; int unmapped_vectors[vp_prob->num_items]; int num_unmapped_vectors = vp_prob->num_items; int b, v, best_v, best_v_idx; double best_val, val; int bin_idxs[vp_prob->num_bins]; int *open_bins = bin_idxs; int num_open_bins = vp_prob->num_bins; vp_solution_t vp_soln = new_vp_solution(vp_prob); // initialize unmapped vectors and vector dims for (i = 0; i < vp_prob->num_items; i++) unmapped_vectors[i] = i; // initialize open bins for (i = 0; i < vp_prob->num_bins; i++) open_bins[i] = i; if (cmp_bin_idxs) QSORT_R(open_bins, num_open_bins, sizeof(int), vp_prob->bins, cmp_bin_idxs); while (num_open_bins > 0 && num_unmapped_vectors > 0) { b = *open_bins; best_v = -1; best_v_idx = -1; // Find the first vector that can be put in the bin for (i = 0; i < num_unmapped_vectors; i++) { v = unmapped_vectors[i]; if (vp_item_can_fit_in_bin(vp_soln, v, b)) { best_v = v; best_v_idx = i; best_val = pairwise_distance(vp_soln, b, v); break; } } for (i++; i < num_unmapped_vectors; i++) { v = unmapped_vectors[i]; if (!vp_item_can_fit_in_bin(vp_soln, v, b)) continue; val = pairwise_distance(vp_soln, b, v); // FIXME: pick the one that minimizes pairwise distance... if (val < best_val || (val == best_val && cmp_item_idxs && QSORT_CMP_CALL(cmp_item_idxs, vp_prob->items, &v, &best_v) < 0)) { best_v = v; best_v_idx = i; best_val = val; } } // if we found a vector put it in the bin and delete from the list of // unmapped vectors -- otherwise advance to the next bin if (best_v > -1) { vp_put_item_in_bin(vp_soln, best_v, b); num_unmapped_vectors--; unmapped_vectors[best_v_idx] = unmapped_vectors[num_unmapped_vectors]; } else { open_bins++; num_open_bins--; } } if (!num_unmapped_vectors) return vp_soln; free_vp_solution(vp_soln); return NULL; }