XCSF  1.4.7
XCSF learning classifier system
dgp.c
Go to the documentation of this file.
1 /*
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation, either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  */
15 
24 #include "dgp.h"
25 #include "sam.h"
26 #include "utils.h"
27 
28 #define FUZZY_NOT (0)
29 #define FUZZY_CFMQVS_AND (1)
30 #define FUZZY_CFMQVS_OR (2)
31 #define NUM_FUNC (3)
32 #define N_MU (3)
33 
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")
37 
41 static const int MU_TYPE[N_MU] = {
45 };
46 
52 static int
53 random_connection(const int n_nodes, const int n_inputs)
54 {
55  // another node within the graph
56  if (rand_uniform(0, 1) < 0.5) {
57  return rand_uniform_int(0, n_nodes) + n_inputs;
58  }
59  // external input
60  return rand_uniform_int(0, n_inputs);
61 }
62 
68 static bool
70 {
71  bool mod = false;
72  for (int i = 0; i < dgp->n; ++i) {
73  if (rand_uniform(0, 1) < dgp->mu[0]) {
74  const int orig = dgp->function[i];
75  dgp->function[i] = rand_uniform_int(0, NUM_FUNC);
76  if (orig != dgp->function[i]) {
77  mod = true;
78  }
79  }
80  }
81  return mod;
82 }
83 
89 static bool
91 {
92  bool mod = false;
93  for (int i = 0; i < dgp->klen; ++i) {
94  if (rand_uniform(0, 1) < dgp->mu[1]) {
95  const int orig = dgp->connectivity[i];
96  dgp->connectivity[i] = random_connection(dgp->n, dgp->n_inputs);
97  if (orig != dgp->connectivity[i]) {
98  mod = true;
99  }
100  }
101  }
102  return mod;
103 }
104 
110 static bool
112 {
113  const int n = (int) round((2 * dgp->mu[2]) - 1);
114  if (dgp->t + n < 1 || dgp->t + n > dgp->max_t) {
115  return false;
116  }
117  dgp->t += n;
118  return true;
119 }
120 
128 static double
129 node_activate(int function, const double *inputs, const int K)
130 {
131  double state = 0;
132  switch (function) {
133  case FUZZY_NOT:
134  state = 1 - inputs[0];
135  break;
136  case FUZZY_CFMQVS_AND:
137  state = inputs[0];
138  for (int i = 1; i < K; ++i) {
139  state *= inputs[i];
140  }
141  break;
142  case FUZZY_CFMQVS_OR:
143  state = inputs[0];
144  for (int i = 1; i < K; ++i) {
145  state += inputs[i];
146  }
147  break;
148  default: // Invalid function
149  printf("Error updating node: Invalid function: %d\n", function);
150  exit(EXIT_FAILURE);
151  }
152  state = clamp(state, 0, 1);
153  return state;
154 }
155 
161 static const char *
162 function_string(const int function)
163 {
164  switch (function) {
165  case FUZZY_NOT:
166  return STRING_FUZZY_NOT;
167  case FUZZY_CFMQVS_AND:
169  case FUZZY_CFMQVS_OR:
170  return STRING_FUZZY_CFMQVS_OR;
171  default:
172  printf("dgp_function_string(): invalid node function: %d\n",
173  function);
174  exit(EXIT_FAILURE);
175  }
176 }
177 
183 static int
184 function_int(const char *function)
185 {
186  if (strncmp(function, STRING_FUZZY_NOT, 10) == 0) {
187  return FUZZY_NOT;
188  } else if (strncmp(function, STRING_FUZZY_CFMQVS_AND, 10) == 0) {
189  return FUZZY_CFMQVS_AND;
190  } else if (strncmp(function, STRING_FUZZY_CFMQVS_OR, 9) == 0) {
191  return FUZZY_CFMQVS_OR;
192  }
193  printf("dgp_function_int(): invalid node function: %s\n", function);
194  exit(EXIT_FAILURE);
195 }
196 
202 static void
203 synchronous_update(const struct Graph *dgp, const double *inputs)
204 {
205  for (int i = 0; i < dgp->n; ++i) {
206  for (int k = 0; k < dgp->max_k; ++k) {
207  const int c = dgp->connectivity[i * dgp->max_k + k];
208  if (c < dgp->n_inputs) { // external input
209  dgp->tmp_input[k] = inputs[c];
210  } else { // another node within the graph
211  dgp->tmp_input[k] = dgp->state[c - dgp->n_inputs];
212  }
213  }
214  dgp->tmp_state[i] =
215  node_activate(dgp->function[i], dgp->tmp_input, dgp->max_k);
216  }
217  memcpy(dgp->state, dgp->tmp_state, sizeof(double) * dgp->n);
218 }
219 
225 void
226 graph_init(struct Graph *dgp, const struct ArgsDGP *args)
227 {
228  dgp->n_inputs = args->n_inputs;
229  dgp->n = args->n;
230  dgp->t = args->max_t;
231  dgp->max_t = args->max_t;
232  dgp->max_k = args->max_k;
233  dgp->evolve_cycles = args->evolve_cycles;
234  dgp->klen = dgp->n * dgp->max_k;
235  dgp->state = malloc(sizeof(double) * dgp->n);
236  dgp->initial_state = malloc(sizeof(double) * dgp->n);
237  dgp->tmp_state = malloc(sizeof(double) * dgp->n);
238  dgp->tmp_input = malloc(sizeof(double) * dgp->max_k);
239  dgp->function = malloc(sizeof(int) * dgp->n);
240  dgp->connectivity = malloc(sizeof(int) * dgp->klen);
241  dgp->mu = malloc(sizeof(double) * N_MU);
242  sam_init(dgp->mu, N_MU, MU_TYPE);
243 }
244 
250 void
251 graph_copy(struct Graph *dest, const struct Graph *src)
252 {
253  dest->t = src->t;
254  dest->n = src->n;
255  dest->klen = src->klen;
256  dest->max_k = src->max_k;
257  dest->max_t = src->max_t;
258  dest->n_inputs = src->n_inputs;
259  dest->evolve_cycles = src->evolve_cycles;
260  memcpy(dest->state, src->state, sizeof(double) * src->n);
261  memcpy(dest->initial_state, src->initial_state, sizeof(double) * src->n);
262  memcpy(dest->function, src->function, sizeof(int) * src->n);
263  memcpy(dest->connectivity, src->connectivity, sizeof(int) * src->klen);
264  memcpy(dest->mu, src->mu, sizeof(double) * N_MU);
265 }
266 
273 double
274 graph_output(const struct Graph *dgp, const int IDX)
275 {
276  return dgp->state[IDX];
277 }
278 
283 void
284 graph_reset(const struct Graph *dgp)
285 {
286  for (int i = 0; i < dgp->n; ++i) {
287  dgp->state[i] = dgp->initial_state[i];
288  }
289 }
290 
295 void
296 graph_rand(struct Graph *dgp)
297 {
298  if (dgp->evolve_cycles) {
299  dgp->t = rand_uniform_int(1, dgp->max_t);
300  }
301  for (int i = 0; i < dgp->n; ++i) {
302  dgp->function[i] = rand_uniform_int(0, NUM_FUNC);
303  dgp->initial_state[i] = rand_uniform(0, 1);
304  dgp->state[i] = rand_uniform(0, 1);
305  }
306  for (int i = 0; i < dgp->klen; ++i) {
307  dgp->connectivity[i] = random_connection(dgp->n, dgp->n_inputs);
308  }
309 }
310 
317 void
318 graph_update(const struct Graph *dgp, const double *inputs, const bool reset)
319 {
320  if (reset) {
321  graph_reset(dgp);
322  }
323  for (int t = 0; t < dgp->t; ++t) {
324  synchronous_update(dgp, inputs);
325  }
326 }
327 
332 void
333 graph_print(const struct Graph *dgp)
334 {
335  char *json_str = graph_json_export(dgp);
336  printf("%s\n", json_str);
337  free(json_str);
338 }
339 
345 char *
346 graph_json_export(const struct Graph *dgp)
347 {
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) {
359  cJSON *str = cJSON_CreateString(function_string(dgp->function[i]));
360  cJSON_AddItemToArray(functions, str);
361  }
362  cJSON *connectivity = cJSON_CreateIntArray(dgp->connectivity, dgp->klen);
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);
367  cJSON_Delete(json);
368  return string;
369 }
370 
376 static void
377 graph_json_import_current_state(struct Graph *dgp, const cJSON *json)
378 {
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");
383  exit(EXIT_FAILURE);
384  }
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");
389  exit(EXIT_FAILURE);
390  }
391  dgp->state[i] = item_i->valuedouble;
392  }
393  }
394 }
395 
401 static void
402 graph_json_import_initial_state(struct Graph *dgp, const cJSON *json)
403 {
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");
408  exit(EXIT_FAILURE);
409  }
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");
414  exit(EXIT_FAILURE);
415  }
416  dgp->initial_state[i] = item_i->valuedouble;
417  }
418  }
419 }
420 
426 static void
427 graph_json_import_functions(struct Graph *dgp, const cJSON *json)
428 {
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");
433  exit(EXIT_FAILURE);
434  }
435  for (int i = 0; i < dgp->n; ++i) {
436  const cJSON *item_i = cJSON_GetArrayItem(item, i);
437  if (cJSON_IsString(item_i)) {
438  dgp->function[i] = function_int(item_i->valuestring);
439  }
440  }
441  }
442 }
443 
449 static void
450 graph_json_import_connectivity(struct Graph *dgp, const cJSON *json)
451 {
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");
456  exit(EXIT_FAILURE);
457  }
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");
463  exit(EXIT_FAILURE);
464  }
465  dgp->connectivity[i] = item_i->valueint;
466  }
467  }
468 }
469 
476 void
477 graph_json_import(struct Graph *dgp, const struct ArgsDGP *args,
478  const cJSON *json)
479 {
480  dgp->n = args->n;
481  const cJSON *n = cJSON_GetObjectItem(json, "n");
482  if (n != NULL) {
483  if (!cJSON_IsNumber(n) || n->valueint < 1) {
484  printf("Import error: invalid n\n");
485  exit(EXIT_FAILURE);
486  }
487  dgp->n = n->valueint;
488  }
489  dgp->n_inputs = args->n_inputs;
490  dgp->max_t = args->max_t;
491  dgp->max_k = args->max_k;
492  dgp->evolve_cycles = args->evolve_cycles;
493  dgp->klen = dgp->n * dgp->max_k;
494  dgp->state = malloc(sizeof(double) * dgp->n);
495  dgp->initial_state = malloc(sizeof(double) * dgp->n);
496  dgp->tmp_state = malloc(sizeof(double) * dgp->n);
497  dgp->tmp_input = malloc(sizeof(double) * dgp->max_k);
498  dgp->function = malloc(sizeof(int) * dgp->n);
499  dgp->connectivity = malloc(sizeof(int) * dgp->klen);
500  dgp->mu = malloc(sizeof(double) * N_MU);
501  graph_rand(dgp);
502  const cJSON *t = cJSON_GetObjectItem(json, "t");
503  if (t != NULL) {
504  if (!cJSON_IsNumber(t) || t->valueint < 1) {
505  printf("Import error: invalid t}\n");
506  exit(EXIT_FAILURE);
507  } else {
508  dgp->t = t->valueint;
509  }
510  }
513  graph_json_import_functions(dgp, json);
515  sam_json_import(dgp->mu, N_MU, json);
516 }
517 
522 void
523 graph_free(const struct Graph *dgp)
524 {
525  free(dgp->connectivity);
526  free(dgp->state);
527  free(dgp->initial_state);
528  free(dgp->tmp_state);
529  free(dgp->tmp_input);
530  free(dgp->function);
531  free(dgp->mu);
532 }
533 
539 bool
540 graph_mutate(struct Graph *dgp)
541 {
542  bool mod = false;
543  sam_adapt(dgp->mu, N_MU, MU_TYPE);
544  if (graph_mutate_functions(dgp)) {
545  mod = true;
546  }
547  if (graph_mutate_connectivity(dgp)) {
548  mod = true;
549  }
550  if (dgp->evolve_cycles && graph_mutate_cycles(dgp)) {
551  mod = true;
552  }
553  return mod;
554 }
555 
562 size_t
563 graph_save(const struct Graph *dgp, FILE *fp)
564 {
565  size_t s = 0;
566  s += fwrite(&dgp->evolve_cycles, sizeof(bool), 1, fp);
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);
574  s += fwrite(dgp->initial_state, sizeof(double), dgp->n, fp);
575  s += fwrite(dgp->function, sizeof(int), dgp->n, fp);
576  s += fwrite(dgp->connectivity, sizeof(int), dgp->klen, fp);
577  s += fwrite(dgp->mu, sizeof(double), N_MU, fp);
578  return s;
579 }
580 
587 size_t
588 graph_load(struct Graph *dgp, FILE *fp)
589 {
590  size_t s = 0;
591  s += fread(&dgp->evolve_cycles, sizeof(bool), 1, 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");
600  dgp->n = 1;
601  dgp->klen = 1;
602  exit(EXIT_FAILURE);
603  }
604  dgp->state = malloc(sizeof(double) * dgp->n);
605  dgp->initial_state = malloc(sizeof(double) * dgp->n);
606  dgp->tmp_state = malloc(sizeof(double) * dgp->n);
607  dgp->tmp_input = malloc(sizeof(double) * dgp->max_k);
608  dgp->function = malloc(sizeof(int) * dgp->n);
609  dgp->connectivity = malloc(sizeof(int) * dgp->klen);
610  dgp->mu = malloc(sizeof(double) * N_MU);
611  s += fread(dgp->state, sizeof(double), dgp->n, fp);
612  s += fread(dgp->initial_state, sizeof(double), dgp->n, fp);
613  s += fread(dgp->function, sizeof(int), dgp->n, fp);
614  s += fread(dgp->connectivity, sizeof(int), dgp->klen, fp);
615  s += fread(dgp->mu, sizeof(double), N_MU, fp);
616  return s;
617 }
618 
623 void
625 {
626  args->max_k = 0;
627  args->max_t = 0;
628  args->n = 0;
629  args->n_inputs = 0;
630  args->evolve_cycles = false;
631 }
632 
638 char *
639 graph_args_json_export(const struct ArgsDGP *args)
640 {
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);
647  cJSON_Delete(json);
648  return string;
649 }
650 
657 char *
658 graph_args_json_import(struct ArgsDGP *args, cJSON *json)
659 {
660  for (cJSON *iter = json; iter != NULL; iter = iter->next) {
661  if (strncmp(iter->string, "max_k\0", 6) == 0 && cJSON_IsNumber(iter)) {
662  graph_param_set_max_k(args, iter->valueint);
663  } else if (strncmp(iter->string, "max_t\0", 6) == 0 &&
664  cJSON_IsNumber(iter)) {
665  graph_param_set_max_t(args, iter->valueint);
666  } else if (strncmp(iter->string, "n\0", 2) == 0 &&
667  cJSON_IsNumber(iter)) {
668  graph_param_set_n(args, iter->valueint);
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;
672  graph_param_set_evolve_cycles(args, evolve);
673  } else {
674  return iter->string;
675  }
676  }
677  return NULL;
678 }
679 
686 size_t
687 graph_args_save(const struct ArgsDGP *args, FILE *fp)
688 {
689  size_t s = 0;
690  s += fwrite(&args->evolve_cycles, sizeof(bool), 1, fp);
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);
695  return s;
696 }
697 
704 size_t
705 graph_args_load(struct ArgsDGP *args, FILE *fp)
706 {
707  size_t s = 0;
708  s += fread(&args->evolve_cycles, sizeof(bool), 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);
713  return s;
714 }
715 
716 /* parameter setters */
717 
718 void
719 graph_param_set_max_k(struct ArgsDGP *args, const int a)
720 {
721  if (a < 1) {
722  printf("Warning: tried to set DGP MAX_K too small\n");
723  args->max_k = 1;
724  } else {
725  args->max_k = a;
726  }
727 }
728 
729 void
730 graph_param_set_max_t(struct ArgsDGP *args, const int a)
731 {
732  if (a < 1) {
733  printf("Warning: tried to set DGP MAX_T too small\n");
734  args->max_t = 1;
735  } else {
736  args->max_t = a;
737  }
738 }
739 
740 void
741 graph_param_set_n(struct ArgsDGP *args, const int a)
742 {
743  if (a < 1) {
744  printf("Warning: tried to set DGP N too small\n");
745  args->n = 1;
746  } else {
747  args->n = a;
748  }
749 }
750 
751 void
752 graph_param_set_n_inputs(struct ArgsDGP *args, const int a)
753 {
754  if (a < 1) {
755  printf("Warning: tried to set DGP N_INPUTS too small\n");
756  args->n_inputs = 1;
757  } else {
758  args->n_inputs = a;
759  }
760 }
761 
762 void
763 graph_param_set_evolve_cycles(struct ArgsDGP *args, const bool a)
764 {
765  args->evolve_cycles = a;
766 }
size_t graph_args_save(const struct ArgsDGP *args, FILE *fp)
Saves DGP parameters.
Definition: dgp.c:687
void graph_print(const struct Graph *dgp)
Prints a DGP graph.
Definition: dgp.c:333
char * graph_args_json_export(const struct ArgsDGP *args)
Returns a json formatted string of the DGP parameters.
Definition: dgp.c:639
void graph_param_set_max_t(struct ArgsDGP *args, const int a)
Definition: dgp.c:730
static void graph_json_import_functions(struct Graph *dgp, const cJSON *json)
Sets DGP functions from a cJSON object.
Definition: dgp.c:427
static void synchronous_update(const struct Graph *dgp, const double *inputs)
Performs a synchronous update.
Definition: dgp.c:203
void graph_copy(struct Graph *dest, const struct Graph *src)
Copies a DGP graph.
Definition: dgp.c:251
static const int MU_TYPE[(3)]
Self-adaptation method for mutating DGP graphs.
Definition: dgp.c:41
#define FUZZY_NOT
Fuzzy NOT function.
Definition: dgp.c:28
void graph_free(const struct Graph *dgp)
Frees a DGP graph.
Definition: dgp.c:523
size_t graph_args_load(struct ArgsDGP *args, FILE *fp)
Loads DGP parameters.
Definition: dgp.c:705
void graph_rand(struct Graph *dgp)
Randomises a specified DGP graph.
Definition: dgp.c:296
void graph_param_set_n(struct ArgsDGP *args, const int a)
Definition: dgp.c:741
static int random_connection(const int n_nodes, const int n_inputs)
Returns a random connection.
Definition: dgp.c:53
size_t graph_save(const struct Graph *dgp, FILE *fp)
Writes DGP graph to a file.
Definition: dgp.c:563
#define STRING_FUZZY_CFMQVS_AND
Fuzzy AND.
Definition: dgp.c:35
void graph_args_init(struct ArgsDGP *args)
Sets DGP parameters to default values.
Definition: dgp.c:624
void graph_json_import(struct Graph *dgp, const struct ArgsDGP *args, const cJSON *json)
Creates a DGP graph from a cJSON object.
Definition: dgp.c:477
static void graph_json_import_current_state(struct Graph *dgp, const cJSON *json)
Sets DGP current states from a cJSON object.
Definition: dgp.c:377
#define FUZZY_CFMQVS_AND
Fuzzy AND (CFMQVS) function.
Definition: dgp.c:29
#define N_MU
Number of DGP graph mutation rates.
Definition: dgp.c:32
#define STRING_FUZZY_NOT
Fuzzy NOT.
Definition: dgp.c:34
void graph_update(const struct Graph *dgp, const double *inputs, const bool reset)
Updates a DGP graph T cycles.
Definition: dgp.c:318
#define FUZZY_CFMQVS_OR
Fuzzy OR (CFMQVS) function.
Definition: dgp.c:30
static bool graph_mutate_functions(struct Graph *dgp)
Mutates the node functions within a DGP graph.
Definition: dgp.c:69
#define NUM_FUNC
Number of selectable node functions.
Definition: dgp.c:31
static bool graph_mutate_connectivity(struct Graph *dgp)
Mutates the connectivity of a DGP graph.
Definition: dgp.c:90
void graph_init(struct Graph *dgp, const struct ArgsDGP *args)
Initialises a new DGP graph.
Definition: dgp.c:226
static void graph_json_import_connectivity(struct Graph *dgp, const cJSON *json)
Sets DGP mutation rates from a cJSON object.
Definition: dgp.c:450
double graph_output(const struct Graph *dgp, const int IDX)
Returns the current state of a specified node in the graph.
Definition: dgp.c:274
void graph_param_set_n_inputs(struct ArgsDGP *args, const int a)
Definition: dgp.c:752
#define STRING_FUZZY_CFMQVS_OR
Fuzzy OR.
Definition: dgp.c:36
char * graph_json_export(const struct Graph *dgp)
Returns a json formatted string representation of a DGP graph.
Definition: dgp.c:346
static bool graph_mutate_cycles(struct Graph *dgp)
Mutates the number of update cycles performed by a DGP graph.
Definition: dgp.c:111
static double node_activate(int function, const double *inputs, const int K)
Returns the result from applying a specified activation function.
Definition: dgp.c:129
void graph_param_set_max_k(struct ArgsDGP *args, const int a)
Definition: dgp.c:719
static int function_int(const char *function)
Returns the integer value of a specified node function.
Definition: dgp.c:184
size_t graph_load(struct Graph *dgp, FILE *fp)
Reads DGP graph from a file.
Definition: dgp.c:588
static const char * function_string(const int function)
Returns the name of a specified node function.
Definition: dgp.c:162
char * graph_args_json_import(struct ArgsDGP *args, cJSON *json)
Sets the DGP graph parameters from a cJSON object.
Definition: dgp.c:658
void graph_param_set_evolve_cycles(struct ArgsDGP *args, const bool a)
Definition: dgp.c:763
void graph_reset(const struct Graph *dgp)
Resets the states to their initial state.
Definition: dgp.c:284
static void graph_json_import_initial_state(struct Graph *dgp, const cJSON *json)
Sets DGP initial states from a cJSON object.
Definition: dgp.c:402
bool graph_mutate(struct Graph *dgp)
Mutates a specified DGP graph.
Definition: dgp.c:540
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.
Definition: sam.c:100
void sam_init(double *mu, const int N, const int *type)
Initialises self-adaptive mutation rates.
Definition: sam.c:43
void sam_adapt(double *mu, const int N, const int *type)
Self-adapts mutation rates.
Definition: sam.c:68
Self-adaptive mutation functions.
#define SAM_LOG_NORMAL
Log normal self-adaptation.
Definition: sam.h:28
#define SAM_UNIFORM
Uniformly random self-adaptation.
Definition: sam.h:30
Parameters for initialising DGP graphs.
Definition: dgp.h:31
int max_t
Maximum number of update cycles.
Definition: dgp.h:34
int max_k
Maximum number of connections a node may have.
Definition: dgp.h:33
int n_inputs
Number of inputs to the graph.
Definition: dgp.h:36
int n
Number of nodes in the graph.
Definition: dgp.h:35
bool evolve_cycles
Whether to evolve the number of update cycles.
Definition: dgp.h:32
Dynamical GP graph data structure.
Definition: dgp.h:42
int n_inputs
Number of inputs to the graph.
Definition: dgp.h:54
double * mu
Mutation rates.
Definition: dgp.h:56
int * connectivity
Connectivity map.
Definition: dgp.h:48
double * state
Current state of each node.
Definition: dgp.h:45
double * initial_state
Initial node states.
Definition: dgp.h:44
int t
Number of cycles to run.
Definition: dgp.h:55
int n
Number of nodes.
Definition: dgp.h:53
bool evolve_cycles
Whether to evolve the number of update cycles.
Definition: dgp.h:43
int max_t
Maximum number of update cycles.
Definition: dgp.h:52
int max_k
Maximum number of connections a node may have.
Definition: dgp.h:51
double * tmp_state
Temporary storage for synchronous update.
Definition: dgp.h:47
int * function
Node activation functions.
Definition: dgp.h:49
double * tmp_input
Temporary storage for updating the graph.
Definition: dgp.h:46
int klen
Length of connectivity map.
Definition: dgp.h:50
int rand_uniform_int(const int min, const int max)
Returns a uniform random integer [min,max] not inclusive of max.
Definition: utils.c:74
double rand_uniform(const double min, const double max)
Returns a uniform random float [min,max].
Definition: utils.c:62
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.
Definition: utils.h:60