diff --git a/C/README.md b/C/README.md new file mode 100644 index 0000000000000000000000000000000000000000..31b51eb53dfec8ea4845724ac748d401e131a2e2 --- /dev/null +++ b/C/README.md @@ -0,0 +1,91 @@ +# TP : optimisation +Mathématiques en technologies de l'information +Landrecy Lucas et Pott Dorian + +--- + +Introduction +--- + +Ce projet nous sert à mettre en pratique des notions d'optimisations vu en cours de mathématiques dans le cadre d'un programme informatique. + +Pour démarrer le projet, plusieurs éléments on été intégré. Une structure de données de type vecteur possédant des valeurs typées *double*, une interface graphique fournie par une librairie python, ainsi que des formules de maths. + +Afin d'éviter de perdre trop de temps sur une partie ou une autre, nous nous sommes répartis le travail comme suit : +- Lucas s'est chargé du code en c. +- Dorian s'est chargéx de la résolution de l'équation mathématique, de la documentation et de la relecture du code. + +Pour la suite de ce rapport, nous allons commencé par parler de la solution analytique, présenter l'équation. Puis nous présenterons certaines fonctions qui nous ont permis de réaliser ce projet avant de conclure. + +Solution Analytique +--- + +Pour pouvoir avancer dans le projet, il nous fallait d'abord résoudre une équation pour laquelle en fonction des paramètres a et b, on peut obtenir la dérivée. + +On a commencé par isolé chaque paramètre dans sa propre équation : + + +Puis on a remplacé la valeur de b par l'équation 4 dans l'équation 3 : + + +Et finalement, on a retrouvé b en fonction de a et pour les vérifications de l'équation, nous avons pris l'ensemble de points \[0,1,2,3]. + + +Avant d'en arriver là, il y eu plusieurs versions infructueuses d'équations... Approximativement une trentaine. +(Aucune feuille de papier n'a été blessée lors de ce projet. En revanche, nous ne sommes pas en mesure de garantir la même chose pour les crayons..) + + +Solution Numérique +--- + +Pour le programme, en attendant la formule, il a été utilisé une formule temporaire afin d'éviter de perdre trop de temps. + + + +Bien que nous ayons utilisé la librairie de vecteurs fournies, on y a ajouté deux fonctions : **arrayCopy** et **array_union**. +**arrayCopy** nous permettant de copier un autre vecteur et array_union implémantant l'opération booléenne d'union entre deux vecteurs. + +Lors de l'utilisation de **arrayCopy**, comme la génération de points aléatoires se fait indépendemment de cette fonction, lorsqu'on l'utilise plus tard dans le code du programme principal, on passe directement en paramètre un ensemble de définition des points. +~~~ +double_vector_t *G1_X = arrayCopy(X, 0, N); +double_vector_t *G2_X = arrayCopy(X, N, N); +double_vector_t *G3_X = arrayCopy(X, N*2, N); +~~~ + +Ainsi, chaque vecteur possède un ensemble de points de longueur **N**. Chaque vecteurs commence par la fin de l'ensemble précédant. + +Fonctions +--- + +Pour trouver les différentes droites d'optimisation, nous avons évidemment eu besoin d'implémenter plusieurs fonctions. + +**genXLine** permet d'obtenir des valeurs contenues entre \[X.0 et X.9] au lieu de nombre double pseudo entiers. Pour correspondre aux bornes choisies. (Vu qu'on a trois groupes de points, alors il faut faire la taille d'un ensemble de point * 3 pour obtenir la bonne précision) + +**genLine** est une fonction qui génère les droites de régression linéaire en fonction du couple de valeurs a et b. + +**genLinePoints** est une fonction permettant de générer le nuage de points de façon aléatoire tout en restant entre deux droites définies de façon arbitraire de pente 1.1 et 0.1. + +La structure **couple** sert principalement à garder dans une même variable les valeurs de a et b et éviter d'utiliser un tableau en valeur de retour de fonction, car les tableaux de valeurs sont un peu crontraignant et pas toujours lisible. + +**gradiant** est la fonction de dérivation de la formule analytique pour a\[i] et b\[i], présenté précédemment dans la partie de solution analytique. + +**ab1** Implémentation de la fonction 2.3 de l'énoncé. + +**linear_regression** Implémentation de la formule 2.4 de régression linéaire. + +Le fichier **gen_vector.sh** sert à simplifier le déploiement du programme pour que tout soit automatisé et prévient la génération des fichiers .o par le makefile. (donc éviter du bazar) + +Résultats +--- + +Résultat sous forme de ligne de commande : + + +Pour l'affichage graphique, nous avons utilisé la librairie python fournie par l'assistant avec laquelle on a généré un fichier **show.sh** qui nous affiche les droites telles que : + + +Conclusion +--- + +Dorian a appris à utiliser hedgedoc et mettre en pratique les éléments théoriques vus en classe, mais aussi à ne pas perdre patience lorsqu'iel ne trouvait pas la solution à l'équation. +Ce projet pourrait par la suite être réutilisé pour résoudre des équations, trouver des intersections de droites ou encore trouver les zéros d'une fonction. \ No newline at end of file diff --git a/C/main.c b/C/main.c index 81eff94910da1f3112dea20cedc98f2253847e5b..7e3a9d8cb0375b94183aed38decd50bcaed23c15 100644 --- a/C/main.c +++ b/C/main.c @@ -6,6 +6,7 @@ #include "opti.h" double N; +double s; double len; couple a; @@ -17,14 +18,7 @@ double genX(double x){ return my_random(0, 1.0); } -/** @brief - * An exemple of mathematical function - * in 1 dimension. - * - * @param x A double variable. - * @return f(x) = 2.0*sin(x) - 3.0*cos(x) - */ -double my_function(double x) +double genLinePoints(double x) { double r = my_random(-line_rand, line_rand); return line_a*x+line_b+r; @@ -39,19 +33,19 @@ double genXline(double x){ } int main() -{ +{ N = 100.0; len = N*3; - - /* Intializes my_random number generator */ - time_t t; + + // Initialise the seed to use random numbers + time_t t; srand((unsigned) time(&t)); - + // Create a vector X = [0,1,2...99] double_vector_t *X1 = iota((uint32_t)len); double_vector_t *X2 = apply_function(X1, genXline); double_vector_t *X = apply_function(X1, genX); - + double_vector_t *G1_X = arrayCopy(X, 0, N); double_vector_t *G2_X = arrayCopy(X, N, N); double_vector_t *G3_X = arrayCopy(X, N*2, N); @@ -60,9 +54,9 @@ int main() double_vector_t *G1_G3_X = vector_union(G1_X, G3_X, N, N); double_vector_t *G2_G3_X = vector_union(G2_X, G3_X, N, N); - // Create a vector Y = my_function(x) - double_vector_t *Y = apply_function(X, my_function); - + // Create a vector Y = genLinePoints(x) + double_vector_t *Y = apply_function(X, genLinePoints); + double_vector_t *G1_Y = arrayCopy(Y, 0, N); double_vector_t *G2_Y = arrayCopy(Y, N, N); double_vector_t *G3_Y = arrayCopy(Y, N*2, N); @@ -70,12 +64,12 @@ int main() double_vector_t *G1_G2_Y = vector_union(G1_Y, G2_Y, N, N); double_vector_t *G1_G3_Y = vector_union(G1_Y, G3_Y, N, N); double_vector_t *G2_G3_Y = vector_union(G2_Y, G3_Y, N, N); - - couple deriver_E = deriver(X, Y); - - couple G1_G2 = calcule_AB(0.001, G1_G2_X, G1_G2_Y); - couple G1_G3 = calcule_AB(0.001, G1_G3_X, G1_G3_Y); - couple G2_G3 = calcule_AB(0.001, G2_G3_X, G2_G3_Y); + + couple derivative_E = derivative(X, Y); + + couple G1_G2 = linear_regression(0.001, G1_G2_X, G1_G2_Y); + couple G1_G3 = linear_regression(0.001, G1_G3_X, G1_G3_Y); + couple G2_G3 = linear_regression(0.001, G2_G3_X, G2_G3_Y); a = G1_G2; double_vector_t *Y_line_G1_G2 = apply_function(X2, genLine); @@ -84,7 +78,7 @@ int main() a = G2_G3; double_vector_t *Y_line_G2_G3 = apply_function(X2, genLine); - + // Export our vectors into files export_vector("../X.vec", X2); export_vector("../G1_G2_Y.vec", Y_line_G1_G2); @@ -101,19 +95,19 @@ int main() export_vector("../G3_Y.vec", G3_Y); // Print - printf("The line follow by points\n"); + printf("Line of points\n"); printf(" A: %f\n B: %f\n\n", line_a, line_b); - printf("The théorique line\n"); - printf(" A: %f\n B: %f\n\n", deriver_E.a, deriver_E.b); + printf("Theoretical line\n"); + printf(" A: %f\n B: %f\n\n", derivative_E.a, derivative_E.b); - printf("The line by regrestion\n"); - printf(" G1_G2 et tester sur G3\n"); - printf(" A: %f\n B: %f\n Erreur quadratique: %f\n", G1_G2.a, G1_G2.b, erreur_quad(G1_G2 ,G1_G2_X, G1_G2_Y)); - printf(" G1_G3 et tester sur G2\n"); - printf(" A: %f\n B: %f\n Erreur quadratique: %f\n", G1_G3.a, G1_G3.b, erreur_quad(G1_G3 ,G1_G3_X, G1_G3_Y)); - printf(" G2_G3 et tester sur G1\n"); - printf(" A: %f\n B: %f\n Erreur quadratique: %f\n", G2_G3.a, G2_G3.b, erreur_quad(G2_G3 ,G2_G3_X, G2_G3_Y)); + printf("Linear regression\n"); + printf(" G1_G2 and tested on G3\n"); + printf(" A: %f\n B: %f\n mean-squared error: %f\n", G1_G2.a, G1_G2.b, erreur_quad(G1_G2 ,G1_G2_X, G1_G2_Y)); + printf(" G1_G3 and tested on G2\n"); + printf(" A: %f\n B: %f\n mean-squared error: %f\n", G1_G3.a, G1_G3.b, erreur_quad(G1_G3 ,G1_G3_X, G1_G3_Y)); + printf(" G2_G3 and tested on G1\n"); + printf(" A: %f\n B: %f\n mean-squared error: %f\n", G2_G3.a, G2_G3.b, erreur_quad(G2_G3 ,G2_G3_X, G2_G3_Y)); // Free our vectors destroy_vector(&Y); @@ -141,5 +135,5 @@ int main() destroy_vector(&G1_G3_Y); destroy_vector(&G2_G3_Y); - printf("Vector generation succes\n"); -} \ No newline at end of file + printf("Successful vector generation\n"); +} diff --git a/C/opti.c b/C/opti.c index fb8f2f3178519f63ef7d3fc3bb64f60d7b08ffd2..c01b78b5ad6a8ce3d25902ef68e2aaacd6f431ca 100644 --- a/C/opti.c +++ b/C/opti.c @@ -11,37 +11,40 @@ double my_random(double min, double max){ couple gradiant(couple point, double_vector_t* X, double_vector_t* Y){ - double somme_X = 0; - double somme_X2 = 0; - double somme_YX = 0; - double somme_Y = 0; + double sum_x = 0; + double sum_x2 = 0; + double sum_yx = 0; + double sum_y = 0; couple a; for (int i = 0; i < (int)X->N;i++){ double x = X->components[i]; double y = Y->components[i]; - somme_X += x; - somme_X2 += x*x; - somme_YX += x*y; - somme_Y += y; + sum_x += x; + sum_x2 += x*x; + sum_yx += x*y; + sum_y += y; } - + int N = X->N; - a.a = point.a * somme_X2 + point.b * somme_X - somme_YX; - a.b = point.a * somme_X + N * point.b - somme_Y; + a.a = point.a * sum_x2 + point.b * sum_x - sum_yx; + a.b = point.a * sum_x + N * point.b - sum_y; return a; } -couple ab1(couple current, double lambda, couple deriver_E){ +/* + * Implementation of 2.3 +*/ +couple ab1(couple current, double lambda, couple derivative_E){ couple a1; - a1.a = current.a - (lambda * deriver_E.a); - a1.b = current.b - (lambda * deriver_E.b); + a1.a = current.a - (lambda * derivative_E.a); + a1.b = current.b - (lambda * derivative_E.b); return a1; } -couple calcule_AB(double epsilone, double_vector_t* X, double_vector_t* Y){ +couple linear_regression(double epsilone, double_vector_t* X, double_vector_t* Y){ couple current; couple next; - + // init a et b 0 my_random double r = my_random(0, 1); next.a = r; @@ -52,38 +55,38 @@ couple calcule_AB(double epsilone, double_vector_t* X, double_vector_t* Y){ r = my_random(0,0.002); // r devient lambda while (norme >= epsilone){ current = next; - + // a et b i+1 next = ab1(current, r, gradiant(current, X, Y)); - + // calcul norme double a = next.a - current.a; double b = next.b - current.b; norme = sqrt(((a*a) + (b*b))); // printf("A: %f, B: %f; Norme: %f\n", current.a, current.b, norme); } - + return current; -} +} -couple deriver(double_vector_t* X, double_vector_t* Y){ - double somme_X = 0; - double somme_X2 = 0; - double somme_YX = 0; - double somme_Y = 0; +couple derivative(double_vector_t* X, double_vector_t* Y){ + double sum_x = 0; + double sum_x2 = 0; + double sum_yx = 0; + double sum_y = 0; couple a; for (int i = 0; i < (int)X->N;i++){ double x = X->components[i]; double y = Y->components[i]; - somme_X += x; - somme_X2 += x*x; - somme_YX += x*y; - somme_Y += y; + sum_x += x; + sum_x2 += x*x; + sum_yx += x*y; + sum_y += y; } - + int N = X->N; - a.b = (somme_Y * somme_X2 - somme_YX* somme_X)/(N * somme_X2 - somme_X * somme_X); - a.a = (somme_Y - N * a.b)/ somme_X; + a.b = (sum_y * sum_x2 - sum_yx* sum_x)/(N * sum_x2 - sum_x * sum_x); + a.a = (sum_y - N * a.b)/ sum_x; return a; } @@ -92,4 +95,4 @@ double erreur_quad(couple a, double_vector_t *X, double_vector_t *Y){ for (int i = 0; i < X->N; i++){ somme += pow((a.a * X->components[i] + a.b - Y->components[i]), 2); } -} \ No newline at end of file +} diff --git a/C/opti.h b/C/opti.h index ece6ccbe70aaf57c18d1a2cf4f1fdf5dcfb83663..7db35b8b81abf374a3175adb3ac3ed1e43046007 100644 --- a/C/opti.h +++ b/C/opti.h @@ -14,9 +14,9 @@ couple gradiant(couple point, double_vector_t* X, double_vector_t* Y); couple ab1(couple current, double lambda, couple deriver_E); -couple calcule_AB(double epsilone, double_vector_t* X, double_vector_t* Y); +couple linear_regression(double epsilone, double_vector_t* X, double_vector_t* Y); -couple deriver(double_vector_t* X, double_vector_t* Y); +couple derivative(double_vector_t* X, double_vector_t* Y); double erreur_quad(couple a, double_vector_t *X, double_vector_t *Y); -#endif \ No newline at end of file +#endif