diff --git a/Makefile b/Makefile index 10ebfcd4fd6cc78dd78e599f6c6bdbed920af59e..d856502eb00c8874a3ece597297736debadc95aa 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ TARGETS=\ cerberus \ chrony \ debie1 \ + genann \ gzip124 \ hiredis \ icpc \ diff --git a/README.md b/README.md index 9e9c7550aca2ba46656f4b0b3fccefc2c99d2058..0fb01735f56315fa807934f98a80c847f39e1145 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ when available. We also summarize the license of each directory below. - `debie1`: distribution and use authorized by Patria Aviation Oy, Space Systems Finland Ltd. and Tidorum Ltd, see `README.txt` and `terms_of_use-2014-05.pdf` +- `genann`: Zlib, see `LICENSE` - `gzip124`: GPL - `hiredis`: Redis license (BSD-style), see `COPYING` - `icpc`: Unlicense diff --git a/frama-c b/frama-c index 086dbf6774409ce5457bbc1ddb232e1f97714b23..4adb46e09b8f6bd9809fa98cf1bbc7731c8eea87 160000 --- a/frama-c +++ b/frama-c @@ -1 +1 @@ -Subproject commit 086dbf6774409ce5457bbc1ddb232e1f97714b23 +Subproject commit 4adb46e09b8f6bd9809fa98cf1bbc7731c8eea87 diff --git a/genann/.frama-c/GNUmakefile b/genann/.frama-c/GNUmakefile new file mode 100644 index 0000000000000000000000000000000000000000..614826732f32e132fe5165595d155a00de41c682 --- /dev/null +++ b/genann/.frama-c/GNUmakefile @@ -0,0 +1,49 @@ +# Makefile template for Frama-C/Eva case studies. +# For details and usage information, see the Frama-C User Manual. + +### Prologue. Do not modify this block. ####################################### +-include path.mk +FRAMAC ?= frama-c +include $(shell $(FRAMAC)-config -print-share-path)/analysis-scripts/prologue.mk +############################################################################### + +# Edit below as needed. Suggested flags are optional. + +MACHDEP = gcc_x86_64 + +# The source code uses the __FILE__ macro; to obtain stable oracles, we use +# a specific GCC option based on the directory containing this Makefile. +mkfile_path := $(abspath $(firstword $(MAKEFILE_LIST))/../..) + +## Preprocessing flags (for -cpp-extra-args) +CPPFLAGS += \ + -ffile-prefix-map=$(mkfile_path)=. + +## General flags +FCFLAGS += \ + -add-symbolic-path=..:. \ + -kernel-warn-key annot:missing-spec=abort \ + -kernel-warn-key typing:implicit-function-declaration=abort \ + +## Eva-specific flags +EVAFLAGS += \ + -eva-warn-key builtins:missing-spec=abort \ + -eva-slevel 9 \ + +## GUI-only flags +FCGUIFLAGS += \ + +## Analysis targets (suffixed with .eva) +TARGETS = genann.eva + +### Each target <t>.eva needs a rule <t>.parse with source files as prerequisites +genann.parse: \ + ../genann.c \ + ../test.c \ + +### Epilogue. Do not modify this block. ####################################### +include $(shell $(FRAMAC)-config -print-share-path)/analysis-scripts/epilogue.mk +############################################################################### + +# optional, for OSCS +-include ../../Makefile.common diff --git a/genann/.frama-c/genann.eva/alarms.csv b/genann/.frama-c/genann.eva/alarms.csv new file mode 100644 index 0000000000000000000000000000000000000000..d353cf06ad00ff0e9a4f7bbe8c2db2a8e1960492 --- /dev/null +++ b/genann/.frama-c/genann.eva/alarms.csv @@ -0,0 +1,76 @@ +directory file line function property kind status property +. genann.c 115 genann_init signed_overflow Unknown (int)((int)(inputs + 1) * hidden) + (int)((int)((int)(hidden_layers - 1) * (int)(hidden + 1)) * hidden) ≤ 2147483647 +. genann.c 115 genann_init signed_overflow Unknown (int)(inputs + 1) * hidden ≤ 2147483647 +. genann.c 115 genann_init signed_overflow Unknown inputs + 1 ≤ 2147483647 +. genann.c 115 genann_init signed_overflow Unknown (int)((int)(hidden_layers - 1) * (int)(hidden + 1)) * hidden ≤ 2147483647 +. genann.c 115 genann_init signed_overflow Unknown (int)(hidden_layers - 1) * (int)(hidden + 1) ≤ 2147483647 +. genann.c 115 genann_init signed_overflow Unknown hidden + 1 ≤ 2147483647 +. genann.c 116 genann_init signed_overflow Unknown tmp_0 * outputs ≤ 2147483647 +. genann.c 116 genann_init signed_overflow Unknown inputs + 1 ≤ 2147483647 +. genann.c 117 genann_init signed_overflow Unknown hidden_weights + output_weights ≤ 2147483647 +. genann.c 119 genann_init signed_overflow Unknown (int)(inputs + (int)(hidden * hidden_layers)) + outputs ≤ 2147483647 +. genann.c 119 genann_init signed_overflow Unknown inputs + (int)(hidden * hidden_layers) ≤ 2147483647 +. genann.c 119 genann_init signed_overflow Unknown hidden * hidden_layers ≤ 2147483647 +. genann.c 122 genann_init signed_overflow Unknown (int)(total_weights + total_neurons) + (int)(total_neurons - inputs) ≤ 2147483647 +. genann.c 122 genann_init signed_overflow Unknown total_weights + total_neurons ≤ 2147483647 +. genann.c 126 genann_init mem_access Unknown \valid(&ret->inputs) +. genann.c 127 genann_init mem_access Unknown \valid(&ret->hidden_layers) +. genann.c 128 genann_init mem_access Unknown \valid(&ret->hidden) +. genann.c 129 genann_init mem_access Unknown \valid(&ret->outputs) +. genann.c 131 genann_init mem_access Unknown \valid(&ret->total_weights) +. genann.c 132 genann_init mem_access Unknown \valid(&ret->total_neurons) +. genann.c 135 genann_init mem_access Unknown \valid(&ret->weight) +. genann.c 136 genann_init mem_access Unknown \valid(&ret->output) +. genann.c 136 genann_init mem_access Unknown \valid_read(&ret->total_weights) +. genann.c 136 genann_init mem_access Unknown \valid_read(&ret->weight) +. genann.c 137 genann_init mem_access Unknown \valid(&ret->delta) +. genann.c 137 genann_init mem_access Unknown \valid_read(&ret->output) +. genann.c 137 genann_init mem_access Unknown \valid_read(&ret->total_neurons) +. genann.c 141 genann_init mem_access Unknown \valid(&ret->activation_hidden) +. genann.c 142 genann_init mem_access Unknown \valid(&ret->activation_output) +. genann.c 164 genann_read mem_access Unknown \valid_read(&ann->total_weights) +. genann.c 166 fscanf_va_2 precondition Unknown \valid(param0) +. genann.c 166 genann_read mem_access Unknown \valid_read(&ann->weight) +. genann.c 166 genann_read precondition of fscanf_va_2 Unknown \valid(param0) +. genann.c 180 genann_copy mem_access Unknown \valid_read(&ann->inputs) +. genann.c 180 genann_copy mem_access Unknown \valid_read(&ann->total_neurons) +. genann.c 180 genann_copy mem_access Unknown \valid_read(&ann->total_weights) +. genann.c 197 genann_randomize mem_access Unknown \valid_read(&ann->total_weights) +. genann.c 200 genann_randomize mem_access Unknown \valid(ann->weight + i) +. genann.c 200 genann_randomize mem_access Unknown \valid_read(&ann->weight) +. genann.c 212 genann_run mem_access Unknown \valid_read(&ann->weight) +. genann.c 397 genann_write mem_access Unknown \valid_read(&ann->outputs) +. genann.c 401 genann_write initialization Unknown \initialized(ann->weight + i) +. test.c 37 basic mem_access Unknown \valid_read(&ann->total_weights) +. test.c 71 xor mem_access Unknown \valid(&ann->activation_hidden) +. test.c 201 persist precondition of fclose Unknown valid_stream: \valid(stream) +. test.c 206 persist precondition of fclose Unknown valid_stream: \valid(stream) +. test.c 208 persist mem_access Unknown \valid_read(&second->inputs) +. test.c 209 persist mem_access Unknown \valid_read(&second->hidden_layers) +. test.c 210 persist mem_access Unknown \valid_read(&second->hidden) +. test.c 211 persist mem_access Unknown \valid_read(&second->outputs) +. test.c 212 persist mem_access Unknown \valid_read(&second->total_weights) +. test.c 216 persist signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 216 persist initialization Unknown \initialized(first->weight + i) +. test.c 216 persist initialization Unknown \initialized(second->weight + i) +. test.c 216 persist is_nan_or_infinite Unknown \is_finite(*(second->weight + i)) +. test.c 216 persist mem_access Unknown \valid_read(&second->weight) +. test.c 216 persist mem_access Unknown \valid_read(second->weight + i) +. test.c 216 persist signed_overflow Unknown lfails + 1 ≤ 2147483647 +. test.c 229 copy signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 229 copy mem_access Unknown \valid_read(&second->inputs) +. test.c 230 copy signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 231 copy signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 232 copy signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 233 copy signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 237 copy signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 237 copy initialization Unknown \initialized(first->weight + i) +. test.c 237 copy initialization Unknown \initialized(second->weight + i) +. test.c 237 copy signed_overflow Unknown lfails + 1 ≤ 2147483647 +. test.c 251 sigmoid signed_overflow Unknown ltests + 1 ≤ 2147483647 +. test.c 251 sigmoid signed_overflow Unknown lfails + 1 ≤ 2147483647 +. test.c 270 main signed_overflow Unknown (int)(ltests - ts_6) - (int)(lfails - fs_6) ≤ 2147483647 +. test.c 270 main signed_overflow Unknown -2147483648 ≤ (int)(ltests - ts_6) - (int)(lfails - fs_6) +. test.c 271 main signed_overflow Unknown (int)(ltests - ts_7) - (int)(lfails - fs_7) ≤ 2147483647 +. test.c 271 main signed_overflow Unknown -2147483648 ≤ (int)(ltests - ts_7) - (int)(lfails - fs_7) +FRAMAC_SHARE/libc stdio.h 120 fclose precondition Unknown valid_stream: \valid(stream) diff --git a/genann/.frama-c/genann.eva/metrics.log b/genann/.frama-c/genann.eva/metrics.log new file mode 100644 index 0000000000000000000000000000000000000000..c489c1d7860d89e4d32e8b88d150a68f986b313f --- /dev/null +++ b/genann/.frama-c/genann.eva/metrics.log @@ -0,0 +1,39 @@ +[metrics] Eva coverage statistics +======================= +Syntactically reachable functions = 25 (out of 25) +Semantically reached functions = 24 +Coverage estimation = 96.0% + +Unreached functions (1) = + <genann.c>: genann_act_linear; +[metrics] References to non-analyzed functions +------------------------------------ +Function genann_train references genann_act_linear (at genann.c:292) +Function genann_train references genann_act_linear (at genann.c:293) +[metrics] Statements analyzed by Eva +-------------------------- +1042 stmts in analyzed functions, 947 stmts analyzed (90.9%) +backprop: 18 stmts out of 18 (100.0%) +genann_act_hidden_indirect: 2 stmts out of 2 (100.0%) +genann_act_output_indirect: 2 stmts out of 2 (100.0%) +genann_act_threshold: 2 stmts out of 2 (100.0%) +genann_copy: 12 stmts out of 12 (100.0%) +genann_free: 2 stmts out of 2 (100.0%) +genann_init: 48 stmts out of 48 (100.0%) +genann_init_sigmoid_lookup: 10 stmts out of 10 (100.0%) +genann_randomize: 10 stmts out of 10 (100.0%) +genann_read: 30 stmts out of 30 (100.0%) +genann_write: 9 stmts out of 9 (100.0%) +main: 116 stmts out of 116 (100.0%) +persist: 45 stmts out of 45 (100.0%) +sigmoid: 21 stmts out of 21 (100.0%) +train_and: 71 stmts out of 71 (100.0%) +train_or: 72 stmts out of 72 (100.0%) +train_xor: 71 stmts out of 71 (100.0%) +basic: 78 stmts out of 80 (97.5%) +genann_train: 132 stmts out of 152 (86.8%) +genann_act_sigmoid_cached: 22 stmts out of 26 (84.6%) +genann_run: 91 stmts out of 118 (77.1%) +copy: 31 stmts out of 41 (75.6%) +xor: 47 stmts out of 73 (64.4%) +genann_act_sigmoid: 5 stmts out of 11 (45.5%) diff --git a/genann/.frama-c/genann.eva/nonterm.log b/genann/.frama-c/genann.eva/nonterm.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/genann/.frama-c/genann.eva/warnings.log b/genann/.frama-c/genann.eva/warnings.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/genann/.frama-c/genann.parse/framac.ast b/genann/.frama-c/genann.parse/framac.ast new file mode 100644 index 0000000000000000000000000000000000000000..2cd55aae413401085745e4d29e28d6b1fbc2995a --- /dev/null +++ b/genann/.frama-c/genann.parse/framac.ast @@ -0,0 +1,2402 @@ +/* Generated by Frama-C */ +#include "assert.h" +#include "errno.h" +#include "math.h" +#include "signal.h" +#include "stdarg.h" +#include "stddef.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "strings.h" +#include "time.h" +struct genann; +struct genann { + int inputs ; + int hidden_layers ; + int hidden ; + int outputs ; + double (*activation_hidden)(struct genann const *ann, double a) ; + double (*activation_output)(struct genann const *ann, double a) ; + int total_weights ; + int total_neurons ; + double *weight ; + double *output ; + double *delta ; +}; +typedef struct genann genann; +genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs); + +genann *genann_read(FILE *in); + +void genann_randomize(genann *ann); + +genann *genann_copy(genann const *ann); + +void genann_free(genann *ann); + +double const *genann_run(genann const *ann, double const *inputs); + +void genann_train(genann const *ann, double const *inputs, + double const *desired_outputs, double learning_rate); + +void genann_write(genann const *ann, FILE *out); + +void genann_init_sigmoid_lookup(genann const *ann); + +double genann_act_sigmoid(genann const *ann __attribute__((__unused__)), + double a); + +double genann_act_sigmoid_cached(genann const *ann __attribute__((__unused__)), + double a); + +double genann_act_threshold(struct genann const *ann __attribute__((__unused__)), + double a); + +double genann_act_linear(struct genann const *ann __attribute__((__unused__)), + double a); + +double genann_act_hidden_indirect(struct genann const *ann, double a) +{ + double tmp; + tmp = (*(ann->activation_hidden))(ann,a); + return tmp; +} + +double genann_act_output_indirect(struct genann const *ann, double a) +{ + double tmp; + tmp = (*(ann->activation_output))(ann,a); + return tmp; +} + +double const sigmoid_dom_min = - 15.0; +double const sigmoid_dom_max = 15.0; +double interval; +double lookup[4096]; +double genann_act_sigmoid(genann const *ann __attribute__((__unused__)), + double a) +{ + double __retres; + double tmp; + if (a < - 45.0) { + __retres = (double)0; + goto return_label; + } + if (a > 45.0) { + __retres = (double)1; + goto return_label; + } + tmp = exp(- a); + __retres = 1.0 / ((double)1 + tmp); + return_label: return __retres; +} + +void genann_init_sigmoid_lookup(genann const *ann) +{ + int i; + double const f = (sigmoid_dom_max - sigmoid_dom_min) / (double)4096; + interval = (double)4096 / (sigmoid_dom_max - sigmoid_dom_min); + i = 0; + while (i < 4096) { + lookup[i] = genann_act_sigmoid(ann,sigmoid_dom_min + f * (double)i); + i ++; + } + return; +} + +double genann_act_sigmoid_cached(genann const *ann __attribute__((__unused__)), + double a) +{ + double __retres; + int tmp_2; + int tmp_1; + if (sizeof(a) == sizeof(float)) { + int tmp; + tmp = __fc_fpclassifyf((float)a); + tmp_1 = tmp == 0; + } + else { + int tmp_0; + tmp_0 = __fc_fpclassify(a); + tmp_1 = tmp_0 == 0; + } + if (tmp_1) tmp_2 = 0; else tmp_2 = 1; + __FC_assert(tmp_2 != 0,"genann.c",87,"!isnan(a)"); + if (a < sigmoid_dom_min) { + __retres = lookup[0]; + goto return_label; + } + if (a >= sigmoid_dom_max) { + __retres = lookup[4096 - 1]; + goto return_label; + } + size_t j = (unsigned long)((a - sigmoid_dom_min) * interval + 0.5); + if ((long)(! (! (j >= (size_t)4096)))) { + __retres = lookup[4096 - 1]; + goto return_label; + } + __retres = lookup[j]; + return_label: return __retres; +} + +double genann_act_linear(struct genann const *ann __attribute__((__unused__)), + double a) +{ + return a; +} + +double genann_act_threshold(struct genann const *ann __attribute__((__unused__)), + double a) +{ + double __retres; + __retres = (double)(a > (double)0); + return __retres; +} + +genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs) +{ + genann *__retres; + int tmp; + int tmp_0; + if (hidden_layers < 0) { + __retres = (genann *)0; + goto return_label; + } + if (inputs < 1) { + __retres = (genann *)0; + goto return_label; + } + if (outputs < 1) { + __retres = (genann *)0; + goto return_label; + } + if (hidden_layers > 0) + if (hidden < 1) { + __retres = (genann *)0; + goto return_label; + } + if (hidden_layers) tmp = (inputs + 1) * hidden + ((hidden_layers - 1) * ( + hidden + 1)) * hidden; + else tmp = 0; + int const hidden_weights = tmp; + if (hidden_layers) tmp_0 = hidden + 1; else tmp_0 = inputs + 1; + int const output_weights = tmp_0 * outputs; + int const total_weights = hidden_weights + output_weights; + int const total_neurons = (inputs + hidden * hidden_layers) + outputs; + int const size = + (int)(sizeof(genann) + sizeof(double) * (unsigned long)((total_weights + total_neurons) + ( + total_neurons - inputs))); + genann *ret = malloc((unsigned long)size); + if (! ret) { + __retres = (genann *)0; + goto return_label; + } + ret->inputs = inputs; + ret->hidden_layers = hidden_layers; + ret->hidden = hidden; + ret->outputs = outputs; + ret->total_weights = total_weights; + ret->total_neurons = total_neurons; + ret->weight = (double *)((char *)ret + sizeof(genann)); + ret->output = ret->weight + ret->total_weights; + ret->delta = ret->output + ret->total_neurons; + genann_randomize(ret); + ret->activation_hidden = (double (*)(struct genann const *ann, double a))(& genann_act_sigmoid_cached); + ret->activation_output = (double (*)(struct genann const *ann, double a))(& genann_act_sigmoid_cached); + genann_init_sigmoid_lookup((genann const *)ret); + __retres = ret; + return_label: return __retres; +} + +/*@ requires valid_read_string(format); + requires \valid(param3); + requires \valid(param2); + requires \valid(param1); + requires \valid(param0); + ensures \initialized(param3); + ensures \initialized(param2); + ensures \initialized(param1); + ensures \initialized(param0); + assigns \result, stream->__fc_FILE_data, *param3, *param2, *param1, + *param0; + assigns \result + \from (indirect: stream->__fc_FILE_id), + (indirect: stream->__fc_FILE_data), + (indirect: *(format + (0 ..))); + assigns stream->__fc_FILE_data + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))); + assigns *param3 + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))); + assigns *param2 + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))); + assigns *param1 + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))); + assigns *param0 + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))); + */ +int fscanf_va_1(FILE * __restrict stream, char const * __restrict format, + int *param0, int *param1, int *param2, int *param3); + +/*@ requires valid_read_string(format); + requires \valid(param0); + ensures \initialized(param0); + assigns \result, stream->__fc_FILE_data, *param0; + assigns \result + \from (indirect: stream->__fc_FILE_id), + (indirect: stream->__fc_FILE_data), + (indirect: *(format + (0 ..))); + assigns stream->__fc_FILE_data + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))); + assigns *param0 + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))); + */ +int fscanf_va_2(FILE * __restrict stream, char const * __restrict format, + double *param0); + +genann *genann_read(FILE *in) +{ + genann *__retres; + int inputs; + int hidden_layers; + int hidden; + int outputs; + int rc; + int i; + __fc_errno = 0; + rc = fscanf(in,"%d %d %d %d",& inputs,& hidden_layers,& hidden,& outputs); /* fscanf_va_1 */ + if (rc < 4) goto _LOR; + else + if (__fc_errno != 0) { + _LOR: { + perror("fscanf"); + __retres = (genann *)0; + goto return_label; + } + } + genann *ann = genann_init(inputs,hidden_layers,hidden,outputs); + i = 0; + while (i < ann->total_weights) { + __fc_errno = 0; + rc = fscanf(in," %le",ann->weight + i); /* fscanf_va_2 */ + if (rc < 1) goto _LOR_0; + else + if (__fc_errno != 0) { + _LOR_0: + { + perror("fscanf"); + genann_free(ann); + __retres = (genann *)0; + goto return_label; + } + } + i ++; + } + __retres = ann; + return_label: return __retres; +} + +genann *genann_copy(genann const *ann) +{ + genann *__retres; + int const size = + (int)(sizeof(genann) + sizeof(double) * (unsigned long)((ann->total_weights + ann->total_neurons) + ( + ann->total_neurons - ann->inputs))); + genann *ret = malloc((unsigned long)size); + if (! ret) { + __retres = (genann *)0; + goto return_label; + } + memcpy((void *)ret,(void const *)ann,(unsigned long)size); + ret->weight = (double *)((char *)ret + sizeof(genann)); + ret->output = ret->weight + ret->total_weights; + ret->delta = ret->output + ret->total_neurons; + __retres = ret; + return_label: return __retres; +} + +void genann_randomize(genann *ann) +{ + int i; + i = 0; + while (i < ann->total_weights) { + { + int tmp; + tmp = rand(); + double r = (double)tmp / (double)32767; + *(ann->weight + i) = r - 0.5; + } + i ++; + } + return; +} + +void genann_free(genann *ann) +{ + free((void *)ann); + return; +} + +double const *genann_run(genann const *ann, double const *inputs) +{ + double const *__retres; + int h; + int j; + int k; + double const *w = (double const *)ann->weight; + double *o = ann->output + ann->inputs; + double const *i = (double const *)ann->output; + memcpy((void *)ann->output,(void const *)inputs, + sizeof(double) * (unsigned long)ann->inputs); + if (! ann->hidden_layers) { + double *ret = o; + j = 0; + while (j < ann->outputs) { + { + double const *tmp; + double *tmp_1; + tmp = w; + w ++; + double sum = *tmp * - 1.0; + k = 0; + while (k < ann->inputs) { + { + double const *tmp_0; + tmp_0 = w; + w ++; + sum += *tmp_0 * *(i + k); + } + k ++; + } + tmp_1 = o; + o ++; + *tmp_1 = genann_act_output_indirect(ann,sum); + } + j ++; + } + __retres = (double const *)ret; + goto return_label; + } + j = 0; + while (j < ann->hidden) { + { + double const *tmp_2; + double *tmp_4; + tmp_2 = w; + w ++; + double sum_0 = *tmp_2 * - 1.0; + k = 0; + while (k < ann->inputs) { + { + double const *tmp_3; + tmp_3 = w; + w ++; + sum_0 += *tmp_3 * *(i + k); + } + k ++; + } + tmp_4 = o; + o ++; + *tmp_4 = genann_act_hidden_indirect(ann,sum_0); + } + j ++; + } + i += ann->inputs; + h = 1; + while (h < ann->hidden_layers) { + j = 0; + while (j < ann->hidden) { + { + double const *tmp_5; + double *tmp_7; + tmp_5 = w; + w ++; + double sum_1 = *tmp_5 * - 1.0; + k = 0; + while (k < ann->hidden) { + { + double const *tmp_6; + tmp_6 = w; + w ++; + sum_1 += *tmp_6 * *(i + k); + } + k ++; + } + tmp_7 = o; + o ++; + *tmp_7 = genann_act_hidden_indirect(ann,sum_1); + } + j ++; + } + i += ann->hidden; + h ++; + } + double const *ret_0 = (double const *)o; + j = 0; + while (j < ann->outputs) { + { + double const *tmp_8; + double *tmp_10; + tmp_8 = w; + w ++; + double sum_2 = *tmp_8 * - 1.0; + k = 0; + while (k < ann->hidden) { + { + double const *tmp_9; + tmp_9 = w; + w ++; + sum_2 += *tmp_9 * *(i + k); + } + k ++; + } + tmp_10 = o; + o ++; + *tmp_10 = genann_act_output_indirect(ann,sum_2); + } + j ++; + } + __FC_assert((w - ann->weight == (long)ann->total_weights) != 0,"genann.c", + 271,"w - ann->weight == ann->total_weights"); + __FC_assert((o - ann->output == (long)ann->total_neurons) != 0,"genann.c", + 272,"o - ann->output == ann->total_neurons"); + __retres = ret_0; + return_label: return __retres; +} + +void genann_train(genann const *ann, double const *inputs, + double const *desired_outputs, double learning_rate) +{ + int h; + int j; + int k; + genann_run(ann,inputs); + { + double const *o = + (double const *)((ann->output + ann->inputs) + ann->hidden * ann->hidden_layers); + double *d = ann->delta + ann->hidden * ann->hidden_layers; + double const *t = desired_outputs; + if (& genann_act_output_indirect == & genann_act_linear) goto _LOR; + else + if (ann->activation_output == & genann_act_linear) { + _LOR: + { + j = 0; + while (j < ann->outputs) { + { + double *tmp; + double const *tmp_0; + double const *tmp_1; + tmp = d; + d ++; + tmp_0 = t; + t ++; + tmp_1 = o; + o ++; + *tmp = *tmp_0 - *tmp_1; + } + j ++; + } + } + } + else { + j = 0; + while (j < ann->outputs) { + { + double *tmp_2; + tmp_2 = d; + d ++; + *tmp_2 = ((*t - *o) * *o) * (1.0 - *o); + o ++; + t ++; + } + j ++; + } + } + } + h = ann->hidden_layers - 1; + while (h >= 0) { + { + double const *o_0 = + (double const *)((ann->output + ann->inputs) + h * ann->hidden); + double *d_0 = ann->delta + h * ann->hidden; + double const * const dd = + (double const *)(ann->delta + (h + 1) * ann->hidden); + double const * const ww = + (double const *)((ann->weight + (ann->inputs + 1) * ann->hidden) + + ((ann->hidden + 1) * ann->hidden) * h); + j = 0; + while (j < ann->hidden) { + { + double delta = (double)0; + k = 0; + while (1) { + int tmp_3; + if (h == ann->hidden_layers - 1) tmp_3 = ann->outputs; + else tmp_3 = ann->hidden; + ; + if (! (k < tmp_3)) break; + { + double const forward_delta = *(dd + k); + int const windex = k * (ann->hidden + 1) + (j + 1); + double const forward_weight = *(ww + windex); + delta += forward_delta * forward_weight; + } + k ++; + } + *d_0 = (*o_0 * (1.0 - *o_0)) * delta; + d_0 ++; + o_0 ++; + } + j ++; + } + } + h --; + } + { + int tmp_4; + int tmp_5; + double const *d_1 = + (double const *)(ann->delta + ann->hidden * ann->hidden_layers); + if (ann->hidden_layers) tmp_4 = (ann->inputs + 1) * ann->hidden + + ((ann->hidden + 1) * ann->hidden) * ( + ann->hidden_layers - 1); + else tmp_4 = 0; + double *w = ann->weight + tmp_4; + if (ann->hidden_layers) tmp_5 = ann->inputs + ann->hidden * (ann->hidden_layers - 1); + else tmp_5 = 0; + double const * const i = (double const *)(ann->output + tmp_5); + j = 0; + while (j < ann->outputs) { + { + double *tmp_6; + tmp_6 = w; + w ++; + *tmp_6 += (*d_1 * learning_rate) * - 1.0; + k = 1; + while (1) { + int tmp_8; + if (ann->hidden_layers) tmp_8 = ann->hidden; + else tmp_8 = ann->inputs; + ; + if (! (k < tmp_8 + 1)) break; + { + double *tmp_7; + tmp_7 = w; + w ++; + *tmp_7 += (*d_1 * learning_rate) * *(i + (k - 1)); + } + k ++; + } + d_1 ++; + } + j ++; + } + __FC_assert((w - ann->weight == (long)ann->total_weights) != 0, + "genann.c",362,"w - ann->weight == ann->total_weights"); + } + h = ann->hidden_layers - 1; + while (h >= 0) { + { + int tmp_9; + int tmp_10; + double const *d_2 = (double const *)(ann->delta + h * ann->hidden); + if (h) tmp_9 = ann->inputs + ann->hidden * (h - 1); else tmp_9 = 0; + double const *i_0 = (double const *)(ann->output + tmp_9); + if (h) tmp_10 = (ann->inputs + 1) * ann->hidden + ((ann->hidden + 1) * ann->hidden) * ( + h - 1); + else tmp_10 = 0; + double *w_0 = ann->weight + tmp_10; + j = 0; + while (j < ann->hidden) { + { + double *tmp_11; + tmp_11 = w_0; + w_0 ++; + *tmp_11 += (*d_2 * learning_rate) * - 1.0; + k = 1; + while (1) { + int tmp_13; + if (h == 0) tmp_13 = ann->inputs; else tmp_13 = ann->hidden; + ; + if (! (k < tmp_13 + 1)) break; + { + double *tmp_12; + tmp_12 = w_0; + w_0 ++; + *tmp_12 += (*d_2 * learning_rate) * *(i_0 + (k - 1)); + } + k ++; + } + d_2 ++; + } + j ++; + } + } + h --; + } + return; +} + +/*@ requires valid_read_string(format); + assigns \result, stream->__fc_FILE_data; + assigns \result + \from (indirect: stream->__fc_FILE_id), + (indirect: stream->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), (indirect: param0); + assigns stream->__fc_FILE_data + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))), param3, param2, param1, param0; + */ +int fprintf_va_1(FILE * __restrict stream, char const * __restrict format, + int param0, int param1, int param2, int param3); + +/*@ requires valid_read_string(format); + assigns \result, stream->__fc_FILE_data; + assigns \result + \from (indirect: stream->__fc_FILE_id), + (indirect: stream->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param0); + assigns stream->__fc_FILE_data + \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data, + (indirect: *(format + (0 ..))), param0; + */ +int fprintf_va_2(FILE * __restrict stream, char const * __restrict format, + double param0); + +void genann_write(genann const *ann, FILE *out) +{ + int i; + fprintf(out,"%d %d %d %d",ann->inputs,ann->hidden_layers,ann->hidden, + ann->outputs); /* fprintf_va_1 */ + i = 0; + while (i < ann->total_weights) { + fprintf(out," %.20e",*(ann->weight + i)); /* fprintf_va_2 */ + i ++; + } + return; +} + +static int ltests = 0; +static int lfails = 0; +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_1(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_2(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_3(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_4(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_5(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_6(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_7(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +void basic(void) +{ + double a; + genann *ann = genann_init(1,0,0,1); + ltests ++; + if (ann->total_weights != 2) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",37,ann->total_weights,2); /* printf_va_1 */ + } + a = (double)0; + *(ann->weight + 0) = (double)0; + *(ann->weight + 1) = (double)0; + { + double tmp_2; + double const *tmp_1; + ltests ++; + tmp_1 = genann_run((genann const *)ann,(double const *)(& a)); + ; + tmp_2 = fabs(0.5 - *tmp_1); + if (tmp_2 > 0.001) { + double const *tmp_0; + lfails ++; + tmp_0 = genann_run((genann const *)ann,(double const *)(& a)); + printf("%s:%d (%f != %f)\n",(char *)"./test.c",44,0.5,*tmp_0); /* printf_va_2 */ + } + } + a = (double)1; + { + double tmp_5; + double const *tmp_4; + ltests ++; + tmp_4 = genann_run((genann const *)ann,(double const *)(& a)); + ; + tmp_5 = fabs(0.5 - *tmp_4); + if (tmp_5 > 0.001) { + double const *tmp_3; + lfails ++; + tmp_3 = genann_run((genann const *)ann,(double const *)(& a)); + printf("%s:%d (%f != %f)\n",(char *)"./test.c",47,0.5,*tmp_3); /* printf_va_3 */ + } + } + a = (double)11; + { + double tmp_8; + double const *tmp_7; + ltests ++; + tmp_7 = genann_run((genann const *)ann,(double const *)(& a)); + ; + tmp_8 = fabs(0.5 - *tmp_7); + if (tmp_8 > 0.001) { + double const *tmp_6; + lfails ++; + tmp_6 = genann_run((genann const *)ann,(double const *)(& a)); + printf("%s:%d (%f != %f)\n",(char *)"./test.c",50,0.5,*tmp_6); /* printf_va_4 */ + } + } + a = (double)1; + *(ann->weight + 0) = (double)1; + *(ann->weight + 1) = (double)1; + { + double tmp_11; + double const *tmp_10; + ltests ++; + tmp_10 = genann_run((genann const *)ann,(double const *)(& a)); + ; + tmp_11 = fabs(0.5 - *tmp_10); + if (tmp_11 > 0.001) { + double const *tmp_9; + lfails ++; + tmp_9 = genann_run((genann const *)ann,(double const *)(& a)); + printf("%s:%d (%f != %f)\n",(char *)"./test.c",55,0.5,*tmp_9); /* printf_va_5 */ + } + } + a = (double)10; + *(ann->weight + 0) = (double)1; + *(ann->weight + 1) = (double)1; + { + double tmp_14; + double const *tmp_13; + ltests ++; + tmp_13 = genann_run((genann const *)ann,(double const *)(& a)); + ; + tmp_14 = fabs(1.0 - *tmp_13); + if (tmp_14 > 0.001) { + double const *tmp_12; + lfails ++; + tmp_12 = genann_run((genann const *)ann,(double const *)(& a)); + printf("%s:%d (%f != %f)\n",(char *)"./test.c",60,1.0,*tmp_12); /* printf_va_6 */ + } + } + a = (double)(-10); + { + double tmp_17; + double const *tmp_16; + ltests ++; + tmp_16 = genann_run((genann const *)ann,(double const *)(& a)); + ; + tmp_17 = fabs(0.0 - *tmp_16); + if (tmp_17 > 0.001) { + double const *tmp_15; + lfails ++; + tmp_15 = genann_run((genann const *)ann,(double const *)(& a)); + printf("%s:%d (%f != %f)\n",(char *)"./test.c",63,0.0,*tmp_15); /* printf_va_7 */ + } + } + genann_free(ann); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_8(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_9(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_10(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_11(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_12(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +void xor(void) +{ + genann *ann = genann_init(2,1,2,1); + ann->activation_hidden = & genann_act_threshold; + ann->activation_output = & genann_act_threshold; + ltests ++; + if (ann->total_weights != 9) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",74,ann->total_weights,9); /* printf_va_8 */ + } + *(ann->weight + 0) = .5; + *(ann->weight + 1) = (double)1; + *(ann->weight + 2) = (double)1; + *(ann->weight + 3) = (double)1; + *(ann->weight + 4) = (double)1; + *(ann->weight + 5) = (double)1; + *(ann->weight + 6) = .5; + *(ann->weight + 7) = (double)1; + *(ann->weight + 8) = (double)(-1); + double input[4][2] = + {{(double)0, (double)0}, + {(double)0, (double)1}, + {(double)1, (double)0}, + {(double)1, (double)1}}; + double output[4] = {(double)0, (double)1, (double)1, (double)0}; + { + double tmp_2; + double const *tmp_1; + ltests ++; + tmp_1 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + tmp_2 = fabs(output[0] - *tmp_1); + if (tmp_2 > 0.001) { + double const *tmp_0; + lfails ++; + tmp_0 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",95,output[0],*tmp_0); /* printf_va_9 */ + } + } + { + double tmp_5; + double const *tmp_4; + ltests ++; + tmp_4 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + tmp_5 = fabs(output[1] - *tmp_4); + if (tmp_5 > 0.001) { + double const *tmp_3; + lfails ++; + tmp_3 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",96,output[1],*tmp_3); /* printf_va_10 */ + } + } + { + double tmp_8; + double const *tmp_7; + ltests ++; + tmp_7 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + tmp_8 = fabs(output[2] - *tmp_7); + if (tmp_8 > 0.001) { + double const *tmp_6; + lfails ++; + tmp_6 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",97,output[2],*tmp_6); /* printf_va_11 */ + } + } + { + double tmp_11; + double const *tmp_10; + ltests ++; + tmp_10 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + tmp_11 = fabs(output[3] - *tmp_10); + if (tmp_11 > 0.001) { + double const *tmp_9; + lfails ++; + tmp_9 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",98,output[3],*tmp_9); /* printf_va_12 */ + } + } + genann_free(ann); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param1, *(param0 + (0 ..)); + */ +int printf_va_13(char const * __restrict format, char *param0, int param1); + +void backprop(void) +{ + double input; + double output; + double const *tmp_0; + double const *tmp_1; + genann *ann = genann_init(1,0,0,1); + input = .5; + output = (double)1; + tmp_0 = genann_run((genann const *)ann,(double const *)(& input)); + double first_try = *tmp_0; + genann_train((genann const *)ann,(double const *)(& input), + (double const *)(& output),.5); + tmp_1 = genann_run((genann const *)ann,(double const *)(& input)); + double second_try = *tmp_1; + { + double tmp_2; + double tmp_3; + ltests ++; + tmp_2 = fabs(first_try - output); + tmp_3 = fabs(second_try - output); + if (! (tmp_2 > tmp_3)) { + lfails ++; + printf("%s:%d error \n",(char *)"./test.c",114); /* printf_va_13 */ + } + } + genann_free(ann); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_14(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_15(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_16(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_17(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +void train_and(void) +{ + int i; + int j; + double input[4][2] = + {{(double)0, (double)0}, + {(double)0, (double)1}, + {(double)1, (double)0}, + {(double)1, (double)1}}; + double output[4] = {(double)0, (double)0, (double)0, (double)1}; + genann *ann = genann_init(2,0,0,1); + i = 0; + while (i < 50) { + j = 0; + while (j < 4) { + genann_train((genann const *)ann,(double const *)(input[j]), + (double const *)(& output[j]),.8); + j ++; + } + i ++; + } + ann->activation_output = & genann_act_threshold; + { + double tmp_2; + double const *tmp_1; + ltests ++; + tmp_1 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + tmp_2 = fabs(output[0] - *tmp_1); + if (tmp_2 > 0.001) { + double const *tmp_0; + lfails ++; + tmp_0 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",135,output[0],*tmp_0); /* printf_va_14 */ + } + } + { + double tmp_5; + double const *tmp_4; + ltests ++; + tmp_4 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + tmp_5 = fabs(output[1] - *tmp_4); + if (tmp_5 > 0.001) { + double const *tmp_3; + lfails ++; + tmp_3 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",136,output[1],*tmp_3); /* printf_va_15 */ + } + } + { + double tmp_8; + double const *tmp_7; + ltests ++; + tmp_7 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + tmp_8 = fabs(output[2] - *tmp_7); + if (tmp_8 > 0.001) { + double const *tmp_6; + lfails ++; + tmp_6 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",137,output[2],*tmp_6); /* printf_va_16 */ + } + } + { + double tmp_11; + double const *tmp_10; + ltests ++; + tmp_10 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + tmp_11 = fabs(output[3] - *tmp_10); + if (tmp_11 > 0.001) { + double const *tmp_9; + lfails ++; + tmp_9 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",138,output[3],*tmp_9); /* printf_va_17 */ + } + } + genann_free(ann); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_18(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_19(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_20(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_21(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +void train_or(void) +{ + int i; + int j; + double input[4][2] = + {{(double)0, (double)0}, + {(double)0, (double)1}, + {(double)1, (double)0}, + {(double)1, (double)1}}; + double output[4] = {(double)0, (double)1, (double)1, (double)1}; + genann *ann = genann_init(2,0,0,1); + genann_randomize(ann); + i = 0; + while (i < 50) { + j = 0; + while (j < 4) { + genann_train((genann const *)ann,(double const *)(input[j]), + (double const *)(& output[j]),.8); + j ++; + } + i ++; + } + ann->activation_output = & genann_act_threshold; + { + double tmp_2; + double const *tmp_1; + ltests ++; + tmp_1 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + tmp_2 = fabs(output[0] - *tmp_1); + if (tmp_2 > 0.001) { + double const *tmp_0; + lfails ++; + tmp_0 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",160,output[0],*tmp_0); /* printf_va_18 */ + } + } + { + double tmp_5; + double const *tmp_4; + ltests ++; + tmp_4 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + tmp_5 = fabs(output[1] - *tmp_4); + if (tmp_5 > 0.001) { + double const *tmp_3; + lfails ++; + tmp_3 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",161,output[1],*tmp_3); /* printf_va_19 */ + } + } + { + double tmp_8; + double const *tmp_7; + ltests ++; + tmp_7 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + tmp_8 = fabs(output[2] - *tmp_7); + if (tmp_8 > 0.001) { + double const *tmp_6; + lfails ++; + tmp_6 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",162,output[2],*tmp_6); /* printf_va_20 */ + } + } + { + double tmp_11; + double const *tmp_10; + ltests ++; + tmp_10 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + tmp_11 = fabs(output[3] - *tmp_10); + if (tmp_11 > 0.001) { + double const *tmp_9; + lfails ++; + tmp_9 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",163,output[3],*tmp_9); /* printf_va_21 */ + } + } + genann_free(ann); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_22(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_23(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_24(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_25(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +void train_xor(void) +{ + int i; + int j; + double input[4][2] = + {{(double)0, (double)0}, + {(double)0, (double)1}, + {(double)1, (double)0}, + {(double)1, (double)1}}; + double output[4] = {(double)0, (double)1, (double)1, (double)0}; + genann *ann = genann_init(2,1,2,1); + i = 0; + while (i < 500) { + j = 0; + while (j < 4) { + genann_train((genann const *)ann,(double const *)(input[j]), + (double const *)(& output[j]),(double)3); + j ++; + } + i ++; + } + ann->activation_output = & genann_act_threshold; + { + double tmp_2; + double const *tmp_1; + ltests ++; + tmp_1 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + tmp_2 = fabs(output[0] - *tmp_1); + if (tmp_2 > 0.001) { + double const *tmp_0; + lfails ++; + tmp_0 = genann_run((genann const *)ann,(double const *)(input[0])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",186,output[0],*tmp_0); /* printf_va_22 */ + } + } + { + double tmp_5; + double const *tmp_4; + ltests ++; + tmp_4 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + tmp_5 = fabs(output[1] - *tmp_4); + if (tmp_5 > 0.001) { + double const *tmp_3; + lfails ++; + tmp_3 = genann_run((genann const *)ann,(double const *)(input[1])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",187,output[1],*tmp_3); /* printf_va_23 */ + } + } + { + double tmp_8; + double const *tmp_7; + ltests ++; + tmp_7 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + tmp_8 = fabs(output[2] - *tmp_7); + if (tmp_8 > 0.001) { + double const *tmp_6; + lfails ++; + tmp_6 = genann_run((genann const *)ann,(double const *)(input[2])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",188,output[2],*tmp_6); /* printf_va_24 */ + } + } + { + double tmp_11; + double const *tmp_10; + ltests ++; + tmp_10 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + tmp_11 = fabs(output[3] - *tmp_10); + if (tmp_11 > 0.001) { + double const *tmp_9; + lfails ++; + tmp_9 = genann_run((genann const *)ann,(double const *)(input[3])); + ; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",189,output[3],*tmp_9); /* printf_va_25 */ + } + } + genann_free(ann); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_26(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_27(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_28(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_29(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_30(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param1, *(param0 + (0 ..)); + */ +int printf_va_31(char const * __restrict format, char *param0, int param1); + +void persist(void) +{ + int i; + genann *first = genann_init(1000,5,50,10); + FILE *out = fopen("persist.txt","w"); + genann_write((genann const *)first,out); + fclose(out); + FILE *in = fopen("persist.txt","r"); + genann *second = genann_read(in); + fclose(in); + ltests ++; + if (first->inputs != second->inputs) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",208,first->inputs, + second->inputs); /* printf_va_26 */ + } + ltests ++; + if (first->hidden_layers != second->hidden_layers) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",209,first->hidden_layers, + second->hidden_layers); /* printf_va_27 */ + } + ltests ++; + if (first->hidden != second->hidden) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",210,first->hidden, + second->hidden); /* printf_va_28 */ + } + ltests ++; + if (first->outputs != second->outputs) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",211,first->outputs, + second->outputs); /* printf_va_29 */ + } + ltests ++; + if (first->total_weights != second->total_weights) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",212,first->total_weights, + second->total_weights); /* printf_va_30 */ + } + i = 0; + while (i < first->total_weights) { + ltests ++; + if (! (*(first->weight + i) == *(second->weight + i))) { + lfails ++; + printf("%s:%d error \n",(char *)"./test.c",216); /* printf_va_31 */ + } + i ++; + } + genann_free(first); + genann_free(second); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_32(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_33(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_34(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_35(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_36(char const * __restrict format, char *param0, int param1, + int param2, int param3); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_37(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +void copy(void) +{ + int i; + genann *first = genann_init(1000,5,50,10); + genann *second = genann_copy((genann const *)first); + ltests ++; + if (first->inputs != second->inputs) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",229,first->inputs, + second->inputs); /* printf_va_32 */ + } + ltests ++; + if (first->hidden_layers != second->hidden_layers) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",230,first->hidden_layers, + second->hidden_layers); /* printf_va_33 */ + } + ltests ++; + if (first->hidden != second->hidden) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",231,first->hidden, + second->hidden); /* printf_va_34 */ + } + ltests ++; + if (first->outputs != second->outputs) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",232,first->outputs, + second->outputs); /* printf_va_35 */ + } + ltests ++; + if (first->total_weights != second->total_weights) { + lfails ++; + printf("%s:%d (%d != %d)\n",(char *)"./test.c",233,first->total_weights, + second->total_weights); /* printf_va_36 */ + } + i = 0; + while (i < first->total_weights) { + { + double tmp_1; + ltests ++; + tmp_1 = fabs(*(first->weight + i) - *(second->weight + i)); + if (tmp_1 > 0.001) { + lfails ++; + printf("%s:%d (%f != %f)\n",(char *)"./test.c",237, + *(first->weight + i),*(second->weight + i)); /* printf_va_37 */ + } + } + i ++; + } + genann_free(first); + genann_free(second); + return; +} + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param3), + (indirect: param2), (indirect: param1), + (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param3, param2, param1, *(param0 + (0 ..)); + */ +int printf_va_38(char const * __restrict format, char *param0, int param1, + double param2, double param3); + +void sigmoid(void) +{ + double i = (double)(-20); + double const max = (double)20; + double const d = .0001; + while (i < max) { + { + double tmp_3; + double tmp_1; + double tmp_2; + ltests ++; + tmp_1 = genann_act_sigmoid((genann const *)0,i); + tmp_2 = genann_act_sigmoid_cached((genann const *)0,i); + tmp_3 = fabs(tmp_1 - tmp_2); + if (tmp_3 > 0.001) { + double tmp; + double tmp_0; + lfails ++; + tmp = genann_act_sigmoid_cached((genann const *)0,i); + tmp_0 = genann_act_sigmoid((genann const *)0,i); + printf("%s:%d (%f != %f)\n",(char *)"./test.c",251,tmp_0,tmp); /* printf_va_38 */ + } + } + i += d; + } + return; +} + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))); + */ +int printf_va_39(char const * __restrict format); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_40(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_41(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_42(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_43(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_44(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_45(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_46(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_47(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_48(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_49(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_50(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_51(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_52(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_53(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_54(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_55(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + requires valid_read_string(param0); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..))); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + *(param0 + (0 ..)); + */ +int printf_va_56(char const * __restrict format, char *param0); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param2), + (indirect: param1), (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param2, param1, param0; + */ +int printf_va_57(char const * __restrict format, int param0, int param1, + int param2); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param1), + (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param1, param0; + */ +int printf_va_58(char const * __restrict format, int param0, int param1); + +/*@ requires valid_read_string(format); + assigns \result, __fc_stdout->__fc_FILE_data; + assigns \result + \from (indirect: __fc_stdout->__fc_FILE_id), + (indirect: __fc_stdout->__fc_FILE_data), + (indirect: *(format + (0 ..))), (indirect: param1), + (indirect: param0); + assigns __fc_stdout->__fc_FILE_data + \from (indirect: __fc_stdout->__fc_FILE_id), + __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))), + param1, param0; + */ +int printf_va_59(char const * __restrict format, int param0, int param1); + +int main(int argc, char **argv) +{ + int __retres; + printf("GENANN TEST SUITE\n"); /* printf_va_39 */ + srand((unsigned int)100); + { + clock_t tmp_0; + int const ts = ltests; + int const fs = lfails; + clock_t const start = clock(); + printf("\t%-14s",(char *)"basic"); /* printf_va_40 */ + basic(); + tmp_0 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts) - (lfails - fs), + lfails - fs, + (int)((long)((tmp_0 - start) * (clock_t)1000) / (long)1000000)); /* printf_va_41 */ + } + { + clock_t tmp_2; + int const ts_0 = ltests; + int const fs_0 = lfails; + clock_t const start_0 = clock(); + printf("\t%-14s",(char *)"xor"); /* printf_va_42 */ + xor(); + tmp_2 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_0) - (lfails - fs_0), + lfails - fs_0, + (int)((long)((tmp_2 - start_0) * (clock_t)1000) / (long)1000000)); /* printf_va_43 */ + } + { + clock_t tmp_4; + int const ts_1 = ltests; + int const fs_1 = lfails; + clock_t const start_1 = clock(); + printf("\t%-14s",(char *)"backprop"); /* printf_va_44 */ + backprop(); + tmp_4 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_1) - (lfails - fs_1), + lfails - fs_1, + (int)((long)((tmp_4 - start_1) * (clock_t)1000) / (long)1000000)); /* printf_va_45 */ + } + { + clock_t tmp_6; + int const ts_2 = ltests; + int const fs_2 = lfails; + clock_t const start_2 = clock(); + printf("\t%-14s",(char *)"train and"); /* printf_va_46 */ + train_and(); + tmp_6 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_2) - (lfails - fs_2), + lfails - fs_2, + (int)((long)((tmp_6 - start_2) * (clock_t)1000) / (long)1000000)); /* printf_va_47 */ + } + { + clock_t tmp_8; + int const ts_3 = ltests; + int const fs_3 = lfails; + clock_t const start_3 = clock(); + printf("\t%-14s",(char *)"train or"); /* printf_va_48 */ + train_or(); + tmp_8 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_3) - (lfails - fs_3), + lfails - fs_3, + (int)((long)((tmp_8 - start_3) * (clock_t)1000) / (long)1000000)); /* printf_va_49 */ + } + { + clock_t tmp_10; + int const ts_4 = ltests; + int const fs_4 = lfails; + clock_t const start_4 = clock(); + printf("\t%-14s",(char *)"train xor"); /* printf_va_50 */ + train_xor(); + tmp_10 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_4) - (lfails - fs_4), + lfails - fs_4, + (int)((long)((tmp_10 - start_4) * (clock_t)1000) / (long)1000000)); /* printf_va_51 */ + } + { + clock_t tmp_12; + int const ts_5 = ltests; + int const fs_5 = lfails; + clock_t const start_5 = clock(); + printf("\t%-14s",(char *)"persist"); /* printf_va_52 */ + persist(); + tmp_12 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_5) - (lfails - fs_5), + lfails - fs_5, + (int)((long)((tmp_12 - start_5) * (clock_t)1000) / (long)1000000)); /* printf_va_53 */ + } + { + clock_t tmp_14; + int const ts_6 = ltests; + int const fs_6 = lfails; + clock_t const start_6 = clock(); + printf("\t%-14s",(char *)"copy"); /* printf_va_54 */ + copy(); + tmp_14 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_6) - (lfails - fs_6), + lfails - fs_6, + (int)((long)((tmp_14 - start_6) * (clock_t)1000) / (long)1000000)); /* printf_va_55 */ + } + { + clock_t tmp_16; + int const ts_7 = ltests; + int const fs_7 = lfails; + clock_t const start_7 = clock(); + printf("\t%-14s",(char *)"sigmoid"); /* printf_va_56 */ + sigmoid(); + tmp_16 = clock(); + ; + ; + ; + printf("pass:%2d fail:%2d %4dms\n",(ltests - ts_7) - (lfails - fs_7), + lfails - fs_7, + (int)((long)((tmp_16 - start_7) * (clock_t)1000) / (long)1000000)); /* printf_va_57 */ + } + if (lfails == 0) printf("ALL TESTS PASSED (%d/%d)\n",ltests,ltests); /* printf_va_58 */ + else printf("SOME TESTS FAILED (%d/%d)\n",ltests - lfails,ltests); /* printf_va_59 */ + __retres = lfails != 0; + return __retres; +} + + diff --git a/genann/.frama-c/genann.parse/metrics.log b/genann/.frama-c/genann.parse/metrics.log new file mode 100644 index 0000000000000000000000000000000000000000..b26c37df8186b3973b640f94bc10ab1056db468f --- /dev/null +++ b/genann/.frama-c/genann.parse/metrics.log @@ -0,0 +1,45 @@ +[metrics] Defined functions (25) +====================== + backprop (1 call); basic (1 call); copy (1 call); + genann_act_hidden_indirect (2 calls); + genann_act_linear (address taken) (0 call); + genann_act_output_indirect (address taken) (2 calls); + genann_act_sigmoid (3 calls); + genann_act_sigmoid_cached (address taken) (2 calls); + genann_act_threshold (address taken) (0 call); genann_copy (1 call); + genann_free (11 calls); genann_init (9 calls); + genann_init_sigmoid_lookup (1 call); genann_randomize (2 calls); + genann_read (1 call); genann_run (47 calls); genann_train (4 calls); + genann_write (1 call); main (0 call); persist (1 call); sigmoid (1 call); + train_and (1 call); train_or (1 call); train_xor (1 call); xor (1 call); + +Specified-only functions (0) +============================ + + +Undefined and unspecified functions (0) +======================================= + + +'Extern' global variables (0) +============================= + + +Potential entry points (1) +========================== + main; + +Global metrics +============== +Sloc = 1043 +Decision point = 101 +Global variables = 6 +If = 101 +Loop = 32 +Goto = 17 +Assignment = 477 +Exit point = 25 +Function = 25 +Function call = 224 +Pointer dereferencing = 309 +Cyclomatic complexity = 126 diff --git a/genann/.frama-c/genann.parse/warnings.log b/genann/.frama-c/genann.parse/warnings.log new file mode 100644 index 0000000000000000000000000000000000000000..accee9a71d9cec6fdb9a8bfcddfe80aa32ef2658 --- /dev/null +++ b/genann/.frama-c/genann.parse/warnings.log @@ -0,0 +1,2 @@ +test.c:44:[kernel:parser:decimal-float] warning: Floating-point constant 0.001 is not represented exactly. Will use 0x1.0624dd2f1a9fcp-10. +(warn-once: no further messages from category 'parser:decimal-float' will be emitted) diff --git a/genann/.frama-c/path.mk b/genann/.frama-c/path.mk new file mode 120000 index 0000000000000000000000000000000000000000..57620d6d4816c69648f7a48a2ab302665cd5ac66 --- /dev/null +++ b/genann/.frama-c/path.mk @@ -0,0 +1 @@ +../../path.mk \ No newline at end of file diff --git a/genann/LICENSE b/genann/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..5ab017c453ce1b0073247fae68c1babcccc62aba --- /dev/null +++ b/genann/LICENSE @@ -0,0 +1,20 @@ +zlib License + +Copyright (C) 2015-2018 Lewis Van Winkle + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgement in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + diff --git a/genann/Makefile b/genann/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..427e3be711070d6b6f290bbd30b9fb6942becef7 --- /dev/null +++ b/genann/Makefile @@ -0,0 +1,34 @@ +CFLAGS = -Wall -Wshadow -O3 -g -march=native +LDLIBS = -lm + +all: check example1 example2 example3 example4 + +sigmoid: CFLAGS += -Dgenann_act=genann_act_sigmoid_cached +sigmoid: all + +threshold: CFLAGS += -Dgenann_act=genann_act_threshold +threshold: all + +linear: CFLAGS += -Dgenann_act=genann_act_linear +linear: all + +test: test.o genann.o + +check: test + ./$^ + +example1: example1.o genann.o + +example2: example2.o genann.o + +example3: example3.o genann.o + +example4: example4.o genann.o + + +clean: + $(RM) *.o + $(RM) test example1 example2 example3 example4 *.exe + $(RM) persist.txt + +.PHONY: sigmoid threshold linear clean diff --git a/genann/README.md b/genann/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4e04d47af117e185f83eba51805b8234d0efd631 --- /dev/null +++ b/genann/README.md @@ -0,0 +1,154 @@ +[](https://travis-ci.org/codeplea/genann) + +<img alt="Genann logo" src="https://codeplea.com/public/content/genann_logo.png" align="right" /> + +# Genann + +Genann is a minimal, well-tested library for training and using feedforward +artificial neural networks (ANN) in C. Its primary focus is on being simple, +fast, reliable, and hackable. It achieves this by providing only the necessary +functions and little extra. + +## Features + +- **C99 with no dependencies**. +- Contained in a single source code and header file. +- Simple. +- Fast and thread-safe. +- Easily extendible. +- Implements backpropagation training. +- *Compatible with alternative training methods* (classic optimization, genetic algorithms, etc) +- Includes examples and test suite. +- Released under the zlib license - free for nearly any use. + +## Building + +Genann is self-contained in two files: `genann.c` and `genann.h`. To use Genann, simply add those two files to your project. + +## Example Code + +Four example programs are included with the source code. + +- [`example1.c`](./example1.c) - Trains an ANN on the XOR function using backpropagation. +- [`example2.c`](./example2.c) - Trains an ANN on the XOR function using random search. +- [`example3.c`](./example3.c) - Loads and runs an ANN from a file. +- [`example4.c`](./example4.c) - Trains an ANN on the [IRIS data-set](https://archive.ics.uci.edu/ml/datasets/Iris) using backpropagation. + +## Quick Example + +We create an ANN taking 2 inputs, having 1 layer of 3 hidden neurons, and +providing 2 outputs. It has the following structure: + + + +We then train it on a set of labeled data using backpropagation and ask it to +predict on a test data point: + +```C +#include "genann.h" + +/* Not shown, loading your training and test data. */ +double **training_data_input, **training_data_output, **test_data_input; + +/* New network with 2 inputs, + * 1 hidden layer of 3 neurons each, + * and 2 outputs. */ +genann *ann = genann_init(2, 1, 3, 2); + +/* Learn on the training set. */ +for (i = 0; i < 300; ++i) { + for (j = 0; j < 100; ++j) + genann_train(ann, training_data_input[j], training_data_output[j], 0.1); +} + +/* Run the network and see what it predicts. */ +double const *prediction = genann_run(ann, test_data_input[0]); +printf("Output for the first test data point is: %f, %f\n", prediction[0], prediction[1]); + +genann_free(ann); +``` + +This example is to show API usage, it is not showing good machine learning +techniques. In a real application you would likely want to learn on the test +data in a random order. You would also want to monitor the learning to prevent +over-fitting. + + +## Usage + +### Creating and Freeing ANNs +```C +genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs); +genann *genann_copy(genann const *ann); +void genann_free(genann *ann); +``` + +Creating a new ANN is done with the `genann_init()` function. Its arguments +are the number of inputs, the number of hidden layers, the number of neurons in +each hidden layer, and the number of outputs. It returns a `genann` struct pointer. + +Calling `genann_copy()` will create a deep-copy of an existing `genann` struct. + +Call `genann_free()` when you're finished with an ANN returned by `genann_init()`. + + +### Training ANNs +```C +void genann_train(genann const *ann, double const *inputs, + double const *desired_outputs, double learning_rate); +``` + +`genann_train()` will preform one update using standard backpropogation. It +should be called by passing in an array of inputs, an array of expected outputs, +and a learning rate. See *example1.c* for an example of learning with +backpropogation. + +A primary design goal of Genann was to store all the network weights in one +contigious block of memory. This makes it easy and efficient to train the +network weights using direct-search numeric optimization algorthims, +such as [Hill Climbing](https://en.wikipedia.org/wiki/Hill_climbing), +[the Genetic Algorithm](https://en.wikipedia.org/wiki/Genetic_algorithm), [Simulated +Annealing](https://en.wikipedia.org/wiki/Simulated_annealing), etc. +These methods can be used by searching on the ANN's weights directly. +Every `genann` struct contains the members `int total_weights;` and +`double *weight;`. `*weight` points to an array of `total_weights` +size which contains all weights used by the ANN. See *example2.c* for +an example of training using random hill climbing search. + +### Saving and Loading ANNs + +```C +genann *genann_read(FILE *in); +void genann_write(genann const *ann, FILE *out); +``` + +Genann provides the `genann_read()` and `genann_write()` functions for loading or saving an ANN in a text-based format. + +### Evaluating + +```C +double const *genann_run(genann const *ann, double const *inputs); +``` + +Call `genann_run()` on a trained ANN to run a feed-forward pass on a given set of inputs. `genann_run()` +will provide a pointer to the array of predicted outputs (of `ann->outputs` length). + + +## Hints + +- All functions start with `genann_`. +- The code is simple. Dig in and change things. + +## Extra Resources + +The [comp.ai.neural-nets +FAQ](http://www.faqs.org/faqs/ai-faq/neural-nets/part1/) is an excellent +resource for an introduction to artificial neural networks. + +If you need an even smaller neural network library, check out the excellent single-hidden-layer library [tinn](https://github.com/glouw/tinn). + +If you're looking for a heavier, more opinionated neural network library in C, +I recommend the [FANN library](http://leenissen.dk/fann/wp/). Another +good library is Peter van Rossum's [Lightweight Neural +Network](http://lwneuralnet.sourceforge.net/), which despite its name, is +heavier and has more features than Genann. diff --git a/genann/doc/e1.dot b/genann/doc/e1.dot new file mode 100644 index 0000000000000000000000000000000000000000..9e498c2359ec30482f762850535ae617e64bc435 --- /dev/null +++ b/genann/doc/e1.dot @@ -0,0 +1,9 @@ +digraph G { + rankdir=LR; + + {i1 i2} -> {h1 h2 h3} -> {o1 o2}; + i1, i2, h1, h2, h3, o1, o2 [shape=circle; label="";]; + + input -> hidden -> output [style=invis;]; + input, hidden, output [shape=plaintext;]; +} diff --git a/genann/doc/e1.png b/genann/doc/e1.png new file mode 100644 index 0000000000000000000000000000000000000000..4a6cb9de7d606843b9d537fd8e3de9a8747fbc26 Binary files /dev/null and b/genann/doc/e1.png differ diff --git a/genann/example/iris.data b/genann/example/iris.data new file mode 100644 index 0000000000000000000000000000000000000000..a3490e0e07dc9d99f655a73e4f53580c8ead9b7d --- /dev/null +++ b/genann/example/iris.data @@ -0,0 +1,150 @@ +5.1,3.5,1.4,0.2,Iris-setosa +4.9,3.0,1.4,0.2,Iris-setosa +4.7,3.2,1.3,0.2,Iris-setosa +4.6,3.1,1.5,0.2,Iris-setosa +5.0,3.6,1.4,0.2,Iris-setosa +5.4,3.9,1.7,0.4,Iris-setosa +4.6,3.4,1.4,0.3,Iris-setosa +5.0,3.4,1.5,0.2,Iris-setosa +4.4,2.9,1.4,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +5.4,3.7,1.5,0.2,Iris-setosa +4.8,3.4,1.6,0.2,Iris-setosa +4.8,3.0,1.4,0.1,Iris-setosa +4.3,3.0,1.1,0.1,Iris-setosa +5.8,4.0,1.2,0.2,Iris-setosa +5.7,4.4,1.5,0.4,Iris-setosa +5.4,3.9,1.3,0.4,Iris-setosa +5.1,3.5,1.4,0.3,Iris-setosa +5.7,3.8,1.7,0.3,Iris-setosa +5.1,3.8,1.5,0.3,Iris-setosa +5.4,3.4,1.7,0.2,Iris-setosa +5.1,3.7,1.5,0.4,Iris-setosa +4.6,3.6,1.0,0.2,Iris-setosa +5.1,3.3,1.7,0.5,Iris-setosa +4.8,3.4,1.9,0.2,Iris-setosa +5.0,3.0,1.6,0.2,Iris-setosa +5.0,3.4,1.6,0.4,Iris-setosa +5.2,3.5,1.5,0.2,Iris-setosa +5.2,3.4,1.4,0.2,Iris-setosa +4.7,3.2,1.6,0.2,Iris-setosa +4.8,3.1,1.6,0.2,Iris-setosa +5.4,3.4,1.5,0.4,Iris-setosa +5.2,4.1,1.5,0.1,Iris-setosa +5.5,4.2,1.4,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +5.0,3.2,1.2,0.2,Iris-setosa +5.5,3.5,1.3,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +4.4,3.0,1.3,0.2,Iris-setosa +5.1,3.4,1.5,0.2,Iris-setosa +5.0,3.5,1.3,0.3,Iris-setosa +4.5,2.3,1.3,0.3,Iris-setosa +4.4,3.2,1.3,0.2,Iris-setosa +5.0,3.5,1.6,0.6,Iris-setosa +5.1,3.8,1.9,0.4,Iris-setosa +4.8,3.0,1.4,0.3,Iris-setosa +5.1,3.8,1.6,0.2,Iris-setosa +4.6,3.2,1.4,0.2,Iris-setosa +5.3,3.7,1.5,0.2,Iris-setosa +5.0,3.3,1.4,0.2,Iris-setosa +7.0,3.2,4.7,1.4,Iris-versicolor +6.4,3.2,4.5,1.5,Iris-versicolor +6.9,3.1,4.9,1.5,Iris-versicolor +5.5,2.3,4.0,1.3,Iris-versicolor +6.5,2.8,4.6,1.5,Iris-versicolor +5.7,2.8,4.5,1.3,Iris-versicolor +6.3,3.3,4.7,1.6,Iris-versicolor +4.9,2.4,3.3,1.0,Iris-versicolor +6.6,2.9,4.6,1.3,Iris-versicolor +5.2,2.7,3.9,1.4,Iris-versicolor +5.0,2.0,3.5,1.0,Iris-versicolor +5.9,3.0,4.2,1.5,Iris-versicolor +6.0,2.2,4.0,1.0,Iris-versicolor +6.1,2.9,4.7,1.4,Iris-versicolor +5.6,2.9,3.6,1.3,Iris-versicolor +6.7,3.1,4.4,1.4,Iris-versicolor +5.6,3.0,4.5,1.5,Iris-versicolor +5.8,2.7,4.1,1.0,Iris-versicolor +6.2,2.2,4.5,1.5,Iris-versicolor +5.6,2.5,3.9,1.1,Iris-versicolor +5.9,3.2,4.8,1.8,Iris-versicolor +6.1,2.8,4.0,1.3,Iris-versicolor +6.3,2.5,4.9,1.5,Iris-versicolor +6.1,2.8,4.7,1.2,Iris-versicolor +6.4,2.9,4.3,1.3,Iris-versicolor +6.6,3.0,4.4,1.4,Iris-versicolor +6.8,2.8,4.8,1.4,Iris-versicolor +6.7,3.0,5.0,1.7,Iris-versicolor +6.0,2.9,4.5,1.5,Iris-versicolor +5.7,2.6,3.5,1.0,Iris-versicolor +5.5,2.4,3.8,1.1,Iris-versicolor +5.5,2.4,3.7,1.0,Iris-versicolor +5.8,2.7,3.9,1.2,Iris-versicolor +6.0,2.7,5.1,1.6,Iris-versicolor +5.4,3.0,4.5,1.5,Iris-versicolor +6.0,3.4,4.5,1.6,Iris-versicolor +6.7,3.1,4.7,1.5,Iris-versicolor +6.3,2.3,4.4,1.3,Iris-versicolor +5.6,3.0,4.1,1.3,Iris-versicolor +5.5,2.5,4.0,1.3,Iris-versicolor +5.5,2.6,4.4,1.2,Iris-versicolor +6.1,3.0,4.6,1.4,Iris-versicolor +5.8,2.6,4.0,1.2,Iris-versicolor +5.0,2.3,3.3,1.0,Iris-versicolor +5.6,2.7,4.2,1.3,Iris-versicolor +5.7,3.0,4.2,1.2,Iris-versicolor +5.7,2.9,4.2,1.3,Iris-versicolor +6.2,2.9,4.3,1.3,Iris-versicolor +5.1,2.5,3.0,1.1,Iris-versicolor +5.7,2.8,4.1,1.3,Iris-versicolor +6.3,3.3,6.0,2.5,Iris-virginica +5.8,2.7,5.1,1.9,Iris-virginica +7.1,3.0,5.9,2.1,Iris-virginica +6.3,2.9,5.6,1.8,Iris-virginica +6.5,3.0,5.8,2.2,Iris-virginica +7.6,3.0,6.6,2.1,Iris-virginica +4.9,2.5,4.5,1.7,Iris-virginica +7.3,2.9,6.3,1.8,Iris-virginica +6.7,2.5,5.8,1.8,Iris-virginica +7.2,3.6,6.1,2.5,Iris-virginica +6.5,3.2,5.1,2.0,Iris-virginica +6.4,2.7,5.3,1.9,Iris-virginica +6.8,3.0,5.5,2.1,Iris-virginica +5.7,2.5,5.0,2.0,Iris-virginica +5.8,2.8,5.1,2.4,Iris-virginica +6.4,3.2,5.3,2.3,Iris-virginica +6.5,3.0,5.5,1.8,Iris-virginica +7.7,3.8,6.7,2.2,Iris-virginica +7.7,2.6,6.9,2.3,Iris-virginica +6.0,2.2,5.0,1.5,Iris-virginica +6.9,3.2,5.7,2.3,Iris-virginica +5.6,2.8,4.9,2.0,Iris-virginica +7.7,2.8,6.7,2.0,Iris-virginica +6.3,2.7,4.9,1.8,Iris-virginica +6.7,3.3,5.7,2.1,Iris-virginica +7.2,3.2,6.0,1.8,Iris-virginica +6.2,2.8,4.8,1.8,Iris-virginica +6.1,3.0,4.9,1.8,Iris-virginica +6.4,2.8,5.6,2.1,Iris-virginica +7.2,3.0,5.8,1.6,Iris-virginica +7.4,2.8,6.1,1.9,Iris-virginica +7.9,3.8,6.4,2.0,Iris-virginica +6.4,2.8,5.6,2.2,Iris-virginica +6.3,2.8,5.1,1.5,Iris-virginica +6.1,2.6,5.6,1.4,Iris-virginica +7.7,3.0,6.1,2.3,Iris-virginica +6.3,3.4,5.6,2.4,Iris-virginica +6.4,3.1,5.5,1.8,Iris-virginica +6.0,3.0,4.8,1.8,Iris-virginica +6.9,3.1,5.4,2.1,Iris-virginica +6.7,3.1,5.6,2.4,Iris-virginica +6.9,3.1,5.1,2.3,Iris-virginica +5.8,2.7,5.1,1.9,Iris-virginica +6.8,3.2,5.9,2.3,Iris-virginica +6.7,3.3,5.7,2.5,Iris-virginica +6.7,3.0,5.2,2.3,Iris-virginica +6.3,2.5,5.0,1.9,Iris-virginica +6.5,3.0,5.2,2.0,Iris-virginica +6.2,3.4,5.4,2.3,Iris-virginica +5.9,3.0,5.1,1.8,Iris-virginica diff --git a/genann/example/iris.names b/genann/example/iris.names new file mode 100644 index 0000000000000000000000000000000000000000..062b486d07bbeaecee0406160a3ced8e73d2f9d7 --- /dev/null +++ b/genann/example/iris.names @@ -0,0 +1,69 @@ +1. Title: Iris Plants Database + Updated Sept 21 by C.Blake - Added discrepency information + +2. Sources: + (a) Creator: R.A. Fisher + (b) Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov) + (c) Date: July, 1988 + +3. Past Usage: + - Publications: too many to mention!!! Here are a few. + 1. Fisher,R.A. "The use of multiple measurements in taxonomic problems" + Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions + to Mathematical Statistics" (John Wiley, NY, 1950). + 2. Duda,R.O., & Hart,P.E. (1973) Pattern Classification and Scene Analysis. + (Q327.D83) John Wiley & Sons. ISBN 0-471-22361-1. See page 218. + 3. Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System + Structure and Classification Rule for Recognition in Partially Exposed + Environments". IEEE Transactions on Pattern Analysis and Machine + Intelligence, Vol. PAMI-2, No. 1, 67-71. + -- Results: + -- very low misclassification rates (0% for the setosa class) + 4. Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule". IEEE + Transactions on Information Theory, May 1972, 431-433. + -- Results: + -- very low misclassification rates again + 5. See also: 1988 MLC Proceedings, 54-64. Cheeseman et al's AUTOCLASS II + conceptual clustering system finds 3 classes in the data. + +4. Relevant Information: + --- This is perhaps the best known database to be found in the pattern + recognition literature. Fisher's paper is a classic in the field + and is referenced frequently to this day. (See Duda & Hart, for + example.) The data set contains 3 classes of 50 instances each, + where each class refers to a type of iris plant. One class is + linearly separable from the other 2; the latter are NOT linearly + separable from each other. + --- Predicted attribute: class of iris plant. + --- This is an exceedingly simple domain. + --- This data differs from the data presented in Fishers article + (identified by Steve Chadwick, spchadwick@espeedaz.net ) + The 35th sample should be: 4.9,3.1,1.5,0.2,"Iris-setosa" + where the error is in the fourth feature. + The 38th sample: 4.9,3.6,1.4,0.1,"Iris-setosa" + where the errors are in the second and third features. + +5. Number of Instances: 150 (50 in each of three classes) + +6. Number of Attributes: 4 numeric, predictive attributes and the class + +7. Attribute Information: + 1. sepal length in cm + 2. sepal width in cm + 3. petal length in cm + 4. petal width in cm + 5. class: + -- Iris Setosa + -- Iris Versicolour + -- Iris Virginica + +8. Missing Attribute Values: None + +Summary Statistics: + Min Max Mean SD Class Correlation + sepal length: 4.3 7.9 5.84 0.83 0.7826 + sepal width: 2.0 4.4 3.05 0.43 -0.4194 + petal length: 1.0 6.9 3.76 1.76 0.9490 (high!) + petal width: 0.1 2.5 1.20 0.76 0.9565 (high!) + +9. Class Distribution: 33.3% for each of 3 classes. diff --git a/genann/example/xor.ann b/genann/example/xor.ann new file mode 100644 index 0000000000000000000000000000000000000000..c11a96817b02164da0b52c0d1f45280849ec0440 --- /dev/null +++ b/genann/example/xor.ann @@ -0,0 +1 @@ +2 1 2 1 -1.777 -5.734 -6.029 -4.460 -3.261 -3.172 2.444 -6.581 5.826 diff --git a/genann/example1.c b/genann/example1.c new file mode 100644 index 0000000000000000000000000000000000000000..b45393c8308fa0ab26cd8e35e2c2e0e2289bf59b --- /dev/null +++ b/genann/example1.c @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include "genann.h" + +int main(int argc, char *argv[]) +{ + printf("GENANN example 1.\n"); + printf("Train a small ANN to the XOR function using backpropagation.\n"); + + /* This will make the neural network initialize differently each run. */ + /* If you don't get a good result, try again for a different result. */ + srand(time(0)); + + /* Input and expected out data for the XOR function. */ + const double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + const double output[4] = {0, 1, 1, 0}; + int i; + + /* New network with 2 inputs, + * 1 hidden layer of 2 neurons, + * and 1 output. */ + genann *ann = genann_init(2, 1, 2, 1); + + /* Train on the four labeled data points many times. */ + for (i = 0; i < 500; ++i) { + genann_train(ann, input[0], output + 0, 3); + genann_train(ann, input[1], output + 1, 3); + genann_train(ann, input[2], output + 2, 3); + genann_train(ann, input[3], output + 3, 3); + } + + /* Run the network and see what it predicts. */ + printf("Output for [%1.f, %1.f] is %1.f.\n", input[0][0], input[0][1], *genann_run(ann, input[0])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[1][0], input[1][1], *genann_run(ann, input[1])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[2][0], input[2][1], *genann_run(ann, input[2])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[3][0], input[3][1], *genann_run(ann, input[3])); + + genann_free(ann); + return 0; +} diff --git a/genann/example2.c b/genann/example2.c new file mode 100644 index 0000000000000000000000000000000000000000..fe635697eaec6150b0c50b6bfe82c304e8970d89 --- /dev/null +++ b/genann/example2.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <math.h> +#include "genann.h" + +int main(int argc, char *argv[]) +{ + printf("GENANN example 2.\n"); + printf("Train a small ANN to the XOR function using random search.\n"); + + srand(time(0)); + + /* Input and expected out data for the XOR function. */ + const double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + const double output[4] = {0, 1, 1, 0}; + int i; + + /* New network with 2 inputs, + * 1 hidden layer of 2 neurons, + * and 1 output. */ + genann *ann = genann_init(2, 1, 2, 1); + + double err; + double last_err = 1000; + int count = 0; + + do { + ++count; + if (count % 1000 == 0) { + /* We're stuck, start over. */ + genann_randomize(ann); + last_err = 1000; + } + + genann *save = genann_copy(ann); + + /* Take a random guess at the ANN weights. */ + for (i = 0; i < ann->total_weights; ++i) { + ann->weight[i] += ((double)rand())/RAND_MAX-0.5; + } + + /* See how we did. */ + err = 0; + err += pow(*genann_run(ann, input[0]) - output[0], 2.0); + err += pow(*genann_run(ann, input[1]) - output[1], 2.0); + err += pow(*genann_run(ann, input[2]) - output[2], 2.0); + err += pow(*genann_run(ann, input[3]) - output[3], 2.0); + + /* Keep these weights if they're an improvement. */ + if (err < last_err) { + genann_free(save); + last_err = err; + } else { + genann_free(ann); + ann = save; + } + + } while (err > 0.01); + + printf("Finished in %d loops.\n", count); + + /* Run the network and see what it predicts. */ + printf("Output for [%1.f, %1.f] is %1.f.\n", input[0][0], input[0][1], *genann_run(ann, input[0])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[1][0], input[1][1], *genann_run(ann, input[1])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[2][0], input[2][1], *genann_run(ann, input[2])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[3][0], input[3][1], *genann_run(ann, input[3])); + + genann_free(ann); + return 0; +} diff --git a/genann/example3.c b/genann/example3.c new file mode 100644 index 0000000000000000000000000000000000000000..2ace13b4577ed722438fc12e1cfb55101ce78837 --- /dev/null +++ b/genann/example3.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> +#include "genann.h" + +const char *save_name = "example/xor.ann"; + +int main(int argc, char *argv[]) +{ + printf("GENANN example 3.\n"); + printf("Load a saved ANN to solve the XOR function.\n"); + + + FILE *saved = fopen(save_name, "r"); + if (!saved) { + printf("Couldn't open file: %s\n", save_name); + exit(1); + } + + genann *ann = genann_read(saved); + fclose(saved); + + if (!ann) { + printf("Error loading ANN from file: %s.", save_name); + exit(1); + } + + + /* Input data for the XOR function. */ + const double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + + /* Run the network and see what it predicts. */ + printf("Output for [%1.f, %1.f] is %1.f.\n", input[0][0], input[0][1], *genann_run(ann, input[0])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[1][0], input[1][1], *genann_run(ann, input[1])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[2][0], input[2][1], *genann_run(ann, input[2])); + printf("Output for [%1.f, %1.f] is %1.f.\n", input[3][0], input[3][1], *genann_run(ann, input[3])); + + genann_free(ann); + return 0; +} diff --git a/genann/example4.c b/genann/example4.c new file mode 100644 index 0000000000000000000000000000000000000000..14de78363db84d4e8473c2f5b3a3bfaf6bed10e5 --- /dev/null +++ b/genann/example4.c @@ -0,0 +1,119 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#include <math.h> +#include "genann.h" + +/* This example is to illustrate how to use GENANN. + * It is NOT an example of good machine learning techniques. + */ + +const char *iris_data = "example/iris.data"; + +double *input, *class; +int samples; +const char *class_names[] = {"Iris-setosa", "Iris-versicolor", "Iris-virginica"}; + +void load_data() { + /* Load the iris data-set. */ + FILE *in = fopen("example/iris.data", "r"); + if (!in) { + printf("Could not open file: %s\n", iris_data); + exit(1); + } + + /* Loop through the data to get a count. */ + char line[1024]; + while (!feof(in) && fgets(line, 1024, in)) { + ++samples; + } + fseek(in, 0, SEEK_SET); + + printf("Loading %d data points from %s\n", samples, iris_data); + + /* Allocate memory for input and output data. */ + input = malloc(sizeof(double) * samples * 4); + class = malloc(sizeof(double) * samples * 3); + + /* Read the file into our arrays. */ + int i, j; + for (i = 0; i < samples; ++i) { + double *p = input + i * 4; + double *c = class + i * 3; + c[0] = c[1] = c[2] = 0.0; + + if (fgets(line, 1024, in) == NULL) { + perror("fgets"); + exit(1); + } + + char *split = strtok(line, ","); + for (j = 0; j < 4; ++j) { + p[j] = atof(split); + split = strtok(0, ","); + } + + split[strlen(split)-1] = 0; + if (strcmp(split, class_names[0]) == 0) {c[0] = 1.0;} + else if (strcmp(split, class_names[1]) == 0) {c[1] = 1.0;} + else if (strcmp(split, class_names[2]) == 0) {c[2] = 1.0;} + else { + printf("Unknown class %s.\n", split); + exit(1); + } + + /* printf("Data point %d is %f %f %f %f -> %f %f %f\n", i, p[0], p[1], p[2], p[3], c[0], c[1], c[2]); */ + } + + fclose(in); +} + + +int main(int argc, char *argv[]) +{ + printf("GENANN example 4.\n"); + printf("Train an ANN on the IRIS dataset using backpropagation.\n"); + + srand(time(0)); + + /* Load the data from file. */ + load_data(); + + /* 4 inputs. + * 1 hidden layer(s) of 4 neurons. + * 3 outputs (1 per class) + */ + genann *ann = genann_init(4, 1, 4, 3); + + int i, j; + int loops = 5000; + + /* Train the network with backpropagation. */ + printf("Training for %d loops over data.\n", loops); + for (i = 0; i < loops; ++i) { + for (j = 0; j < samples; ++j) { + genann_train(ann, input + j*4, class + j*3, .01); + } + /* printf("%1.2f ", xor_score(ann)); */ + } + + int correct = 0; + for (j = 0; j < samples; ++j) { + const double *guess = genann_run(ann, input + j*4); + if (class[j*3+0] == 1.0) {if (guess[0] > guess[1] && guess[0] > guess[2]) ++correct;} + else if (class[j*3+1] == 1.0) {if (guess[1] > guess[0] && guess[1] > guess[2]) ++correct;} + else if (class[j*3+2] == 1.0) {if (guess[2] > guess[0] && guess[2] > guess[1]) ++correct;} + else {printf("Logic error.\n"); exit(1);} + } + + printf("%d/%d correct (%0.1f%%).\n", correct, samples, (double)correct / samples * 100.0); + + + + genann_free(ann); + free(input); + free(class); + + return 0; +} diff --git a/genann/genann.c b/genann/genann.c new file mode 100644 index 0000000000000000000000000000000000000000..b05fa4fc737b6125ad5944ba1ea709d11bd7c6ab --- /dev/null +++ b/genann/genann.c @@ -0,0 +1,405 @@ +/* + * GENANN - Minimal C Artificial Neural Network + * + * Copyright (c) 2015-2018 Lewis Van Winkle + * + * http://CodePlea.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgement in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + */ + +#include "genann.h" + +#include <assert.h> +#include <errno.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef genann_act +#define genann_act_hidden genann_act_hidden_indirect +#define genann_act_output genann_act_output_indirect +#else +#define genann_act_hidden genann_act +#define genann_act_output genann_act +#endif + +#define LOOKUP_SIZE 4096 + +double genann_act_hidden_indirect(const struct genann *ann, double a) { + return ann->activation_hidden(ann, a); +} + +double genann_act_output_indirect(const struct genann *ann, double a) { + return ann->activation_output(ann, a); +} + +const double sigmoid_dom_min = -15.0; +const double sigmoid_dom_max = 15.0; +double interval; +double lookup[LOOKUP_SIZE]; + +#ifdef __GNUC__ +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#define unused __attribute__((unused)) +#else +#define likely(x) x +#define unlikely(x) x +#define unused +#pragma warning(disable : 4996) /* For fscanf */ +#endif + + +double genann_act_sigmoid(const genann *ann unused, double a) { + if (a < -45.0) return 0; + if (a > 45.0) return 1; + return 1.0 / (1 + exp(-a)); +} + +void genann_init_sigmoid_lookup(const genann *ann) { + const double f = (sigmoid_dom_max - sigmoid_dom_min) / LOOKUP_SIZE; + int i; + + interval = LOOKUP_SIZE / (sigmoid_dom_max - sigmoid_dom_min); + for (i = 0; i < LOOKUP_SIZE; ++i) { + lookup[i] = genann_act_sigmoid(ann, sigmoid_dom_min + f * i); + } +} + +double genann_act_sigmoid_cached(const genann *ann unused, double a) { + assert(!isnan(a)); + + if (a < sigmoid_dom_min) return lookup[0]; + if (a >= sigmoid_dom_max) return lookup[LOOKUP_SIZE - 1]; + + size_t j = (size_t)((a-sigmoid_dom_min)*interval+0.5); + + /* Because floating point... */ + if (unlikely(j >= LOOKUP_SIZE)) return lookup[LOOKUP_SIZE - 1]; + + return lookup[j]; +} + +double genann_act_linear(const struct genann *ann unused, double a) { + return a; +} + +double genann_act_threshold(const struct genann *ann unused, double a) { + return a > 0; +} + +genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs) { + if (hidden_layers < 0) return 0; + if (inputs < 1) return 0; + if (outputs < 1) return 0; + if (hidden_layers > 0 && hidden < 1) return 0; + + + const int hidden_weights = hidden_layers ? (inputs+1) * hidden + (hidden_layers-1) * (hidden+1) * hidden : 0; + const int output_weights = (hidden_layers ? (hidden+1) : (inputs+1)) * outputs; + const int total_weights = (hidden_weights + output_weights); + + const int total_neurons = (inputs + hidden * hidden_layers + outputs); + + /* Allocate extra size for weights, outputs, and deltas. */ + const int size = sizeof(genann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs)); + genann *ret = malloc(size); + if (!ret) return 0; + + ret->inputs = inputs; + ret->hidden_layers = hidden_layers; + ret->hidden = hidden; + ret->outputs = outputs; + + ret->total_weights = total_weights; + ret->total_neurons = total_neurons; + + /* Set pointers. */ + ret->weight = (double*)((char*)ret + sizeof(genann)); + ret->output = ret->weight + ret->total_weights; + ret->delta = ret->output + ret->total_neurons; + + genann_randomize(ret); + + ret->activation_hidden = genann_act_sigmoid_cached; + ret->activation_output = genann_act_sigmoid_cached; + + genann_init_sigmoid_lookup(ret); + + return ret; +} + + +genann *genann_read(FILE *in) { + int inputs, hidden_layers, hidden, outputs; + int rc; + + errno = 0; + rc = fscanf(in, "%d %d %d %d", &inputs, &hidden_layers, &hidden, &outputs); + if (rc < 4 || errno != 0) { + perror("fscanf"); + return NULL; + } + + genann *ann = genann_init(inputs, hidden_layers, hidden, outputs); + + int i; + for (i = 0; i < ann->total_weights; ++i) { + errno = 0; + rc = fscanf(in, " %le", ann->weight + i); + if (rc < 1 || errno != 0) { + perror("fscanf"); + genann_free(ann); + + return NULL; + } + } + + return ann; +} + + +genann *genann_copy(genann const *ann) { + const int size = sizeof(genann) + sizeof(double) * (ann->total_weights + ann->total_neurons + (ann->total_neurons - ann->inputs)); + genann *ret = malloc(size); + if (!ret) return 0; + + memcpy(ret, ann, size); + + /* Set pointers. */ + ret->weight = (double*)((char*)ret + sizeof(genann)); + ret->output = ret->weight + ret->total_weights; + ret->delta = ret->output + ret->total_neurons; + + return ret; +} + + +void genann_randomize(genann *ann) { + int i; + for (i = 0; i < ann->total_weights; ++i) { + double r = GENANN_RANDOM(); + /* Sets weights from -0.5 to 0.5. */ + ann->weight[i] = r - 0.5; + } +} + + +void genann_free(genann *ann) { + /* The weight, output, and delta pointers go to the same buffer. */ + free(ann); +} + + +double const *genann_run(genann const *ann, double const *inputs) { + double const *w = ann->weight; + double *o = ann->output + ann->inputs; + double const *i = ann->output; + + /* Copy the inputs to the scratch area, where we also store each neuron's + * output, for consistency. This way the first layer isn't a special case. */ + memcpy(ann->output, inputs, sizeof(double) * ann->inputs); + + int h, j, k; + + if (!ann->hidden_layers) { + double *ret = o; + for (j = 0; j < ann->outputs; ++j) { + double sum = *w++ * -1.0; + for (k = 0; k < ann->inputs; ++k) { + sum += *w++ * i[k]; + } + *o++ = genann_act_output(ann, sum); + } + + return ret; + } + + /* Figure input layer */ + for (j = 0; j < ann->hidden; ++j) { + double sum = *w++ * -1.0; + for (k = 0; k < ann->inputs; ++k) { + sum += *w++ * i[k]; + } + *o++ = genann_act_hidden(ann, sum); + } + + i += ann->inputs; + + /* Figure hidden layers, if any. */ + for (h = 1; h < ann->hidden_layers; ++h) { + for (j = 0; j < ann->hidden; ++j) { + double sum = *w++ * -1.0; + for (k = 0; k < ann->hidden; ++k) { + sum += *w++ * i[k]; + } + *o++ = genann_act_hidden(ann, sum); + } + + i += ann->hidden; + } + + double const *ret = o; + + /* Figure output layer. */ + for (j = 0; j < ann->outputs; ++j) { + double sum = *w++ * -1.0; + for (k = 0; k < ann->hidden; ++k) { + sum += *w++ * i[k]; + } + *o++ = genann_act_output(ann, sum); + } + + /* Sanity check that we used all weights and wrote all outputs. */ + assert(w - ann->weight == ann->total_weights); + assert(o - ann->output == ann->total_neurons); + + return ret; +} + + +void genann_train(genann const *ann, double const *inputs, double const *desired_outputs, double learning_rate) { + /* To begin with, we must run the network forward. */ + genann_run(ann, inputs); + + int h, j, k; + + /* First set the output layer deltas. */ + { + double const *o = ann->output + ann->inputs + ann->hidden * ann->hidden_layers; /* First output. */ + double *d = ann->delta + ann->hidden * ann->hidden_layers; /* First delta. */ + double const *t = desired_outputs; /* First desired output. */ + + + /* Set output layer deltas. */ + if (genann_act_output == genann_act_linear || + ann->activation_output == genann_act_linear) { + for (j = 0; j < ann->outputs; ++j) { + *d++ = *t++ - *o++; + } + } else { + for (j = 0; j < ann->outputs; ++j) { + *d++ = (*t - *o) * *o * (1.0 - *o); + ++o; ++t; + } + } + } + + + /* Set hidden layer deltas, start on last layer and work backwards. */ + /* Note that loop is skipped in the case of hidden_layers == 0. */ + for (h = ann->hidden_layers - 1; h >= 0; --h) { + + /* Find first output and delta in this layer. */ + double const *o = ann->output + ann->inputs + (h * ann->hidden); + double *d = ann->delta + (h * ann->hidden); + + /* Find first delta in following layer (which may be hidden or output). */ + double const * const dd = ann->delta + ((h+1) * ann->hidden); + + /* Find first weight in following layer (which may be hidden or output). */ + double const * const ww = ann->weight + ((ann->inputs+1) * ann->hidden) + ((ann->hidden+1) * ann->hidden * (h)); + + for (j = 0; j < ann->hidden; ++j) { + + double delta = 0; + + for (k = 0; k < (h == ann->hidden_layers-1 ? ann->outputs : ann->hidden); ++k) { + const double forward_delta = dd[k]; + const int windex = k * (ann->hidden + 1) + (j + 1); + const double forward_weight = ww[windex]; + delta += forward_delta * forward_weight; + } + + *d = *o * (1.0-*o) * delta; + ++d; ++o; + } + } + + + /* Train the outputs. */ + { + /* Find first output delta. */ + double const *d = ann->delta + ann->hidden * ann->hidden_layers; /* First output delta. */ + + /* Find first weight to first output delta. */ + double *w = ann->weight + (ann->hidden_layers + ? ((ann->inputs+1) * ann->hidden + (ann->hidden+1) * ann->hidden * (ann->hidden_layers-1)) + : (0)); + + /* Find first output in previous layer. */ + double const * const i = ann->output + (ann->hidden_layers + ? (ann->inputs + (ann->hidden) * (ann->hidden_layers-1)) + : 0); + + /* Set output layer weights. */ + for (j = 0; j < ann->outputs; ++j) { + *w++ += *d * learning_rate * -1.0; + for (k = 1; k < (ann->hidden_layers ? ann->hidden : ann->inputs) + 1; ++k) { + *w++ += *d * learning_rate * i[k-1]; + } + + ++d; + } + + assert(w - ann->weight == ann->total_weights); + } + + + /* Train the hidden layers. */ + for (h = ann->hidden_layers - 1; h >= 0; --h) { + + /* Find first delta in this layer. */ + double const *d = ann->delta + (h * ann->hidden); + + /* Find first input to this layer. */ + double const *i = ann->output + (h + ? (ann->inputs + ann->hidden * (h-1)) + : 0); + + /* Find first weight to this layer. */ + double *w = ann->weight + (h + ? ((ann->inputs+1) * ann->hidden + (ann->hidden+1) * (ann->hidden) * (h-1)) + : 0); + + + for (j = 0; j < ann->hidden; ++j) { + *w++ += *d * learning_rate * -1.0; + for (k = 1; k < (h == 0 ? ann->inputs : ann->hidden) + 1; ++k) { + *w++ += *d * learning_rate * i[k-1]; + } + ++d; + } + + } + +} + + +void genann_write(genann const *ann, FILE *out) { + fprintf(out, "%d %d %d %d", ann->inputs, ann->hidden_layers, ann->hidden, ann->outputs); + + int i; + for (i = 0; i < ann->total_weights; ++i) { + fprintf(out, " %.20e", ann->weight[i]); + } +} + + diff --git a/genann/genann.h b/genann/genann.h new file mode 100644 index 0000000000000000000000000000000000000000..e4b7383de7880fdf01cc29ba7e0b539403ae1895 --- /dev/null +++ b/genann/genann.h @@ -0,0 +1,108 @@ +/* + * GENANN - Minimal C Artificial Neural Network + * + * Copyright (c) 2015-2018 Lewis Van Winkle + * + * http://CodePlea.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgement in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + */ + + +#ifndef GENANN_H +#define GENANN_H + +#include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GENANN_RANDOM +/* We use the following for uniform random numbers between 0 and 1. + * If you have a better function, redefine this macro. */ +#define GENANN_RANDOM() (((double)rand())/RAND_MAX) +#endif + +struct genann; + +typedef double (*genann_actfun)(const struct genann *ann, double a); + +typedef struct genann { + /* How many inputs, outputs, and hidden neurons. */ + int inputs, hidden_layers, hidden, outputs; + + /* Which activation function to use for hidden neurons. Default: gennann_act_sigmoid_cached*/ + genann_actfun activation_hidden; + + /* Which activation function to use for output. Default: gennann_act_sigmoid_cached*/ + genann_actfun activation_output; + + /* Total number of weights, and size of weights buffer. */ + int total_weights; + + /* Total number of neurons + inputs and size of output buffer. */ + int total_neurons; + + /* All weights (total_weights long). */ + double *weight; + + /* Stores input array and output of each neuron (total_neurons long). */ + double *output; + + /* Stores delta of each hidden and output neuron (total_neurons - inputs long). */ + double *delta; + +} genann; + +/* Creates and returns a new ann. */ +genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs); + +/* Creates ANN from file saved with genann_write. */ +genann *genann_read(FILE *in); + +/* Sets weights randomly. Called by init. */ +void genann_randomize(genann *ann); + +/* Returns a new copy of ann. */ +genann *genann_copy(genann const *ann); + +/* Frees the memory used by an ann. */ +void genann_free(genann *ann); + +/* Runs the feedforward algorithm to calculate the ann's output. */ +double const *genann_run(genann const *ann, double const *inputs); + +/* Does a single backprop update. */ +void genann_train(genann const *ann, double const *inputs, double const *desired_outputs, double learning_rate); + +/* Saves the ann. */ +void genann_write(genann const *ann, FILE *out); + +void genann_init_sigmoid_lookup(const genann *ann); +double genann_act_sigmoid(const genann *ann, double a); +double genann_act_sigmoid_cached(const genann *ann, double a); +double genann_act_threshold(const genann *ann, double a); +double genann_act_linear(const genann *ann, double a); + + +#ifdef __cplusplus +} +#endif + +#endif /*GENANN_H*/ diff --git a/genann/minctest.h b/genann/minctest.h new file mode 100644 index 0000000000000000000000000000000000000000..eb3ad41817cfbc2456b17e889a0526a911114f96 --- /dev/null +++ b/genann/minctest.h @@ -0,0 +1,127 @@ +/* + * + * MINCTEST - Minimal C Test Library - 0.1 + * + * Copyright (c) 2014, 2015, 2016 Lewis Van Winkle + * + * http://CodePlea.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgement in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + */ + + + +/* + * MINCTEST - Minimal testing library for C + * + * + * Example: + * + * void test1() { + * lok('a' == 'a'); + * } + * + * void test2() { + * lequal(5, 6); + * lfequal(5.5, 5.6); + * } + * + * int main() { + * lrun("test1", test1); + * lrun("test2", test2); + * lresults(); + * return lfails != 0; + * } + * + * + * + * Hints: + * All functions/variables start with the letter 'l'. + * + */ + + +#ifndef __MINCTEST_H__ +#define __MINCTEST_H__ + +#include <stdio.h> +#include <math.h> +#include <time.h> + + +/* How far apart can floats be before we consider them unequal. */ +#define LTEST_FLOAT_TOLERANCE 0.001 + + +/* Track the number of passes, fails. */ +/* NB this is made for all tests to be in one file. */ +static int ltests = 0; +static int lfails = 0; + + +/* Display the test results. */ +#define lresults() do {\ + if (lfails == 0) {\ + printf("ALL TESTS PASSED (%d/%d)\n", ltests, ltests);\ + } else {\ + printf("SOME TESTS FAILED (%d/%d)\n", ltests-lfails, ltests);\ + }\ +} while (0) + + +/* Run a test. Name can be any string to print out, test is the function name to call. */ +#define lrun(name, test) do {\ + const int ts = ltests;\ + const int fs = lfails;\ + const clock_t start = clock();\ + printf("\t%-14s", name);\ + test();\ + printf("pass:%2d fail:%2d %4dms\n",\ + (ltests-ts)-(lfails-fs), lfails-fs,\ + (int)((clock() - start) * 1000 / CLOCKS_PER_SEC));\ +} while (0) + + +/* Assert a true statement. */ +#define lok(test) do {\ + ++ltests;\ + if (!(test)) {\ + ++lfails;\ + printf("%s:%d error \n", __FILE__, __LINE__);\ + }} while (0) + + +/* Assert two integers are equal. */ +#define lequal(a, b) do {\ + ++ltests;\ + if ((a) != (b)) {\ + ++lfails;\ + printf("%s:%d (%d != %d)\n", __FILE__, __LINE__, (a), (b));\ + }} while (0) + + +/* Assert two floats are equal (Within LTEST_FLOAT_TOLERANCE). */ +#define lfequal(a, b) do {\ + ++ltests;\ + if (fabs((double)(a)-(double)(b)) > LTEST_FLOAT_TOLERANCE) {\ + ++lfails;\ + printf("%s:%d (%f != %f)\n", __FILE__, __LINE__, (double)(a), (double)(b));\ + }} while (0) + + +#endif /*__MINCTEST_H__*/ diff --git a/genann/outputs b/genann/outputs new file mode 100644 index 0000000000000000000000000000000000000000..b00d5f10a05c2db489c38baddcf6f9751e8548f8 --- /dev/null +++ b/genann/outputs @@ -0,0 +1,14 @@ +test.c:208: lequal(first->inputs, second->inputs); +test.c:209: lequal(first->hidden_layers, second->hidden_layers); +test.c:210: lequal(first->hidden, second->hidden); +test.c:211: lequal(first->outputs, second->outputs); +test.c:212: lequal(first->total_weights, second->total_weights); +test.c:215: for (i = 0; i < first->total_weights; ++i) { +test.c:216: lok(first->weight[i] == second->weight[i]); +test.c:229: lequal(first->inputs, second->inputs); +test.c:230: lequal(first->hidden_layers, second->hidden_layers); +test.c:231: lequal(first->hidden, second->hidden); +test.c:232: lequal(first->outputs, second->outputs); +test.c:233: lequal(first->total_weights, second->total_weights); +test.c:236: for (i = 0; i < first->total_weights; ++i) { +test.c:237: lfequal(first->weight[i], second->weight[i]); diff --git a/genann/test.c b/genann/test.c new file mode 100644 index 0000000000000000000000000000000000000000..a7f895e07e21abf734d0063ee0656d89dfe80dce --- /dev/null +++ b/genann/test.c @@ -0,0 +1,276 @@ +/* + * GENANN - Minimal C Artificial Neural Network + * + * Copyright (c) 2015-2018 Lewis Van Winkle + * + * http://CodePlea.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgement in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + */ + +#include "genann.h" +#include "minctest.h" +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + + + +void basic() { + genann *ann = genann_init(1, 0, 0, 1); + + lequal(ann->total_weights, 2); + double a; + + + a = 0; + ann->weight[0] = 0; + ann->weight[1] = 0; + lfequal(0.5, *genann_run(ann, &a)); + + a = 1; + lfequal(0.5, *genann_run(ann, &a)); + + a = 11; + lfequal(0.5, *genann_run(ann, &a)); + + a = 1; + ann->weight[0] = 1; + ann->weight[1] = 1; + lfequal(0.5, *genann_run(ann, &a)); + + a = 10; + ann->weight[0] = 1; + ann->weight[1] = 1; + lfequal(1.0, *genann_run(ann, &a)); + + a = -10; + lfequal(0.0, *genann_run(ann, &a)); + + genann_free(ann); +} + + +void xor() { + genann *ann = genann_init(2, 1, 2, 1); + ann->activation_hidden = genann_act_threshold; + ann->activation_output = genann_act_threshold; + + lequal(ann->total_weights, 9); + + /* First hidden. */ + ann->weight[0] = .5; + ann->weight[1] = 1; + ann->weight[2] = 1; + + /* Second hidden. */ + ann->weight[3] = 1; + ann->weight[4] = 1; + ann->weight[5] = 1; + + /* Output. */ + ann->weight[6] = .5; + ann->weight[7] = 1; + ann->weight[8] = -1; + + + double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + double output[4] = {0, 1, 1, 0}; + + lfequal(output[0], *genann_run(ann, input[0])); + lfequal(output[1], *genann_run(ann, input[1])); + lfequal(output[2], *genann_run(ann, input[2])); + lfequal(output[3], *genann_run(ann, input[3])); + + genann_free(ann); +} + + +void backprop() { + genann *ann = genann_init(1, 0, 0, 1); + + double input, output; + input = .5; + output = 1; + + double first_try = *genann_run(ann, &input); + genann_train(ann, &input, &output, .5); + double second_try = *genann_run(ann, &input); + lok(fabs(first_try - output) > fabs(second_try - output)); + + genann_free(ann); +} + + +void train_and() { + double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + double output[4] = {0, 0, 0, 1}; + + genann *ann = genann_init(2, 0, 0, 1); + + int i, j; + + for (i = 0; i < 50; ++i) { + for (j = 0; j < 4; ++j) { + genann_train(ann, input[j], output + j, .8); + } + } + + ann->activation_output = genann_act_threshold; + lfequal(output[0], *genann_run(ann, input[0])); + lfequal(output[1], *genann_run(ann, input[1])); + lfequal(output[2], *genann_run(ann, input[2])); + lfequal(output[3], *genann_run(ann, input[3])); + + genann_free(ann); +} + + +void train_or() { + double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + double output[4] = {0, 1, 1, 1}; + + genann *ann = genann_init(2, 0, 0, 1); + genann_randomize(ann); + + int i, j; + + for (i = 0; i < 50; ++i) { + for (j = 0; j < 4; ++j) { + genann_train(ann, input[j], output + j, .8); + } + } + + ann->activation_output = genann_act_threshold; + lfequal(output[0], *genann_run(ann, input[0])); + lfequal(output[1], *genann_run(ann, input[1])); + lfequal(output[2], *genann_run(ann, input[2])); + lfequal(output[3], *genann_run(ann, input[3])); + + genann_free(ann); +} + + + +void train_xor() { + double input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + double output[4] = {0, 1, 1, 0}; + + genann *ann = genann_init(2, 1, 2, 1); + + int i, j; + + for (i = 0; i < 500; ++i) { + for (j = 0; j < 4; ++j) { + genann_train(ann, input[j], output + j, 3); + } + /* printf("%1.2f ", xor_score(ann)); */ + } + + ann->activation_output = genann_act_threshold; + lfequal(output[0], *genann_run(ann, input[0])); + lfequal(output[1], *genann_run(ann, input[1])); + lfequal(output[2], *genann_run(ann, input[2])); + lfequal(output[3], *genann_run(ann, input[3])); + + genann_free(ann); +} + + + +void persist() { + genann *first = genann_init(1000, 5, 50, 10); + + FILE *out = fopen("persist.txt", "w"); + genann_write(first, out); + fclose(out); + + + FILE *in = fopen("persist.txt", "r"); + genann *second = genann_read(in); + fclose(in); + + lequal(first->inputs, second->inputs); + lequal(first->hidden_layers, second->hidden_layers); + lequal(first->hidden, second->hidden); + lequal(first->outputs, second->outputs); + lequal(first->total_weights, second->total_weights); + + int i; + for (i = 0; i < first->total_weights; ++i) { + lok(first->weight[i] == second->weight[i]); + } + + genann_free(first); + genann_free(second); +} + + +void copy() { + genann *first = genann_init(1000, 5, 50, 10); + + genann *second = genann_copy(first); + + lequal(first->inputs, second->inputs); + lequal(first->hidden_layers, second->hidden_layers); + lequal(first->hidden, second->hidden); + lequal(first->outputs, second->outputs); + lequal(first->total_weights, second->total_weights); + + int i; + for (i = 0; i < first->total_weights; ++i) { + lfequal(first->weight[i], second->weight[i]); + } + + genann_free(first); + genann_free(second); +} + + +void sigmoid() { + double i = -20; + const double max = 20; + const double d = .0001; + + while (i < max) { + lfequal(genann_act_sigmoid(NULL, i), genann_act_sigmoid_cached(NULL, i)); + i += d; + } +} + + +int main(int argc, char *argv[]) +{ + printf("GENANN TEST SUITE\n"); + + srand(100); //Repeatable test results. + + lrun("basic", basic); + lrun("xor", xor); + lrun("backprop", backprop); + lrun("train and", train_and); + lrun("train or", train_or); + lrun("train xor", train_xor); + lrun("persist", persist); + lrun("copy", copy); + lrun("sigmoid", sigmoid); + + lresults(); + + return lfails != 0; +}