Namespaces#

EvoAI#

namespace EvoAI#

Typedefs

using EvoString = EvoVector<char>#

Functions

template<class T>
inline void hashCombine(std::size_t &seed, const T &v) noexcept#

Combines two hashes.

Template Parameters:

T – number type

Parameters:
  • seed – std::size_t&

  • v – const T& hasheable Object

template<typename ...Args>
inline constexpr std::size_t joinHashes(std::size_t seed, const Args&... args) noexcept#

joins hashes

auto seed = 42u;
auto hash = EvoAI::joinHashes(seed, 1,2,3,4,5);

Template Parameters:

...Args – seq of numbers(same type)

Parameters:
  • seed[in] to use

  • args[in] number seq

Returns:

std::size_t hash

template<typename T = float>
inline constexpr T normalize(const T &val, const T &normMin, const T &normMax, const T &min, const T &max) noexcept#

normalize values from one range to another

normalize<float>(50,-1.0,1.0,0.0,100.0);

Template Parameters:

number – type

Parameters:
  • val – T

  • normMin – T

  • normMax – T

  • min – T

  • max – T

Returns:

T

template<typename T = float>
inline constexpr T stableNormalize(const T &val, const T &min, const T &max) noexcept#

normalize values from one range to another

normalize<float>(50,0.0,100.0);

Template Parameters:

number – type

Parameters:
  • val – T

  • min – T

  • max – T

Returns:

T

template<typename T>
inline constexpr T distanceManhattan(const T &x1, const T &y1, const T &x2, const T &y2) noexcept#

Calculates the distance using Manhattan between x1,y1 and x2, y2.

Parameters:
  • x1 – const T&

  • y1 – const T&

  • x2 – const T&

  • y2 – const T&

Returns:

T

template<typename T>
inline constexpr T distanceChebyshev(const T &x1, const T &y1, const T &x2, const T &y2) noexcept#

Calculates the distance using Chebyshev between x1,y1 and x2, y2.

Parameters:
  • x1 – const T&

  • y1 – const T&

  • x2 – const T&

  • y2 – const T&

Returns:

T

template<typename T>
inline constexpr T distanceEuclidean(const T &x1, const T &y1, const T &x2, const T &y2) noexcept#

Calculates the distance using Euclidean between x1,y1 and x2, y2.

Parameters:
  • x1 – const T&

  • y1 – const T&

  • x2 – const T&

  • y2 – const T&

Returns:

T

template<typename T>
inline constexpr T distanceCenter(const T &x, const T &y, const T &width, const T &height) noexcept#

Calculates the distance to Center.

Parameters:
  • x – const T&

  • y – const T&

  • width – const T&

  • height – const T&

Returns:

T

EvoAI_API std::unique_ptr< NeuralNetwork > createFeedForwardNN (const size_t &numInputs, const size_t &numHidden, const std::vector< size_t > &numNeuronsPerHidden, std::size_t numOutputs, double bias)

Creates a FeedForward Neural Network. weight init default Xavier uniform.

Parameters:
  • numInputs

  • numHidden

  • numNeuronsPerHidden

  • numOutputs

  • bias

Returns:

std::unique_ptr<NeuralNetwork>

EvoAI_API std::unique_ptr< NeuralNetwork > createElmanNeuralNetwork (std::size_t numInputs, std::size_t numHidden, const std::vector< std::size_t > &numNeuronsPerHiddenLayer, std::size_t numOutputs, double bias)

Creates an Elman Neural Network.

This will create a Neural Network with a context layer per every hidden layer.

Parameters:
  • numInputs – number of inputs

  • numHidden – number of hidden layers

  • numNeuronsPerHiddenLayer – number of neurons per hidden layer

  • numOutputs – number of outputs

  • bias – bias

Returns:

std::unique_ptr<NeuralNetwork>

EvoAI_API std::unique_ptr< NeuralNetwork > createFullyConnectedCPPN (std::size_t numInputs, std::size_t numHidden, const std::vector< std::size_t > &numNeuronsPerHiddenLayer, std::size_t numOutputs, double bias)

Creates a fully connected CPPN with random activations functions. weight init default Xavier uniform.

Parameters:
  • numInputs – number of inputs

  • numHidden – number of hidden layers

  • numNeuronsPerHiddenLayer – number of neurons per hidden layer

  • numOutputs – number of outputs

  • bias – bias

Returns:

std::unique_ptr<NeuralNetwork>

EvoAI_API std::unique_ptr< NeuralNetwork > createCPPN (std::size_t numInputs, std::size_t numHidden, const std::vector< std::size_t > &numNeuronsPerHiddenLayer, std::size_t numOutputs, double bias)

Creates a CPPN with random activations functions and some random connections.

Parameters:
  • numInputs – number of inputs

  • numHidden – number of hidden layers

  • numNeuronsPerHiddenLayer – number of neurons per hidden layer

  • numOutputs – number of outputs

  • bias – bias

Returns:

std::unique_ptr<NeuralNetwork>

EvoAI_API void UniformInit (NeuralNetwork &nn) noexcept

Uniform initialization uses randomGen().random(-1.0, 1.0, layerSize)

Parameters:

nnNeuralNetwork&

EvoAI_API void LeCunInit (NeuralNetwork &nn) noexcept

LeCun initialization uniform distribution.

Parameters:

nnNeuralNetwork&

EvoAI_API void LeCunInitNormal (NeuralNetwork &nn) noexcept

LeCun initialization normal distribution.

Parameters:

nnNeuralNetwork&

EvoAI_API void HeInit (NeuralNetwork &nn) noexcept

He initialization uniform distribution.

Parameters:

nnNeuralNetwork&

EvoAI_API void HeInitNormal (NeuralNetwork &nn) noexcept

He initialization normal distribution.

Parameters:

nnNeuralNetwork&

EvoAI_API void XavierInit (NeuralNetwork &nn) noexcept

Xavier initialization uniform distribution.

Parameters:

nnNeuralNetwork&

EvoAI_API void XavierInitNormal (NeuralNetwork &nn) noexcept

Xavier initialization normal distribution.

Parameters:

nnNeuralNetwork&

EvoAI_API void writeMultiPlot (std::string_view filename, const std::vector< std::string > &legend, const std::vector< std::vector< double >> &data) noexcept

write data to a file to render with tools/showMultiLinePlot.py

Parameters:
  • filename – std::string_view filename to save info into.

  • legend – std::vector<std::string> legend for the plots

  • data – std::vector<std::vector<double>> data for the plot

EvoAI_API std::size_t Argmax (const std::vector< double > &outputs) noexcept

gives the index of maximum value

Parameters:

outputs – const std::vector<double>&

Returns:

std::size index of maximum value

EvoAI_API std::size_t Argmax (NeuronLayer &outputs) noexcept

gives the index of maximum value

Parameters:

outputsNeuronLayer&

Returns:

std::size_t index of maximum value

template<typename Iterator>
std::size_t Argmax(Iterator begin, Iterator end) noexcept#

gives the index of maximum value of given range (0 to size()-1)

Template Parameters:

Interator

Parameters:
  • begin – Interator

  • end – Interator

Returns:

std::size_t index of maximum value in given range.

template<typename Iterator, typename Fn>
std::size_t Argmax(Iterator begin, Iterator end, Fn &&fn) noexcept#

gives the index of maximum value of given range (0 to size()-1) using Fn as comparator.

Template Parameters:
  • Iterator

  • Fn – Comparator

Parameters:
  • begin – Iterator

  • end – Iterator

  • fn – Fn

Returns:

std::size_t index of maximum value in given range

EvoAI_API RandomGenerator & randomGen () noexcept

RandomGenerator.

template<typename Fn, typename ...Args>
auto TimeThis(Fn &&fn, const Args&... args) noexcept#

calculates time it takes Fn in milliseconds

Template Parameters:
  • Fn – funtion to evaluate

  • Args – args for funtion

Parameters:
  • fn – function to measure

  • args – args for function

Returns:

double

template<typename Fn>
auto TimeThis(Fn &&fn) noexcept#

calculates time it takes Fn in milliseconds

Template Parameters:

Fn – funtion to evaluate

Parameters:

fn – function to measure

Returns:

double milliseconds

template<typename ...Jsons>
JsonBox::Value makeJsonFrom(const std::array<std::string, sizeof...(Jsons)> &names, const Jsons&... jsons) noexcept#

creates a json object from each Jsons::toJson() to the given names.

Warning

Jsons should have implemented ::toJson() const noexcept;

// class to serialize
auto ffnn = EvoAI::createFeedForwardNN(2,3,{1,5,3},2, 1.0);
// convert ffnn to json into key "ffnn" and EvoAI::Scaler<double> to "sc"
auto v = EvoAI::makeJsonFrom({"ffnn","sc"},*ffnn,EvoAI::Scaler<double>());
// write to file
v.writeToFile("ffnnAndSCTest.json");

Template Parameters:

Jsons...

Parameters:
  • names – std::array<std::String,sizeof…(Jsons)>

  • jsons – objects to call ::toJson()

Returns:

JsonBox::Value

template<typename ...Jsons>
std::tuple<Jsons...> loadJsonFrom(const std::string &filename, const std::array<std::string, sizeof...(Jsons)> &names) noexcept#

returns a std::tuple with the deserialized classes from the json.

Warning

Jsons should have implemented a Jsons::Jsons(JsonBox::Object) constructor.

// read from a json filename and deserialize into ffNN and sc
auto [ffNN, sc] = EvoAI::loadJsonFrom<NeuralNetwork,Scaler<double>>("ffnnAndSCTest.json", {"ffnn", "sc"});

Parameters:
  • filename – std::string

  • names – std::array<std::string,sizeof…(Jsons)>

Returns:

std::tuple<Jsons…>

EvoAI_API std::vector< std::vector< std::string > > readCSVFile (std::istream &istr, char delimiter=',')

simple csv file parser it will read the file and returns a std::vector<std::vector<std::string>>

Parameters:
  • istr – std::istream&

  • delimiter – char& defaulted to comma

Returns:

std::vector<std::vector<std::string>> with the csv data.

EvoAI_API void writeCSVFile (const std::vector< std::vector< std::string >> &csvData, std::ostream &ostr, char delimiter=',')

writes a csv file.

Parameters:
  • csvData – const std::vector<std::vector<std::string>>&

  • ostr – std::ostream&

  • delimiter – char

Variables

static constexpr double PI = 3.14159265358979323846#
class Link#
#include <Connection.hpp>

A simple link defining a source point layer, neuron.

Author

Cristian Glez Cristian.glez.m@gmail.com

Public Functions

Link(std::size_t lyr, std::size_t nrn)#

default constructor

Parameters:
  • lyr – std::size_t

  • nrn – std::size_t

Link(JsonBox::Object o)#
JsonBox::Value toJson() const noexcept#

Public Members

std::size_t layer#
std::size_t neuron#
class Connection#
#include <Connection.hpp>

A Connection used to connect neurons from different layers.

Author

Cristian Glez Cristian.glez.m@gmail.com

Public Functions

Connection()#

default Constructor

Constructor with src and dest.

Parameters:
Connection(const Link &src, const Link &dest, double w)#

Constructor with src, dest and weight.

Parameters:
  • srcLink&

  • destLink&

  • w – double Weight of the connection

Connection(JsonBox::Object o)#

Constructor json object.

Parameters:

o – JsonBox::Object&

inline bool isRecurrent() const noexcept#

check if is a recurrent connection

Returns:

bool

setter for src

Parameters:

lLink&

Returns:

Connection&

inline const Link &getSrc() const noexcept#

getter for src

Returns:

Link& const

setter for dest

Parameters:

lLink&

Returns:

Connection&

inline const Link &getDest() const noexcept#

getter for dest

Returns:

Link& const

inline const bool &isVisited() const noexcept#

checks if this connection has been visited.

Returns:

bool

Connection &setVisited(bool b)#

setter for visited

Parameters:

b

Returns:

Connection&

inline double getWeight() const noexcept#

getter for weight

Returns:

double&

Connection &setWeight(double w)#

setter for Weight

Parameters:

w – Weight

Returns:

Connection&

Connection &setCycles(int c)#

setter for cycles

Parameters:

c – cycles

Returns:

Connection&

inline int getCycles() const noexcept#

getter for cycles

Returns:

int&

std::string toString() const noexcept#

returns a string with the info of the connection.

Returns:

std::string

JsonBox::Value toJson() const noexcept#

converts the Connection to JsonBox::Value

Returns:

JsonBox::Value

bool operator==(const Connection &rhs) const#

compare connections

Parameters:

rhs

Connection &setGradient(double grad) noexcept#

setter for gradient

Parameters:

grad

Returns:

Connection

Connection &addGradient(double val) noexcept#

adds the val to gradients

Parameters:

val

Returns:

Connection

inline double getGradient() const noexcept#

getter for gradients

Returns:

double&

void reset()#

resets the connection, visited, and gradient.

Connection &setFrozen(bool frzen) noexcept#

setter for frozen, set true to not change the weight

Parameters:

frzen – bool

Returns:

Connection&

inline bool isFrozen() const noexcept#

getter for frozen

Returns:

bool

class ConnectionGene#
#include <ConnectionGene.hpp>

ConnectionGene for the NEAT algorithm.

Author

Cristian Glez Cristian.glez.m@gmail.com

Public Functions

ConnectionGene(const NodeGene &src, const NodeGene &dest, double w)#

Constructor.

Parameters:
ConnectionGene(const Link &src, const Link &dest, double w)#

Constructor.

Parameters:
  • srcLink

  • destLink

  • w – double weight

ConnectionGene(const ConnectionGene &rhs) noexcept#

copy constructor

Parameters:

rhs – const ConnectionGene&

ConnectionGene(ConnectionGene &&rhs) noexcept#

move constructor

Parameters:

rhsConnectionGene&&

void operator=(const ConnectionGene &rhs) noexcept#
void operator=(ConnectionGene &&rhs) noexcept#
constexpr bool operator<(const ConnectionGene &rhs) const noexcept#
constexpr bool operator>(const ConnectionGene &rhs) const noexcept#
ConnectionGene(JsonBox::Object o)#

Constructor with json object.

Parameters:

o – JsonBox::Object&

bool isEnabled() const noexcept#

returns if is enabled

Returns:

bool

void setEnabled(bool en) noexcept#

setter for enabled

Parameters:

en

std::string toString(const std::string &delimiter = " ") const noexcept#

returns a std::string

Returns:

std::string

JsonBox::Value toJson() const noexcept#

returns a json of the connectionGene

Returns:

JsonBox::Value

void addWeight(double amount) noexcept#

adds the amount to the current weight.

Parameters:

amount

void setWeight(double w) noexcept#

setter for weight

Parameters:

w

double getWeight() const noexcept#

getter for weight

Returns:

double

const Link &getSrc() const noexcept#

getter for src

Returns:

Link

const Link &getDest() const noexcept#

getter for dest

Returns:

Link

const Connection &getConnection() const noexcept#

getter for connection

Returns:

Connection&

void setFrozen(bool frzen) noexcept#

setter for frozen set true to not change the weight

Parameters:

frzen

bool isFrozen() const noexcept#

getter for frozen

Returns:

bool

std::size_t getInnovationID() const noexcept#

getter for innovationID

Returns:

std::size_t

bool operator==(const ConnectionGene &rhs) const#
bool operator!=(const ConnectionGene &rhs) const#
~ConnectionGene() = default#

Friends

inline friend std::ostream &operator<<(std::ostream &o, const EvoAI::ConnectionGene &cg) noexcept#
template<class Dataset>
class DataLoader#
#include <DataLoader.hpp>

Dataloader to process Dataset.

Dataset needs to fulfill these requirements:

  • const std::pair<std::vector<double>&, std::vector<double>&> operator()() noexcept;

  • std::size_t size() const noexcept;

  • std::size_t getBatchSize() const noexcept;

  • void shuffle() noexcept;

    EvoAI::DataLoader trainingDataset(EvoAI::Dataset(std::move(inputs), std::move(outputs), batchSize));
    

Template Parameters:

Dataset

Public Types

using type = Dataset#

Public Functions

DataLoader(Dataset &&ds, bool randomize = true)#

constructor

Parameters:
  • dsDataset

  • randomize – bool

std::pair<std::vector<double>&, std::vector<double>&> operator()() noexcept#

next sample

Returns:

std::pair<std::vector<double>&, std::vector<double>&>

std::size_t size() noexcept#

size of (samples + batchSize - 1) / batchSize

Returns:

std::size_t

std::size_t getBatchSize() noexcept#

gets batchSize

Returns:

std::size_t

void shuffle() noexcept#

shuffle the samples

Dataset &getDataset() noexcept#

gets direct access to Dataset

Returns:

Dataset&

class Dataset#
#include <DataSet.hpp>

Dataset.

EvoAI::Dataset dataset(std::move(inputs), std::move(outputs), batchSize);

Public Types

using TrainingFormat = std::vector<std::pair<std::vector<double>, std::vector<double>>>#

expected input and target type

Public Functions

Dataset(std::size_t batchSize) noexcept#

constructor for empty dataset.

Warning

You will need to add samples with Dataset::add before using it.

Parameters:

batchSize

Dataset(TrainingFormat &&data, std::size_t batchSize) noexcept#

constructor

Parameters:
Dataset(std::vector<std::vector<double>> &&inputs, std::vector<std::vector<double>> &&targets, std::size_t batchSize) noexcept#

constructor

Parameters:
  • inputs – std::vector<std::vector<double>>&&

  • targets – std::vector<std::vector<double>>&&

  • batchSize – std::size_t

const std::pair<std::vector<double>&, std::vector<double>&> operator()() noexcept#

next sample

Returns:

const std::pair<std::vector<double>&, std::vector<double>&>

void add(std::pair<std::vector<double>, std::vector<double>> &&sample) noexcept#

add sample to dataset.

Parameters:

sample – std::pair<std::vector<double>, std::vector<double>>&&

std::size_t size() const noexcept#

size of (samples + batchSize - 1) / batchSize

Returns:

std::size_t

std::size_t getBatchSize() const noexcept#

get BatchSize

Returns:

std::size_t

void shuffle() noexcept#

method to shuffle the samples after the epoch

template<typename T>
class EvoVector#
#include <EvoVector.hpp>

Simple class representing a Evolvable Vector.

Template Parameters:

T

Public Types

using value_type = typename std::vector<T>::value_type#
using reference = typename std::vector<T>::reference#
using const_reference = typename std::vector<T>::const_reference#
using iterator = typename std::vector<T>::iterator#
using const_iterator = typename std::vector<T>::const_iterator#
using DNA = typename std::vector<T>#

Public Functions

explicit EvoVector(std::size_t size) noexcept#

constructor

Parameters:

size – std::size_t

template<typename Generator>
explicit EvoVector(std::size_t size, Generator &&fn) noexcept#

constructor with generator fn

Parameters:
  • size – std::size_t

  • fn – Generator&&

explicit EvoVector(DNA &&dna) noexcept#

constructor for EvoVector children

Parameters:

dna – DNA&&

EvoVector(JsonBox::Object o) noexcept#

constructor JsonBox::Object

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

converts to json

Returns:

JsonBox::Value

value_type *data() noexcept#

pointer to internal vector.data()

Returns:

T*

inline void setID(std::size_t ID) noexcept#

sets the EvoVector id

Parameters:

ID – std::size_t

inline std::size_t getID() const noexcept#

gets the EvoVector id

Returns:

std::size_t

inline void setSpeciesID(std::size_t spcID) noexcept#

setter for species ID

Parameters:

spcID – species id

inline void setFitness(double fit) noexcept#

sets the fitness

Parameters:

fit – double

inline void addFitness(double amount) noexcept#

adds the amount to the current fitness.

Parameters:

amount – double

inline double getFitness() const noexcept#

gets the fitness

Returns:

double

inline std::size_t getSpeciesID() const noexcept#

returns the species id.

Returns:

std::size_t

inline std::size_t size() const noexcept#

returns size

Returns:

std::size_t

void mutate(float rate = 0.5) noexcept#

mutates the EvoVector

Parameters:

rate – float

inline reference operator[](int index) noexcept#
inline const_reference operator[](int index) const noexcept#
inline iterator begin() noexcept#
inline iterator end() noexcept#
inline const_iterator begin() const noexcept#
inline const_iterator end() const noexcept#

Public Static Functions

static EvoVector reproduce(const EvoVector &es1, const EvoVector &es2) noexcept#

reproduce

Parameters:
Returns:

EvoVector

static double distance(const EvoVector &es1, const EvoVector &es2, [[maybe_unused]] double c1 = 2.0, [[maybe_unused]] double c2 = 2.0, [[maybe_unused]] double c3 = 1.0) noexcept#

Calculates the distance between two EvoVectors. 1000 if size dont match up.

Parameters:
  • es1EvoVector

  • es2EvoVector

  • c1 – coefficient Gives importance to [not used]

  • c2 – coefficient Gives importance to [not used]

  • c3 – coefficient Gives importance to [not used]

Returns:

double

class Genome#
#include <Genome.hpp>

A genome is a description of a EvoAI::NeuralNetwork.

Author

Cristian Gonzalez Cristian.glez.m@gmail.com

Public Types

using matchingNodeGenes = std::pair<Range<NodeGene>, Range<NodeGene>>#
using matchingConnectionGenes = std::pair<Range<ConnectionGene>, Range<ConnectionGene>>#
using matchingChromosomes = std::pair<matchingNodeGenes, matchingConnectionGenes>#
using excessNodeGenes = std::pair<Range<NodeGene>, Range<NodeGene>>#
using excessConnectionGenes = std::pair<Range<ConnectionGene>, Range<ConnectionGene>>#
using excessGenes = std::pair<excessNodeGenes, excessConnectionGenes>#
using disjointNodeGenes = std::pair<Range<NodeGene>, Range<NodeGene>>#
using disjointConnectionGenes = std::pair<Range<ConnectionGene>, Range<ConnectionGene>>#
using disjointGenes = std::pair<disjointNodeGenes, disjointConnectionGenes>#

Public Functions

Genome() noexcept#

default constructor builds an empty Genome.

Genome(const Genome &rhs) noexcept#

copy constructor

Parameters:

rhs – const Genome&

Genome(Genome &&rhs) noexcept#

move constructor

Parameters:

rhsGenome&&

Genome(std::size_t numInputs, std::size_t numOutputs, bool canBeRecursive = false, bool CPPN = false) noexcept#

builds a Genome that is feedforward connected from inputs to outputs.

Parameters:
  • numInputs

  • numOutputs

  • canBeRecursive

  • CPPN – with this true the genome will have random activation functions and will be able to change activations with Genome::mutate

Genome(std::size_t numInputs, std::size_t numHidden, std::size_t numOutputs, bool canBeRecursive = false, bool CPPN = false) noexcept#

builds a Genome that is feedforward connected from inputs to hidden to outputs.

Parameters:
  • numInputs – std::size_t

  • numHidden – std::size_t

  • numOutputs – std::size_t

  • canBeRecursive – bool

  • CPPN – bool with this true the genome will have random activations and will be able to change activations with Genome::mutate

Genome(JsonBox::Object o)#

loads a Genome JsonBox::Object

Parameters:

o – JsonBox::Object

Genome(const std::string &jsonfile)#

loads a Genome from a jsonfile previously saved with Genome::writeToFile

Parameters:

jsonfile – std::string&

void addGene(const NodeGene &ng) noexcept#

adds a NodeGene

Parameters:

ngNodeGene

void addGene(const ConnectionGene &cg) noexcept#

adds a ConnectionGene

Parameters:

cgConnectionGene

void setNodeChromosomes(std::vector<NodeGene> &&ngenes) noexcept#

setter for the NodeGene.

Parameters:

ngenes – std::vector<NodeGene>&&

std::vector<NodeGene> &getNodeChromosomes() noexcept#

getter for NodeGenes

Returns:

std::vector<NodeGene>&

const std::vector<NodeGene> &getNodeChromosomes() const noexcept#

const getter for NodeGenes

Returns:

const std::vector<NodeGene>&

void setConnectionChromosomes(std::vector<ConnectionGene> &&cgenes) noexcept#

setter for the ConnectionGene

Parameters:

cgenes – std::vector<ConnectionGene>&&

std::vector<ConnectionGene> &getConnectionChromosomes() noexcept#

getter for the connectionGenes

Returns:

std::vector<ConnectionGene>&

const std::vector<ConnectionGene> &getConnectionChromosomes() const noexcept#

const getter for the connectionGenes

Returns:

const std::vector<ConnectionGene>&

std::size_t getNumOfNodes(std::size_t layerID) const noexcept#

gets the number of nodes from a layer.

Parameters:

layerID – std::size_t count the nodes from that layer.

Returns:

std::size_t number of nodes

JsonBox::Value toJson() const noexcept#

returns a Json value with the information of the genome.

Returns:

JsonBox::Value

void writeToFile(const std::string &filename) const noexcept#

writes the genome to a json file.

EvoAI::Genome g(jsonfile);

Parameters:

filename – std::string file to write

void setFitness(double fit) noexcept#

sets the genome fitness

Parameters:

fit – double

void addFitness(double amount) noexcept#

adds the amount to the current fitness.

Parameters:

amount – double

double getFitness() const noexcept#

gets the fitness

Returns:

double

bool hasNodeGene(const NodeGene &ng) const noexcept#

Checks if it has the NodeGene.

Parameters:

ngNodeGene

Returns:

bool

bool hasConnectionGene(const ConnectionGene &cg) const noexcept#

Checks if it has the ConnectionGene.

Parameters:

cgConnectionGene

Returns:

bool true if it has the connection gene.

void setID(std::size_t gnmID) noexcept#

sets the genome id

Parameters:

gnmID – std::size_t

std::size_t getID() const noexcept#

gets the genome id

Returns:

std::size_t

void setSpeciesID(std::size_t spcID) noexcept#

setter for species ID

Parameters:

spcID – species id

std::size_t getSpeciesID() const noexcept#

returns the species id.

Returns:

std::size_t&

void setCppn(bool isCppn) noexcept#

setter for cppn

Parameters:

isCppn – bool

bool isCppn() const noexcept#

returns true if is a CPPN

Returns:

bool

inline void setRecurrentAllowed(bool isRecurrentAllowed) noexcept#

setter to change RecurrentAllowed

Parameters:

isRecurrentAllowed – bool

inline bool isRecurrentAllowed() const noexcept#

returns true if it allows to have recurrent connections.

Returns:

bool

void mutateAddNode() noexcept#

Adds a node and random connection and slices the connection adding the node in between.

void mutateAddConnection() noexcept#

Adds a random connection between two nodeGenes.

void mutateRemoveConnection() noexcept#

Removes a random connection between two nodeGenes.

void mutateWeights(double power) noexcept#

mutates the weights of a NodeGene or ConnectionGene.

Parameters:

power

void mutateDisable() noexcept#

selects a random connectionGene that is enabled and disables it

void mutateEnable() noexcept#

selects a random connectionGene that is not enabled and enables it.

void mutateActivationType() noexcept#

selects a random nodeGene and changes it activation function.

void mutate(float nodeRate = 0.2, float addConnRate = 0.3, float removeConnRate = 0.2, float perturbWeightsRate = 0.6, float enableRate = 0.35, float disableRate = 0.3, float actTypeRate = 0.4) noexcept#

mutates the genome only once depending on rates, the first activated is the only thing mutating. Rates from 0.0 to 1.0

Parameters:
  • nodeRate – float

  • addConnRate – float

  • removeConnRate – float

  • perturbWeightsRate – float

  • enableRate – float

  • disableRate – float

  • actTypeRate – float

bool isValid() noexcept#

Checks if the genome is valid.

Returns:

bool true if all is ok

~Genome() = default#
Genome &operator=(const Genome &rhs) noexcept#
Genome &operator=(Genome &&rhs) noexcept#
constexpr bool operator==(const Genome &rhs) const noexcept#
constexpr bool operator<(const Genome &rhs) const noexcept#
constexpr bool operator>(const Genome &rhs) const noexcept#

Public Static Functions

static Neuron::ActivationType getRandomActivationType() noexcept#

returns a random ActivationType.

Returns:

Neuron::ActivationType

static double distance(const Genome &g1, const Genome &g2, double c1 = 2.0, double c2 = 2.0, double c3 = 1.0) noexcept#

Calculates the distance between two genomes.

Parameters:
  • g1Genome

  • g2Genome

  • c1 – coefficient Gives importance to Excess Genes

  • c2 – coefficient Gives importance to Disjoints Genes

  • c3 – coefficient Gives importance to Weight Differences

Returns:

double

static matchingNodeGenes getMatchingNodeGenes(const Genome &g1, const Genome &g2) noexcept#

It returns a matchingNodeGenes of matching NodeGenes between g1 and g2.

Parameters:
Returns:

matchingNodeGenes

static matchingConnectionGenes getMatchingConnectionGenes(const Genome &g1, const Genome &g2) noexcept#

It returns a MatchingConnectionGenes of matching ConnectionGenes between g1 and g2.

Parameters:
Returns:

matchingConnectionGenes

static matchingChromosomes getMatchingChromosomes(const Genome &g1, const Genome &g2) noexcept#

It returns a matchingChromosomes of matching NodeGene, ConnectionGene between g1 and g2.

Parameters:
Returns:

matchingChromosomes

static excessGenes getExcessGenes(const Genome &g1, const Genome &g2, disjointGenes *hint = nullptr) noexcept#

It returns the excessGenes between g1 and g2.

Parameters:
  • g1 – const Genome&

  • g2 – const Genome&

  • hint – disjointGenes*

Returns:

excessGenes

static disjointGenes getDisjointGenes(const Genome &g1, const Genome &g2, matchingChromosomes *hint = nullptr) noexcept#

It returns the disjointGenes between g1 and g2.

Parameters:
  • g1 – const Genome&

  • g2 – const Genome&

  • hint – matchingChromosomes*

Returns:

disjointGenes

static Genome reproduce(const Genome &g1, const Genome &g2) noexcept#

Creates a new Genome from two parents, inheriting CPPN and RecurrentAllowed from any of the parents that is true. if g1 and g2 are equal it will copy g1.

Parameters:
Returns:

Genome

static NeuralNetwork makePhenotype(const Genome &g) noexcept#

Creates a NeuralNetwork from a Genome.

Parameters:

gGenome

Returns:

NeuralNetwork

static Genome makeGenome(NeuralNetwork &nn) noexcept#

Creates a genome from a neural network, it will not be exactly the same if the network wasn’t made from a genome.

Parameters:

nnNeuralNetwork

Returns:

Genome

template<class T, class InputIt = typename std::vector<T>::const_iterator>
struct Range#
#include <Genome.hpp>

helper struct for reproduce, getDisjointGenes, getExcessGenes, getMatching*

Public Types

using iterator = typename std::vector<T>::iterator#
using const_iterator = typename std::vector<T>::const_iterator#

Public Functions

inline Range(InputIt first, InputIt last)#
inline std::size_t size() const#
inline const T &operator[](std::size_t index) const noexcept#

Public Members

InputIt begin#
InputIt end#
class SubstrateInfo#
#include <HyperNeat.hpp>

A simple struct describing the number of inputs, hidden layers and neurons and the number of outputs for the substrate.

Author

Cristian Glez Cristian.glez.m@gmail.com

Public Functions

SubstrateInfo()#

default Constructor

SubstrateInfo(std::size_t nInputs, std::size_t nHiddenLayers, const std::vector<std::size_t> &nHiddenNeurons, std::size_t nOutputs, double LEO = 0.5, double minMaxWeight = 8.0, double Bias = 1.0)#

Constructor with all the info.

Parameters:
  • nInputs – std::size_t number of inputs

  • nHiddenLayers – std::size_t number of hidden layers

  • nHiddenNeurons – const std::vector<std::size_t>& numbers of hidden neurons in each hidden layer

  • nOutputs – std::size_t number of outputs

  • LEO – double leo min to set connection or not

  • minMaxWeight – double min and max weight

  • Bias – double bias for the network

SubstrateInfo(JsonBox::Object o)#

Constructor to load a JsonBox::Object.

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

returns a JsonBox::Value

Returns:

JsonBox::Value

~SubstrateInfo() = default#

Public Members

std::size_t numInputs#
std::size_t numHiddenLayers#
std::vector<std::size_t> numHiddenNeurons#
std::size_t numOutputs#
double leo#
double minmaxWeight#
double bias#
class HyperNeat#
#include <HyperNeat.hpp>

A HyperNeat is a Neural Network thats generates from a cppn.

Author

Cristian Glez Cristian.glez.m@gmail.com

Public Types

enum SubstrateConfiguration#

How the substrate will be decided. GRID: requires a genome that has 3 inputs and 2 outputs. SANDWICH: Requires a genome that has 5 inputs and 2 outputs.

Values:

enumerator GRID#
enumerator SANDWICH#

Public Functions

HyperNeat(JsonBox::Object o)#

constructor for a JsonBox::Object

Parameters:

o – JsonBox::Object

HyperNeat(const std::string &filename)#

constructor that loads a file wrote with HyperNeat::writeToFile

Parameters:

filename – const std::string&

HyperNeat(const SubstrateInfo &si, Genome &g, SubstrateConfiguration sc)#

constructs a HyperNeat from the genome specicied, It copies the genome.

Parameters:
  • si – const SubstrateInfo information about the substrate

  • gGenome& the genome

  • sc – SubstrateConfiguration

HyperNeat(const SubstrateInfo &si, SubstrateConfiguration sc = SubstrateConfiguration::GRID)#

constructs a HyperNeat, makes the genome.

Parameters:
  • si – const SubstrateInfo information about the substrate

  • sc – SubstrateConfiguration

void setNumInputs(std::size_t num) noexcept#

setter for numInputs

Parameters:

num – std::size_t

std::size_t getNumInputs() const noexcept#

getter for the numInputs

Returns:

std::size_t

void setNumHiddenLayers(std::size_t num) noexcept#

setter for numHiddenLayers

Parameters:

num – std::size_t

std::size_t getNumHiddenLayers() const noexcept#

getter for the numHiddenLayers

Returns:

std::size_t

void setNumHiddenNeurons(const std::vector<std::size_t> &num) noexcept#

setter for numHiddenNeurons

Parameters:

num – const std::vector<std::size_t>&

const std::vector<std::size_t> &getNumHiddenNeurons() const noexcept#

getter for the numHiddenNeurons

Returns:

const std::vector<std::size_t>&

void setNumOutputs(std::size_t num) noexcept#

setter for numOutputs

Parameters:

num – std::size_t

std::size_t getNumOutputs() const noexcept#

getter for the numOutputs.

Returns:

std::size_t

void setGenome(Genome &g)#

setter for the genome.

Parameters:

gGenome&

const Genome &getGenome() const noexcept#

getter for the genome.

Returns:

const Genome&

void setSubstrate(NeuralNetwork &&subst) noexcept#

This assumes that subst is a valid substrate for this HyperNeat.

this can be used when the substrate has been trained using backward but is recommended to use it directly.

Warning

substrate will be made again if changed by calling a invalidating method.

Parameters:

substNeuralNetwork&&

NeuralNetwork &getSubstrate() noexcept#

getter for the substrate

Returns:

NeuralNetwork&

void makeSubstrate() noexcept#

makes the substrate if is not in invalid state. call this after the setters.

void setInputs(std::vector<double> &&inputs)#

sets the inputs for the substrate.

Parameters:

inputs – std::vector<double>&&

void setInputs(const std::vector<double> &ins) noexcept#

sets the inputs returns true if succeeded, false if it failed.

Parameters:

ins – const std::vector<double>&

std::vector<double> run() noexcept#

runs the substrate

Returns:

std::vector<double>

std::vector<double> forward(const std::vector<double> &input) noexcept#

calls setsInput and calls run

Parameters:

input – const std::vector<double>&

Returns:

const std::vector<double>&

std::vector<double> forward(std::vector<double> &&input) noexcept#

calls setsInput and calls run

Parameters:

input – std::vector<double>&&

Returns:

std::vector<double>&&

void backward(std::vector<double> &&gradientLoss) noexcept#

calculates the gradients for the network.

Warning

It needs to be called before calling reset as the outputs and gradients would be 0.0

// ...
auto outputs = nn.forward({...});
nn.backward(lossFn{}.backward(...));
optim.step(epoch);
nn.reset() // it will reset the network

Parameters:

gradientLoss – std::vector<double>&&

void reset() noexcept#

resets the calculations done in substrate

void mutate(float nodeRate = 0.2, float addConnRate = 0.3, float removeConnRate = 0.2, float perturbWeightsRate = 0.6, float enableRate = 0.35, float disableRate = 0.3, float actTypeRate = 0.4) noexcept#

mutates the genome, rates from 0.0 to 1.0

Parameters:
  • nodeRate – float

  • addConnRate – float

  • removeConnRate – float

  • perturbWeightsRate – float

  • enableRate – float

  • disableRate – float

  • actTypeRate – float

void setFitness(double fitness) noexcept#

setter for fitness

Parameters:

fitness – double

double getFitness() const noexcept#

getter for fitness

Returns:

double

void setActivationType(std::size_t layer, Neuron::ActivationType at) noexcept#

changes the activation type for an entire layer in the substrate.

Parameters:
JsonBox::Value toJson() const noexcept#

returns a JsonBox::Value that’s the HyperNeat.

Returns:

JsonBox::Value

void writeToFile(const std::string &filename) const noexcept#

writes the HyperNeat object to a file.

Parameters:

filename – const std::string&

bool writeDotFile(const std::string &filename) noexcept#

writes a dot file for graphviz dot program.

Parameters:

filename

Returns:

bool

~HyperNeat() = default#

Public Static Functions

static std::string SubstrateConfigurationToString(SubstrateConfiguration sc) noexcept#

enum to string

Parameters:

scHyperNeat::SubstrateConfiguration

Returns:

std::string

static SubstrateConfiguration SubstrateConfigurationToEnum(const std::string &sc) noexcept#

string to enum

Parameters:

scHyperNeat::SubstrateConfiguration

Returns:

HyperNeat::SubstrateConfiguration

class NeuralNetwork#
#include <NeuralNetwork.hpp>

Author

Cristian Glez cristian.glez.m@gmail.com

Date

01/01/2016

Public Types

using trainingFormat = std::vector<std::vector<double>>#

Public Functions

NeuralNetwork()#

default constructor

NeuralNetwork(std::size_t numInputs, std::size_t numHiddenLayers, const std::vector<std::size_t> &numNeuronsPerHiddenLayer, std::size_t numOutputs, double bias)#

This will build the basic structure without connections.

Parameters:
  • numInputs – std::size_t Inputs that the nn will take.

  • numHiddenLayers – std::size_t Hidden layers that will be created.

  • numNeuronsPerHiddenLayer – const std::vector<std::size_t>& neurons per hidden layer

  • numOutputs – std::size_t number of outputs

  • bias – double bias for the neural network, it will put the same for every layer.

NeuralNetwork(JsonBox::Object o)#

Constructor for a json object.

Parameters:

o – JsonBox::Object

NeuralNetwork(const std::string &filename)#

Load the NN from a json file.

Parameters:

filename

NeuralNetwork &addLayer(const NeuronLayer &l)#

adds a layer to the neural network

Parameters:

l – const NeuronLayer&

Returns:

NeuralNetwork&

bool removeLayer(const NeuronLayer &l)#

Removes a layer.

Parameters:

l – const NeuronLayer&

Returns:

bool

std::vector<double> run()#

Process the NeuralNetwork.

Returns:

std::vector<double>

std::vector<double> forward(const std::vector<double> &input) noexcept#

calls setsInput and calls run

Parameters:

input – const std::vector<double>&

Returns:

const std::vector<double>&

std::vector<double> forward(std::vector<double> &&input) noexcept#

calls setsInput and calls run

Parameters:

input – std::vector<double>&&

Returns:

std::vector<double>&&

std::vector<double> backward(std::vector<double> &&gradientLoss) noexcept#

calculates the gradients for the network.

Warning

It needs to be called before calling reset as the outputs and gradients would be 0.0

// ...
auto outputs = nn.forward({...});
nn.backward(lossFn{}.backward(...));
optim.step(epoch);
nn.reset() // it will reset the network

Parameters:

gradientLoss – std::vector<double>&&

Returns:

std::vector<double> gradients of layer[0]

template<typename Optim, typename LossAlgo, class Dataset, typename TestFn>
inline std::vector<std::vector<double>> train(DataLoader<Dataset> &trainingDataset, DataLoader<Dataset> &testDataset, Optim &optim, std::size_t epoch, LossAlgo &&lossAlgo, TestFn &&testFn)#

method to train the neural network.

The test function should be std::pair<double aka avgTest, double aka accuracy> testFn(NeuralNetwork&, DataLoader<Dataset>) noexcept;

Template Parameters:
  • Optim – configured Optimizer

  • LossAlgo – the loss function to use

  • Dataset – dataset for training and testing

  • TestFn – test function

Parameters:
  • trainingDataset – DataLoader<Dataset>&

  • testDataset – DataLoader<Dataset>&

  • optim – Optimizer<Algo, SchedulerAlgo> Optimizer to apply updates for each batch

  • epoch – epoches to do

  • lossAlgo – LossAlgo

  • testFn – TestFn

Returns:

average loss of epoch, avg loss of test and accuracy

NeuralNetwork &setLayers(std::vector<NeuronLayer> &&lys)#

Sets the neural network layers.

Returns:

NeuralNetwork&

inline std::vector<NeuronLayer> &getLayers()#

returns the layers of the neural network.

Returns:

std::vector<NeuronLayer>&

NeuralNetwork &addNeuron(const Neuron &n, std::size_t layerIndex)#

adds a neuron to a specific layer

Parameters:
  • n – const Neuron&

  • layerIndex – std::size_t

Returns:

NeuralNetwork&

bool removeNeuron(Neuron *n)#

Removes a neuron and the connections it has.

Parameters:

nNeuron to remove

Returns:

bool

Link getIndex(Neuron *n) const#

gets the index of the layer and neuron from the neuron specified. Returns a link with -1,-1 for not found

Parameters:

n

Returns:

Link

bool setInputs(std::vector<double> &&ins) noexcept#

sets the inputs returns true if succeeded, false if it failed.

Parameters:

ins – std::vector<double>&&

Returns:

bool

bool setInputs(const std::vector<double> &ins) noexcept#

sets the inputs returns true if succeeded, false if it failed.

Parameters:

ins – const std::vector<double>&

Returns:

bool

NeuralNetwork &addConnection(const Connection &c)#

Adds a Connection.

Parameters:

c – const Connection&

Returns:

NeuralNetwork&

bool removeConnection(Connection &c)#

Removes a connection from the neural network.

Parameters:

cConnection&

Returns:

true if removed successfully.

Removes Connections with dest.

Parameters:

destLink

Removes Connections with src.

Parameters:

srcLink&&

std::vector<Connection*> &getConnections()#

getter for the connections

Returns:

std::vector<Connection*>&

std::vector<Connection*> getParameters() noexcept#

getter for the connections + biases

Returns:

std::vector<Connection*>

std::vector<Neuron*> &getNeurons()#

getter for the neurons

Returns:

std::vector<Neuron*>&

finds a connection returns nullptr if not found.

Parameters:
Returns:

Connection* nullptr if not found

Checks if a connection exists.

Returns:

bool

inline std::size_t size() const#

Returns how many layers it has.

Returns:

std::size_t

void reset()#

resets the neurons that are not Neuron::Type::CONTEXT

void resetContext()#

resets the neurons that are Neuron::Type::CONTEXT

void resetConnections()#

resets the gradients of the connections

JsonBox::Value toJson() const#

Converts to a JsonBox::Value.

Returns:

JsonBox::Value

void writeToFile(const std::string &filename) const#

Writes the neural network json to a file.

Parameters:

filename

bool writeDotFile(const std::string &filename) noexcept#

writes a dot file for graphviz dot program.

Parameters:

filename – const std::string&

Returns:

bool

void clear()#

clears the Neural Network.

inline double getLastAvgLoss() const noexcept#

gives the last Average Loss

Returns:

double lastAvgLoss

inline const std::uint64_t &getGlobalStep() const noexcept#

gives the globalStep

Returns:

const std::uint64_t globalStep

NeuronLayer &operator[](std::size_t index)#

direct access to layers and neurons

neuralnetwork[1][1].setBiasWeight(-0.3); // sets the biasWeight of layer 1 and neuron 1
neuralnetwork[3][0].getOutput(); // gets output of layer 3 and neuron 0

Warning

Does not check if index is out of range.

Parameters:

index – std::size_t index layer

Returns:

NeuronLayer&

std::pair<Neuron&, Neuron&> operator[](Connection &conn) noexcept#

return src and dest of the connection

Parameters:

connEvoAI::Connection&

auto& [src, dest] = nn[conn];

Returns:

std::pair<Neuron&, Neuron&>

bool operator==(const NeuralNetwork &rhs) const#

compares two neural networks

Parameters:

rhs

~NeuralNetwork() = default#
class Neuron#
#include <Neuron.hpp>

A basic neuron.

Author

Cristian Glez Cristian.glez.m@gmail.com

Public Types

enum Type#

Neuron::Type defines the type of a neuron. CONTEXT: makes the neuron remember outputs from other neurons HIDDEN: is a hidden neuron. INPUT: this neuron will take the values provided and just pass them along. OUTPUT: this neuron will hold the results.

Values:

enumerator CONTEXT#
enumerator HIDDEN#
enumerator INPUT#
enumerator OUTPUT#
enum ActivationType#

Type of activation that will be used for the neuron.

Values:

enumerator SINUSOID#
enumerator COSINE#
enumerator GAUSSIAN#
enumerator SIGMOID#
enumerator IDENTITY#
enumerator MODULUS#
enumerator STEPPED_SIGMOID#
enumerator SWISH#
enumerator TANH#
enumerator TAN#
enumerator RELU#
enumerator NOISY_RELU#
enumerator LEAKY_RELU#
enumerator EXPONENTIAL#
enumerator SQUARE#
enumerator CUBE#
enumerator SOFTPLUS#
enumerator CLAMP#
enumerator INV#
enumerator LOG#
enumerator ABS#
enumerator HAT#
enumerator LAST_CPPN_ACTIVATION_TYPE#
enumerator SOFTMAX#

Public Functions

Neuron()#

Default Constructor type defaults to Type::HIDDEN activationType defaults to ActivationType:

Neuron(JsonBox::Object o)#

Constructor for json object.

Parameters:

o – JsonBox::Object

Neuron(Type t)#

Constructor that takes a Neuron::Type parameter.

Parameters:

t – const Type&

Neuron &setType(Type t) noexcept#

Setter for Neuron::Type.

Parameters:

tNeuron::Type

Returns:

Neuron&

inline Type getType() const noexcept#

getter for Neuron::Type

Returns:

Type&

inline double getOutput() const noexcept#

getter for output

Returns:

double&

Neuron &setOutput(double out) noexcept#

setter for Output

Parameters:

out – double

Returns:

Neuron&

Neuron &addSum(double val) noexcept#

add value to Sum

Parameters:

val – double

Returns:

Neuron&

inline double getSum() const noexcept#

getter for sum

Returns:

double

Neuron &setSum(double val) noexcept#

setter for the sum

Parameters:

val – double

Returns:

Neuron&

inline double getGradient() const noexcept#

getter for gradient

Returns:

double&

Neuron &setGradient(double gradient) noexcept#

gradient for backprop

Parameters:

gradient – double

Returns:

Neuron&

Neuron &addGradient(double grad) noexcept#

add to gradient

Parameters:

grad

Returns:

Neuron&

Neuron &reset() noexcept#

resets the neuron if is not Type:CONTEXT

Returns:

Neuron&

Neuron &resetContext() noexcept#

resets the neuron if is Type:CONTEXT

Returns:

Neuron&

JsonBox::Value toJson() const noexcept#

Returns a json value from the object.

Returns:

JsonBox::Value json

std::string toString(const std::string &delimiter = ",") const noexcept#

Serialize the neuron info to string.

Parameters:

delimiter – the thing thats between the values. example: “\n”, “\t” etc.

Returns:

std::string

Neuron &addConnection(const Connection &c) noexcept#

Adds a Connection.

Parameters:

c – const Connection&

Returns:

Neuron&

bool removeConnection(const Connection &c)#

Removes a Connection.

Parameters:

c – const Connection&

Returns:

bool

inline std::vector<Connection> &getConnections() noexcept#

Getter for Connections.

Returns:

std::vector<Connection>&

std::size_t size()#

returns how many connections it has.

Returns:

std::size_t

Connection &operator[](std::size_t index)#

direct access to connections.

Parameters:

index – const std::size_t index

Returns:

Connection&

bool operator==(const Neuron &rhs) const#

Equality Operator.

Parameters:

rhs

Returns:

bool

inline Connection *getBiasPtr() noexcept#

get a ptr to the internal connection bias(for parameters)

Returns:

Connection*

inline double getBiasWeight() const noexcept#

Getter for the Bias Weight.

Returns:

double biasWeight

Neuron &setBiasWeight(double bw) noexcept#

Setter for the bias Weight.

Parameters:

bw – biasWeight

Returns:

Neuron&

Neuron &setBiasGradient(double grad) noexcept#

setter for bias gradient

Parameters:

grad

Returns:

double

inline double getBiasGradient() const noexcept#

getter for bias gradient

Returns:

double

void clearConnections() noexcept#

Clears the neuron’s connections.

inline bool hasConnections() const noexcept#

returns true if has some connection.

Returns:

bool

inline ActivationType getActivationType() const noexcept#

Returns the type of activation that will be used to trigger this neuron.

Returns:

Neuron::ActivationType

Neuron &setActivationType(Neuron::ActivationType atype) noexcept#

setter for activation type

Parameters:

atypeNeuron::ActivationType

Returns:

Neuron&

~Neuron() = default#

Public Static Functions

static std::string typeToString(Neuron::Type t) noexcept#

returns Neuron::Type to String

Parameters:

t

Returns:

std::string

static Type typeToEnum(const std::string &t) noexcept#

returns a string Neuron::Type

Parameters:

t

Returns:

int

static std::string activationTypeToString(Neuron::ActivationType at) noexcept#

returns Neuron::ActivationType to String

Parameters:

at

Returns:

std::string

static ActivationType activationTypeToEnum(const std::string &at) noexcept#

returns a string Neuron::ActivationType

Parameters:

at

Returns:

int

class NeuronLayer#
#include <NeuronLayer.hpp>

A neuron layer.

Author

Cristian Glez Cristian.glez.m@gmail.com

Public Functions

NeuronLayer()#

default contructor

NeuronLayer(std::size_t numNeurons, const Neuron::Type &t, double Bias)#

Constructor that will build the neurons with random bias weights.

Parameters:
  • numNeurons – std::size_t

  • t – const Neuron::Type&

  • Bias – double

NeuronLayer(JsonBox::Object o)#

Constructor from json file.

Parameters:

o – JsonBox::Object

std::vector<Neuron> &getNeurons()#

getter for the neurons

Returns:

std::vector<Neuron>&

NeuronLayer &setNeurons(std::vector<Neuron> &&ns)#

takes a neuron vector and steals it.

Parameters:

ns – std::vector<Neuron>&&

Returns:

NeuronLayer&

std::size_t size() const#

gives the how many neurons it has.

NeuronLayer &setType(Neuron::Type t)#

setter for Neuron::Type will traverse each neuron and set the type to t

Parameters:

tNeuron::Type

Returns:

NeuronLayer&

inline const Neuron::Type &getType() const#

getter for Neuron::Type

Returns:

Neuron::Type&

NeuronLayer &setBias(double Bias)#

setter for bias

Parameters:

Bias – double

Returns:

NeuronLayer&

inline double getBias() const#

getter for the bias

Returns:

double

NeuronLayer &addNeuron(const Neuron &n)#

adds a neuron

Parameters:

n – const Neuron&

Returns:

NeuronLayer&

bool removeNeuron(Neuron *n)#

Removes a Neuron from the layer This method should be called when there are no connections.

Warning

It does not remove connections if some other neuron has a connection to this neuron it won’t be removed and it will cause a segmentation fault, use NeuralNetwork::removeNeuron Instead.

Parameters:

n – Neuron*

Returns:

bool

bool hasNeuron(Neuron *n)#

Checks if a neuron is from this layer.

Parameters:

n – Neuron*

Returns:

bool

NeuronLayer &addConnection(const Connection &c)#

adds a Connection

Warning

Before adding a Connection you need to add the neurons.

Parameters:

c – const Connection&

Returns:

NeuronLayer&

bool removeConnection(const Connection &c)#

removes a connection

Warning

the connection could be invalid.

Parameters:

c – const Connection&

Returns:

bool

void reset()#

will reset the layer’s neurons.

void resetContext()#

will reset the layer’s neurons that are Neuron::Type::CONTEXT

inline Neuron::ActivationType getActivationType() const noexcept#

getter for the ActivationType

Returns:

Neuron::ActivationType

NeuronLayer &setActivationType(Neuron::ActivationType atype)#

setter for activation type It will traverse each neuron and set the ActivationType to atype.

Parameters:

atypeNeuron::ActivationType

Returns:

NeuronLayer&

NeuronLayer &setCyclesLimit(int cycles)#

Sets how many cycles to reset the context neurons.

Parameters:

cycles

Returns:

NeuronLayer&

inline int getCyclesLimit() const noexcept#

getter for the cycles limit

Returns:

int

JsonBox::Value toJson() const#

returns a JsonBox::Value with the current info.

Returns:

JsonBox::Value

Neuron &operator[](std::size_t index)#

Direct Access to Neurons.

Warning

Does not check if index is out of range

NeuronLayer[2].getOutput() // gets outputs of neuron 2

Parameters:

index – std::size_t

Returns:

Neuron&

const Neuron &operator[](std::size_t index) const#

Direct Access to Neurons.

Parameters:

index – std::size_t

Returns:

Neuron& const

bool operator==(const NeuronLayer &rhs) const#

compare layers

Parameters:

rhs

Returns:

bool

std::vector<double> backward() const noexcept#

it will return gradients from its neurons.

// ...
nn2.backward(lossFn.backward(...));
nn1.backward(nn2[0].backward());
// ...

Warning

It should be used after calling NeuralNetwork::backward to connect input layer to another NeuralNetwork.

Returns:

std::vector<double> gradients

~NeuronLayer() = default#
class NodeGene#
#include <NodeGene.hpp>

NodeGene for NEAT Algorithm.

Author

Cristian Glez cristian.glez.m@gmail.com

Public Functions

NodeGene(std::size_t lyrID, std::size_t nrnID)#

Constructor Default Type = Neuron::Type::HIDDEN Default ActType = Neuron::ActivationType::SIGMOID.

Parameters:
  • lyrID – std::size_t

  • nrnID – std::size_t

NodeGene(std::size_t lyrID, std::size_t nrnID, Neuron::Type nt, Neuron::ActivationType nat)#

Constructor.

Parameters:
NodeGene(const NodeGene &rhs) noexcept#

copy constructor

Parameters:

rhs[in] NodeGene

NodeGene(NodeGene &&rhs) noexcept#

move constructor

Parameters:

rhs[in] NodeGene

NodeGene(JsonBox::Object o)#

Constructor with a json object.

Parameters:

o – JsonBox::Object&

std::string toString(std::string delimiter = " ") const noexcept#

convert NodeGene to a std::string

Parameters:

delimiter – default “ “

Returns:

std::string

JsonBox::Value toJson() const noexcept#

returns a json of the nodeGene

Returns:

JsonBox::Value

std::size_t getLayerID() const noexcept#

getter for the layer id

Returns:

std::size_t layer id

std::size_t getNeuronID() const noexcept#

getter for the neuron id

Returns:

std::size_t neuron id

void setNeuronType(Neuron::Type t) noexcept#

sets a new Neuron::Type

Parameters:

tNeuron::Type

Neuron::Type getNeuronType() const noexcept#

getter for Neuron::Type

Returns:

Neuron::Type

void setActType(Neuron::ActivationType at) noexcept#

sets a new Neuron::ActivationType

Parameters:

atNeuron::ActivationType

Neuron::ActivationType getActType() const noexcept#

getter for Neuron::ActivationType

Returns:

Neuron::ActivationType

std::size_t getInnovationID() const noexcept#

getter for InnovationID

Returns:

std::size_t

void addBias(double amount) noexcept#

adds the amount to current bias.

Parameters:

amount

void setBias(double bw) noexcept#

setter for the node bias.

Parameters:

bw – bias weight

double getBias() const noexcept#

getter for bias

Returns:

double bias

bool operator==(const NodeGene &rhs) const#
bool operator!=(const NodeGene &rhs) const#
void operator=(const NodeGene &rhs) noexcept#
void operator=(NodeGene &&rhs) noexcept#
constexpr bool operator<(const NodeGene &rhs) const noexcept#
constexpr bool operator>(const NodeGene &rhs) const noexcept#
~NodeGene() = default#

Friends

inline friend std::ostream &operator<<(std::ostream &o, const EvoAI::NodeGene &ng) noexcept#
struct Adam#
#include <Adam.hpp>

Adam Optimization Algorithm.

Todo:

impl parallelism for updating weights?

Public Functions

explicit Adam(std::vector<Connection*> &&parameters, bool maximize = false, double beta1 = 0.9, double beta2 = 0.999, double epsilon = 1e-8, bool accumGradients = false)#

constructor

Parameters:
  • parameters – std::vector<Connection*>

  • maximize – bool

  • beta1 – double

  • beta2 – double

  • epsilon – double

  • accumGradients – bool if true it won’t average the gradients

Adam(JsonBox::Object o, std::vector<Connection*> &&parameters)#

constructor to load from a JsonBox::Object

Parameters:
  • o – JsonBox::Object

  • parameters – std::vector<Connection*>

JsonBox::Value toJson() const noexcept#

converts to JsonBox::Value

Returns:

JsonBox::Value

void operator()(double lr, std::size_t batchSize) noexcept#

update the weights

Parameters:
  • lr – double learning rate

  • batchSize – double batch size

void zeroGrad() noexcept#

resets the gradients to 0.0.

~Adam() = default#

Public Members

std::vector<Connection*> m_params#
double m_beta1#
double m_beta2#
std::vector<double> m_mWeight#
std::vector<double> m_vWeight#
double m_epsilon#
std::size_t m_t#
bool m_maximize#
bool m_accumGradients#
struct SGD#
#include <SGD.hpp>

Stochastic Gradient Descend Algorithm.

Todo:

impl parallelism for updating weights?

Public Functions

explicit SGD(std::vector<Connection*> &&parameters, double momentum = 0.0, bool nesterov = false, bool maximize = false, bool accumGradients = false)#

constructor

Parameters:
  • parameters – std::vector<Connection*>

  • momentum – double

  • nesterov – bool

  • maximize – bool

  • accumGradients – bool if true it won’t average the gradients

SGD(JsonBox::Object o, std::vector<Connection*> &&parameters)#

constructor for JsonBox::Object

Parameters:
  • o – JsonBox::Object

  • parameters – std::vector<Connection*>

JsonBox::Value toJson() const noexcept#

converts to a JsonBox::Value

Returns:

JsonBox::Value

void operator()(double lr, std::size_t batchSize) noexcept#

updates the weights

Parameters:
  • lr – learning rate

  • batchSize – batch size to average the gradients with.

void zeroGrad() noexcept#

resets the gradients to 0.0.

Public Members

bool m_nesterov#
bool m_maximize#
bool m_accumGradients#
std::vector<Connection*> m_params#
std::vector<double> m_momentumWeights#
std::vector<double> m_velocityWeights#
template<class Algo, class SchedulerAlgo>
class Optimizer#
#include <Optimizers.hpp>

Optimizer.

Algo needs to fulfill these conditions:

Algo has a constructor Algo::Algo(JsonBox::Object, std::vector<Connection*>)

Algo has a member function JsonBox::Value toJson() const

noexcept

Algo has a double operator()(double, std::size_t) const noexcept

Template Parameters:

Public Types

using AlgoType = Algo#
using SchedulerType = Scheduler<SchedulerAlgo>#

Public Functions

Optimizer(double lr, std::size_t batchSize, const Algo &algo, const Scheduler<SchedulerAlgo> &scheduler)#

constructor

Parameters:
Optimizer(JsonBox::Object o, std::vector<Connection*> &&parameters)#

constructor for JsonBox::Object

Parameters:
  • o – JsonBox::Object

  • parameters – std::vector<Connection*>&&

JsonBox::Value toJson() const noexcept#

converts to a JsonBox::Value

Returns:

JsonBox::Value

void setBatchSize(std::size_t batchsize) noexcept#

setter for batch size

std::size_t getBatchSize() const noexcept#

getter for batch size

Returns:

std::size_t

void step(std::size_t epoch) noexcept#

step to update weights and lr if applies.

Parameters:

epoch

void zeroGrad() noexcept#

reset gradients

Algo &getAlgo() noexcept#

get Algo(SGD, Adam, …)

Returns:

Algo&

Scheduler<SchedulerAlgo> &getScheduler() noexcept#

get Scheduler

Returns:

Scheduler<SchedulerAlgo>&

~Optimizer() = default#
template<typename T>
class Population#
#include <Population.hpp>

Population<T> is an utility class that allows to evolve a population easily.

T needs to fulfill these conditions:

T has a member function JsonBox::Value

toJson() const

noexcept

T has a constructor T::T(JsonBox::Object)

T has a member function double getFitness() const noexcept

T has a member function void setFitness(double) noexcept

T has a static member function static double T::distance(const T&, const T&, double, double, double) noexcept

T has a static member function static T T::reproduce(const T&, const T&) noexcept

If Population<T*> it will act as an observer, what does this means: Population<T*>::addMember

will take a T*

If Population<T> it will act as an owner, what does this means:

Population<T>::addMember will take a T&&
Author

Cristian Gonzalez Cristian.glez.m@gmail.com

Warning

You can’t use Population<T*>(JsonBox::Object) or Population<T*>(const std::string& filename) to load a Population.json also you can’t use Population<T*>(std::size_t size, Args…args)

Template Parameters:

T – a class fulfilling meta::is_populable_v<T>

Public Types

using value_type = T#
using reference = std::remove_reference_t<std::remove_pointer_t<T>>&#
using rvalue_reference = std::remove_reference_t<std::remove_pointer_t<T>>&&#
using const_reference = const std::remove_reference_t<std::remove_pointer_t<T>>&#
using pointer = std::remove_pointer_t<T>*#
using const_pointer = const std::remove_pointer_t<T>*#
using species_map = std::map<std::size_t, std::unique_ptr<Species<value_type>>>#
using result_t = typename std::pair<std::vector<pointer>, std::vector<std::remove_pointer_t<std::remove_reference_t<T>>>>#

result_t returned by reproduce and regrowPopulationFromElites when Population is an observer. returns a pair of vector<T*> and vector<T>, the first one is used to replace members that are not performing well, the second is the new members to be added.

using result_or_void_t = typename std::conditional_t<std::is_pointer_v<T>, result_t, void>#
using species_ids_or_void_t = typename std::conditional_t<std::is_pointer_v<T>, std::vector<std::size_t>, void>#

Public Functions

Population()#

basic constructor

Population(const Population<T> &other) noexcept = delete#

copy constructor is deleted.

Parameters:

other – Population<T>

Population(Population<T> &&other) noexcept = default#

move constructor

Parameters:

other – Population<T>

Population(std::function<T()> &&fn, std::size_t size, double c1 = 2.0, double c2 = 2.0, double c3 = 1.0)#

creates a population of size with provided function, if using T* remember to avoid memory re-allocations.

Parameters:
  • fn – std::function<T()>&& generator function

  • size – std::size_t number of members

  • c1 – double coefficient for importance

  • c2 – double coefficient for importance

  • c3 – double coefficient for importance

template<typename ...Args>
Population(std::size_t size, double c1, double c2, double c3, Args&&... args)#

creates a population of specified size with the args provided.

Warning

It cannot be used with T* use “Population(std::function<T()>&& fn, std::size_t size)” instead.

Parameters:
  • size – std::size_t number of members.

  • c1 – double coefficient for importance

  • c2 – double coefficient for importance

  • c3 – double coefficient for importance

  • args – Args&&…

Template Parameters:

Args – arguments for T constructor.

Population(JsonBox::Object o)#

Constructor for JsonBox::Object.

Warning

It cannot be used with T*

Parameters:

o – JsonBox::Object

Population(const std::string &filename)#

Constructor to load a Population from a json file.

Warning

It cannot be used with T*

Parameters:

filename – loads a json file written with Population::writeTofile

void addMember(std::conditional_t<std::is_pointer_v<value_type>, pointer, rvalue_reference> m, double c1 = 2.0, double c2 = 2.0, double c3 = 1.0) noexcept#

Adds a T, It will set T ID if owning it and it will check species, if it is not compatible with any other it will make a new species.

Warning

Invalidates iterators of Population::getMembers().

Parameters:
  • m – T&& if Population<T> otherwise T* if Population<T*>

  • c1 – double coefficient for importance

  • c2 – double coefficient for importance

  • c3 – double coefficient for importance

void removeMember(reference m) noexcept#

removes a T and his species if its left empty.

Warning

Invalidates iterators.

Parameters:

m – const T&

void removeMembers(std::vector<Population<T>::pointer> &&membrs) noexcept#

removes a list of T and his species if its left empty, use this if you need to remove many T* without invalidating them.

Warning

Invalidates iterators.

Parameters:

membrs – std::vector<T*> members to remove

void addSpecies(std::unique_ptr<Species<value_type>> &&sp) noexcept#

adds a Species<T>, doesn’t change its ID but it will overwrite the species if already added.

Parameters:

sp – std::unique_ptr<Species<T>>&&

void removeSpecies(const Species<value_type> &sp) noexcept#

removes a Species<T>

Warning

Invalidates iterators of Population::getMembers() and Population::getSpecies().

Parameters:

sp – const Species&

pointer findMember(std::size_t id) noexcept#

finds a member, returns nullptr if not found

Parameters:

id – std::size_t member ID

Returns:

T* or nullptr if not found

pointer getBestMember() noexcept#

gets the best member it has in the Population.

Returns:

T* or nullptr if not found.

Species<value_type> *findSpecies(std::size_t id) noexcept#

finds a Species, returns nullptr if not found.

Parameters:

id – std::size_t Species ID

Returns:

Species* or nullptr if not found.

void eval(std::function<void(reference)> &&fn) noexcept#

evaluate the members of the population.

Parameters:

fn – std::function<void(T&)>&&

std::vector<pointer> &getMembers() noexcept#

returns the population cache

Warning

The pointers will get invalidated if added or removed a species or member to the population.

Returns:

std::vector<T*>&

species_map &getSpecies() noexcept#

returns the species_map

Returns:

species_map&

void clear() noexcept#

clears all species and their members.

species_ids_or_void_t removeOldSpecies() noexcept#

It removes species older than Population::maxAge or that are empty.

it returns the ids of the species that had been removed when T* otherwise void.

std::vector<T> storage(...);
storage.reserve(maxPop);
// createMembers can use a stack / queue / etc to check dead members to 
// replace them or add new members. (possible implementation at PopulationTest.hpp)
Population<T*> p(createMembers, 100);
// more code
auto ids = p.removeOldSpecies();
// will check all members and those that their speciesID match will be
// added to deadMembers. (possible implementation at PopulationTest.hpp)
addToDeadMembers(ids);

Returns:

species_ids_or_void_t std::vector<std::size_t> when T* or void if T

void increaseAge() noexcept#

Increases the age by 1 or 2 if species is stagnant.

if there are novel species it will make them not novel, if a species is stagnant it will increase its age by 2 otherwise by 1.

species_ids_or_void_t increaseAgeAndRemoveOldSpecies() noexcept#

Increases the age by 1 or 2 if species is stagnant and removes species that are over Population<T>::maxAge or empty.

if there are novel species it will make them not novel, if a species is stagnant it will increase its age by 2 otherwise by 1, it will remove those species that are greater than maxAge or empty, it returns the ids of the species that had been removed when T* otherwise void.

Returns:

species_ids_or_void_t std::vector<std::size_t> when T* or void if T

template<typename ...Args>
void regrowPopulation(double c1, double c2, double c3, Args&&... args) noexcept#

Add new members to the population.

Warning

It cannot be used if using T* use “Population<T*>::regrowPopulation(Fn&& fn)”.

Parameters:
  • c1 – double coefficient for importance

  • c2 – double coefficient for importance

  • c3 – double coefficient for importance

  • args – arguments for constructor of T

template<typename Fn>
void regrowPopulation(Fn &&fn, double c1 = 2.0, double c2 = 2.0, double c3 = 1.0) noexcept#

Add new members to the population, remember to assign an id to T when using Population<T*>.

std::vector<T> storage;
storage.reserve(maxPop);
Population<T*> pop(createMembers, maxPop); // createMembers possible implementation at tests/PopulationTest.hpp
// more code
pop.regrowPopulation(createMembers);

Template Parameters:

Fn – function

Parameters:
  • fn – fn function returning a T or T*

  • c1 – double coefficient for importance

  • c2 – double coefficient for importance

  • c3 – double coefficient for importance

template<typename SelectionAlgo>
result_or_void_t regrowPopulationFromElites(SelectionAlgo &&sa, bool interSpecies, double c1 = 2.0, double c2 = 2.0, double c3 = 1.0) noexcept#

regrow the population from the best members, the returned pair.first is always empty, in case we are using removeOldSpecies or increaseAgeAndRemoveOldSpecies we also need to call regrowPopulation in case *removeOldSpecies kills the whole population.

// code
Population<T*> pop(createMembers, maxPop);
auto sa = SelectionAlgorithms::Truncation<Genome*>{maxPop};
// more code
auto res = p.regrowPopulationFromElites(sa, false);
replace(res.first, res.second); // replace possible implementation at PopulationTest.hpp
// more code

Template Parameters:

SelectionAlgo

Parameters:
  • sa – Selection algorithm to use.

  • interSpecies – if is permitted to reproduce between other species.

  • c1 – double coefficient for importance

  • c2 – double coefficient for importance

  • c3 – double coefficient for importance

Returns:

result_or_void_t void if Population is the owner result_t otherwise.

template<typename SelectionAlgo>
result_or_void_t reproduce(SelectionAlgo &&sa, bool interSpecies) noexcept#

Replaces the members with less fitness of the Population with the children of the selected couples.

In case you want your own selection algorithm you will need to implement a functor overloading operator() This one will handle interspecies reproduction by selecting couples from members

std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*>& members, std::size_t numberToSelect) noexcept;

and this will handle species reproduction by selecting couples from species

std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>>& species, std::size_t numberToSelect) noexcept;

they must return a std::vector<Selected<T>> where every Selected<T>::loser should be unique.

// code
Population<T*> pop(createMembers, maxPop);
auto sa = SelectionAlgorithms::Truncation<Genome*>{maxPop};
// more code
auto res = p.reproduce(sa, false);
replace(res.first, res.second); // replace possible implementation at PopulationTest.hpp
// more code

Parameters:
  • sa[in] Selection algorithm to use

  • interSpecies[in] if is permitted to reproduce between other species.

Returns:

result_or_void_t void if Population is the owner result_t otherwise.

void orderMembersByFitness() noexcept#

orders the members from the population by fitness

void orderMembersByID() noexcept#

orders the members from the population by their ids

void rankWithinSpecies() noexcept#

Orders all the members inside their own species by fitness.

std::size_t getPopulationSize() noexcept#

returns the population current size.

Returns:

std::size_t

void setPopulationMaxSize(std::size_t maxSize) noexcept#

sets the max size of the population, use regrowPopulation to regrow to max population.

Parameters:

maxSize[in] max size for population

std::size_t getPopulationMaxSize() const noexcept#

returns the population Max Size.

Returns:

std::size_t

std::size_t getSpeciesSize() const noexcept#

return number of species.

Returns:

std::size_t

void setMaxAge(std::size_t age) noexcept#

setter for maxAge

Parameters:

age – std::size_t

std::size_t getMaxAge() const noexcept#

returns maxAge

Parameters:

std::size_t

void setCompatibilityThreshold(double compThreshold) noexcept#

setter for the comparability Threshold

Parameters:

compThreshold – double

double getCompatibilityThreshold() const noexcept#

getter for the comparability Threshold

Returns:

double

double computeAvgFitness() noexcept#

computes the average fitness of the Population.

Returns:

double

JsonBox::Value toJson() const noexcept#

returns a JsonBox::Value with the current info.

Returns:

JsonBox::Value

void writeToFile(const std::string &filename)#

Writes the Population to a json file.

Parameters:

filename – const std::string&

~Population() = default#
Population<T> &operator=(const Population<T> &rhs) noexcept = delete#
Population<T> &operator=(Population<T> &&rhs) noexcept = default#
template<typename SelectionAlgo>
Population<T>::result_or_void_t regrowPopulationFromElites(SelectionAlgo &&sa, bool interSpecies, [[maybe_unused]] double c1, [[maybe_unused]] double c2, [[maybe_unused]] double c3) noexcept#

Public Static Functions

static inline result_t make_result() noexcept#

Utility to make a result_t, used by reproduce and regrowPopulationFromElites to manage ownership.

Returns:

result_t

struct ConstantLR#
#include <ConstantLR.hpp>

ConstantLR Scheduler Algorithm.

Learning rate will not change

Public Functions

ConstantLR() = default#

default constructor

ConstantLR(JsonBox::Object o)#

constructor for JsonBox::Object

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

converts to JsonBox::Value

Returns:

JsonBox::Value

double operator()(double lr, std::size_t epoch) const noexcept#

applies the scheduling to lr

Parameters:
  • lr

  • epoch

struct ExponentialLR#
#include <ExponentialLR.hpp>

ExponentialLR Scheduler Algorithm.

Param m_gamma:

double

auto eLR = ExponentialLR{0.5};

Public Functions

ExponentialLR(double gamma = 0.1)#

constructor

Parameters:

gamma

ExponentialLR(JsonBox::Object o)#

constructor for JsonBox::Object

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

converts to a JsonBox::Value

Returns:

JsonBox::Value

double operator()(double lr, std::size_t epoch) const noexcept#

applies the scheduling to lr

Parameters:
  • lr

  • epoch

Public Members

double m_gamma#
struct MultiplicativeLR#
#include <MultiplicativeLR.hpp>

MultiplicativeLR Scheduler Algorithm.

auto mLR = MultiplicativeLR{0.1};

Public Functions

MultiplicativeLR(double factor = 0.1)#

constructor

Parameters:

factor

MultiplicativeLR(JsonBox::Object o)#

constructor for JsonBox::Object

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

converts to a JsonBox::Value

Returns:

JsonBox::Value

double operator()(double lr, std::size_t epoch) const noexcept#

applies the scheduling to lr

Parameters:
  • lr

  • epoch

Public Members

double m_factor#
struct MultiStepLR#
#include <MultiStepLR.hpp>

MultiStepLR Scheduler Algorithm.

auto msLR = MultiStepLR{{10,20,50,55}, 0.1};

Public Functions

MultiStepLR(std::vector<std::size_t> &&steps, double gamma = 0.1)#

Constructor.

Parameters:
  • steps – std::vector<std::size_t>&&

  • gamma – double

MultiStepLR(JsonBox::Object o)#

constructor for JsonBox::Object

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

converts to a JsonBox::Value

Returns:

JsonBox::Value

double operator()(double lr, std::size_t epoch) const noexcept#

applies the scheduling to lr

Parameters:
  • lr – double

  • epoch – std::size_t

Public Members

std::vector<std::size_t> m_steps#
double m_gamma#
mutable std::size_t m_counter#
struct StepLR#
#include <StepLR.hpp>

StepLR Scheduler Algorithm.

auto sLR = StepLR{10,0.1}; // every 10 steps will update lr

Public Functions

StepLR(std::size_t step = 10u, double gamma = 0.1)#

constructor

Parameters:
  • step – std::size_t

  • gamma – double

StepLR(JsonBox::Object o)#

constructor for JsonBox::Object

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

converts to JsonBox::Value

Returns:

JsonBox::Value

double operator()(double lr, std::size_t epoch) const noexcept#

applies the scheduler to lr

Parameters:
  • lr

  • epoch

Public Members

std::size_t m_step#
double m_gamma#
template<class Algo>
struct Scheduler#
#include <Schedulers.hpp>

Scheduler to update the learning rate.

Algo needs to fulfill these conditions:

Algo has a member function JsonBox::Value

toJson() const

noexcept

Algo has a constructor Algo::Algo(JsonBox::Object)

Algo has a double operator()(double, std::size_t) const noexcept

Template Parameters:

Algo – is an scheduling algorithm

Public Types

using type = Algo#

Public Functions

Scheduler(Algo &&algo)#

constructor

Parameters:

algo – Algo&& scheduling algorithm (SGD, Adam, …)

Scheduler(JsonBox::Object o)#

constructor for JsonBox::Object

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

converts to JsonBox::Value

Returns:

JsonBox::Value

double step(double lr, std::size_t epoch) const noexcept#

applies the scheduling step

Parameters:
  • lr

  • epoch

Returns:

double updated learning rate

Algo &getAlgo() const noexcept#

returns the Algo& to change settings, etc.

Returns:

Algo&

~Scheduler() = default#

Public Members

Algo stepFn#
template<typename T>
class Species#
#include <Species.hpp>

Class that represents a Species.

T needs to fulfill these conditions:

T has a member function JsonBox::Value

toJson() const

noexcept

T has a constructor T::T(JsonBox::Object)

T has a member function double getFitness() const noexcept

T has a member function void setFitness(double) noexcept

If Species<T*> it will act as an observer what does this means:

Species<T*>::add(T* t) will accept a T* by value

Species<T*>::remove(T* t) will accept a T* by value

Species<T*>::has(T* t) will accept a T* by value

If Species<T> it will act as an owner what does this means:

Species<T>::add(T&& t) will take a T&&

Species<T>::remove(std::size_t id) will take an id by value

Species<T>::has(std::size_t id) will take an id by value

Author

Cristian Gonzalez Cristian.glez.m@gmail.com

Warning

You can’t use Species<T*>(JsonBox::Object) or Species<T*>(const std::string& filename) to load a Species.json

Public Types

using value_type = T#
using reference = std::remove_reference_t<std::remove_pointer_t<T>>&#
using rvalue_reference = std::remove_reference_t<std::remove_pointer_t<T>>&&#
using const_reference = const std::remove_reference_t<std::remove_pointer_t<T>>&#
using pointer = std::remove_pointer_t<T>*#
using const_pointer = const std::remove_pointer_t<T>*#

Public Functions

Species() noexcept#

basic Constructor

Species(const Species<T> &rhs) noexcept = default#

copy Constructor

Species(Species<T> &&rhs) noexcept = default#

move Constructor

Species(std::size_t Id, bool Novel) noexcept#

Creates a Species With the id and novel.

Parameters:
  • Id – std::size_T

  • Novel – bool if the species is a new one.

Species(JsonBox::Object o) noexcept#

loads a Species from a JsonBox::Object, cannot be used with Species<T*>

Parameters:

o – JsonBox::Object

Species(const std::string &filename)#

It loads the species from a json file saved with Species::writeToFile, cannot be used with Species<T*>

Parameters:

filename – const std::string&

void adjustFitness() noexcept#

Adjust the fitness of the species dividing the fitness with the size of the species.

void computeAvgFitness() noexcept#

computes the Average fitness

void computeMaxFitness() noexcept#

computes the max fitness

void rank() noexcept#

orders by fitness.

template<typename Fn>
void rank(Fn &&fn) noexcept#

orders by Fn(auto& m1, auto& m2)

Template Parameters:

Fn – function to pass to std::sort

Parameters:

fn – Fn lambda args can be pointers or references depending what type of Species you are using.

Species<T>::const_pointer getRepresentative() const noexcept#

returns the first member of this species

Returns:

const T*

Species<T>::pointer getChampion() noexcept#

returns the best performing member of the species.

Returns:

T*

bool isNovel() const noexcept#

returns if is novel.

Returns:

bool

void setNovel(bool n) noexcept#

setter for novel

Parameters:

n – bool

bool isKillable() const noexcept#

returns if is killable

Returns:

bool

void setKillable(bool k) noexcept#

setter for killable

Parameters:

k – bool killable

void setID(std::size_t speciesID) noexcept#

sets the ID of the species.

Parameters:

speciesID – std::size_t

std::size_t getID() const noexcept#

returns Species ID.

Returns:

std::size_t

void setAge(std::size_t speciesAge) noexcept#

setter for the age of the species.

Parameters:

speciesAge – std::size_t

void addAge(std::size_t amount) noexcept#

adds the amount to the current age of the species.

Parameters:

amount – std::size_t

std::size_t getAge() const noexcept#

returns the current age of the species.

void setMembers(std::vector<T> &&ms) noexcept#

setter for members.

std::vector<T> &getMembers() noexcept#

returns the members from this species.

Returns:

std::vector<T>&

void add(std::conditional_t<std::is_pointer_v<value_type>, pointer, rvalue_reference> m) noexcept#

adds a member to the species and sets its SpeciesID to Species::getID().

Parameters:

m – T&& if T is not a pointer T* otherwise.

void remove(std::conditional_t<std::is_pointer_v<value_type>, pointer, std::size_t> Id) noexcept#

removes a member from the species.

Parameters:

Id – std::size_t if T is not a pointer T* otherwise.

bool has(std::conditional_t<std::is_pointer_v<value_type>, pointer, std::size_t> id) noexcept#

checks if this T is in this species.

Parameters:

id – std::size_t if T is not a pointer T* otherwise.

Returns:

bool

void orderMembersByID() noexcept#

orders the members from the species by ID.

double getAvgFitness() const noexcept#

Call Species<T>::computeAvgFitness first, returns the average fitness of the species.

Returns:

double

double getMaxFitness() const noexcept#

Call Species<T>::computeMaxFitness first, returns the max fitness that it has.

Returns:

double

std::size_t getSize() const noexcept#

returns the number of members in the species.

Returns:

std::size_t

bool empty() const noexcept#

checks if is empty.

Returns:

bool

bool isStagnant() const noexcept#

checks if has stopped getting better it needs to have Species<T>::computeAvgFitness run first.

Returns:

bool

JsonBox::Value toJson() const noexcept#

returns a JsonBox::Value with the current info.

Returns:

JsonBox::Value

void writeToFile(const std::string &filename) const noexcept#

writes the Species to a file

Parameters:

filename

~Species() = default#
Species<T> &operator=(const Species<T> &rhs) noexcept = default#
Species<T> &operator=(Species<T> &&rhs) noexcept = default#
template<typename T>
struct Scaler#
#include <MathUtils.hpp>

Scales a number to be between normalized min and normalized max.

Template Parameters:

T – type

Public Types

using type = T#
using value_type = std::remove_reference_t<std::remove_pointer_t<T>>#
using reference = value_type&#
using rvalue_reference = value_type&&#
using const_reference = const value_type&#
using pointer = value_type*#

Public Functions

Scaler(value_type normalizedMin = 0.0, value_type normalizedMax = 1.0)#

Constructor scaled values to be (default: 0.0, 1.0)

Parameters:
  • normalizedMin – value_type

  • normalizedMax – value_type

Scaler(JsonBox::Object o)#

Constructor for a JsonBox::Object.

Parameters:

o – JsonBox::Object

JsonBox::Value toJson() const noexcept#

Use this to get a JsonBox::Value.

Returns:

JsonBox::Value

template<typename U>
void transform(std::vector<U> &data) noexcept#

Detects and saves min and max from the data and applies the transform to scale the values to be within normMin and normMax.

std::vector<double> data = {10.0, 2.0, 3.0, 1.0, 5.0}
EvoAI::Scaler<double> sc(0.0, 1.0);
sc.tranform(data);

Parameters:

data – std::vector<type>& transforms the data

template<typename Iter>
void transform(Iter begin, Iter end) noexcept#

Detects and saves min and max from the data and applies the transform to scale the range to be within normMin and normMax.

std::vector<double> data = {10.0, 2.0, 3.0, 1.0, 5.0}
EvoAI::Scaler<double> sc(0.0, 1.0);
sc.tranform(std::begin(data),std::end(data));

Parameters:
  • begin – Iter

  • end – Iter

value_type transform(value_type val) noexcept#

Applies transform to a single value, set the min and max by hand or use transform(std::vector<T>&) first.

Warning

set .min and .max before calling this method.

EvoAI::Scaler<double> sc(0.0, 1.0); 
sc.min = 0.0; 
sc.max = 100.0;
auto newData = sc.tranform(5.42);

Parameters:

val

Returns:

T new value

template<typename U>
void inverseTransform(std::vector<U> &data) noexcept#

converts the data to the unscaled data.

std::vector<double> data = {10.0, 2.0, 3.0, 1.0, 5.0}
EvoAI::Scaler<double> sc(0.0, 1.0);
sc.inverseTranform(data);

Parameters:

data – std::vector<type> modifies the data

template<typename Iter>
void inverseTransform(Iter begin, Iter end) noexcept#

converts the data in the range to the unscaled data.

std::vector<double> data = {10.0, 2.0, 3.0, 1.0, 5.0}
EvoAI::Scaler<double> sc(0.0, 1.0);
sc.inverseTranform(std::begin(data),std::end(data));

Parameters:
  • begin – Iter

  • end – Iter

value_type inverseTransform(value_type val) noexcept#

converts a single value, set the min and max by hand or use transform(std::vector<T>&) or transform(Iter begin, Iter end) first

Warning

set .min and .max

EvoAI::Scaler<double> sc(0.0, 1.0); 
sc.min = 0.0; 
sc.max = 100.0;
auto newData = sc.inverseTranform(5.42);

Parameters:

val

Returns:

T new value

~Scaler() = default#
template<typename T>
inline Scaler<T>::value_type transform(Scaler<T>::value_type val) noexcept#
template<typename T>
inline Scaler<T>::value_type inverseTransform(Scaler<T>::value_type val) noexcept#

Public Members

value_type normMin#
value_type normMax#
value_type min#
value_type max#
class RandomGenerator#
#include <RandomUtils.hpp>

Class to generate random numbers.

Public Functions

RandomGenerator()#
RandomGenerator(std::size_t seed)#

constructor with seed.

Parameters:

seed

double random(double min, double max, double layerSize) noexcept#

returns a random number between min and max and multiplies for sqrt of 2.0/layerSize

Parameters:
  • min – double

  • max – double

  • layerSize – double

Returns:

double

double lecunInit(std::size_t inputSize) noexcept#

LeCun initialization uniform distribution.

Parameters:

inputSize – std::size_t

Returns:

double

double lecunInitNormal(std::size_t inputSize) noexcept#

LeCun initialization normal distribution aka Gaussian.

Parameters:

inputSize – std::size_t

Returns:

double

double heInit(std::size_t inputSize) noexcept#

He initialization uniform distribution.

Parameters:

inputSize – std::size_t

Returns:

double

double heInitNormal(std::size_t inputSize) noexcept#

He initialization normal distribution aka Gaussian.

Parameters:

inputSize – std::size_t

Returns:

double

double xavierInit(std::size_t inputSize, std::size_t outputSize) noexcept#

Xavier initialization uniform distribution.

Parameters:
  • inputSize – std::size_t

  • outputSize – std::size_t

Returns:

double

double xavierInitNormal(std::size_t inputSize, std::size_t outputSize) noexcept#

Xavier initialization normal distribution aka Gaussian.

Parameters:
  • inputSize – std::size_t

  • outputSize – std::size_t

Returns:

double

template<typename T>
T random(T min, T max) noexcept#

returns a random number between min and max.

Parameters:
  • min – T

  • max – T

Returns:

T

bool random(float rate) noexcept#

gives a random true or false given the rate.

Parameters:

rate – float 0.0-1.0

Returns:

bool

inline std::size_t getSeed() const noexcept#

get the seed

Returns:

std::size_t seed

void setSeed(std::size_t seed) noexcept#

set the seed and update engine.

Parameters:

seed – std::size_t

inline std::mt19937_64 &getEngine() noexcept#

get the engine

Returns:

std::mt19937_64

~RandomGenerator() = default#
template<class T>
class Guard#
#include <Utils.hpp>

guards a T from multiple threads accessing it.

Template Parameters:

T – object to guard

Public Functions

inline Guard() noexcept#

constructor without args

template<typename ...Args>
inline Guard(Args&&... args) noexcept#

constructor with args

Template Parameters:

...Args – pack

Parameters:

...args – args to construct T

template<typename Fn>
inline auto visit(Fn &&fn) noexcept#

visit the protected data

Template Parameters:

Fn – function

Parameters:

fn – Fn&&

Returns:

auto

namespace Activations#

Functions

EvoAI_API double identity (double v) noexcept

identity activation

Parameters:

v – double

Returns:

double

EvoAI_API double sigmoid (double v) noexcept

a sigmoid activation

Parameters:

v – double

Returns:

double

EvoAI_API double steepenedSigmoid (double v) noexcept

steepenedSigmoid activation

Parameters:

v – double

Returns:

double

EvoAI_API double swish (double x, double b=1.0) noexcept

swish activation

Parameters:
  • x – double

  • b – double

Returns:

double

EvoAI_API double tanh (double v) noexcept

tanh activation

Parameters:

v – double

Returns:

double

EvoAI_API double sinusoid (double v) noexcept

sinusoid activation

Parameters:

v – double

Returns:

double

EvoAI_API double cosine (double v) noexcept

cosine activation

Parameters:

v – double

Returns:

double

EvoAI_API double tan (double v) noexcept

tan activation

Parameters:

v – double

Returns:

double

EvoAI_API double relu (double v) noexcept

relu activation

Parameters:

v – double

Returns:

double

EvoAI_API double noisyRelu (double v) noexcept

noisyRelu activation

Parameters:

v – double

Returns:

double

EvoAI_API double leakyRelu (double x) noexcept

leakyRelu activation

Parameters:

x – double

Returns:

double

EvoAI_API double exponential (double v) noexcept

exponential activation

Parameters:

v – double

Returns:

double

EvoAI_API void softmax (NeuronLayer &outputs) noexcept

softmax activation

Parameters:

outputsNeuronLayer&

EvoAI_API double gaussian (double v) noexcept

gaussian activation

Parameters:

v – double

Returns:

double

EvoAI_API double modulus (double v, double div=2.0) noexcept

modulus activation

Parameters:
  • v – double

  • div – double

Returns:

double

EvoAI_API double square (double v) noexcept

square activation

Parameters:

v – double

Returns:

double

EvoAI_API double cube (double v) noexcept

cube activation

Parameters:

v – double

Returns:

double

EvoAI_API double softplus (double v) noexcept

softplus activation

Parameters:

v – double

Returns:

double

EvoAI_API double clamp (double v) noexcept

clamp activation

Parameters:

v – double

Returns:

double

EvoAI_API double inv (double v) noexcept

inv activation

Parameters:

v – double

Returns:

double

EvoAI_API double log (double v) noexcept

log activation

Parameters:

v – double

Returns:

double

EvoAI_API double abs (double v) noexcept

abs activation

Parameters:

v – double

Returns:

double

EvoAI_API double hat (double v) noexcept

hat activation

Parameters:

v – double

Returns:

double

namespace Derivatives#

Functions

EvoAI_API double identity (double v) noexcept

identity derivative

Parameters:

v – double

Returns:

double

EvoAI_API double modulus (double v, double div) noexcept

modulus derivative

Parameters:
  • v – double

  • div – double

Returns:

double

EvoAI_API double sigmoid (double v) noexcept

sigmoid derivative

Parameters:

v – double

Returns:

double

EvoAI_API double steepenedSigmoid (double v) noexcept

a steepened Sigmoid function

Parameters:

v – double

Returns:

double

EvoAI_API double swish (double x, double b=1.0) noexcept

swish derivative

Parameters:
  • x – double

  • b – double

Returns:

double

EvoAI_API double tanh (double v) noexcept

tanh derivative

Parameters:

v – double

Returns:

double

EvoAI_API double cosine (double v) noexcept

cosine derivative

Parameters:

v – double

Returns:

double

EvoAI_API double tan (double v) noexcept

tan derivative

Parameters:

v – double

Returns:

double

EvoAI_API double sinusoid (double v) noexcept

sinusoid derivative

Parameters:

v – double

Returns:

double

EvoAI_API double relu (double v) noexcept

relu derivative

Parameters:

v – double

Returns:

double

EvoAI_API double noisyRelu (double v) noexcept

noisyRelu derivative

Parameters:

v – double

Returns:

double

EvoAI_API double leakyRelu (double x) noexcept

leakyRelu derivative

Parameters:

x – double

Returns:

double

EvoAI_API double exponential (double v) noexcept

exponential derivative

Parameters:

v – double

Returns:

double

EvoAI_API void softmax (NeuronLayer &outputs) noexcept

Softmax derivative.

Parameters:

outputsNeuronLayer&

EvoAI_API double gaussian (double v) noexcept

gaussian derivative

Parameters:

v – double

Returns:

double

EvoAI_API double square (double v) noexcept

square derivative

Parameters:

v – double

Returns:

double

EvoAI_API double cube (double v) noexcept

cube derivative

Parameters:

v – double

Returns:

double

EvoAI_API double softplus (double v) noexcept

softplus derivative

Parameters:

v – double

Returns:

double

EvoAI_API double clamp (double v) noexcept

clamp derivative

Parameters:

v – double

Returns:

double

EvoAI_API double inv (double v) noexcept

inv derivative

Parameters:

v – double

Returns:

double

EvoAI_API double log (double v) noexcept

log derivative

Parameters:

v – double

Returns:

double

EvoAI_API double abs (double v) noexcept

abs derivative

Parameters:

v – double

Returns:

double

EvoAI_API double hat (double v) noexcept

hat derivative

Parameters:

v – double

Returns:

double

namespace Loss#
struct BinaryCrossEntropy#
#include <BinaryCrossEntropy.hpp>

Binary Cross Entropy.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MeanAbsoluteError#
#include <MeanAbsoluteError.hpp>

Mean Absolute Error.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MeanError#
#include <MeanError.hpp>

Mean Error.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MeanSquaredError#
#include <MeanSquaredError.hpp>

Mean Squared Error.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MultiClassCrossEntropy#
#include <MultiClassCrossEntropy.hpp>

Multi-Class Cross Entropy.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

template<class Algo>
struct Loss#
#include <Loss.hpp>

Algo needs to fulfill these requirements:

Algo has a double

operator()(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs)

noexcept

Algo has a std::vector<double>

backward(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs) noexcept

Template Parameters:

Algo

Public Functions

inline Loss(Algo &&algo)#

constructor

Parameters:

algo – Algo struct implementing is_a_loss_v

inline double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

inline std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept#

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

Public Members

Algo loss#
namespace meta#

Typedefs

template<class T>
using serializable_t = decltype(std::declval<T>().toJson())#

T has a member function JsonBox::Value toJson() const noexcept.

template<class T>
using serializable_constructible_t = decltype(T{std::declval<JsonBox::Object>()})#

T has a constructor T::T(JsonBox::Object)

template<class T>
using get_id_t = decltype(std::declval<T>().getID())#

T has a member function std::size_t getID() const noexcept.

template<class T>
using set_id_t = decltype(std::declval<T>().setID(std::declval<std::size_t>()))#

T has a member function void setID(std::size_t) noexcept.

template<class T>
using get_species_id_t = decltype(std::declval<T>().getSpeciesID())#

T has a member function std::size_t getSpeciesID() const noexcept.

template<class T>
using set_species_id_t = decltype(std::declval<T>().setSpeciesID(std::declval<std::size_t>()))#

T has a member function void setSpeciesID(std::size_t) noexcept.

template<class T>
using set_fitness_t = decltype(std::declval<T>().setFitness(std::declval<double>()))#

T has a member function void setFitness(double) noexcept.

template<class T>
using get_fitness_t = decltype(std::declval<T>().getFitness())#

T has a member function double getFitness() const noexcept.

template<class T>
using distance_t = decltype(T::distance(std::declval<const T&>(), std::declval<const T&>(), std::declval<double>(), std::declval<double>(), std::declval<double>()))#

T has a static double T::distance(const T&, const T&, double, double, double) noexcept;.

template<class T>
using reproduce_t = decltype(T::reproduce(std::declval<const T&>(), std::declval<const T&>()))#

T has a static T T::reproduce(const T&, const T&) noexcept;.

template<class T, class C>
using serializable_constructible_with_param_t = decltype(T{std::declval<JsonBox::Object>(), std::declval<C>()})#

T has a constructor T::T(JsonBox::Object, C)

Todo:

use this when c++20

Template Parameters:
  • T – Class or struct with constructor T::T(JsonBox::Object, C);

  • C – additional parameter for the constructor

template<class T>
using optimizer_algo_t = decltype(std::declval<T>().(std::declval<double>(), std::declval<std::size_t>()))#

T has a void T::operator()(double, std::size_t) const noexcept;.

template<class T>
using scheduler_algo_t = decltype(std::declval<T>().(std::declval<double>(), std::declval<std::size_t>()))#

T has a double T::operator()(double, std::size_t) const noexcept;.

template<class T>
using has_forward_t = decltype(std::declval<T>().(std::declval<const std::vector<double>&>(), std::declval<const std::vector<double>&>()))#

T has a member function double operator()(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs) noexcept.

template<class T>
using has_backward_t = decltype(std::declval<T>().backward(std::declval<const std::vector<double>&>(), std::declval<const std::vector<double>&>()))#

T has a member function std::vector<double> backward(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs) noexcept.

template<class T>
using has_empty_operator_t = decltype(std::declval<T>().())#

T has a member function std::pair<std::vector<double>&, std::vector<double>&> operator()() noexcept.

template<class T>
using has_size_t = decltype(std::declval<T>().size())#

T has a member function std::size_t size() noexcept.

template<class T>
using has_get_batch_size_t = decltype(std::declval<T>().getBatchSize())#

T has a member function std::size_t getBatchSize() noexcept.

template<class T>
using has_shuffle_t = decltype(std::declval<T>().shuffle())#

T has a member function void shuffle() noexcept.

Variables

template<class T>
constexpr bool serializable_v = estd::is_detected<serializable_t, T>::value#
template<class T>
constexpr bool serializable_constructible_v = estd::is_detected<serializable_constructible_t, T>::value#
template<class T>
constexpr bool get_id_v = estd::is_detected<get_id_t, T>::value#
template<class T>
constexpr bool set_id_v = estd::is_detected<set_id_t, T>::value#
template<class T>
constexpr bool get_species_id_v = estd::is_detected<get_species_id_t, T>::value#
template<class T>
constexpr bool set_species_id_v = estd::is_detected<set_species_id_t, T>::value#
template<class T>
constexpr bool set_fitness_v = estd::is_detected<set_fitness_t, T>::value#
template<class T>
constexpr bool get_fitness_v = estd::is_detected<get_fitness_t, T>::value#
template<class T>
constexpr bool distance_v = estd::is_detected<distance_t, T>::value#
template<class T>
constexpr bool reproduce_v = estd::is_detected<reproduce_t, T>::value#
template<typename T>
static constexpr bool is_speciable_v = is_speciable<T>::value#
template<typename T>
static constexpr bool is_populable_v = is_populable<T>::value#
template<class T, class C>
constexpr bool serializable_constructible_with_param_v = estd::is_detected<serializable_constructible_with_param_t, T, C>::value#
template<class T>
constexpr bool optimizer_algo_v = estd::is_detected<optimizer_algo_t, T>::value#
template<class T, class C>
static constexpr bool is_an_optimizer_algorithm_v = is_an_optimizer_algorithm<T, C>::value#
template<class T>
constexpr bool scheduler_algo_v = estd::is_detected<scheduler_algo_t, T>::value#
template<class T>
static constexpr bool is_a_scheduler_algorithm_v = is_a_scheduler_algorithm<T>::value#
template<class T>
static constexpr bool has_forward_v = estd::is_detected<has_forward_t, T>::value#
template<class T>
static constexpr bool has_backward_v = estd::is_detected<has_backward_t, T>::value#
template<class T>
static constexpr bool is_a_loss_v = has_forward_v<T> && has_backward_v<T>#

T is a loss algorithm.

template<class T>
static constexpr bool has_empty_operator_v = estd::is_detected<has_empty_operator_t, T>::value#
template<class T>
static constexpr bool has_size_v = estd::is_detected<has_size_t, T>::value#
template<class T>
static constexpr bool has_get_batch_size_v = estd::is_detected<has_get_batch_size_t, T>::value#
template<class T>
static constexpr bool has_shuffle_v = estd::is_detected<has_shuffle_t, T>::value#
template<class T>
static constexpr bool is_a_dataset_v = has_empty_operator_v<T> && has_size_v<T> && has_get_batch_size_v<T> && has_shuffle_v<T>#
template<class T>
struct is_speciable#
#include <TypeUtils.hpp>

T requires to have these functions:

T has a member function JsonBox::Value toJson() const noexcept; T has a constructor T::T(JsonBox::Object); T has a member function double getFitness() const noexcept; T has a member function void setFitness(double) noexcept;

Public Static Attributes

static constexpr bool value = serializable_v<T> && serializable_constructible_v<T> && get_fitness_v<T> && set_fitness_v<T>#
template<class T>
struct is_populable#
#include <TypeUtils.hpp>

T is required to have these functions:

T has a member function JsonBox::Value toJson() const noexcept; T has a constructor T::T(JsonBox::Object); T has a member function double getFitness() const noexcept; T has a member function void setFitness(double) noexcept; T has a member function void setSpeciesID(std::size_t) noexcept; T has a member function std::size_t getSpeciesID() const noexcept; T has a member function void setID(std::size_t) noexcept; T has a member function std::size_t getID() const noexcept; T has a static double T::distance(const T&, const T&, double, double, double) noexcept; T has a static T T::reproduce(const T&, const T&) noexcept;

Public Static Attributes

static constexpr bool value = is_speciable<T>::value && get_species_id_v<T> && get_id_v<T> && set_species_id_v<T> && set_id_v<T> && distance_v<T> && reproduce_v<T>#
template<class T, class C>
struct is_an_optimizer_algorithm#
#include <TypeUtils.hpp>

T is required to have these functions:

T has a constructor T::T(JsonBox::Object, NeuralNetwork*); T has a member function JsonBox::Value toJson() const noexcept; T has a T::operator()(double, std::size_t) const noexcept;

Public Static Attributes

static constexpr bool value = serializable_v<T> && serializable_constructible_with_param_v<T, C> && optimizer_algo_v<T>#
template<class T>
struct is_a_scheduler_algorithm#
#include <TypeUtils.hpp>

T is required to have these functions:

T has a constructor T::T(JsonBox::Object); T has a member function JsonBox::Value toJson() const noexcept; T has a T::operator()(double, std::size_t) const noexcept;

Public Static Attributes

static constexpr bool value = serializable_v<T> && serializable_constructible_v<T> && scheduler_algo_v<T>#
namespace priv#

helper functions

Todo:

move to typeUtils? better way?

Functions

template<typename T>
std::remove_pointer_t<T> *to_pointer(std::remove_reference_t<std::remove_pointer_t<T>> &t) noexcept#
template<typename T>
const std::remove_pointer_t<T> *to_pointer(const std::remove_reference_t<std::remove_pointer_t<T>> &t) noexcept#
template<typename T>
std::remove_pointer_t<T> *to_pointer(std::remove_pointer_t<T> *t) noexcept#
template<typename T>
std::remove_pointer_t<T> *to_pointer(std::unique_ptr<T> &t) noexcept#
template<typename T>
std::remove_pointer_t<T> *to_pointer(std::shared_ptr<T> &t) noexcept#
template<typename T>
T *to_pointer(std::remove_reference_t<T> &&t) noexcept = delete#
template<typename T>
std::remove_reference_t<T> &to_ref(std::remove_reference_t<std::remove_pointer_t<T>> &t) noexcept#
template<typename T>
const std::remove_reference_t<T> &to_ref(const std::remove_reference_t<std::remove_pointer_t<T>> &t) noexcept#
template<typename T>
std::remove_reference_t<T> &to_ref(std::remove_pointer_t<T> *t) noexcept#
template<typename T>
std::remove_reference_t<T> &to_ref(std::unique_ptr<T> &t) noexcept#
template<typename T>
std::remove_reference_t<T> &to_ref(std::shared_ptr<T> &t) noexcept#
template<typename T>
std::remove_reference_t<T> &to_ref(std::remove_reference_t<T> &&t) noexcept = delete#
template<typename NamesTuple, typename JsonsTuple, std::size_t... Is>
JsonBox::Value makeJsonFrom_impl(const NamesTuple &names, const JsonsTuple &jsons, std::index_sequence<Is...>) noexcept#
template<typename ...Jsons, std::size_t... Is>
std::tuple<Jsons...> loadJsonFrom_impl(const std::string &filename, const std::array<std::string, sizeof...(Jsons)> &names, std::index_sequence<Is...>) noexcept#
namespace SelectionAlgorithms#

Algorithms of Selection Strategies.

In case you want your own selection algorithm you will need to implement a functor overloading operator() they must return a std::vector<Selected<T>> where every Selected<T>.loser should be unique. The algorithm can return less than the number of selected required, and should handle T and T*.

template<typename T>
struct EvoAI_API new_algorithm{
    //This one will handle interspecies reproduction by selecting couples from members
    std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*>& members, std::size_t numberToSelect) noexcept;
    //and this will handle species reproduction by selecting couples from species
    std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>>& species, std::size_t numberToSelect) noexcept;
};

template<typename T>
struct Selected#
#include <SelectionAlgorithms.hpp>

Standard container for SelectionAlgorithms.

Public Types

using pointer = std::remove_pointer_t<T>*#

Public Functions

inline Selected(pointer dad, pointer mom, pointer losr) noexcept#

Public Members

pointer father#
pointer mother#
pointer loser#
template<typename T>
struct Truncation#
#include <SelectionAlgorithms.hpp>

Truncation Selection algorithm.

When using interspecies it will order members by fitness and then select couples from the fittest members and a loser from the bottom of the list, when using species only it will select the fittest members from the species by using a percentage calculated from the size of the species, the bigger the species the more selected members from that species.

Public Types

using pointer = std::remove_pointer_t<T>*#

Public Functions

Truncation(std::size_t maxPop) noexcept#

constructor

Parameters:

maxPop – maxPopulation

std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*> &members, std::size_t numberToSelect) noexcept#

selects couples independent of their species.

Parameters:
  • members – std::vector<std::remove_pointer_t<T>*>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>> &species, std::size_t numberToSelect) noexcept#

select couples of the same species.

Parameters:
  • species – std::map<std::size_t, std::unique_ptr<Species<T>>>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

Public Members

std::size_t maxPopulation#
template<typename T>
struct Tournament#
#include <SelectionAlgorithms.hpp>

Tournament Selection algorithm.

It will randomly select members and compare their fitness, choosing a new contender for each round, the winner will be a parent, when using species only it will select more members of the biggest species.

Public Types

using pointer = std::remove_pointer_t<T>*#

Public Functions

Tournament(std::size_t maxPopulation, std::size_t rnds = 10) noexcept#

constructor

Parameters:
  • maxPopulation – maxPopulation used to calculate the number To select per species.

  • rnds – rounds to select a champion and loser. (default = 10)

template<typename Members>
std::pair<pointer, pointer> fight(Members &members) noexcept#

randomly selects some members and compare their fitness, the champion is the one with the highest fitness.

Template Parameters:

[in] – members Members vector<T> for T and T*

Returns:

std::pair<pointer, pointer> champion and loser

std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*> &members, std::size_t numberToSelect) noexcept#

selects couples independent of their species.

Parameters:
  • members – std::vector<std::remove_pointer_t<T>*>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>> &species, std::size_t numberToSelect) noexcept#

select couples of the same species.

Parameters:
  • species – std::map<std::size_t, std::unique_ptr<Species<T>>>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

template<typename Members>
std::pair<typename Tournament<T>::pointer, typename Tournament<T>::pointer> fight(Members &members) noexcept#

Public Members

std::size_t maxPop#
std::size_t rounds#
template<typename T>
struct FPS#
#include <SelectionAlgorithms.hpp>

Fitness Proportionate Selection aka roulette wheel selection algorithm.

calculates the proportion using fitness and randomly selects a couple and a loser.

Public Types

using pointer = std::remove_pointer_t<T>*#

Public Functions

explicit FPS(std::size_t maxPopulation) noexcept#

constructor

Parameters:

maxPopulation – std::size_t maxPopulation used to calculate the number To select per species.

template<typename Members>
pointer FPSelection(Members &members, double totalFitness) noexcept#

randomly select a number and select a member that the sum of its fitness is over that number.

Template Parameters:

Members – vector<T> for T and T*

Parameters:
  • members – vector<T> for T and T*

  • totalFitness – double

Returns:

T* it can be a nullptr

std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*> &members, std::size_t numberToSelect) noexcept#

selects couples independent of their species.

Parameters:
  • members – std::vector<std::remove_pointer_t<T>*>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>> &species, std::size_t numberToSelect) noexcept#

select couples of the same species.

Parameters:
  • species – std::map<std::size_t, std::unique_ptr<Species<T>>>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

Public Members

std::size_t maxPop#

Activations#

namespace Activations

Functions

EvoAI_API double identity (double v) noexcept

identity activation

Parameters:

v – double

Returns:

double

EvoAI_API double sigmoid (double v) noexcept

a sigmoid activation

Parameters:

v – double

Returns:

double

EvoAI_API double steepenedSigmoid (double v) noexcept

steepenedSigmoid activation

Parameters:

v – double

Returns:

double

EvoAI_API double swish (double x, double b=1.0) noexcept

swish activation

Parameters:
  • x – double

  • b – double

Returns:

double

EvoAI_API double tanh (double v) noexcept

tanh activation

Parameters:

v – double

Returns:

double

EvoAI_API double sinusoid (double v) noexcept

sinusoid activation

Parameters:

v – double

Returns:

double

EvoAI_API double cosine (double v) noexcept

cosine activation

Parameters:

v – double

Returns:

double

EvoAI_API double tan (double v) noexcept

tan activation

Parameters:

v – double

Returns:

double

EvoAI_API double relu (double v) noexcept

relu activation

Parameters:

v – double

Returns:

double

EvoAI_API double noisyRelu (double v) noexcept

noisyRelu activation

Parameters:

v – double

Returns:

double

EvoAI_API double leakyRelu (double x) noexcept

leakyRelu activation

Parameters:

x – double

Returns:

double

EvoAI_API double exponential (double v) noexcept

exponential activation

Parameters:

v – double

Returns:

double

EvoAI_API void softmax (NeuronLayer &outputs) noexcept

softmax activation

Parameters:

outputsNeuronLayer&

EvoAI_API double gaussian (double v) noexcept

gaussian activation

Parameters:

v – double

Returns:

double

EvoAI_API double modulus (double v, double div=2.0) noexcept

modulus activation

Parameters:
  • v – double

  • div – double

Returns:

double

EvoAI_API double square (double v) noexcept

square activation

Parameters:

v – double

Returns:

double

EvoAI_API double cube (double v) noexcept

cube activation

Parameters:

v – double

Returns:

double

EvoAI_API double softplus (double v) noexcept

softplus activation

Parameters:

v – double

Returns:

double

EvoAI_API double clamp (double v) noexcept

clamp activation

Parameters:

v – double

Returns:

double

EvoAI_API double inv (double v) noexcept

inv activation

Parameters:

v – double

Returns:

double

EvoAI_API double log (double v) noexcept

log activation

Parameters:

v – double

Returns:

double

EvoAI_API double abs (double v) noexcept

abs activation

Parameters:

v – double

Returns:

double

EvoAI_API double hat (double v) noexcept

hat activation

Parameters:

v – double

Returns:

double

Derivatives#

namespace Derivatives

Functions

EvoAI_API double identity (double v) noexcept

identity derivative

Parameters:

v – double

Returns:

double

EvoAI_API double modulus (double v, double div) noexcept

modulus derivative

Parameters:
  • v – double

  • div – double

Returns:

double

EvoAI_API double sigmoid (double v) noexcept

sigmoid derivative

Parameters:

v – double

Returns:

double

EvoAI_API double steepenedSigmoid (double v) noexcept

a steepened Sigmoid function

Parameters:

v – double

Returns:

double

EvoAI_API double swish (double x, double b=1.0) noexcept

swish derivative

Parameters:
  • x – double

  • b – double

Returns:

double

EvoAI_API double tanh (double v) noexcept

tanh derivative

Parameters:

v – double

Returns:

double

EvoAI_API double cosine (double v) noexcept

cosine derivative

Parameters:

v – double

Returns:

double

EvoAI_API double tan (double v) noexcept

tan derivative

Parameters:

v – double

Returns:

double

EvoAI_API double sinusoid (double v) noexcept

sinusoid derivative

Parameters:

v – double

Returns:

double

EvoAI_API double relu (double v) noexcept

relu derivative

Parameters:

v – double

Returns:

double

EvoAI_API double noisyRelu (double v) noexcept

noisyRelu derivative

Parameters:

v – double

Returns:

double

EvoAI_API double leakyRelu (double x) noexcept

leakyRelu derivative

Parameters:

x – double

Returns:

double

EvoAI_API double exponential (double v) noexcept

exponential derivative

Parameters:

v – double

Returns:

double

EvoAI_API void softmax (NeuronLayer &outputs) noexcept

Softmax derivative.

Parameters:

outputsNeuronLayer&

EvoAI_API double gaussian (double v) noexcept

gaussian derivative

Parameters:

v – double

Returns:

double

EvoAI_API double square (double v) noexcept

square derivative

Parameters:

v – double

Returns:

double

EvoAI_API double cube (double v) noexcept

cube derivative

Parameters:

v – double

Returns:

double

EvoAI_API double softplus (double v) noexcept

softplus derivative

Parameters:

v – double

Returns:

double

EvoAI_API double clamp (double v) noexcept

clamp derivative

Parameters:

v – double

Returns:

double

EvoAI_API double inv (double v) noexcept

inv derivative

Parameters:

v – double

Returns:

double

EvoAI_API double log (double v) noexcept

log derivative

Parameters:

v – double

Returns:

double

EvoAI_API double abs (double v) noexcept

abs derivative

Parameters:

v – double

Returns:

double

EvoAI_API double hat (double v) noexcept

hat derivative

Parameters:

v – double

Returns:

double

Loss#

namespace Loss
struct BinaryCrossEntropy
#include <BinaryCrossEntropy.hpp>

Binary Cross Entropy.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MeanAbsoluteError
#include <MeanAbsoluteError.hpp>

Mean Absolute Error.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MeanError
#include <MeanError.hpp>

Mean Error.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MeanSquaredError
#include <MeanSquaredError.hpp>

Mean Squared Error.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

struct MultiClassCrossEntropy
#include <MultiClassCrossEntropy.hpp>

Multi-Class Cross Entropy.

Public Functions

double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

template<class Algo>
struct Loss
#include <Loss.hpp>

Algo needs to fulfill these requirements:

Algo has a double

operator()(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs)

noexcept

Algo has a std::vector<double>

backward(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs) noexcept

Template Parameters:

Algo

Public Functions

inline Loss(Algo &&algo)

constructor

Parameters:

algo – Algo struct implementing is_a_loss_v

inline double operator()(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

forward step to calculate loss

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

double

inline std::vector<double> backward(const std::vector<double> &expectedOutputs, const std::vector<double> &outputs) noexcept

backward step to calculate gradients

Parameters:
  • expectedOutputs – std::vector<double>&

  • outputs – std::vector<double>&

Returns:

std::vector<double> gradients for output layer

Public Members

Algo loss

SelectionAlgorithms#

namespace SelectionAlgorithms

Algorithms of Selection Strategies.

In case you want your own selection algorithm you will need to implement a functor overloading operator() they must return a std::vector<Selected<T>> where every Selected<T>.loser should be unique. The algorithm can return less than the number of selected required, and should handle T and T*.

template<typename T>
struct EvoAI_API new_algorithm{
    //This one will handle interspecies reproduction by selecting couples from members
    std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*>& members, std::size_t numberToSelect) noexcept;
    //and this will handle species reproduction by selecting couples from species
    std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>>& species, std::size_t numberToSelect) noexcept;
};

template<typename T>
struct Selected
#include <SelectionAlgorithms.hpp>

Standard container for SelectionAlgorithms.

Public Types

using pointer = std::remove_pointer_t<T>*

Public Functions

inline Selected(pointer dad, pointer mom, pointer losr) noexcept

Public Members

pointer father
pointer mother
pointer loser
template<typename T>
struct Truncation
#include <SelectionAlgorithms.hpp>

Truncation Selection algorithm.

When using interspecies it will order members by fitness and then select couples from the fittest members and a loser from the bottom of the list, when using species only it will select the fittest members from the species by using a percentage calculated from the size of the species, the bigger the species the more selected members from that species.

Public Types

using pointer = std::remove_pointer_t<T>*

Public Functions

Truncation(std::size_t maxPop) noexcept

constructor

Parameters:

maxPop – maxPopulation

std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*> &members, std::size_t numberToSelect) noexcept

selects couples independent of their species.

Parameters:
  • members – std::vector<std::remove_pointer_t<T>*>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>> &species, std::size_t numberToSelect) noexcept

select couples of the same species.

Parameters:
  • species – std::map<std::size_t, std::unique_ptr<Species<T>>>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

Public Members

std::size_t maxPopulation
template<typename T>
struct Tournament
#include <SelectionAlgorithms.hpp>

Tournament Selection algorithm.

It will randomly select members and compare their fitness, choosing a new contender for each round, the winner will be a parent, when using species only it will select more members of the biggest species.

Public Types

using pointer = std::remove_pointer_t<T>*

Public Functions

Tournament(std::size_t maxPopulation, std::size_t rnds = 10) noexcept

constructor

Parameters:
  • maxPopulation – maxPopulation used to calculate the number To select per species.

  • rnds – rounds to select a champion and loser. (default = 10)

template<typename Members>
std::pair<pointer, pointer> fight(Members &members) noexcept

randomly selects some members and compare their fitness, the champion is the one with the highest fitness.

Template Parameters:

[in] – members Members vector<T> for T and T*

Returns:

std::pair<pointer, pointer> champion and loser

std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*> &members, std::size_t numberToSelect) noexcept

selects couples independent of their species.

Parameters:
  • members – std::vector<std::remove_pointer_t<T>*>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>> &species, std::size_t numberToSelect) noexcept

select couples of the same species.

Parameters:
  • species – std::map<std::size_t, std::unique_ptr<Species<T>>>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

template<typename Members>
std::pair<typename Tournament<T>::pointer, typename Tournament<T>::pointer> fight(Members &members) noexcept

Public Members

std::size_t maxPop
std::size_t rounds
template<typename T>
struct FPS
#include <SelectionAlgorithms.hpp>

Fitness Proportionate Selection aka roulette wheel selection algorithm.

calculates the proportion using fitness and randomly selects a couple and a loser.

Public Types

using pointer = std::remove_pointer_t<T>*

Public Functions

explicit FPS(std::size_t maxPopulation) noexcept

constructor

Parameters:

maxPopulation – std::size_t maxPopulation used to calculate the number To select per species.

template<typename Members>
pointer FPSelection(Members &members, double totalFitness) noexcept

randomly select a number and select a member that the sum of its fitness is over that number.

Template Parameters:

Members – vector<T> for T and T*

Parameters:
  • members – vector<T> for T and T*

  • totalFitness – double

Returns:

T* it can be a nullptr

std::vector<Selected<T>> operator()(std::vector<std::remove_pointer_t<T>*> &members, std::size_t numberToSelect) noexcept

selects couples independent of their species.

Parameters:
  • members – std::vector<std::remove_pointer_t<T>*>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

std::vector<Selected<T>> operator()(std::map<std::size_t, std::unique_ptr<Species<T>>> &species, std::size_t numberToSelect) noexcept

select couples of the same species.

Parameters:
  • species – std::map<std::size_t, std::unique_ptr<Species<T>>>&

  • numberToSelect – std::size_t

Returns:

std::vector<Selected<T>> selected

Public Members

std::size_t maxPop

Meta#

namespace meta

Typedefs

template<class T>
using serializable_t = decltype(std::declval<T>().toJson())

T has a member function JsonBox::Value toJson() const noexcept.

template<class T>
using serializable_constructible_t = decltype(T{std::declval<JsonBox::Object>()})

T has a constructor T::T(JsonBox::Object)

template<class T>
using get_id_t = decltype(std::declval<T>().getID())

T has a member function std::size_t getID() const noexcept.

template<class T>
using set_id_t = decltype(std::declval<T>().setID(std::declval<std::size_t>()))

T has a member function void setID(std::size_t) noexcept.

template<class T>
using get_species_id_t = decltype(std::declval<T>().getSpeciesID())

T has a member function std::size_t getSpeciesID() const noexcept.

template<class T>
using set_species_id_t = decltype(std::declval<T>().setSpeciesID(std::declval<std::size_t>()))

T has a member function void setSpeciesID(std::size_t) noexcept.

template<class T>
using set_fitness_t = decltype(std::declval<T>().setFitness(std::declval<double>()))

T has a member function void setFitness(double) noexcept.

template<class T>
using get_fitness_t = decltype(std::declval<T>().getFitness())

T has a member function double getFitness() const noexcept.

template<class T>
using distance_t = decltype(T::distance(std::declval<const T&>(), std::declval<const T&>(), std::declval<double>(), std::declval<double>(), std::declval<double>()))

T has a static double T::distance(const T&, const T&, double, double, double) noexcept;.

template<class T>
using reproduce_t = decltype(T::reproduce(std::declval<const T&>(), std::declval<const T&>()))

T has a static T T::reproduce(const T&, const T&) noexcept;.

template<class T, class C>
using serializable_constructible_with_param_t = decltype(T{std::declval<JsonBox::Object>(), std::declval<C>()})

T has a constructor T::T(JsonBox::Object, C)

Todo:

use this when c++20

Template Parameters:
  • T – Class or struct with constructor T::T(JsonBox::Object, C);

  • C – additional parameter for the constructor

template<class T>
using optimizer_algo_t = decltype(std::declval<T>().(std::declval<double>(), std::declval<std::size_t>()))

T has a void T::operator()(double, std::size_t) const noexcept;.

template<class T>
using scheduler_algo_t = decltype(std::declval<T>().(std::declval<double>(), std::declval<std::size_t>()))

T has a double T::operator()(double, std::size_t) const noexcept;.

template<class T>
using has_forward_t = decltype(std::declval<T>().(std::declval<const std::vector<double>&>(), std::declval<const std::vector<double>&>()))

T has a member function double operator()(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs) noexcept.

template<class T>
using has_backward_t = decltype(std::declval<T>().backward(std::declval<const std::vector<double>&>(), std::declval<const std::vector<double>&>()))

T has a member function std::vector<double> backward(const std::vector<double>& expectedOutputs, const std::vector<double>& outputs) noexcept.

template<class T>
using has_empty_operator_t = decltype(std::declval<T>().())

T has a member function std::pair<std::vector<double>&, std::vector<double>&> operator()() noexcept.

template<class T>
using has_size_t = decltype(std::declval<T>().size())

T has a member function std::size_t size() noexcept.

template<class T>
using has_get_batch_size_t = decltype(std::declval<T>().getBatchSize())

T has a member function std::size_t getBatchSize() noexcept.

template<class T>
using has_shuffle_t = decltype(std::declval<T>().shuffle())

T has a member function void shuffle() noexcept.

Variables

template<class T>
constexpr bool serializable_v = estd::is_detected<serializable_t, T>::value
template<class T>
constexpr bool serializable_constructible_v = estd::is_detected<serializable_constructible_t, T>::value
template<class T>
constexpr bool get_id_v = estd::is_detected<get_id_t, T>::value
template<class T>
constexpr bool set_id_v = estd::is_detected<set_id_t, T>::value
template<class T>
constexpr bool get_species_id_v = estd::is_detected<get_species_id_t, T>::value
template<class T>
constexpr bool set_species_id_v = estd::is_detected<set_species_id_t, T>::value
template<class T>
constexpr bool set_fitness_v = estd::is_detected<set_fitness_t, T>::value
template<class T>
constexpr bool get_fitness_v = estd::is_detected<get_fitness_t, T>::value
template<class T>
constexpr bool distance_v = estd::is_detected<distance_t, T>::value
template<class T>
constexpr bool reproduce_v = estd::is_detected<reproduce_t, T>::value
template<typename T>
static constexpr bool is_speciable_v = is_speciable<T>::value
template<typename T>
static constexpr bool is_populable_v = is_populable<T>::value
template<class T, class C>
constexpr bool serializable_constructible_with_param_v = estd::is_detected<serializable_constructible_with_param_t, T, C>::value
template<class T>
constexpr bool optimizer_algo_v = estd::is_detected<optimizer_algo_t, T>::value
template<class T, class C>
static constexpr bool is_an_optimizer_algorithm_v = is_an_optimizer_algorithm<T, C>::value
template<class T>
constexpr bool scheduler_algo_v = estd::is_detected<scheduler_algo_t, T>::value
template<class T>
static constexpr bool is_a_scheduler_algorithm_v = is_a_scheduler_algorithm<T>::value
template<class T>
static constexpr bool has_forward_v = estd::is_detected<has_forward_t, T>::value
template<class T>
static constexpr bool has_backward_v = estd::is_detected<has_backward_t, T>::value
template<class T>
static constexpr bool is_a_loss_v = has_forward_v<T> && has_backward_v<T>

T is a loss algorithm.

template<class T>
static constexpr bool has_empty_operator_v = estd::is_detected<has_empty_operator_t, T>::value
template<class T>
static constexpr bool has_size_v = estd::is_detected<has_size_t, T>::value
template<class T>
static constexpr bool has_get_batch_size_v = estd::is_detected<has_get_batch_size_t, T>::value
template<class T>
static constexpr bool has_shuffle_v = estd::is_detected<has_shuffle_t, T>::value
template<class T>
static constexpr bool is_a_dataset_v = has_empty_operator_v<T> && has_size_v<T> && has_get_batch_size_v<T> && has_shuffle_v<T>
template<class T>
struct is_speciable
#include <TypeUtils.hpp>

T requires to have these functions:

T has a member function JsonBox::Value toJson() const noexcept; T has a constructor T::T(JsonBox::Object); T has a member function double getFitness() const noexcept; T has a member function void setFitness(double) noexcept;

Public Static Attributes

static constexpr bool value = serializable_v<T> && serializable_constructible_v<T> && get_fitness_v<T> && set_fitness_v<T>
template<class T>
struct is_populable
#include <TypeUtils.hpp>

T is required to have these functions:

T has a member function JsonBox::Value toJson() const noexcept; T has a constructor T::T(JsonBox::Object); T has a member function double getFitness() const noexcept; T has a member function void setFitness(double) noexcept; T has a member function void setSpeciesID(std::size_t) noexcept; T has a member function std::size_t getSpeciesID() const noexcept; T has a member function void setID(std::size_t) noexcept; T has a member function std::size_t getID() const noexcept; T has a static double T::distance(const T&, const T&, double, double, double) noexcept; T has a static T T::reproduce(const T&, const T&) noexcept;

Public Static Attributes

static constexpr bool value = is_speciable<T>::value && get_species_id_v<T> && get_id_v<T> && set_species_id_v<T> && set_id_v<T> && distance_v<T> && reproduce_v<T>
template<class T, class C>
struct is_an_optimizer_algorithm
#include <TypeUtils.hpp>

T is required to have these functions:

T has a constructor T::T(JsonBox::Object, NeuralNetwork*); T has a member function JsonBox::Value toJson() const noexcept; T has a T::operator()(double, std::size_t) const noexcept;

Public Static Attributes

static constexpr bool value = serializable_v<T> && serializable_constructible_with_param_v<T, C> && optimizer_algo_v<T>
template<class T>
struct is_a_scheduler_algorithm
#include <TypeUtils.hpp>

T is required to have these functions:

T has a constructor T::T(JsonBox::Object); T has a member function JsonBox::Value toJson() const noexcept; T has a T::operator()(double, std::size_t) const noexcept;

Public Static Attributes

static constexpr bool value = serializable_v<T> && serializable_constructible_v<T> && scheduler_algo_v<T>