void Restaurant::updateSeatingForDpp(void) { for (int idx=0; idx<numPatrons; idx++) { // get a pointer to the element and its current table Patron *p = patrons[idx]; Table *tablePtr = p->getTable(); // remove the element from the table tablePtr->removePatronFromTable(p); if (tablePtr->getNumPatrons() == 0) deleteTable(tablePtr); // calculate the likelihood when the element is seated at all possible tables vector<double> probs; for (int i=0; i<getNumTables(); i++) { Table *tp = getTable(i); probs.push_back( tp->lnLikelihood(p) + log(tp->getNumPatrons()) ); } probs.push_back( p->getLnLikelihoodalone() + log(concentrationParm) ); normalizeVector( probs ); // pick a table for reassignment int whichTable = multinomialRv(probs); // add the element to that table if (whichTable < getNumTables()) { tablePtr = getTable(whichTable); tablePtr->addPatronToTable(p); } else { tablePtr = new Table(this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), lnFactorial); addTableToRestaurant( tablePtr ); tablePtr->addPatronToTable(p); } } }
void Restaurant::updateSeatingForFixedTables(void) { // allocate memory for reassignment probabilities vector<double> probs; // loop over all patrons, attempting to reseat each for (int idx=0; idx<numPatrons; idx++) { // get a pointer to the element and its current table Patron *p = patrons[idx]; Table *tablePtr = p->getTable(); // remove the element from the table tablePtr->removePatronFromTable(p); if (assumingAdmixture == true) popCounts[ p->getIndividual() ][ getIndexForTable(tablePtr) ]--; // calculate the likelihood when the element is seated at all possible tables for (int i=0; i<getNumTables(); i++) { Table *tp = getTable(i); double lnC = 0.0; if (assumingAdmixture == true) lnC = log( popProbs[ p->getIndividual() ][ i ] ); probs.push_back( tp->lnLikelihood(p) + lnC ); } normalizeVector( probs ); // pick a table for reassignment tablePtr = getTable( multinomialRv(probs) ); // add the element to that table tablePtr->addPatronToTable(p); if (assumingAdmixture == true) popCounts[ p->getIndividual() ][ getIndexForTable(tablePtr) ]++; // clear the probs vector probs.clear(); } }
double Restaurant::lnPriorProbability(void) { if (assumingAdmixture == false && assumingDpp == false) { // fixed number of populations with no admixture return -numPatrons * log(getNumTables()); } else if (assumingAdmixture == true && assumingDpp == false) { // fixed number of poulations with admixture double lnP = 0.0; for (int idx=0; idx<numPatrons; idx++) { Patron *p = patrons[idx]; Table *tablePtr = p->getTable(); lnP += log(popProbs[ p->getIndividual() ][ getIndexForTable(tablePtr) ]); } return lnP; } else if (assumingAdmixture == false && assumingDpp == true) { // number of populations is a random variable, but no admixture /* f({\mathbf z}, k | \alpha, c) = \alpha^k {\prod_{i=1}^k(\eta_i - 1)! \over \prod_{i=1}^c(\alpha + i - 1)} */ double lnSum1 = 0.0; for (vector<Table *>::iterator p=tables.begin(); p != tables.end(); p++) { lnSum1 += lnFactorial[ (*p)->getNumPatrons() - 1 ]; } double lnSum2 = 0.0; for (int i=1; i<=numPatrons; i++) lnSum2 += log(concentrationParm + i - 1.0); double lnP = getNumTables() * log(concentrationParm) + lnSum1 - lnSum2; return lnP; } return 0.0; }
void Franchise::updateSeating(void) { // loop over the restaurants for (vector<Restaurant *>::iterator r=restaurants.begin(); r != restaurants.end(); r++) { // loop over the patrons in a restaurant for (int idx=0; idx<(*r)->getNumPatronsInRestaurant(); idx++) { // get a pointer to the patron and its current table Patron *p = (*r)->getRestaurantPatron(idx); Table *tablePtr = p->getTable(); Menu *menuItemPtr = tablePtr->getMenuItem(); // remove the element from the table tablePtr->removePatronFromTable(p); if (tablePtr->getNumPatrons() == 0) { menuItemPtr->deleteTableFromMenu(tablePtr); if (menuItemPtr->getNumTables() == 0) deleteMenuItem(menuItemPtr); (*r)->deleteTable(tablePtr); } // calculate the probability of reseating patron at each of the tables int n = (*r)->getNumTables() + 1; vector<double> probs; for (int i=0; i<(*r)->getNumTables(); i++) { Table *t = (*r)->getTable(i); Menu *m = t->getMenuItem(); int n_jt = t->getNumPatrons(); probs.push_back( m->lnLikelihood(p) + log(n_jt) ); } vector<double> lnProbsNew; probs.push_back( log(restaurantAlpha) + lnLikelihoodNewTable(p, lnProbsNew) ); (*r)->normalizeVector(probs); // pick a table int whichTable = (*r)->multinomialRv( probs ); Table *newTablePtr = NULL; if (whichTable < n-1) newTablePtr = (*r)->getTable(whichTable); // seat the patron if (newTablePtr == NULL) { // we are seating the patron at a new table, which may have an already used menu item, or a brand new menu item Table *newRestaurantTablePtr = new Table( (*r), ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), (*r)->getFactorialPtr() ); newRestaurantTablePtr->addPatronToTable( p ); (*r)->addTableToRestaurant( newRestaurantTablePtr ); (*r)->normalizeVector(lnProbsNew); whichTable = (*r)->multinomialRv( lnProbsNew ); Menu *newMenuItemPtr = NULL; if (whichTable < lnProbsNew.size()-1) { newMenuItemPtr = menus[whichTable]; } else { newMenuItemPtr = new Menu( this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), (*r)->getFactorialPtr() ); menus.push_back( newMenuItemPtr ); } newMenuItemPtr->addTableToMenu( newRestaurantTablePtr ); newRestaurantTablePtr->setMenuItem(newMenuItemPtr); } else { // otherwise, we are seating the element at one of the pre-existing tables newTablePtr->addPatronToTable( p ); } //print(); //getchar(); } } }