29 #define FUZZY_CFMQVS_AND (1)
30 #define FUZZY_CFMQVS_OR (2)
34 #define STRING_FUZZY_NOT ("Fuzzy NOT\0")
35 #define STRING_FUZZY_CFMQVS_AND ("Fuzzy AND\0")
36 #define STRING_FUZZY_CFMQVS_OR ("Fuzzy OR\0")
72 for (
int i = 0; i < dgp->
n; ++i) {
93 for (
int i = 0; i < dgp->
klen; ++i) {
113 const int n = (int) round((2 * dgp->
mu[2]) - 1);
114 if (dgp->
t + n < 1 || dgp->t + n > dgp->
max_t) {
134 state = 1 - inputs[0];
138 for (
int i = 1; i < K; ++i) {
144 for (
int i = 1; i < K; ++i) {
149 printf(
"Error updating node: Invalid function: %d\n",
function);
152 state =
clamp(state, 0, 1);
172 printf(
"dgp_function_string(): invalid node function: %d\n",
193 printf(
"dgp_function_int(): invalid node function: %s\n",
function);
205 for (
int i = 0; i < dgp->
n; ++i) {
206 for (
int k = 0; k < dgp->
max_k; ++k) {
208 if (c < dgp->n_inputs) {
235 dgp->
state = malloc(
sizeof(
double) * dgp->
n);
237 dgp->
tmp_state = malloc(
sizeof(
double) * dgp->
n);
239 dgp->
function = malloc(
sizeof(
int) * dgp->
n);
241 dgp->
mu = malloc(
sizeof(
double) *
N_MU);
260 memcpy(dest->
state, src->
state,
sizeof(
double) * src->
n);
264 memcpy(dest->
mu, src->
mu,
sizeof(
double) *
N_MU);
276 return dgp->
state[IDX];
286 for (
int i = 0; i < dgp->
n; ++i) {
301 for (
int i = 0; i < dgp->
n; ++i) {
306 for (
int i = 0; i < dgp->
klen; ++i) {
323 for (
int t = 0; t < dgp->
t; ++t) {
336 printf(
"%s\n", json_str);
348 cJSON *json = cJSON_CreateObject();
349 cJSON_AddNumberToObject(json,
"n", dgp->
n);
350 cJSON_AddNumberToObject(json,
"t", dgp->
t);
351 cJSON_AddNumberToObject(json,
"n_inputs", dgp->
n_inputs);
352 cJSON *istate = cJSON_CreateDoubleArray(dgp->
initial_state, dgp->
n);
353 cJSON_AddItemToObject(json,
"initial_state", istate);
354 cJSON *state = cJSON_CreateDoubleArray(dgp->
state, dgp->
n);
355 cJSON_AddItemToObject(json,
"current_state", state);
356 cJSON *functions = cJSON_CreateArray();
357 cJSON_AddItemToObject(json,
"functions", functions);
358 for (
int i = 0; i < dgp->
n; ++i) {
360 cJSON_AddItemToArray(functions, str);
363 cJSON_AddItemToObject(json,
"connectivity", connectivity);
364 cJSON *mutation = cJSON_CreateDoubleArray(dgp->
mu,
N_MU);
365 cJSON_AddItemToObject(json,
"mutation", mutation);
366 char *
string = cJSON_Print(json);
379 const cJSON *item = cJSON_GetObjectItem(json,
"current_state");
380 if (item != NULL && cJSON_IsArray(item)) {
381 if (cJSON_GetArraySize(item) != dgp->
n) {
382 printf(
"Import error: current_state length mismatch\n");
385 for (
int i = 0; i < dgp->
n; ++i) {
386 const cJSON *item_i = cJSON_GetArrayItem(item, i);
387 if (item_i->valuedouble < 0 || item_i->valuedouble > 1) {
388 printf(
"Import error: current state value out of bounds\n");
391 dgp->
state[i] = item_i->valuedouble;
404 const cJSON *item = cJSON_GetObjectItem(json,
"initial_state");
405 if (item != NULL && cJSON_IsArray(item)) {
406 if (cJSON_GetArraySize(item) != dgp->
n) {
407 printf(
"Import error: initial_state length mismatch\n");
410 for (
int i = 0; i < dgp->
n; ++i) {
411 const cJSON *item_i = cJSON_GetArrayItem(item, i);
412 if (item_i->valuedouble < 0 || item_i->valuedouble > 1) {
413 printf(
"Import error: initial state value out of bounds\n");
429 const cJSON *item = cJSON_GetObjectItem(json,
"functions");
430 if (item != NULL && cJSON_IsArray(item)) {
431 if (cJSON_GetArraySize(item) != dgp->
n) {
432 printf(
"Import error: functions length mismatch\n");
435 for (
int i = 0; i < dgp->
n; ++i) {
436 const cJSON *item_i = cJSON_GetArrayItem(item, i);
437 if (cJSON_IsString(item_i)) {
452 const cJSON *item = cJSON_GetObjectItem(json,
"connectivity");
453 if (item != NULL && cJSON_IsArray(item)) {
454 if (cJSON_GetArraySize(item) != dgp->
klen) {
455 printf(
"Import error: connectivity length mismatch\n");
458 const int max_c = dgp->
n + dgp->
n_inputs;
459 for (
int i = 0; i < dgp->
klen; ++i) {
460 const cJSON *item_i = cJSON_GetArrayItem(item, i);
461 if (item_i->valueint < 0 || item_i->valueint > max_c) {
462 printf(
"Import error: connectivity value out of bounds\n");
481 const cJSON *n = cJSON_GetObjectItem(json,
"n");
483 if (!cJSON_IsNumber(n) || n->valueint < 1) {
484 printf(
"Import error: invalid n\n");
487 dgp->
n = n->valueint;
494 dgp->
state = malloc(
sizeof(
double) * dgp->
n);
496 dgp->
tmp_state = malloc(
sizeof(
double) * dgp->
n);
498 dgp->
function = malloc(
sizeof(
int) * dgp->
n);
500 dgp->
mu = malloc(
sizeof(
double) *
N_MU);
502 const cJSON *t = cJSON_GetObjectItem(json,
"t");
504 if (!cJSON_IsNumber(t) || t->valueint < 1) {
505 printf(
"Import error: invalid t}\n");
508 dgp->
t = t->valueint;
567 s += fwrite(&dgp->
n_inputs,
sizeof(
int), 1, fp);
568 s += fwrite(&dgp->
n,
sizeof(
int), 1, fp);
569 s += fwrite(&dgp->
t,
sizeof(
int), 1, fp);
570 s += fwrite(&dgp->
klen,
sizeof(
int), 1, fp);
571 s += fwrite(&dgp->
max_t,
sizeof(
int), 1, fp);
572 s += fwrite(&dgp->
max_k,
sizeof(
int), 1, fp);
573 s += fwrite(dgp->
state,
sizeof(
double), dgp->
n, fp);
575 s += fwrite(dgp->
function,
sizeof(
int), dgp->
n, fp);
577 s += fwrite(dgp->
mu,
sizeof(
double),
N_MU, fp);
592 s += fread(&dgp->
n_inputs,
sizeof(
int), 1, fp);
593 s += fread(&dgp->
n,
sizeof(
int), 1, fp);
594 s += fread(&dgp->
t,
sizeof(
int), 1, fp);
595 s += fread(&dgp->
klen,
sizeof(
int), 1, fp);
596 s += fread(&dgp->
max_t,
sizeof(
int), 1, fp);
597 s += fread(&dgp->
max_k,
sizeof(
int), 1, fp);
598 if (dgp->
n < 1 || dgp->
klen < 1) {
599 printf(
"graph_load(): read error\n");
604 dgp->
state = malloc(
sizeof(
double) * dgp->
n);
606 dgp->
tmp_state = malloc(
sizeof(
double) * dgp->
n);
608 dgp->
function = malloc(
sizeof(
int) * dgp->
n);
610 dgp->
mu = malloc(
sizeof(
double) *
N_MU);
611 s += fread(dgp->
state,
sizeof(
double), dgp->
n, fp);
613 s += fread(dgp->
function,
sizeof(
int), dgp->
n, fp);
615 s += fread(dgp->
mu,
sizeof(
double),
N_MU, fp);
641 cJSON *json = cJSON_CreateObject();
642 cJSON_AddNumberToObject(json,
"max_k", args->
max_k);
643 cJSON_AddNumberToObject(json,
"max_t", args->
max_t);
644 cJSON_AddNumberToObject(json,
"n", args->
n);
645 cJSON_AddBoolToObject(json,
"evolve_cycles", args->
evolve_cycles);
646 char *
string = cJSON_Print(json);
660 for (cJSON *iter = json; iter != NULL; iter = iter->next) {
661 if (strncmp(iter->string,
"max_k\0", 6) == 0 && cJSON_IsNumber(iter)) {
663 }
else if (strncmp(iter->string,
"max_t\0", 6) == 0 &&
664 cJSON_IsNumber(iter)) {
666 }
else if (strncmp(iter->string,
"n\0", 2) == 0 &&
667 cJSON_IsNumber(iter)) {
669 }
else if (strncmp(iter->string,
"evolve_cycles\0", 14) == 0 &&
670 cJSON_IsBool(iter)) {
671 const bool evolve =
true ? iter->type == cJSON_True :
false;
691 s += fwrite(&args->
max_k,
sizeof(
int), 1, fp);
692 s += fwrite(&args->
max_t,
sizeof(
int), 1, fp);
693 s += fwrite(&args->
n,
sizeof(
int), 1, fp);
694 s += fwrite(&args->
n_inputs,
sizeof(
int), 1, fp);
709 s += fread(&args->
max_k,
sizeof(
int), 1, fp);
710 s += fread(&args->
max_t,
sizeof(
int), 1, fp);
711 s += fread(&args->
n,
sizeof(
int), 1, fp);
712 s += fread(&args->
n_inputs,
sizeof(
int), 1, fp);
722 printf(
"Warning: tried to set DGP MAX_K too small\n");
733 printf(
"Warning: tried to set DGP MAX_T too small\n");
744 printf(
"Warning: tried to set DGP N too small\n");
755 printf(
"Warning: tried to set DGP N_INPUTS too small\n");
size_t graph_args_save(const struct ArgsDGP *args, FILE *fp)
Saves DGP parameters.
void graph_print(const struct Graph *dgp)
Prints a DGP graph.
char * graph_args_json_export(const struct ArgsDGP *args)
Returns a json formatted string of the DGP parameters.
void graph_param_set_max_t(struct ArgsDGP *args, const int a)
static void graph_json_import_functions(struct Graph *dgp, const cJSON *json)
Sets DGP functions from a cJSON object.
static void synchronous_update(const struct Graph *dgp, const double *inputs)
Performs a synchronous update.
void graph_copy(struct Graph *dest, const struct Graph *src)
Copies a DGP graph.
static const int MU_TYPE[(3)]
Self-adaptation method for mutating DGP graphs.
#define FUZZY_NOT
Fuzzy NOT function.
void graph_free(const struct Graph *dgp)
Frees a DGP graph.
size_t graph_args_load(struct ArgsDGP *args, FILE *fp)
Loads DGP parameters.
void graph_rand(struct Graph *dgp)
Randomises a specified DGP graph.
void graph_param_set_n(struct ArgsDGP *args, const int a)
static int random_connection(const int n_nodes, const int n_inputs)
Returns a random connection.
size_t graph_save(const struct Graph *dgp, FILE *fp)
Writes DGP graph to a file.
#define STRING_FUZZY_CFMQVS_AND
Fuzzy AND.
void graph_args_init(struct ArgsDGP *args)
Sets DGP parameters to default values.
void graph_json_import(struct Graph *dgp, const struct ArgsDGP *args, const cJSON *json)
Creates a DGP graph from a cJSON object.
static void graph_json_import_current_state(struct Graph *dgp, const cJSON *json)
Sets DGP current states from a cJSON object.
#define FUZZY_CFMQVS_AND
Fuzzy AND (CFMQVS) function.
#define N_MU
Number of DGP graph mutation rates.
#define STRING_FUZZY_NOT
Fuzzy NOT.
void graph_update(const struct Graph *dgp, const double *inputs, const bool reset)
Updates a DGP graph T cycles.
#define FUZZY_CFMQVS_OR
Fuzzy OR (CFMQVS) function.
static bool graph_mutate_functions(struct Graph *dgp)
Mutates the node functions within a DGP graph.
#define NUM_FUNC
Number of selectable node functions.
static bool graph_mutate_connectivity(struct Graph *dgp)
Mutates the connectivity of a DGP graph.
void graph_init(struct Graph *dgp, const struct ArgsDGP *args)
Initialises a new DGP graph.
static void graph_json_import_connectivity(struct Graph *dgp, const cJSON *json)
Sets DGP mutation rates from a cJSON object.
double graph_output(const struct Graph *dgp, const int IDX)
Returns the current state of a specified node in the graph.
void graph_param_set_n_inputs(struct ArgsDGP *args, const int a)
#define STRING_FUZZY_CFMQVS_OR
Fuzzy OR.
char * graph_json_export(const struct Graph *dgp)
Returns a json formatted string representation of a DGP graph.
static bool graph_mutate_cycles(struct Graph *dgp)
Mutates the number of update cycles performed by a DGP graph.
static double node_activate(int function, const double *inputs, const int K)
Returns the result from applying a specified activation function.
void graph_param_set_max_k(struct ArgsDGP *args, const int a)
static int function_int(const char *function)
Returns the integer value of a specified node function.
size_t graph_load(struct Graph *dgp, FILE *fp)
Reads DGP graph from a file.
static const char * function_string(const int function)
Returns the name of a specified node function.
char * graph_args_json_import(struct ArgsDGP *args, cJSON *json)
Sets the DGP graph parameters from a cJSON object.
void graph_param_set_evolve_cycles(struct ArgsDGP *args, const bool a)
void graph_reset(const struct Graph *dgp)
Resets the states to their initial state.
static void graph_json_import_initial_state(struct Graph *dgp, const cJSON *json)
Sets DGP initial states from a cJSON object.
bool graph_mutate(struct Graph *dgp)
Mutates a specified DGP graph.
An implementation of dynamical GP graphs with fuzzy activations.
void sam_json_import(double *mu, const int N, const cJSON *json)
Initialises a mutation vector from a cJSON object.
void sam_init(double *mu, const int N, const int *type)
Initialises self-adaptive mutation rates.
void sam_adapt(double *mu, const int N, const int *type)
Self-adapts mutation rates.
Self-adaptive mutation functions.
#define SAM_LOG_NORMAL
Log normal self-adaptation.
#define SAM_UNIFORM
Uniformly random self-adaptation.
Parameters for initialising DGP graphs.
int max_t
Maximum number of update cycles.
int max_k
Maximum number of connections a node may have.
int n_inputs
Number of inputs to the graph.
int n
Number of nodes in the graph.
bool evolve_cycles
Whether to evolve the number of update cycles.
Dynamical GP graph data structure.
int n_inputs
Number of inputs to the graph.
double * mu
Mutation rates.
int * connectivity
Connectivity map.
double * state
Current state of each node.
double * initial_state
Initial node states.
int t
Number of cycles to run.
bool evolve_cycles
Whether to evolve the number of update cycles.
int max_t
Maximum number of update cycles.
int max_k
Maximum number of connections a node may have.
double * tmp_state
Temporary storage for synchronous update.
int * function
Node activation functions.
double * tmp_input
Temporary storage for updating the graph.
int klen
Length of connectivity map.
int rand_uniform_int(const int min, const int max)
Returns a uniform random integer [min,max] not inclusive of max.
double rand_uniform(const double min, const double max)
Returns a uniform random float [min,max].
Utility functions for random number handling, etc.
static double clamp(const double a, const double min, const double max)
Returns a float clamped within the specified range.