public DistanceDependentCRPGibbsOperator( Parameter links, Parameter assignments, Parameter chiParameter, NPAntigenicLikelihood Likelihood, double weight) { this.links = links; this.assignments = assignments; this.modelLikelihood = Likelihood; this.chiParameter = chiParameter; this.depMatrix = Likelihood.getLogDepMatrix(); for (int i = 0; i < links.getDimension(); i++) { links.setParameterValue(i, i); } setWeight(weight); // double[][] x=modelLikelihood.getData(); // modelLikelihood.printInformtion(x[0][0]); this.m = new double[2]; m[0] = modelLikelihood.priorMean.getParameterValue(0); m[1] = modelLikelihood.priorMean.getParameterValue(1); this.v0 = 2; this.k0 = modelLikelihood.priorPrec.getParameterValue(0) / modelLikelihood.clusterPrec.getParameterValue(0); this.T0Inv = new double[2][2]; T0Inv[0][0] = v0 / modelLikelihood.clusterPrec.getParameterValue(0); T0Inv[1][1] = v0 / modelLikelihood.clusterPrec.getParameterValue(0); T0Inv[1][0] = 0.0; T0Inv[0][1] = 0.0; this.logDetT0 = -Math.log(T0Inv[0][0] * T0Inv[1][1]); }
/** change the parameter and return the hastings ratio. */ public final double doOperation() { int index = MathUtils.nextInt(links.getDimension()); int oldGroup = (int) assignments.getParameterValue(index); /* * Set index customer link to index and all connected to it to a new assignment (min value empty) */ int minEmp = minEmpty(modelLikelihood.getLogLikelihoodsVector()); links.setParameterValue(index, index); int[] visited = connected(index, links); int ii = 0; while (visited[ii] != 0) { assignments.setParameterValue(visited[ii] - 1, minEmp); ii++; } /* * Adjust likvector for group separated */ modelLikelihood.setLogLikelihoodsVector(oldGroup, getLogLikGroup(oldGroup)); modelLikelihood.setLogLikelihoodsVector(minEmp, getLogLikGroup(minEmp)); int maxFull = maxFull(modelLikelihood.getLogLikelihoodsVector()); double[] liks = modelLikelihood.getLogLikelihoodsVector(); /* * computing likelihoods of joint groups */ double[] crossedLiks = new double[maxFull + 1]; for (int ll = 0; ll < maxFull + 1; ll++) { if (ll != minEmp) { crossedLiks[ll] = getLogLik2Group(ll, minEmp); } } /* * Add logPrior */ double[] logP = new double[links.getDimension()]; for (int jj = 0; jj < links.getDimension(); jj++) { logP[jj] += depMatrix[index][jj]; int n = (int) assignments.getParameterValue(jj); if (n != minEmp) { logP[jj] += crossedLiks[n] - liks[n] - liks[minEmp]; } } logP[index] = Math.log(chiParameter.getParameterValue(0)); /* * possibilidade de mandar p zero as probs muito pequenas */ /* * Gibbs sampling */ this.rescale(logP); // Improve numerical stability this.exp(logP); // Transform back to probability-scale int k = MathUtils.randomChoicePDF(logP); links.setParameterValue(index, k); int newGroup = (int) assignments.getParameterValue(k); ii = 0; while (visited[ii] != 0) { assignments.setParameterValue(visited[ii] - 1, newGroup); ii++; } /* * updating conditional likelihood vector */ modelLikelihood.setLogLikelihoodsVector(newGroup, getLogLikGroup(newGroup)); if (newGroup != minEmp) { modelLikelihood.setLogLikelihoodsVector(minEmp, 0); } sampleMeans(maxFull); return 0.0; }
public void sampleMeans(int maxFull) { double[][] means = new double[maxFull + 2][2]; // sample mean vector for each cluster for (int i = 0; i < maxFull + 1; i++) { // Find all elements in cluster int ngroup = 0; for (int ii = 0; ii < assignments.getDimension(); ii++) { if ((int) assignments.getParameterValue(ii) == i) { ngroup++; } } if (ngroup != 0) { double[][] group = new double[ngroup][2]; double[] groupMean = new double[2]; int count = 0; for (int ii = 0; ii < assignments.getDimension(); ii++) { if ((int) assignments.getParameterValue(ii) == i) { group[count][0] = modelLikelihood.getData()[ii][0]; group[count][1] = modelLikelihood.getData()[ii][1]; groupMean[0] += group[count][0]; groupMean[1] += group[count][1]; count += 1; } } groupMean[0] /= ngroup; groupMean[1] /= ngroup; double kn = k0 + ngroup; double vn = v0 + ngroup; double[][] sumdif = new double[2][2]; for (int jj = 0; jj < ngroup; jj++) { sumdif[0][0] += (group[jj][0] - groupMean[0]) * (group[jj][0] - groupMean[0]); sumdif[0][1] += (group[jj][0] - groupMean[0]) * (group[jj][1] - groupMean[1]); sumdif[1][0] += (group[jj][0] - groupMean[0]) * (group[jj][1] - groupMean[1]); sumdif[1][1] += (group[jj][1] - groupMean[1]) * (group[jj][1] - groupMean[1]); } double[][] TnInv = new double[2][2]; TnInv[0][0] = T0Inv[0][0] + ngroup * (k0 / kn) * (groupMean[0] - m[0]) * (groupMean[0] - m[0]) + sumdif[0][0]; TnInv[0][1] = T0Inv[0][1] + ngroup * (k0 / kn) * (groupMean[1] - m[1]) * (groupMean[0] - m[0]) + sumdif[0][1]; TnInv[1][0] = T0Inv[1][0] + ngroup * (k0 / kn) * (groupMean[0] - m[0]) * (groupMean[1] - m[1]) + sumdif[1][0]; TnInv[1][1] = T0Inv[1][1] + ngroup * (k0 / kn) * (groupMean[1] - m[1]) * (groupMean[1] - m[1]) + sumdif[1][1]; Matrix Tn = new SymmetricMatrix(TnInv).inverse(); double[] posteriorMean = new double[2]; // compute posterior mean posteriorMean[0] = (k0 * m[0] + ngroup * groupMean[0]) / (k0 + ngroup); posteriorMean[1] = (k0 * m[1] + ngroup * groupMean[1]) / (k0 + ngroup); // compute posterior Precision double[][] posteriorPrecision = new WishartDistribution(vn, Tn.toComponents()).nextWishart(); posteriorPrecision[0][0] *= kn; posteriorPrecision[1][0] *= kn; posteriorPrecision[0][1] *= kn; posteriorPrecision[1][1] *= kn; double[] sample = new MultivariateNormalDistribution(posteriorMean, posteriorPrecision) .nextMultivariateNormal(); means[i][0] = sample[0]; means[i][1] = sample[1]; } } // Fill in cluster means for each observation for (int j = 0; j < assignments.getDimension(); j++) { double[] group = new double[2]; group[0] = means[(int) assignments.getParameterValue(j)][0]; group[1] = means[(int) assignments.getParameterValue(j)][1]; modelLikelihood.setMeans(j, group); } }
public double getLogLik2Group(int group1, int group2) { double L = 0.0; int ngroup1 = 0; for (int i = 0; i < assignments.getDimension(); i++) { if ((int) assignments.getParameterValue(i) == group1) { ngroup1++; } } int ngroup2 = 0; for (int i = 0; i < assignments.getDimension(); i++) { if ((int) assignments.getParameterValue(i) == group2) { ngroup2++; } } int ngroup = (ngroup1 + ngroup2); if (ngroup != 0) { double[][] group = new double[ngroup][2]; double mean[] = new double[2]; int count = 0; for (int i = 0; i < assignments.getDimension(); i++) { if ((int) assignments.getParameterValue(i) == group1) { group[count][0] = modelLikelihood.getData()[i][0]; group[count][1] = modelLikelihood.getData()[i][1]; mean[0] += group[count][0]; mean[1] += group[count][1]; count += 1; } } for (int i = 0; i < assignments.getDimension(); i++) { if ((int) assignments.getParameterValue(i) == group2) { group[count][0] = modelLikelihood.getData()[i][0]; group[count][1] = modelLikelihood.getData()[i][1]; mean[0] += group[count][0]; mean[1] += group[count][1]; count += 1; } } mean[0] /= ngroup; mean[1] /= ngroup; double kn = k0 + ngroup; double vn = v0 + ngroup; double[][] sumdif = new double[2][2]; for (int i = 0; i < ngroup; i++) { sumdif[0][0] += (group[i][0] - mean[0]) * (group[i][0] - mean[0]); sumdif[0][1] += (group[i][0] - mean[0]) * (group[i][1] - mean[1]); sumdif[1][0] += (group[i][0] - mean[0]) * (group[i][1] - mean[1]); sumdif[1][1] += (group[i][1] - mean[1]) * (group[i][1] - mean[1]); } double[][] TnInv = new double[2][2]; TnInv[0][0] = T0Inv[0][0] + ngroup * (k0 / kn) * (mean[0] - m[0]) * (mean[0] - m[0]) + sumdif[0][0]; TnInv[0][1] = T0Inv[0][1] + ngroup * (k0 / kn) * (mean[1] - m[1]) * (mean[0] - m[0]) + sumdif[0][1]; TnInv[1][0] = T0Inv[1][0] + ngroup * (k0 / kn) * (mean[0] - m[0]) * (mean[1] - m[1]) + sumdif[1][0]; TnInv[1][1] = T0Inv[1][1] + ngroup * (k0 / kn) * (mean[1] - m[1]) * (mean[1] - m[1]) + sumdif[1][1]; double logDetTn = -Math.log(TnInv[0][0] * TnInv[1][1] - TnInv[0][1] * TnInv[1][0]); L += -(ngroup) * Math.log(Math.PI); L += Math.log(k0) - Math.log(kn); L += (vn / 2) * logDetTn - (v0 / 2) * logDetT0; L += GammaFunction.lnGamma(vn / 2) + GammaFunction.lnGamma((vn / 2) - 0.5); L += -GammaFunction.lnGamma(v0 / 2) - GammaFunction.lnGamma((v0 / 2) - 0.5); } return L; }