Skip to content

Commit

Permalink
Merge pull request #451 from devosoft/mabe-systematics
Browse files Browse the repository at this point in the history
  • Loading branch information
emilydolson authored Mar 2, 2024
2 parents 0678db4 + 9e7165a commit e7ff3cd
Show file tree
Hide file tree
Showing 17 changed files with 3,297 additions and 1,150 deletions.
15 changes: 15 additions & 0 deletions include/emp/Evolve/NK.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,21 @@ namespace emp {
return GetFitness(n, cur_val);
}

/// Get the fitness of a whole bitstring (pass by value so can be modified.)
emp::vector<double> GetFitnesses(emp::BitVector genome) const {
// Use a double-length genome to easily handle wrap-around.
genome.Resize(N*2);
genome |= (genome << N);
emp::vector<double> fits;

size_t mask = emp::MaskLow<size_t>(K+1);
for (size_t i = 0; i < N; i++) {
const size_t cur_val = (genome >> i).GetUInt(0) & mask;
const double cur_fit = GetFitness(i, cur_val);
fits.push_back(cur_fit);
}
return fits;
}

void SetState(size_t n, size_t state, double in_fit) { landscape[n][state] = in_fit; }

Expand Down
2,290 changes: 1,442 additions & 848 deletions include/emp/Evolve/Systematics.hpp

Large diffs are not rendered by default.

20 changes: 12 additions & 8 deletions include/emp/Evolve/World.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ namespace emp {

};

#ifndef DOXYGEN_SHOULD_SKIP_THIS
// =============================================================
// === ===
// === Out-of-class member function definitions from above ===
Expand Down Expand Up @@ -972,7 +973,7 @@ namespace emp {

// Track the new systematics info
for (Ptr<SystematicsBase<ORG> > s : systematics) {
s->AddOrg(*new_org, pos, (int) update);
s->AddOrg(*new_org, pos);
}

SetupOrg(*new_org, pos, *random_ptr);
Expand All @@ -996,7 +997,7 @@ namespace emp {
}

for (Ptr<SystematicsBase<ORG> > s : systematics) {
s->RemoveOrgAfterRepro(pos, update); // Notify systematics about organism removal
s->RemoveOrgAfterRepro(pos); // Notify systematics about organism removal
}

}
Expand Down Expand Up @@ -1489,6 +1490,13 @@ namespace emp {
pop.resize(0);
std::swap(pops[0], pops[1]); // Move next pop into place.

// Tell systematics manager to swap next population and population
// Needs to happen here so that you can refer to systematics in
// OnPlacement functions
for (Ptr<SystematicsBase<ORG>> s : systematics) {
s->Update();
}

// Update the active population.
num_orgs = 0;
for (size_t i = 0; i < pop.size(); i++) {
Expand All @@ -1498,12 +1506,7 @@ namespace emp {
}
}

// 3. Handle systematics and any data files that need to be printed this update.

// Tell systematics manager to swap next population and population
for (Ptr<SystematicsBase<ORG>> s : systematics) {
s->Update();
}
// 3. Handle any data files that need to be printed this update.

for (auto file : files) file->Update(update);

Expand Down Expand Up @@ -1734,6 +1737,7 @@ namespace emp {
os << std::endl;
}
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
}

#endif // #ifndef EMP_EVOLVE_WORLD_HPP_INCLUDE
1 change: 1 addition & 0 deletions include/emp/base/_assert_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define emp_assert_STRINGIFY_IMPL(...) #__VA_ARGS__
#define emp_assert_TO_PAIR(X) emp_assert_STRINGIFY(X) , X
#define emp_assert_GET_ARG_1(a, ...) a
#define emp_assert_GET_ARG_2(a,b, ...) b
#define emp_assert_GET_ARG_21(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t, u, ...) u
#define emp_assert_MERGE(A, B) A ## B
#define emp_assert_ASSEMBLE(BASE, ARG_COUNT, ...) emp_assert_MERGE(BASE, ARG_COUNT) (__VA_ARGS__)
Expand Down
60 changes: 60 additions & 0 deletions include/emp/base/_optional_throw.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* This file is part of Empirical, https://github.com/devosoft/Empirical
* Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md
* date: 2024
*/
/**
* @file
* @brief Implementation of emp_optional_throw.
*/

#ifndef EMP_BASE__OPTIONAL_THROW_HPP_INCLUDE
#define EMP_BASE__OPTIONAL_THROW_HPP_INCLUDE

#include <sstream>
#include <string>

#include "_is_streamable.hpp"

namespace emp {

/// Base case for assert_print...
inline void assert_print_opt(std::stringstream &) { ; }

/// Print out information about the next variable and recurse...
template <typename T, typename... EXTRA>
void assert_print_opt(std::stringstream & ss, std::string name, T && val, EXTRA &&... extra) {
if constexpr ( emp::is_streamable<std::stringstream, T>::value ) {
ss << name << ": [" << val << "]" << std::endl;
} else ss << name << ": (non-streamable type)" << std::endl;
assert_print_opt(ss, std::forward<EXTRA>(extra)...);
}

template <typename T, typename... EXTRA>
void assert_print_second_opt(std::stringstream & ss, std::string name, T && val, EXTRA &&... extra) {
assert_print_opt(ss, std::forward<EXTRA>(extra)...);
}

template <typename T>
void assert_print_second_opt(std::stringstream & ss, std::string name, T && val) {;}

template <typename T, typename... EXTRA>
void assert_print_first_opt(std::stringstream & ss, std::string name, T && val, EXTRA &&... extra) {
if constexpr ( emp::is_streamable<std::stringstream, T>::value ) {
ss << name << ": [" << val << "]" << std::endl;
} else ss << name << ": (non-streamable type)" << std::endl;
assert_print_second_opt(ss, std::forward<EXTRA>(extra)...);
}

void assert_print_first_opt(std::stringstream & ss, int placeholder) {;}

template <typename... EXTRA>
void assert_throw_opt(std::string filename, size_t line, std::string expr, std::string message, EXTRA &&... extra) {
std::stringstream ss;
ss << "Internal Error (in " << filename << " line " << line << "): " << expr << ".\n\n Message: " << message << "\n\n";
assert_print_first_opt(ss, std::forward<EXTRA>(extra)...);
throw(std::runtime_error(ss.str()));
}
}

#endif // #ifndef EMP_BASE__OPTIONAL_THROW_HPP_INCLUDE
14 changes: 14 additions & 0 deletions include/emp/base/always_assert.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include "_assert_macros.hpp"
#include "_assert_trigger.hpp"
#include "_optional_throw.hpp"

#if defined( __EMSCRIPTEN__ )

Expand All @@ -58,6 +59,19 @@

#define emp_always_assert_impl(TEST) emp_always_assert_msvc_impl(TEST)

#elif defined(EMP_OPTIONAL_THROW_ON)

#define emp_always_assert_impl(...) \
do { \
if (!(emp_assert_GET_ARG_1(__VA_ARGS__, ~))) { \
emp::assert_throw( \
__FILE__, __LINE__, \
emp_assert_STRINGIFY( emp_assert_GET_ARG_1(__VA_ARGS__, ~), ), \
emp_assert_TO_PAIRS(__VA_ARGS__)); \
} \
} while(0)


#else

#define emp_always_assert_impl(...) \
Expand Down
70 changes: 70 additions & 0 deletions include/emp/base/optional_throw.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* This file is part of Empirical, https://github.com/devosoft/Empirical
* Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md
* date: 2024
*/
/**
* @file
* @brief A version of emp_assert that throws a runtime error if compiled with -DEMP_OPTIONAL_THROW_ON.
*
* This is useful if you want the option to throw a runtime error outside of debug mode. A common use
* case is wrapping C++ code in Python, since segfaults kill the entire Python interpreter.
*/

#ifndef EMP_BASE_OPTIONAL_THROW_HPP_INCLUDE
#define EMP_BASE_OPTIONAL_THROW_HPP_INCLUDE

#include "assert.hpp"

/// NDEBUG should trigger its EMP equivalent.
#ifdef NDEBUG
#define EMP_NDEBUG
#endif


#if defined( EMP_OPTIONAL_THROW_ON )

// #if defined (_MSC_VER )

#define emp_optional_throw(TEST, MESSAGE) \
do { \
if (!(TEST)) { \
emp::assert_throw_opt(__FILE__, __LINE__, #TEST, MESSAGE, 0); \
} \
} while(0)

/* #define emp_optional_throw_impl(TEST, MESSAGE) emp_optional_throw_mscv_impl(TEST, MESSAGE)
/ #else
/ #define emp_optional_throw_impl(...) \
/ do { \
/ if (!(emp_assert_GET_ARG_1(__VA_ARGS__, ~))) { \
/ emp::assert_throw( \
/ __FILE__, __LINE__, \
/ emp_assert_STRINGIFY( emp_assert_GET_ARG_1(__VA_ARGS__, ~), ), \
/ emp_assert_STRINGIFY( emp_assert_GET_ARG_2(__VA_ARGS__, ~), ), \
/ emp_assert_TO_PAIRS(__VA_ARGS__)); \
/ } \
/ } while(0)
/ #endif
/ #define emp_optional_throw(...) emp_optional_throw_impl(__VA_ARGS__)
*/
#elif defined( EMP_NDEBUG )

#define emp_optional_throw(...)

#else
/// Require a specified condition to be true. If it is false, immediately
/// halt execution. Print also extra information on any variables or
/// expressions provided as variadic args. Note: If NDEBUG is defined,
/// emp_assert() will not do anything. Due to macro parsing limitations, extra
/// information will not be printed when compiling with MSVC.
#define emp_optional_throw(...) emp_assert(__VA_ARGS__)

#endif


#endif // #ifndef EMP_BASE_OPTIONAL_THROW_HPP_INCLUDE
4 changes: 4 additions & 0 deletions include/emp/data/DataManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ namespace emp {
return Has(node_map, name);
}

bool HasNoNode(const std::string & name) {
return !Has(node_map, name);
}

/// Creates and adds a new DataNode
/// @param name the name of the DataNode
node_t & New(const std::string & name) {
Expand Down
13 changes: 13 additions & 0 deletions include/emp/datastructs/map_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ namespace emp {
return in_map.find(key) != in_map.end();
}

/// Take a map where the value is an integer and a key.
/// Increment value associated with that key if its present
/// or if its not add it and set it to 1
template <class MAP_T, class KEY_T>
inline void IncrementCounter( MAP_T & in_map, const KEY_T & key ) {
static_assert( std::is_same< typename MAP_T::key_type, int >::value);
if (emp::Has(in_map, key)) {
in_map[key]++;
} else {
in_map[key] = 1;
}
}

// Check to see if any of the elements in a map satisfy a function.
template <typename KEY_T, typename ELEMENT_T, typename FUN_T>
bool AnyOf(const std::map<KEY_T, ELEMENT_T> & c, FUN_T fun) {
Expand Down
2 changes: 1 addition & 1 deletion include/emp/math/info_theory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace emp {
double entropy = 0.0;
for (auto & o : objs) {
double p = ((double) fun(o)) / total;
entropy -= p * Log2(p);
entropy -= p * log2(p);
}
return entropy;
}
Expand Down
Loading

0 comments on commit e7ff3cd

Please sign in to comment.