diff options
| author | Ethan Werner <mail@ethanwerner.com> | 2024-04-17 16:00:00 -0700 |
|---|---|---|
| committer | Ethan Werner <mail@ethanwerner.com> | 2026-06-08 16:01:49 +0400 |
| commit | f6a144987cc403de8ad6bddd055f756120f8d405 (patch) | |
| tree | 3b4cfc8c76db7adba8504dc0e079466e2a0d336c /example | |
archival commit
Diffstat (limited to 'example')
| -rwxr-xr-x | example/ann_xor.c | 48 | ||||
| -rwxr-xr-x | example/bin.c | 47 | ||||
| -rwxr-xr-x | example/build | 6 | ||||
| -rw-r--r-- | example/direct.c | 33 | ||||
| -rwxr-xr-x | example/escape.c | 62 | ||||
| -rwxr-xr-x | example/genetic_ann.c | 91 | ||||
| -rwxr-xr-x | example/genetic_char.c | 113 | ||||
| -rwxr-xr-x | example/pool.c | 7 | ||||
| -rw-r--r-- | example/pushdown.c | 22 | ||||
| -rw-r--r-- | example/stack.c | 20 |
10 files changed, 449 insertions, 0 deletions
diff --git a/example/ann_xor.c b/example/ann_xor.c new file mode 100755 index 0000000..a39264c --- /dev/null +++ b/example/ann_xor.c @@ -0,0 +1,48 @@ +// example_xor.c - Example XOR training + +#define ANN_IMPLEMENTATION +#include "../include/ann.h" + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +int main(void) { + srand(time(0)); + + ann_t *ann = ann_init(3, (uint_t[]){2, 2, 1}); + ann_set_activation(ann, SIGMOID, SIGMOID); + ann_random(ann); + + fp_t input[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + fp_t output[4] = {0, 0, 0, 0}; + fp_t expected[4] = {0, 1, 1, 0}; + fp_t error = 0; + + for (int_t iteration = 0; iteration < 100000; iteration++) { + for (int_t training = 0; training < 4; training++) { + ann_propagation_forward(ann, (fp_t const *const)&input[training], + &output[training]); + + error += ann_error_total(&output[training], &expected[training], + ann->layer_neuron_n[ann->layer_n - 1]); + + // Train using backpropagation + ann_propagation_backward(ann, (fp_t const *const)&input[training], + &output[training], &expected[training], 0.4); + + // Train using numeric integration + // ann_train_numeric( ann, ( fp_t const * const ) &i[b], &t[b], 0.03 ); + } + } + + ann_print_weight(ann); + + fputs("------------------------------------------------------------\n\n", + stderr); + + for (int i = 0; i < 4; i++) { + ann_propagation_forward(ann, (fp_t const *const)&input[i], &output[i]); + ann_print_neuron(ann, (fp_t const *const)&input[i], &output[i]); + } +} diff --git a/example/bin.c b/example/bin.c new file mode 100755 index 0000000..40a7f77 --- /dev/null +++ b/example/bin.c @@ -0,0 +1,47 @@ +#include <stdint.h> +#include <stdio.h> + +typedef int32_t bin_key_t; + +#define TEST_LENGTH 10 +#define TEST_START -2 +#define TEST_STEP 0.5; + +struct sample_t { + bin_key_t time; + double data; +}; + +#define BIN_IMPLEMENTATION +#include "../include/bin.h" + +int main() { + char const *path = "./test.bin"; + FILE *bin = bin_init(path, sizeof(struct sample_t)); + + bin_key_t half = (bin_key_t)((TEST_START + TEST_LENGTH) / 2.0); + + // Insert half of the values using bin_insert() + for (bin_key_t i = half - 1; i >= TEST_START; i--) { + bin_insert(bin, 0, &(struct sample_t){.time = i, .data = 2.0 * i}, 1); + } + + // Append half of the values to the end + for (bin_key_t i = half; i < TEST_START + TEST_LENGTH; i++) { + bin_append(bin, &(struct sample_t){.time = i, .data = 2.0 * i}, 1); + } + + uint64_t l = bin_length(bin); + uint64_t bs = bin_block_size(bin); + + struct sample_t x[l]; + bin_read(bin, 0, x, l); + + // Test that all values are correct + for (int32_t i = 0; i < TEST_LENGTH; i++) { + bin_key_t key = TEST_START + i; + assert(x[i].time == key && x[i].data == 2.0 * key); + } + + bin_close(bin); +}
\ No newline at end of file diff --git a/example/build b/example/build new file mode 100755 index 0000000..b6c600f --- /dev/null +++ b/example/build @@ -0,0 +1,6 @@ +EXAMPLES=$(ls -1 --color=never *.c | sed 's/\.c//') + +for EXAMPLE in $EXAMPLES +do + gcc -g -fno-fast-math -O0 -o $EXAMPLE $EXAMPLE.c -lm +done diff --git a/example/direct.c b/example/direct.c new file mode 100644 index 0000000..102c0c3 --- /dev/null +++ b/example/direct.c @@ -0,0 +1,33 @@ +typedef double value_t; +#define DT_IMPLEMENTATION +#include "../include/direct.h" +#include <stdio.h> + +int main() { + node_t x0 = {.x = 0.0, .function = dt_add}; + node_t x1 = {.x = 0.0, .function = dt_one}; + node_t x2 = {.x = 0.0, .function = dt_add}; + node_t x3 = {.x = 0.0, .function = dt_add}; + node_t x4 = {.x = 0.0, .function = dt_add}; + node_t x5 = {.x = 0.0, .function = dt_add}; + node_t x6 = {.x = 0.0, .function = dt_one}; + + dt_connect(&x0, &x2); + dt_connect(&x0, &x1); + dt_connect(&x0, &x3); + dt_connect(&x2, &x1); + dt_connect(&x2, &x4); + dt_connect(&x3, &x4); + dt_connect(&x4, &x5); + dt_connect(&x4, &x6); + dt_connect(&x5, &x2); + + dt_update_trace(&x0); + printf("data: %lf\n", x0.x); + dt_update_trace(&x0); + printf("data: %lf\n", x0.x); + dt_update_trace(&x0); + printf("data: %lf\n", x0.x); + + return 0; +}
\ No newline at end of file diff --git a/example/escape.c b/example/escape.c new file mode 100755 index 0000000..c5e71ac --- /dev/null +++ b/example/escape.c @@ -0,0 +1,62 @@ +// escape.c - Simple test print code + + +#include <stdint.h> +#include <tgmath.h> + +#define ESCAPE_IMPLEMENTATION +#include "../include/escape.h" + +#define TEST_STRING "HELLO" + +void hsv_rgb( float h, float s, float v, uint8_t *r, uint8_t *g, uint8_t *b ) +{ + float h0 = h * 6.0; + + float k = fmod( 5.0 + h0, 6.0 ); + *r = 255 * ( v - v * s * fmax( 0.0, fmin( k, fmin( 4.0 - k, 1.0 ) ) ) ); + + k = fmod( 3.0 + h0, 6.0 ); + *g = 255 * ( v - v * s * fmax( 0.0, fmin( k, fmin( 4.0 - k, 1.0 ) ) ) ); + + k = fmod( 1.0 + h0, 6.0 ); + *b = 255 * ( v - v * s * fmax( 0.0, fmin( k, fmin( 4.0 - k, 1.0 ) ) ) ); +} + + +int main( void ) +{ + // Clear screen + fputs( ESC_CLEAR_SCREEN, stdout ); + + // Print a rectangle of Xs with positional coordinates + fputs( ESC_CURSOR_POSITION( 1, 1 ), stdout ); fflush( stdout ); + fputs( ESC_CURSOR_POSITION( 3, 2 ) "X", stdout ); fflush( stdout ); + fputs( ESC_CURSOR_POSITION( 10, 2 ) "X", stdout ); fflush( stdout ); + fputs( ESC_CURSOR_POSITION( 10, 4 ) "X", stdout ); fflush( stdout ); + fputs( ESC_CURSOR_POSITION( 3, 4 ) "X", stdout ); fflush( stdout ); + fputs( "\n", stdout ); + + fputs( "\n" ESC_RESET TEST_STRING "\n\n", stdout ); + fputs( ESC_BOLD TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_OVERLINE TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_UNDERLINE TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_STRIKETHROUGH TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_COLOR_FG_RGB( 0, 128, 128 ) TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_COLOR_BG_RGB( 128, 0, 128 ) TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_BLINK TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_REVERSE TEST_STRING ESC_RESET "\n\n", stdout ); + fputs( ESC_CONCEAL TEST_STRING ESC_REVEAL TEST_STRING ESC_RESET "\n\n", stdout ); + + uint8_t r,g,b; + + for( float i = 0; i < 1; i += 0.01 ) + { + hsv_rgb( i, 1.0, 1.0, &r, &g, &b ); + + esc_color_fg_rgb( r, g, b ); + fputs( "█", stdout ); + } + + fputs( "\n", stdout ); +} diff --git a/example/genetic_ann.c b/example/genetic_ann.c new file mode 100755 index 0000000..071ccf5 --- /dev/null +++ b/example/genetic_ann.c @@ -0,0 +1,91 @@ +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#define ANN_IMPLEMENTATION +#include "../include/ann.h" + +#define POPULATION_N 100 +#define RATE_SELECTION 0.2 +#define RATE_MUTATON 10 +#define MAGNITUDE_MUTATION 0.01 +#define ERROR 0.00001 + +typedef ann_t *ga_individual_t; + +#define GENETIC_IMPLEMENTATION +#include "../include/genetic.h" + +double fitness(ann_t *const x, void const *c) { + fp_t *i = *((fp_t **)c); + fp_t *t = *((fp_t **)c + 1); + fp_t o[4]; + + fp_t e = 0, sum = 0; + for (uint_t b = 0; b < 4; b++) { + ann_propagation_forward(x, &i[2 * b], &o[b]); + e = ann_error_total(&o[b], &t[b], x->layer_neuron_n[x->layer_n - 1]); + sum += e; + } + + return sum; +} + +void crossover(ann_t **y, ann_t *x0, ann_t *x1) { + uint32_t i_crossover = rand() % x0->weight_n; + memcpy((*y)->weight, x0->weight, i_crossover * sizeof(fp_t)); + memcpy((*y)->weight + i_crossover, x1->weight + i_crossover, + (x0->weight_n - i_crossover) * sizeof(fp_t)); +} + +void mutate(ann_t *x) { + uint32_t i_mutation = rand() % x->weight_n; + fp_t r = + (2 * (MAGNITUDE_MUTATION * (fp_t)rand() / RAND_MAX)) - MAGNITUDE_MUTATION; + x->weight[i_mutation] += r; +} + +int main(void) { + srand(time(0)); + + fp_t input[12] = {0, 0, 0, 1, 1, 0, 1, 1}; + fp_t output; + fp_t target[4] = {0, 1, 1, 0}; + + ann_t **networks = malloc(sizeof(ann_t *) * POPULATION_N); + + for (uint_t i = 0; i < POPULATION_N; i++) { + networks[i] = ann_init(3, (uint_t[]){2, 2, 1}); + ann_set_activation(networks[i], SIGMOID, IDENTITY); + ann_random(networks[i]); + } + + fp_t e = ERROR + 1; + uint32_t n = 0, i = 0; + while (e > ERROR) { + e = ga_generation(networks, POPULATION_N, RATE_SELECTION, RATE_MUTATON, + fitness, (fp_t *[2]){input, target}, crossover, mutate); + + n++; + i++; + + if (i > 1000) { + printf("\rERROR: %10.5lf", e); + i = 0; + } + } + + printf("\33[2K\r"); + printf("ERROR: %lf", e); + + for (int i = 0; i < 1; i++) { + for (int j = 0; j < 4; j++) { + ann_propagation_forward(networks[i], (fp_t const *const)&input[2 * j], + &output); + ann_print_neuron(networks[i], &input[2 * j], &output); + } + } + + printf("\nITERATIONS: %u\n", n); +} diff --git a/example/genetic_char.c b/example/genetic_char.c new file mode 100755 index 0000000..7dc24d4 --- /dev/null +++ b/example/genetic_char.c @@ -0,0 +1,113 @@ +// example_string.c - Example training of ann.h ANN, with genetic algorithm + +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +typedef char *ga_individual_t; + +#define GENETIC_IMPLEMENTATION +#include "../include/genetic.h" + +#define POPULATION_N 100 +#define RATE_SELECTION 0.5 +#define RATE_MUTATON 2.0 +#define ERROR 0 + +#define TARGET_STRING \ + " !\"#$%&'()*+,-./" \ + "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ + "abcdefghijklmnopqrstuvwxyz{|}~" + +#define generate() ((char)(rand() % (127 - 32) + 32)) + +void crossover(char **y, char *x0, char *x1) { + uint32_t lx0 = strlen(x0); + uint32_t lx1 = strlen(x1); + + uint32_t ix0 = rand() % lx0; + uint32_t ix1 = rand() % lx1; + + uint32_t ly = ix0 + (lx1 - ix1); + + char *sy = malloc(ly + 1); + strncpy(sy, x0, ix0); + strncpy(sy + ix0, x1 + ix1, lx1 - ix1); + sy[ly] = 0; + + free(*y); + *y = sy; +} + +void mutation(char *x) { + uint32_t l = strlen(x); + uint32_t i = rand() % l; + + x[i] = generate(); +} + +double fitness(char *individual, void const *data) { + double error = 0; + + char const *target = (char const *)data; + + while (*individual && *target) { + error += abs(*target++ - *individual++); + } + while (*individual) { + error += *individual++; + } + while (*target) { + error += *target++; + } + + return error; +} + +int main(void) { + char const *target = TARGET_STRING; + char *population[POPULATION_N]; + + srand(time(0)); + + // Initialize poplation + for (uint64_t i = 0; i < POPULATION_N; i++) { + uint64_t n = rand() % 5 + 20; + char *str = malloc(n + 1); + str[n] = (uint8_t)0; + + for (uint64_t j = 0; j < n; j++) { + str[j] = generate(); + } + + population[i] = str; + } + + printf("TARGET: %s\n", TARGET_STRING); + fflush(stdout); + + time_t t0 = clock(); + + uint32_t n = 0; + + // Conduct opitmization + double error = 1; + while (error > ERROR) { + error = + ga_generation(population, POPULATION_N, RATE_SELECTION, RATE_MUTATON, + fitness, (void const *)target, crossover, mutation); + + n++; + } + + time_t t1 = clock(); + + printf("\nSOLUTION: %s", population[0]); + printf("\nITERATIONS: %d\nTIME: %f ms\n", n, + 1000.0 * (t1 - t0) / CLOCKS_PER_SEC); + + for (int i = 0; i < POPULATION_N; i++) { + free(population[i]); + } +} diff --git a/example/pool.c b/example/pool.c new file mode 100755 index 0000000..8b1fafd --- /dev/null +++ b/example/pool.c @@ -0,0 +1,7 @@ +#define POOL_IMPLEMENTATION +#include "../include/pool.h" + +int main() { + pool_t*p = pool_init(10, 100); + pool_print(p); +}
\ No newline at end of file diff --git a/example/pushdown.c b/example/pushdown.c new file mode 100644 index 0000000..ada8d73 --- /dev/null +++ b/example/pushdown.c @@ -0,0 +1,22 @@ +typedef double pushdown_value_t; +#define STACK_IMPLEMENTATION +#define PUSHDOWN_IMPLEMENTATION +#include "../include/pushdown.h" + +int main() { + pushdown_instruction_t instructions[] = {PUSH, COPY, MUL, END}; + + stack_t input = {}; + stack_t output = {}; + + stack_init(&input); + stack_init(&output); + + stack_push(&input, 4.0); + + pushdown_run(&output, &input, instructions); + + while (output.size) { + printf("%lf\n", stack_pop(&output)); + } +}
\ No newline at end of file diff --git a/example/stack.c b/example/stack.c new file mode 100644 index 0000000..93128f4 --- /dev/null +++ b/example/stack.c @@ -0,0 +1,20 @@ +typedef double stack_value_t; + +#define STACK_IMPLEMENTATION +#include "../include/stack.h" + +void main() { + stack_t stack = { .capacity = 10 }; + stack_init(&stack); + + for(int i = 0; i < 15; i++) { + stack_push(&stack, (stack_value_t) i); + } + + printf("%lf\n", stack_peek(&stack)); + printf("%lf\n", stack_pop(&stack)); + + for(int i = 0; i < 15; i++) { + printf("%lf\n", stack_pop(&stack)); + } +}
\ No newline at end of file |