summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2022-07-25 18:23:02 +0300
committerkartofen <mladenovnasko0@gmail.com>2022-07-25 18:23:02 +0300
commit955b95bc04d68bf3cb68d0ab2d32ea9b6a287394 (patch)
treea8c8e4ef491072af810007512f5192888c327306
big bang
-rwxr-xr-xbuild.sh5
-rwxr-xr-xmainbin0 -> 21608 bytes
-rw-r--r--main.c231
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
diff --git a/main b/main
new file mode 100755
index 0000000..9d48401
--- /dev/null
+++ b/main
Binary files differ
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..7a1f62e
--- /dev/null
+++ b/main.c
@@ -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];
+ }
+}