Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stats managers #63

Merged
merged 53 commits into from
Jun 1, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2164781
Last commit before I completely overhaul OEE.h
emilydolson Apr 6, 2016
eba2749
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson Apr 8, 2016
d70eea3
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson Apr 19, 2016
4e615bc
Adding update signal
emilydolson Apr 22, 2016
24aa95f
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson Apr 22, 2016
0ebbf5c
Complexity and Ecology work
emilydolson May 11, 2016
b787d67
Fixed merge conflict
emilydolson May 11, 2016
2c7be2f
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 11, 2016
6ae3880
All metrics work
emilydolson May 11, 2016
2abc7e5
All metrics work
emilydolson May 12, 2016
fdd1819
All metrics work, skeletonization streamlined
emilydolson May 13, 2016
570aab4
Separate generations deduction works now
emilydolson May 13, 2016
e718cf2
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 13, 2016
24e903a
Cleaned up OEE.h, added comments
emilydolson May 13, 2016
de8731e
Added example for OEE tracker
emilydolson May 14, 2016
7481633
Fixed bug in change deque length, added fitness tracking
emilydolson May 14, 2016
bcb6fa9
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 14, 2016
86fe09b
Added print statement to verify settings
emilydolson May 14, 2016
88b491e
Added template specializations to appease std::vector
emilydolson May 15, 2016
8aac649
Made template specialization of ShannonDiversity to take a World
emilydolson May 18, 2016
1c525dc
Worlds are iterable
emilydolson May 18, 2016
7c51aeb
Fixing merge conflict
emilydolson May 18, 2016
779a6f4
Use world iterator in stats
emilydolson May 19, 2016
89150a8
Merge branch 'master' of github.com:devosoft/Empirical into nullorgs
emilydolson May 19, 2016
e6629c8
Fixed tournament selection to only choose from valid orgs
emilydolson May 19, 2016
229d7d9
NK_OEE now uses const landscapes
emilydolson May 19, 2016
39d792d
Lineage tracker does everything automatically with signals
emilydolson May 19, 2016
b119b08
Made ids actually propagate correctly
emilydolson May 19, 2016
295fd66
Elite selection is null org safe
emilydolson May 19, 2016
7795f83
GetValidOrgIndices actually works now
emilydolson May 19, 2016
0303f20
Merge in Jake and Stevens addition to Stats.h
emilydolson May 20, 2016
c41f784
Merge in null org handling
emilydolson May 20, 2016
a740eb6
Base stats manager functionality works
emilydolson May 20, 2016
f331839
StatsManagers handle output locations
emilydolson May 22, 2016
b718da7
Worlditerator uses pointers
emilydolson May 22, 2016
a848858
Added error message for invalid file
emilydolson May 22, 2016
b68dba6
Created default stats manager, made header
emilydolson May 23, 2016
14a5af0
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 23, 2016
261a9f3
Added comments, cleaned up types
emilydolson May 23, 2016
49744de
OEE stats manager uses base output
emilydolson May 23, 2016
09fdf57
Stats managers have config files
emilydolson May 23, 2016
34198f6
Fixed possible null dereference in tournament fitness calculation
emilydolson May 23, 2016
db2c17d
Guard against null dereference in MutatePop
emilydolson May 23, 2016
39ae05f
StatsManagers can be passed as template arguments
emilydolson May 27, 2016
eb645f2
LineageTracker and OEEStats now follow general StatsManager format
emilydolson May 29, 2016
2149343
LineageTracker and OEEStats now follow general StatsManager format
emilydolson May 29, 2016
4fd1544
Merge branch 'master' of github.com:emilydolson/Empirical
emilydolson May 29, 2016
0a6b803
Lineage tracker automatically hooks up to OEE stats
emilydolson May 29, 2016
97f0ffb
Automatic lineage tracker construction works
emilydolson May 29, 2016
adadaac
Made stats generic and moved them to tools
emilydolson May 29, 2016
a92e954
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 30, 2016
a80244f
Fixed g++ compilation bug
emilydolson May 31, 2016
a6897a1
Stats Manager headers + assorted cleanup
emilydolson Jun 1, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Stats Manager headers + assorted cleanup
  • Loading branch information
emilydolson committed Jun 1, 2016
commit a6897a1043394ef1adcde2574615f8e93363132b
31 changes: 19 additions & 12 deletions evo/LineageTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace evo{
// they belonged to, and which organisms were the parents of which
template <typename POP_MANAGER = PopulationManager_Base<int> >
class LineageTracker {
private:
protected:
using org_ptr = typename POP_MANAGER::value_type;
using ORG = typename std::remove_pointer<org_ptr>::type;
static constexpr bool separate_generations = POP_MANAGER::emp_has_separate_generations;
Expand All @@ -41,7 +41,8 @@ namespace evo{
int next_parent_id = -1;
int next_org_id = 1;
emp::vector<int> generation_since_update;
emp::vector<int> prev_generation;
emp::vector<int> new_generation;
bool inject;

LineageTracker(){;}

Expand Down Expand Up @@ -91,41 +92,47 @@ namespace evo{
//Put newly born organism into the lineage tracker

void Update(int i) {
prev_generation = generation_since_update;
if (separate_generations) {
//TODO: This isn't sufficient - need to add signals for any
//population change event
generation_since_update.resize(0);
generation_since_update = new_generation;
new_generation.resize(0);
}
}

void TrackOffspring(org_ptr org) {
next_org_id = this->AddOrganism(*org, next_parent_id);
inject = false;
}

//Put newly injected organism into the lineage tracker
void TrackInjectedOffspring(org_ptr org) {
next_org_id = this->AddOrganism(*org, 0);
inject = true;
}

//Keep track of location of all orgs in the population so that
//we can translate their ids from the World to ids within the lineage
//tracker
void TrackPlacement(int pos) {
if (pos >= generation_since_update.size()) {
generation_since_update.resize(pos+1);
if (separate_generations && !inject){
if (pos >= new_generation.size()) {
new_generation.resize(pos+1);
}
new_generation[pos] = next_org_id;

} else {
if (pos >= generation_since_update.size()) {
generation_since_update.resize(pos+1);
}
generation_since_update[pos] = next_org_id;
}
generation_since_update[pos] = next_org_id;
}

//Record the org that's about to have an offspring, so we can know
//who the parent of the next org is.
void RecordParent(int id) {
if (separate_generations){
next_parent_id = prev_generation[id];
} else {
next_parent_id = generation_since_update[id];
}
next_parent_id = generation_since_update[id];
}

// Add an organism to the tracker - org is the genome of the organism
Expand Down
6 changes: 3 additions & 3 deletions evo/OEE.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ namespace evo{
using ORG = typename std::remove_pointer<org_ptr>::type;
using skeleton_type = emp::vector<int>;
static constexpr bool separate_generations = POP_MANAGER::emp_has_separate_generations;
//TODO: Make this use existing lineage tracker if there is one

std::set<skeleton_type > novel;

int generations = 50; //How far back do we look for persistance?
int generations = OeeConfig.GENERATIONS(); //How far back do we look for persistance?

// Historical generations needed to count stats. We only need these in
// proportion to resolution.
Expand Down Expand Up @@ -74,6 +73,8 @@ namespace evo{
emp_assert(generations % resolution == 0 &&
"ERROR: Generations required for persistance must be a multiple of resolution.",
resolution, generations);

OeeConfig.Read("OEE_stats.cfg");
generations = OeeConfig.GENERATIONS();
OeeConfig.Write("OEE_stats.cfg");

Expand All @@ -87,7 +88,6 @@ namespace evo{
w->OnUpdate(UpdateFun);
lineage = &(w->lineageM);

//TODO: Figure out how to make this work automatically
output_location << "update" << delimiter << "change" << delimiter
<< "novelty" << delimiter << "ecology" << delimiter
<< "complexity" << std::endl;
Expand Down
45 changes: 31 additions & 14 deletions evo/StatsManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,26 @@ namespace evo{
using StatsManager_Base<POP_MANAGER>::resolution;
using StatsManager_Base<POP_MANAGER>::output_location;
using StatsManager_Base<POP_MANAGER>::delimiter;
bool header_printed = false;
std::string header = "update";

public:
using StatsManager_Base<POP_MANAGER>::emp_is_stats_manager;
fit_fun_type fit_fun;

//Constructor for creating this as a stand-alone object
template <typename WORLD>
StatsManager_FunctionsOnUpdate(WORLD * w,
std::string location = "stats.csv") :
StatsManager_Base<decltype(w->popM)>(location){
Setup(w);
}

//Constructor for use by World object
StatsManager_FunctionsOnUpdate(std::string location = "stats.csv") :
StatsManager_Base<POP_MANAGER>(location){;}

//The fitness function for calculating fitness related stats

template <typename WORLD>
void Setup(WORLD * w){
pop = &(w->PopM);
Expand All @@ -134,17 +137,31 @@ namespace evo{

//Function for adding functions that calculate stats to the
//set to be calculated
void AddFunction(std::function<double(POP_MANAGER*)> func) {
void AddFunction(std::function<double(POP_MANAGER*)> func, std::string label) {
world_stats.Add(func);
if (header_printed){
NotifyWarning("Function added to stats manager after initialization.");
} else {
header += delimiter + label;
}
}

//Version for functions that require a fitness function
void AddFunction(std::function<double(fit_fun_type, POP_MANAGER*)> func) {
void AddFunction(std::function<double(fit_fun_type, POP_MANAGER*)> func, std::string label) {
fitness_stats.Add(func);
if (header_printed){
NotifyWarning("Function added to stats manager after initialization.");
} else {
header += delimiter + label;
}
}

//If this update matches the resolution, calculate and record all the stats
void Update(int update) {
if (!header_printed) {
output_location << header << std::endl;
header_printed = true;
}

if (update % resolution == 0){

Expand Down Expand Up @@ -186,24 +203,23 @@ namespace evo{
using StatsManager_Base<POP_MANAGER>::emp_is_stats_manager;
using StatsManager_FunctionsOnUpdate<POP_MANAGER>::SetDefaultFitnessFun;

//Constructor for use as a stand-alone object
template <typename WORLD>
StatsManager_DefaultStats(WORLD * w, std::string location = "averages.csv")
: StatsManager_FunctionsOnUpdate<decltype(w->popM)>(w, location){

Setup(w);
//Print header
output_location << "update, shannon_diversity, max_fitness, avg_fitness" << std::endl;
}

//Constructor for use as a template parameter for the world
StatsManager_DefaultStats(std::string location = "averages.csv")
: StatsManager_FunctionsOnUpdate<POP_MANAGER>(location){
//Print header
output_location << "update, shannon_diversity, max_fitness, avg_fitness" << std::endl;
}
: StatsManager_FunctionsOnUpdate<POP_MANAGER>(location){;}

//Add appropriate functions to function sets
template <typename WORLD>
void Setup(WORLD * w){
pop = &(w->popM);

//Create std::function object for all of the stats
std::function<double(POP_MANAGER*)> diversity = [](POP_MANAGER * pop){
return ShannonEntropy(*pop);
};
Expand All @@ -214,14 +230,15 @@ namespace evo{
return AverageFunctionReturn(fit_func, *pop);
};

AddFunction(diversity);
AddFunction(max_fitness);
AddFunction(avg_fitness);

std::function<void(int)> UpdateFun = [&] (int ud){
Update(ud);
};

//Add functions to manager
AddFunction(diversity, "shannon_diversity");
AddFunction(max_fitness, "max_fitness");
AddFunction(avg_fitness, "avg_fitness");

w->OnUpdate(UpdateFun);
}

Expand Down
4 changes: 0 additions & 4 deletions evo/World.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ namespace evo {
EMP_SETUP_TYPE_SELECTOR(SelectOrgManager, emp_is_organism_manager);
EMP_SETUP_TYPE_SELECTOR(SelectStatsManager, emp_is_stats_manager);
EMP_SETUP_TYPE_SELECTOR(SelectLineageManager, emp_is_lineage_manager);
EMP_SETUP_TYPE_SELECTOR(NeedsLineageManager, lineage);

template <typename POP_MANAGER> class PopulationIterator;

Expand All @@ -153,8 +152,6 @@ namespace evo {
EMP_CHOOSE_MEMBER_TYPE(DefaultLineage, lineage_type, LineageNull, decltype(statsM));
AdaptTemplate<typename SelectLineageManager<MANAGERS...,DefaultLineage>::type, decltype(popM)> lineageM;

//emp::evo::OEEStatsManager<decltype(popM)> statsM;

Random * random_ptr;
bool random_owner;
int update = 0;
Expand Down Expand Up @@ -333,7 +330,6 @@ namespace evo {
void EliteSelect(std::function<double(ORG*)> fit_fun, int e_count=1, int copy_count=1) {
emp_assert(fit_fun);
emp_assert(e_count > 0 && e_count <= (int) popM.size());

// Load the population into a multimap, sorted by fitness.
std::multimap<double, int> fit_map;
for (int i = 0; i < (int) popM.size(); i++) {
Expand Down
22 changes: 22 additions & 0 deletions tools/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,28 @@ namespace evo{
return (cumulative_value / count);
}

template <typename C, typename RET_TYPE>
emp::vector<RET_TYPE> RunFunctionOnContainer(std::function<RET_TYPE(typename C::value_type)> fun, C & elements) {
emp::vector<RET_TYPE> results;
for (auto element : elements){
results.push_back(fun(element));
}
return results;
}

//This variant is actually super confusing because the value_type of world
//and population managers are pointers whereas the type that they're templated
//on is not. Also because the insert method for emp::vectors doesn't take an
//additional argument?
/*template <template <typename> class C, typename RET_TYPE, typename T>
C<RET_TYPE> RunFunctionOnContainer(std::function<RET_TYPE(T)> fun, C<T> & elements) {
C<RET_TYPE> results;
for (auto element : elements){
results.insert(fun(element), results.back());
}
return results;
}*/

}
}

Expand Down