diff --git a/graph.py b/graph.py index cafe73cc418764c315b4e9576ab2fcd1d1c9dd02..1b312b3d4b9dd6df23ad72b0d07473b886f8617c 100644 --- a/graph.py +++ b/graph.py @@ -2,29 +2,34 @@ import sys import matplotlib.pyplot as plt import numpy as np -x = [] -y = [] -a = 0 -b = 0 - -with open('points.txt') as f: - lines = f.readlines() - - z = lines[0].split(",") - a = float(z[0]) - b = float(z[1]) - - for line in lines[1:]: +x = [[], [], []] +y = [[], [], []] +a = [] +b = [] + +fig, axes = plt.subplots(3, 1, figsize=(18, 15)) +plt.get_current_fig_manager().set_window_title('Graphics') + +for i in range(3): + with open('G' + str(i+1) + '.txt') as f: + for line in f.readlines(): + z = line.split(",") + x[i].append(float(z[0])) + y[i].append(float(z[1])) + +with open('ab.txt') as f: + for line in f.readlines(): z = line.split(",") - x.append(float(z[0])) - y.append(float(z[1])) + a.append(float(z[0])) + b.append(float(z[1])) -fig, ax = plt.subplots() +titles = [(2, r'$G1 \bigcup G2 \longmapsto G3$'), (0, r'$G2 \bigcup G3 \longmapsto G1$'), (1, r'$G1 \bigcup G3 \longmapsto G2$')] # 1st point (0, b) and 2nd point (b, a+b) -xLine, yLine = [0, 1], [b, a+b] -plt.plot(xLine, yLine, marker = 'o') - -ax.plot(x, y, 'o', color='tab:brown') +for i in range(3): + axes[i].set_title(titles[i][1]) + axes[i].axline([0, b[i]], [1, a[i] + b[i]]) + axes[i].plot(x[titles[i][0]], y[titles[i][0]], '.', color='tab:green') + axes[i].grid(True) plt.show() \ No newline at end of file diff --git a/main.c b/main.c index 03adc33d14f20bd06b1033007723c6313502f755..80df2b973f58beb0a0eede4c27818bb1c5a0b3f2 100644 --- a/main.c +++ b/main.c @@ -2,18 +2,21 @@ #include <stdlib.h> #include <math.h> #include <time.h> -//#include <system.h> #include "vec.h" #include "opti_num.h" +#define NB_G 3 + double randNum(); -void write_to_file(vec ab, vec *points, int N, char *filename); +int *rand_order_indexes(int N); +vec **cut_table(int *rand_indexes, int N, vec *points); +void write_to_file(vec *points, int N, char *filename); int main() { srand(time(0)); - int N = 100; + int N = NB_G * 200; vec *points = malloc(sizeof(vec) * N); double c = randNum(), d = randNum(); @@ -23,26 +26,57 @@ int main() { vec tmp; tmp.x = randNum(); - r = randNum() / 100.0; + r = randNum() / 10.0; tmp.y = c * tmp.x + d + r; points[i] = tmp; } - vec ab; - ab.x = rand() % 10; - ab.y = rand() % 10; + int *rnd_indexes = rand_order_indexes(N); + + vec **groups = cut_table(rnd_indexes, N, points); - PrintVec(ab); + vec *ab = malloc(sizeof(vec) * NB_G); + for (int i = 0; i < NB_G; i++) { + ab[i].x = randNum(); + ab[i].y = randNum(); - minimiser(points, N, 0.001, &ab); - printf("%g, %g\n", c, d); + int other = i + 1, to_test = i - 1; + if (other >= NB_G) { + other = 0; + } else if (to_test < 0) { + to_test = NB_G - 1; + } - write_to_file(ab, points, N, "points.txt"); + minimiser(groups[i], groups[other], N / NB_G, 1e-6, &ab[i]); + printf("model: a: %g, b: %g\n", ab[i].x, ab[i].y); + + vec test_ab; + calc_ab(groups[to_test], NB_G, &test_ab); + printf("test: a: %g, b: %g\n\n", test_ab.x, test_ab.y); + } + + //minimiser(points, N, 0.001, &ab); + printf("c: %g, d: %g\n", c, d); + + for (int i = 0; i < NB_G; i++) { + char fname[11]; + sprintf(fname, "G%d.txt", i + 1); + write_to_file(groups[i], N / NB_G, fname); + } + + write_to_file(ab, NB_G, "ab.txt"); system("python3 graph.py"); + free(ab); free(points); + free(rnd_indexes); + + for (int i = 0; i < NB_G; i++) { + free(groups[i]); + } + free(groups); return EXIT_SUCCESS; } @@ -51,15 +85,43 @@ double randNum() { return rand() / (double)RAND_MAX; } -void write_to_file(vec ab, vec *points, int N, char *filename) { +vec **cut_table(int *rand_indexes, int N, vec *points) { + vec **groups = malloc(sizeof(vec*) * NB_G); + + int frac = N / NB_G; + + for (int i = 0; i < NB_G; i++) { + groups[i] = malloc(sizeof(vec) * frac); + } + + for (int i = 0; i < N; i++) { + groups[i / frac][i % frac] = points[rand_indexes[i]]; + } + + return groups; +} + +int *rand_order_indexes(int N) { + int *indexes = calloc(0, sizeof(int) * N); + + for (int i = 1; i < N; i++) { + int rnd_index = rand() % N; + while (indexes[rnd_index] != 0) { + rnd_index = rand() % N; + } + indexes[rnd_index] = i; + } + + return indexes; +} + +void write_to_file(vec *points, int N, char *filename) { FILE *fp = fopen(filename, "w"); if (fp == NULL) { return; } - fprintf(fp, "%f,%f\n", ab.x, ab.y); - for (int i = 0; i < N; i++) { fprintf(fp, "%f,%f\n", points[i].x, points[i].y); } diff --git a/opti_num.c b/opti_num.c index 91ea76d98e3c8070dc17816165feb79f82c72be3..a263a32761ad92cc4e54f8e6c9b895a0214ef3ba 100644 --- a/opti_num.c +++ b/opti_num.c @@ -3,31 +3,48 @@ #include <math.h> #include <stdio.h> -void minimiser(vec *vecs, int N, double lambda, vec *ab) { +void minimiser(vec *vecs1, vec *vecs2, int N, double lambda, vec *ab) { double sum_x = 0, sum_xx = 0, sum_xy = 0, sum_y = 0; - for (int i = 0; i < N; i++) { - sum_x += vecs[i].x; - sum_xx += vecs[i].x * vecs[i].x; - sum_xy += vecs[i].x * vecs[i].y; - sum_y += vecs[i].y; + for (int i = 0; i < 2 * N; i++) { + if (i < N) { + sum_x += vecs1[i].x; + sum_xx += vecs1[i].x * vecs1[i].x; + sum_xy += vecs1[i].x * vecs1[i].y; + sum_y += vecs1[i].y; + } else { + int tmp_i = i % N; + + sum_x += vecs2[tmp_i].x; + sum_xx += vecs2[tmp_i].x * vecs2[tmp_i].x; + sum_xy += vecs2[tmp_i].x * vecs2[tmp_i].y; + sum_y += vecs2[tmp_i].y; + } } - + vec next_ab = *ab, err_quad; do { *ab = next_ab; err_quad.x = ab->x * sum_xx + ab->y * sum_x - sum_xy; - err_quad.y = ab->x * sum_x + N * ab->y - sum_y; + err_quad.y = ab->x * sum_x + (2 * N) * ab->y - sum_y; next_ab = Subtract(*ab, Multiply(err_quad, lambda)); - printf("%g, %g\n", next_ab.x, next_ab.y); } while (GetNorme(Subtract(next_ab, *ab)) > EPSILON); } -void calc_ab(double sum_x, double sum_xx, double sum_xy, double sum_y, int N, vec *ab) { +void calc_ab(vec *points, int N, vec *ab) { + double sum_x = 0, sum_xx = 0, sum_xy = 0, sum_y = 0; + + for (int i = 0; i < N; i++) { + sum_x += points[i].x; + sum_xx += points[i].x * points[i].x; + sum_xy += points[i].x * points[i].y; + sum_y += points[i].y; + } + ab->x = (sum_y * sum_x - N * sum_xy) / (sum_x * sum_x - N * sum_xx); ab->y = (sum_y - ab->x * sum_x) / N; diff --git a/opti_num.h b/opti_num.h index 29826ff195861ac3be9f10bc105b635614d4aa27..2524e6b99afe0c29c270dbafc22bea0490fa83c5 100644 --- a/opti_num.h +++ b/opti_num.h @@ -4,7 +4,7 @@ #define _OPTI_NUM_H_ #define EPSILON 1e-6 -void minimiser(vec *vecs, int N, double lambda, vec *ab); -void calc_ab(double sum_x, double sum_xx, double sum_xy, double sum_y, int N, vec *ab); +void minimiser(vec *vecs1, vec *vecs2, int N, double lambda, vec *ab); +void calc_ab(vec *points, int N, vec *ab); #endif