diff options
author | kartofen <mladenovnasko0@gmail.com> | 2022-07-25 18:23:02 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2022-07-25 18:23:02 +0300 |
commit | 955b95bc04d68bf3cb68d0ab2d32ea9b6a287394 (patch) | |
tree | a8c8e4ef491072af810007512f5192888c327306 |
big bang
-rwxr-xr-x | build.sh | 5 | ||||
-rwxr-xr-x | main | bin | 0 -> 21608 bytes | |||
-rw-r--r-- | main.c | 231 |
3 files changed, 236 insertions, 0 deletions
diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..03692a1 --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +set -xe + +cc -Wall -Wextra -o main main.c -lm Binary files differ@@ -0,0 +1,231 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <assert.h> +#include <unistd.h> + +// #define DEBUG +#define CHECK_SEED 69 +#define BIAS 20 +#define PASSES 999999 + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +#define WIDTH 60 +#define HEIGHT 60 + +float input[HEIGHT][WIDTH]; +float weights[HEIGHT][WIDTH]; + +int rand_range(int low, int high) +{ + assert(low < high); + return rand() % (high - low) + low; +} + +void print_weight(); + +void fill_rect(int x0, int y0, int x1, int x2, float val); +void fill_circle(int cx, int cy, int r, float val); + +void gen_rect(); +void gen_circle(); +void gen_shape(int opt) +{ + if(opt == 0) gen_rect(); + else if(opt == 1) gen_circle(); + else assert(0); +} + +void sub_weights(); +void add_weights(); +void manip_weights(int opt) +{ + if(opt == 0) sub_weights(); + else if(opt == 1) add_weights(); + else assert(0); +} + +float get_out() +{ + float out_node = 0.0f; + + for(int i = 0; i < HEIGHT; i++) + for(int j = 0; j < WIDTH; j++) + { + out_node += (weights[i][j] * input[i][j]); + } + + return out_node; +} + +void train() +{ + memset(input, 0, HEIGHT*WIDTH*4); + int opt = rand_range(0, 2); + + gen_shape(opt); + float out = get_out(); + + if((out > BIAS) != opt) + manip_weights(opt); + +#ifdef DEBUG + printf("OUT %f", out); + print_all(); +#endif +} + +int check() +{ + memset(input, 0, HEIGHT*WIDTH*4); + int opt = rand_range(0, 2); + + gen_shape(opt); + float out = get_out(); + + if((out > BIAS) != opt) + return 0; + + return 1; + +} + +int main() +{ + memset(input, 0, HEIGHT*WIDTH*4); + memset(weights, 0, HEIGHT*WIDTH*4); + + // ----- Train -----// + + time_t cur_time = time(0); + + puts("[INFO] Training model"); + srand(time(0)); + + for(size_t i = 0; i < PASSES; i++) { + train(); +#ifdef DEBUG + sleep(5); +#endif + } + + puts("[INFO] Training completed"); + printf("[INFO] Operation took %ld seconds\n", time(0) - cur_time); + + // ----- Check ----- // + + cur_time = time(0); + + puts("[INFO] Checking model success rate"); + srand(CHECK_SEED); + + int correct = 0; + for(size_t i = 0; i < PASSES; i++) { + correct += check(); + } + + printf("[INFO] Model success rate is %f%%\n", ((float)correct/PASSES)*100); + printf("[INFO] Operation took %ld seconds\n", time(0) - cur_time); + + print_weight(); + + return 0; +} + +void print_weight() +{ + puts("------------------------------------------------------------"); + for(int i = 0; i < HEIGHT; i++) + { + for(int j = 0; j < WIDTH; j++) + { + if(weights[i][j] == 0.0f) + printf("."); + else if(weights[i][j] < 0.0f) + printf("@"); + else + printf("#"); + } + puts(""); + } + puts("------------------------------------------------------------"); +} + +void fill_rect(int x0, int y0, int x1, int y1, float val) +{ + assert(x0 >= 0); assert(x1 >= 0); + assert(x0 < WIDTH); assert(x1 < WIDTH); + + assert(y0 >= 0); assert(y1 >= 0); + assert(y0 < HEIGHT); assert(y1 < HEIGHT); + + assert(x0 <= x1); assert(y0 <= y1); + + for(int y = y0; y <= y1; y++) + { + for(int x = x0; x <= x1; x++) + { + input[y][x] = val; + } + } +} + +void fill_circle(int cx, int cy, int r, float val) +{ + assert(r > 0); + int x0 = cx - r; assert(x0 >= 0); assert(x0 < WIDTH); + int y0 = cy - r; assert(y0 >= 0); assert(y0 < HEIGHT); + int x1 = cx + r; assert(x1 >= 0); assert(x1 < WIDTH); + int y1 = cy + r; assert(y1 >= 0); assert(y1 < HEIGHT); + + for (int y = y0; y <= y1; ++y) + for (int x = x0; x <= x1; ++x) + { + int dx = x - cx; + int dy = y - cy; + if (dx*dx + dy*dy <= r*r) + input[y][x] = val; + } +} + +void gen_rect() +{ + int x0 = rand_range(0, WIDTH); + int y0 = rand_range(0, HEIGHT); + int x1 = rand_range(x0, WIDTH); + int y1 = rand_range(y0, HEIGHT); + + fill_rect(x0, y0, x1, y1, 1.0f); +} + +void gen_circle() +{ + int cx = rand_range(2, WIDTH-2); + int cy = rand_range(2, HEIGHT-2); + int r = MIN( + MIN(cx, WIDTH - cx), + MIN(cy, HEIGHT - cy)); + r = rand_range(1, r); + + fill_circle(cx, cy, r, 1.0f); +} + +void sub_weights() +{ + for(int i = 0; i < HEIGHT; i++) + for(int j = 0; j < WIDTH; j++) + { + weights[i][j] -= input[i][j]; + } +} + +void add_weights() +{ + for(int i = 0; i < HEIGHT; i++) + for(int j = 0; j < WIDTH; j++) + { + weights[i][j] += input[i][j]; + } +} |