/******************************************************* **incrementCurrentDate Description: ** increment current date; increase each Patron's fines ** by 10 cents for each overdue Book they have ** checked out (using amendFine) ** If a book is checked out on day 0, then on day 1, ** the patron has had it for 1 day. On day 21, the ** patron has had it for 21 days, so it is still not ** overdue. On day 22, the book is overdue and ** fines will be charged. *******************************************************/ void Library::incrementCurrentDate() { //increment currentDate first// currentDate++; //loop through Patrons// for (unsigned int pIndex = 0; pIndex < members.size(); pIndex++) { //set local pointer and vector only if the// //Patron has at least one Book checked out// if (members[pIndex]->getCheckedOutBooks().size() > 0) { Patron* pPtr = members[pIndex]; vector<Book*> bVector = pPtr->getCheckedOutBooks(); //loop through Patron's checkedOut Books// for (unsigned int bIndex = 0; bIndex < bVector.size(); bIndex++) { //initiate local variables// int date = bVector[bIndex]->getDateCheckedOut(); int chOutDate = bVector[bIndex]->getCheckOutLength(); //add fine if Book is overdue// if (currentDate > chOutDate + date) pPtr->amendFine(.10); } } } }
/********************************************************************* ** Description: ** applies 10 cent fine to each overdue book by patron per pay *********************************************************************/ void Library::incrementCurrentDate() { int update; Patron* checkOut; string patID; double fineAMT; fineAMT = .10; for( int i = 0; i < holdings.size(); i++) { if(holdings[i]->getLocation() != 0) { update = holdings[i]->getDateCheckedOut() + 1; holdings[i]->setDateCheckedOut(update); if((holdings[i]->getDateCheckedOut() - currentDate) > 21) { // fine applied. checkOut = holdings[i]->getCheckedOutBy(); patID = checkOut->getIdNum(); members[i]->amendFine(fineAMT); } } } currentDate++; cout << "The new date is " << currentDate; }
/* ---------------------------------buildPatrons-------------------------------- buildPatrons - creates patrons from the data file and hands them to the library to appropriately manage. PreConditions: File must be in the valid format, defined for Assignment #3. PostConditions: Every line is read, processed, and each patron generated from the process is handed to the library to insert into the data structures. */ void Manager::buildPatrons() { int inputID = -1; std::string inputName; //While we have stuff to process from the data file... while(!patronsStream.eof()) { inputID = -1; patronsStream >> inputID; //Is the Patron ID valid? if(inputID >= 0 && inputID < MAX_PATRON_SIZE) { //Yes! Let's process the input data and add them to the patron //data structure. patronsStream.get(); getline(patronsStream, inputName); Patron* inputPatron = new Patron(); inputPatron->setName(inputName); inputPatron->setID(inputID); bool inserted = MyLibrary.insert(inputPatron); //delete inputPatron if we are unable to insert them if(inserted == false) { delete inputPatron; } inputPatron = NULL; inputID = -1; //Patron ID is invalid, so we throw away the rest of the line. } else { getline(patronsStream, inputName); } } patronsStream.close(); }
/******************************************************* **returnBook Description: ** if the specified Book is not in the Library, return ** "book not found" ** if the Book is not checked out, return "book already ** in library" ** update the Patron's checkedOutBooks; update the ** Book's location depending on whether another ** Patron has requested it; update the Book's ** checkedOutBy; return "return successful" *******************************************************/ string Library::returnBook(std::string bID) { //find if Book exists// if (getBook(bID) == NULL) return "Book was not found."; //find if Book // if (getBook(bID)->getLocation() != CHECKED_OUT) return "Book is already in Library."; else { //initiate local pointers if Book exists and is not CHECKED_OUT// Book* bPtr = getBook(bID); Patron* pPtr = bPtr->getCheckedOutBy(); //remove Book from Patron's checkOutBooks// pPtr->removeBook(bPtr); //set Book's location based on request status// if (bPtr->getRequestedBy() == NULL) bPtr->setLocation(ON_SHELF); else bPtr->setLocation(ON_HOLD_SHELF); //set Book's checkedOutBy// bPtr->setCheckedOutBy(NULL); //return was successful// return "Return successful."; } }
/********************************************************************* ** Description: ** returns a pointer to a memeber pased off their ID *********************************************************************/ Patron* Library:: getPatron(std::string pID) { Patron* patron; if(checkMember(pID)!=true) { for(int i = 0; i < members.size(); i++) { if(members[i]->getIdNum() == pID) { cout << "Name : " << members[i]->getName() << endl; cout << "ID : " << members[i]->getIdNum() << endl; //Set the dollar format cout << "Fines $" << members[i]->getFineAmount() << endl; //checkouted books cout << "Books Checked Out" << endl; for( int j = 0; j < holdings.size(); j++) { patron = holdings[j]->getCheckedOutBy(); if(pID == patron->getIdNum()) { cout << "Book Name " << holdings[j]->getTitle() << endl; } } } } } else { cout << "Patron not in system" << endl; } return 0; }
void Restaurant::initializeAdmixtureProportions(void) { // set up vectors for admixture if (assumingAdmixture == true && assumingDpp == false) { // what type of prior are we placing on the mixing proportions? if (settingsPtr->getAdmixtureDist() == "fixed") admixtureVarianceParm = settingsPtr->getAdmixtureParm1(); else if (settingsPtr->getAdmixtureDist() == "exponential") admixtureVarianceParm = ranPtr->exponentialRv( settingsPtr->getAdmixtureParm1() ); else if (settingsPtr->getAdmixtureDist() == "uniform") admixtureVarianceParm = ranPtr->uniformRv( settingsPtr->getAdmixtureParm1(), settingsPtr->getAdmixtureParm2() ); else if (settingsPtr->getAdmixtureDist() == "gamma") admixtureVarianceParm = ranPtr->gammaRv( settingsPtr->getAdmixtureParm1(), settingsPtr->getAdmixtureParm2() ); // get the upper and lower limits for the admixture variance parameter if (settingsPtr->getAdmixtureDist() == "uniform") { admixtureLowerLimit = settingsPtr->getAdmixtureParm1(); admixtureUpperLimit = settingsPtr->getAdmixtureParm2(); } else if (settingsPtr->getAdmixtureDist() == "exponential") { admixtureLowerLimit = 0.001; admixtureUpperLimit = ( 1.0 / settingsPtr->getAdmixtureParm1() ) * 100.0; } else if (settingsPtr->getAdmixtureDist() == "gamma") { admixtureLowerLimit = 0.001; admixtureUpperLimit = ( settingsPtr->getAdmixtureParm1() / settingsPtr->getAdmixtureParm2() ) * 100.0; } // initialize the counts and probabilities for the mixing proportions popCounts = new MbVector<int>[observationsPtr->getNumIndividuals()]; popProbs = new MbVector<double>[observationsPtr->getNumIndividuals()]; for (int i=0; i<observationsPtr->getNumIndividuals(); i++) { popCounts[i] = MbVector<int>(modelPtr->getNumPopulations()); popProbs[i] = MbVector<double>(modelPtr->getNumPopulations()); MbVector<double> alp( modelPtr->getNumPopulations() ); for (int j=0; j<modelPtr->getNumPopulations(); j++) alp[j] = admixtureVarianceParm / modelPtr->getNumPopulations(); ranPtr->dirichletRv(alp, popProbs[i]); for (int j=0; j<modelPtr->getNumPopulations(); j++) popCounts[i][j] = 0; } for (int i=0; i<getNumTables(); i++) { Table *tp = getTable(i); for (int j=0; j<tp->getNumPatrons(); j++) { Patron *p = tp->getPatron(j); popCounts[ p->getIndividual() ][ i ]++; } } } }
TEST_F(PatronTest, CreateDefaultsAllFields) { Patron nobody; ASSERT_THAT(nobody.Name(), Eq("")); ASSERT_THAT(nobody.Id(), Eq(0)); ASSERT_THAT(nobody.FineBalance(), Eq(0)); }
/********************************************************************* ** Description: ** Allows a patron to request a book not on shelf based off enums *********************************************************************/ string Library::requestBook(string patronID, string bookID) { Patron* patID; if(checkBook(bookID) != true) { for( int i = 0; i < holdings.size(); i++) { //Puts book on hold if(holdings[i]->getIdCode() == bookID) { // if currently on shelf if(holdings[i]->getLocation() == 0) { holdings[i]->setLocation(ON_HOLD_SHELF); //Connects Hold to a Patron for(int j = 0; j < members.size(); j++) { if(members[j]->getIdNum() == patronID) { holdings[i]->setRequestedBy(members[j]); cout << holdings[i]->getTitle() << " is now on hold for " << members[j]->getName() << endl; } } } // if currently on hold else if(holdings[i]->getLocation() == 1) { cout << "Already on hold by " << holdings[i]->getRequestedBy() << endl; } else { for(int j = 0; j < members.size(); j++) { //if person already has book checked out patID = holdings[i]->getCheckedOutBy(); if(patID->getIdNum() == patronID) { cout << "Already checked out by " << (holdings[i])->getRequestedBy() << endl; } else { holdings[i]->setRequestedBy(members[j]); cout << holdings[i]->getTitle() << " is now on hold for " << members[j]->getName() << endl; } } } } } } else { cout << "book not found" << endl; } return 0; }
/******************************************************************** * void Library::viewBookInfo(std::string bookID) * * Purpose: This function prints the information of the Book object * that matches the specified bookID to the console. * * Preconditions: none * * Postconditions: The information of the Book object is printed to * the console window. *******************************************************************/ void Library::viewBookInfo(std::string bookID) { // declare variable and set to book index int bIndex = findBook(bookID); // validate bookID if (bIndex < 0) { std::cout << "\nThat book ID was not found in the library database.\n"; return; } // print book ID, title and author std::cout << "\nInformation on book ID " << holdings[bIndex].getIdCode() << "\n Title: " << holdings[bIndex].getTitle() << "\n Author: " << holdings[bIndex].getAuthor(); // print book location std::cout << "\n Location: "; switch (holdings[bIndex].getLocation()) { case CHECKED_OUT: std::cout << "Checked out\n"; break; case ON_HOLD: std::cout << "On hold\n"; break; case ON_SHELF: std::cout << "On the shelf\n"; } std::cout << std::endl; // print requestedBy if book has been requested Patron *pPatron = holdings[bIndex].getRequestedBy(); if (pPatron != NULL) std::cout << " This book has been requested by " << pPatron->getName() << ".\n"; // print checkedOutBy and due date if book is checked out pPatron = holdings[bIndex].getCheckedOutBy(); if (pPatron != NULL) { std::cout << " This book is checked out by " << pPatron->getName() << ".\n"; // get due date and print appropriate message int due = holdings[bIndex].getDateCheckedOut() + Book::CHECK_OUT_LENGTH; if (due == currentDate) std::cout << " It is due on day " << due << ", which is today.\n"; else if (due > currentDate) std::cout << " It is due on day " << due << ", " << "which is in " << due - currentDate << " days.\n"; else std::cout << " It is due on day " << due << ", " << "which was " << currentDate - due << " days ago.\n"; } }
void checkin(Patron& p, Book& b) { /* this function receives by reference a patron and book instance changes relevant checkout status returns nothing */ b.setCheckOutStatus(0);//sets book checkout status p.setBorrowedIn(b);//resets array to not include returned book p.setNumberBorrowedIn();//reduces borrowed number by 1 }
void reportCheckout(Patron p, Book b, int test) { /*receives a patron, book and the test value based on test value prints out if book is checked out to patron returns nothing */ if (test==1) cout<< b.getID()<<" is checked out to "<<p.getID()<<".\n"; else cout<<b.getID()<<" could not be checked out to "<< p.getID()<<".\n"; }
TEST_F(HoldingServiceTest, CheckInUpdatesPatronHoldings) { HoldingBarcode barcode(THE_TRIAL_CLASSIFICATION, 1); string patronId("p5"); CheckOut(barcode, branch1, patronId); holdingService.CheckIn(barcode.AsString(), *arbitraryDate + date_duration(1), branch2->Id()); Patron retrieved = FindPatronWithId(patronId); ASSERT_THAT(retrieved.Holdings().size(), Eq(0)); }
TEST_F(PatronAccessTest, FindByNameReturnsChronologicallyFirstMatch) { Patron match1("Langr", 1); access.Save(match1); Patron mismatch("Long", 2); access.Save(mismatch); Patron match2("Langr", 3); access.Save(match2); Patron found = access.FindByName("Langr"); ASSERT_THAT(found.Id(), Eq(1)); }
void Library::check_out_book(const chrono::Date& d,const Patron& p,Book& b) { if(!book_exists(b) || !patron_exists(p)) { throw std::runtime_error("patron or book doesnt exist"); } if(p.has_fee()) { throw std::runtime_error("patron has a fee: " + p.amount_fees_owed()); } transactions.push_back(Transactions(d,p,b)); b.check_out(); }
int main() { Patron PatronInOut; ifstream ifs("Patrons.txt", ifstream::in); if (ifs.is_open()) { while (PatronInOut.readPatron(ifs)) PatronInOut.writePatron(cout) << endl; // close the file after finish reading. ifs.close(); } else { cout << "Can't open file." << endl; } return 0; }
//Takes a patron and book ID //Checks to make sure that the patron and book exist, returns if they dont //If book is on hold, only check out to that patron //If the book is on the shelf, it's fair game, set proper values. void Library::checkOutBook(std::string patronID, std::string bookID) { Book* book = GetBook(bookID); Patron* patron = GetPatron(patronID); if(book == NULL || patron == NULL) { if(book == NULL) { std::cout << std::endl << "No such book in holdings." << std::endl; } if(patron == NULL) { std::cout << std::endl << "No such patron in records." << std::endl; } return; } if(book->getLocation() == CHECKED_OUT) { std::cout << "This book is already checked out." << std::endl << std::endl; } else if(book->getLocation() == ON_HOLD) { if(book->getRequestedBy()->getIdNum() == patron->getIdNum()) { book->setLocation(CHECKED_OUT); book->setCheckedOutBy(GetPatron(patronID)); book->setDateCheckedOut(currentDate); book->setRequestedBy(NULL); patron->addBook(book); } else { std::cout << "This book is on hold and can only be checked out to requestee." << std::endl <<std::endl; } } else { book->setLocation(CHECKED_OUT); book->setCheckedOutBy(patron); book->setDateCheckedOut(currentDate); patron->addBook(book); } }
void HoldingService::ApplyFine(Patron& patronWithHolding, Holding& holding) { unsigned int daysLate = CalculateDaysPastDue(holding); ClassificationService service; Book book = service.RetrieveDetails(holding.Classification()); patronWithHolding.ApplyFine(book, daysLate); }
//Same as above. Uses viewBookInfo to print books checked out to a patron. void Library::viewPatronInfo(std::string patronID) { Patron* patron = GetPatron(patronID); if(patron == NULL) { std::cout << std::endl << "That patron does not exist!" << std::endl; } else { std::cout << std::endl << "Patron ID: " << patron->getIdNum() << std::endl; std::cout << "Name: " << patron->getName() << std::endl; std::cout << "Fines: $" << std::setprecision(2) << std::fixed << patron->getFineAmount() << std::endl; if(patron->getCheckedOutBooks().size() == 0) { std::cout << "No checked out books." << std::endl << std::endl; } else { std::cout << "Checked out books:" << std::endl << std::endl; for(int i = 0; i < patron->getCheckedOutBooks().size(); i++) { viewBookInfo(patron->getCheckedOutBooks().at(i)->getIdCode()); } std::cout << std::endl << std::endl; } } }
//添加读者 void AddPatron(Patron newPatron ) { cout<<"新操作:\t录入读者信息"<<endl; cout<<"准备就绪..."<<endl; if(aPatron.size()>0) for(int i=0;i<aPatron.size();i++) if (aPatron[i].GetCardNum()==newPatron.GetCardNum()) { cout<<"读者已经存在"<<endl<<"操作未完成"<<endl<<endl; return ; } cout<<"正在录入读者信息..."<<endl; aPatron.push_back(newPatron); cout<<"操作完成!"<<endl<<endl; newPatron.DisplayInfo(); }
bool Kasiski::noExiste(Patron patron){ bool noEncontrado = true; list<Patron>::iterator it = this->listaPatrones.begin(); while ((it != this->listaPatrones.end()) and noEncontrado ){ if ( patron.getPalabra() == it->getPalabra() ) noEncontrado = false; it++; } return noEncontrado; }
void DisplayInfo() { cout<<"借阅信息------------------------------"<<endl; cout<<"图书信息----------------"<<endl; cout<<"书名:\t\t"<<inBook.GetName()<<endl; cout<<"作者:\t\t"<<inBook.GetAuthor()<<endl; cout<<"ISBN号:\t"<<inBook.GetISBNNum()<<endl; cout<<"出版日期:\t"<<inBook.GetDat()<<endl; cout<<"读者信息-----------------"<<endl; cout<<"姓名:\t\t"<<inPatron.GetName()<<endl; cout<<"图书卡号:\t"<<inPatron.GetCardNum()<<endl; cout<<"借书日期:\t"<<inDate.GetYear()<<"-"<<inDate.GetMonth()<<"-"<<inDate.GetDay()<<endl; if(inPatron.IsOwed()) cout<<"欠费信息:\t欠费"<<inPatron.GetOweCount()<<"元"<<endl; else cout<<"欠费信息:\t无欠费记录"<<endl; cout<<endl; }
void HoldingService::CheckIn( const string& barCode, date date, const string& branchId) { Branch branch(branchId); mBranchService.Find(branch); Holding holding(barCode); FindByBarCode(holding); holding.CheckIn(date, branch); mCatalog.Update(holding); Patron patronWithBook = FindPatron(holding); patronWithBook.ReturnHolding(holding); if (IsLate(holding, date)) ApplyFine(patronWithBook, holding); mPatronService.Update(patronWithBook); }
void Library::check_out(Patron p, Book b) { // Checks out a book in the library if (!find_book(b)) throw Library_error{}; if (!find_patron(p)) throw Library_error{}; if (p.check_fee()) { // Check if patron owes a fee char ch; cout << "This patron owes fee. Do you want to issue him the book(s)? (y or n)" << endl; cin >> ch; if (ch == 'n') return; if (ch != 'y') error("Wrong character detected\n"); }
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(); } }
/******************************************************* **checkOutBook Description: ** if the specified Book is not in the Library, ** return "book not found" ** if the specified Patron is not in the Library, ** return "patron not found" ** if the specified Book is already checked out, ** return "book already checked out" ** if the specified Book is on hold by another ** Patron, return "book on hold by other patron" ** otherwise update the Book's checkedOutBy, ** dateCheckedOut and Location; if the Book ** was on hold for this Patron, update requestedBy; ** update the Patron's checkedOutBooks; return ** "check out successful" *******************************************************/ string Library::checkOutBook(string pID, string bID) { //find if Book and/or Patron exist// if (getBook(bID) == NULL) return "Book not found."; if (getPatron(pID) == NULL) return "Patron not found."; else { //initiate local pointers if Book and Patron exist// Book* bPtr = getBook(bID); Patron* pPtr = getPatron(pID); //find location of Book// if (bPtr->getLocation() == CHECKED_OUT) return "Book already checked out."; else if (bPtr->getLocation() == ON_HOLD_SHELF && bPtr->getRequestedBy() != pPtr) return "Book is on hold by another Patron."; //set Book's checkedOutBy, dateCheckedOut, location & requestedBy// else { bPtr->setCheckedOutBy(pPtr); bPtr->setDateCheckedOut(currentDate); bPtr->setLocation(CHECKED_OUT); bPtr->setRequestedBy(NULL); //add Book to Patron's checkedOutBooks// pPtr->addBook(bPtr); //check out was successful// return "Check out successful."; } } }
//Return a book, if it is not already on the shelf. void Library::returnBook(std::string bookID) { Book* book = GetBook(bookID); if(book == NULL) { std::cout << std::endl << "No such book in holdings." << std::endl << std::endl; return; } if(book->getLocation() == ON_SHELF) { std::cout << "This book is already on the shelf." << std::endl; } else if(book->getLocation() == ON_HOLD) { std::cout << "This book is on the hold shelf and cannot be returned." << std::endl; } else { Patron* patron = book->getCheckedOutBy(); if(book->getRequestedBy() == NULL) { book->setLocation(ON_SHELF); book->setCheckedOutBy(NULL); book->setDateCheckedOut(-1); patron->removeBook(book); } else { book->setLocation(ON_HOLD); book->setCheckedOutBy(NULL); book->setDateCheckedOut(-1); patron->removeBook(book); } } }
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; }
int checkout(Patron& p, Book& b) { /* receives by reference a patron and book instance tests whether the patron can borrow the book and changes the appropriate attributes if yes returns 1 if checkout is successful and 0 if not */ if (p.getNumberBorrowed() <5) //tests if patron can borrow book and still be within max amount { if (b.getCheckOutStatus()==0) //tests if book is already checked out { b.setCheckOutStatus(1);//changes checkout status of book instance p.setBorrowed(b); //adds book to patron attribute "borrowed" p.setNumberBorrowedOut(); //adds 1 to numberBorrowed return 1; } else { return 0; } } else { return 0; } }
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; } } }