From b119465b09bace3e447528798bdf3b4cafeab266 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.maroneze@cea.fr> Date: Tue, 2 Feb 2021 17:24:46 +0100 Subject: [PATCH] [genann] add new case study --- Makefile | 1 + README.md | 1 + frama-c | 2 +- genann/.frama-c/GNUmakefile | 49 + genann/.frama-c/genann.eva/alarms.csv | 76 + genann/.frama-c/genann.eva/metrics.log | 39 + genann/.frama-c/genann.eva/nonterm.log | 0 genann/.frama-c/genann.eva/warnings.log | 0 genann/.frama-c/genann.parse/framac.ast | 2402 +++++++++++++++++++++ genann/.frama-c/genann.parse/metrics.log | 45 + genann/.frama-c/genann.parse/warnings.log | 2 + genann/.frama-c/path.mk | 1 + genann/LICENSE | 20 + genann/Makefile | 34 + genann/README.md | 154 ++ genann/doc/e1.dot | 9 + genann/doc/e1.png | Bin 0 -> 22067 bytes genann/example/iris.data | 150 ++ genann/example/iris.names | 69 + genann/example/xor.ann | 1 + genann/example1.c | 41 + genann/example2.c | 71 + genann/example3.c | 39 + genann/example4.c | 119 + genann/genann.c | 405 ++++ genann/genann.h | 108 + genann/minctest.h | 127 ++ genann/outputs | 14 + genann/test.c | 276 +++ 29 files changed, 4254 insertions(+), 1 deletion(-) create mode 100644 genann/.frama-c/GNUmakefile create mode 100644 genann/.frama-c/genann.eva/alarms.csv create mode 100644 genann/.frama-c/genann.eva/metrics.log create mode 100644 genann/.frama-c/genann.eva/nonterm.log create mode 100644 genann/.frama-c/genann.eva/warnings.log create mode 100644 genann/.frama-c/genann.parse/framac.ast create mode 100644 genann/.frama-c/genann.parse/metrics.log create mode 100644 genann/.frama-c/genann.parse/warnings.log create mode 120000 genann/.frama-c/path.mk create mode 100644 genann/LICENSE create mode 100644 genann/Makefile create mode 100644 genann/README.md create mode 100644 genann/doc/e1.dot create mode 100644 genann/doc/e1.png create mode 100644 genann/example/iris.data create mode 100644 genann/example/iris.names create mode 100644 genann/example/xor.ann create mode 100644 genann/example1.c create mode 100644 genann/example2.c create mode 100644 genann/example3.c create mode 100644 genann/example4.c create mode 100644 genann/genann.c create mode 100644 genann/genann.h create mode 100644 genann/minctest.h create mode 100644 genann/outputs create mode 100644 genann/test.c diff --git a/Makefile b/Makefile index 10ebfcd4f..d856502eb 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 9e9c7550a..0fb01735f 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 086dbf677..4adb46e09 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 000000000..614826732 --- /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 000000000..d353cf06a --- /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 000000000..c489c1d78 --- /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 000000000..e69de29bb diff --git a/genann/.frama-c/genann.eva/warnings.log b/genann/.frama-c/genann.eva/warnings.log new file mode 100644 index 000000000..e69de29bb diff --git a/genann/.frama-c/genann.parse/framac.ast b/genann/.frama-c/genann.parse/framac.ast new file mode 100644 index 000000000..2cd55aae4 --- /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 000000000..b26c37df8 --- /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 000000000..accee9a71 --- /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 000000000..57620d6d4 --- /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 000000000..5ab017c45 --- /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 000000000..427e3be71 --- /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 000000000..4e04d47af --- /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 000000000..9e498c235 --- /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 GIT binary patch literal 22067 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 Ir1b9pe~Bra{{R30 literal 0 HcmV?d00001 diff --git a/genann/example/iris.data b/genann/example/iris.data new file mode 100644 index 000000000..a3490e0e0 --- /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 000000000..062b486d0 --- /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 000000000..c11a96817 --- /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 000000000..b45393c83 --- /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 000000000..fe635697e --- /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 000000000..2ace13b45 --- /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 000000000..14de78363 --- /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 000000000..b05fa4fc7 --- /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 000000000..e4b7383de --- /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 000000000..eb3ad4181 --- /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 000000000..b00d5f10a --- /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 000000000..a7f895e07 --- /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; +} -- GitLab