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(); } }
void Restaurant::initializeTables(void) { if (assumingDpp == true) { // Dirichlet process prior model for (int i=0; i<numPatrons; i++) { double probNewTable = concentrationParm / (i + concentrationParm); double u = ranPtr->uniformRv(); bool successfullyAddedPatron = false; if (u < probNewTable) { Table *tab = new Table(this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), lnFactorial); tables.push_back( tab ); tab->addPatronToTable( patrons[i] ); patrons[i]->setTable(tab); successfullyAddedPatron = true; } else { double sum = probNewTable; for (vector<Table *>::iterator p=tables.begin(); p != tables.end(); p++) { sum += (double)(*p)->getNumPatrons() / (i + concentrationParm); if (u < sum) { (*p)->addPatronToTable( patrons[i] ); patrons[i]->setTable( (*p) ); successfullyAddedPatron = true; break; } } } if (successfullyAddedPatron == false) { Stmessage::error("Failed to add patron to table"); return; } } } else { // fixed number of tables for (int i=0; i<modelPtr->getNumPopulations(); i++) tables.push_back( new Table(this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), lnFactorial) ); MbVector<int> patronIndices(numPatrons); for (int i=0; i<numPatrons; i++) patronIndices[i] = i; for (int i=0; i<tables.size(); i++) { int whichPatron = (int)(ranPtr->uniformRv()*(numPatrons-i)); Patron *p = patrons[ patronIndices[whichPatron] ]; tables[i]->addPatronToTable( p ); p->setTable(tables[i]); int tempIdx = patronIndices[numPatrons-i-1]; patronIndices[numPatrons-i-1] = patronIndices[whichPatron]; patronIndices[whichPatron] = tempIdx; } for (int i=tables.size(); i<numPatrons; i++) { int whichPatron = (int)(ranPtr->uniformRv()*(numPatrons-i)); Patron *p = patrons[ patronIndices[whichPatron] ]; int whichTable = (int)(ranPtr->uniformRv()*tables.size()); tables[whichTable]->addPatronToTable( p ); p->setTable(tables[whichTable]); int tempIdx = patronIndices[numPatrons-i-1]; patronIndices[numPatrons-i-1] = patronIndices[whichPatron]; patronIndices[whichPatron] = tempIdx; } } }
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(); } } }