Program Listing for File SpeciesList.cpp¶
↰ Return to documentation for file (necsim/SpeciesList.cpp
)
//This file is part of necsim project which is released under MIT license.
//See file **LICENSE.txt** or visit https://opensource.org/licenses/MIT) for full license details.
#include <iostream>
#include "SpeciesList.h"
namespace necsim
{
SpeciesList::SpeciesList() : list_size(0), max_size(0), next_active(0), lineage_indices(), nwrap(0)
{
}
void SpeciesList::initialise(unsigned long maxsizein)
{
max_size = maxsizein;
nwrap = 0;
list_size = 0;
}
void SpeciesList::setMaxsize(unsigned long maxsizein)
{
max_size = maxsizein;
}
void SpeciesList::setSpecies(unsigned long index, unsigned long new_val)
{
#ifdef DEBUG
if(index >= lineage_indices.size())
{
throw out_of_range("List index to change value is out of range of vector size. Please report this bug.");
}
#endif //DEBUG
if(lineage_indices[index] == 0)
{
throw runtime_error("List position to be replaced is zero. Check lineage_indices assignment.");
}
lineage_indices[index] = new_val;
}
void SpeciesList::setSpeciesEmpty(unsigned long index, unsigned long new_val)
{
if(index >= lineage_indices.size())
{
lineage_indices.resize(index + 1, 0);
lineage_indices[index] = 0;
}
if(lineage_indices[index] != 0)
{
throw runtime_error("List position to be replaced is not zero. Check lineage_indices assignment.");
}
lineage_indices[index] = new_val;
list_size++;
}
void SpeciesList::setNext(unsigned long n)
{
next_active = n;
}
void SpeciesList::setNwrap(unsigned long nr)
{
nwrap = nr;
}
unsigned long SpeciesList::addSpecies(const unsigned long &new_spec)
{
#ifdef DEBUG
if(list_size + 1 > max_size)
{
stringstream ss;
ss << "lineage_indices size: " << list_size << endl;
ss << "max size: " << max_size << endl;
writeLog(10, ss.str());
throw out_of_range("Could not add species - lineage_indices size greater than max size.");
}
#endif
// Check if there are empty spaces
if(lineage_indices.size() > list_size)
{
// First loop from the lineage_indices size value
for(unsigned long i = list_size; i < lineage_indices.size(); i++)
{
if(lineage_indices[i] == 0)
{
list_size++;
lineage_indices[i] = new_spec;
return i;
}
}
// Now loop over the rest of the lineages
for(unsigned long i = 0; i < list_size; i++)
{
if(lineage_indices[i] == 0)
{
list_size++;
lineage_indices[i] = new_spec;
return i;
}
}
}
else
{
// Just need to append to the vector
lineage_indices.push_back(new_spec);
list_size++;
return lineage_indices.size() - 1;
}
throw out_of_range("Could not add species - no empty space");
}
void SpeciesList::deleteSpecies(unsigned long index)
{
lineage_indices[index] = 0;
list_size--;
}
void SpeciesList::decreaseNwrap()
{
if(nwrap == 0)
{
throw runtime_error("Nwrap should never be decreased less than 0");
}
else if(nwrap == 1)
{
if(next_active != 0)
{
throw runtime_error("Nwrap is being set at 0 when an wrapped lineage is still present");
}
}
nwrap--;
}
void SpeciesList::increaseListSize()
{
list_size++;
}
void SpeciesList::increaseNwrap()
{
nwrap++;
}
void SpeciesList::changePercentCover(unsigned long newmaxsize)
{
max_size = newmaxsize;
}
unsigned long SpeciesList::getRandLineage(const shared_ptr<RNGController> &rand_no)
{
double rand_index;
if(max_size <= list_size)
{
// Then the lineage_indices size is larger than the actual size. This means we must return a lineage.
try
{
do
{
rand_index = rand_no->d01();
rand_index *= lineage_indices.size();
//os << "ref: " << rand_index << ", " << lineage_indices[round(rand_index)] << endl;
}
while(lineage_indices[floor(rand_index)] == 0);
//os << "RETURNING!" << endl;
return (lineage_indices[floor(rand_index)]);
}
catch(out_of_range &oor)
{
throw runtime_error("Listpos outside max_size.");
}
}
else
{
rand_index = rand_no->d01();
// os << "rand_index: " << rand_index << endl;
rand_index *= max_size;
if(rand_index >= lineage_indices.size())
{
return 0;
}
auto i = static_cast<unsigned long>(floor(rand_index));
#ifdef DEBUG
if(rand_index>max_size)
{
stringstream ss;
ss << "Random index is greater than the max size. Fatal error, please report this bug." << endl;
throw runtime_error(ss.str());
}
#endif // DEBUG
return lineage_indices[i];
}
}
unsigned long SpeciesList::getLineageIndex(unsigned long index) const
{
return lineage_indices[index];
}
unsigned long SpeciesList::getNext() const
{
return next_active;
}
unsigned long SpeciesList::getNwrap() const
{
return nwrap;
}
unsigned long SpeciesList::getListSize() const
{
return list_size;
}
unsigned long SpeciesList::getMaxSize() const
{
return max_size;
}
unsigned long SpeciesList::getListLength() const
{
return lineage_indices.size();
}
void SpeciesList::wipeList()
{
next_active = 0;
nwrap = 0;
list_size = 0;
}
double SpeciesList::getCoalescenceProbability() const
{
return min(double(list_size) / double(max_size), 1.0);
}
ostream &operator<<(ostream &os, const SpeciesList &r)
{
os << r.lineage_indices.size();
return os;
}
istream &operator>>(istream &is, SpeciesList &r)
{
unsigned int size;
is >> size;
r.lineage_indices.resize(size, 0);
return is;
}
}