From e9af3bea060e7f1f815b207ffc7c3a25933db126 Mon Sep 17 00:00:00 2001
From: "paul.albuquer" <paul.albuquerque@hesge.ch>
Date: Mon, 18 Oct 2021 16:00:11 +0200
Subject: [PATCH] added source code fractions in structures, matrix in
 tableaux_2d

---
 source_codes/structures/fractions.c      | 166 ++++++++++++++++++++
 source_codes/structures/fractions_part.c | 172 +++++++++++++++++++++
 source_codes/tableaux_2d/calcul_matrix.c |  16 ++
 source_codes/tableaux_2d/matrix.c        | 187 +++++++++++++++++++++++
 source_codes/tableaux_2d/matrix.h        |  19 +++
 5 files changed, 560 insertions(+)
 create mode 100644 source_codes/structures/fractions.c
 create mode 100644 source_codes/structures/fractions_part.c
 create mode 100644 source_codes/tableaux_2d/calcul_matrix.c
 create mode 100644 source_codes/tableaux_2d/matrix.c
 create mode 100644 source_codes/tableaux_2d/matrix.h

diff --git a/source_codes/structures/fractions.c b/source_codes/structures/fractions.c
new file mode 100644
index 0000000..75f36a5
--- /dev/null
+++ b/source_codes/structures/fractions.c
@@ -0,0 +1,166 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+typedef struct _fraction {
+   int num;
+   int den;
+} fraction;
+
+void print(fraction frac) {
+   printf(" %d/%d ",frac.num,frac.den); 
+}
+
+int pgcd(int n,int m) {
+   assert(n > 0 && m > 0);
+   int tmp_n = n,tmp_m = m;
+   while (tmp_n%tmp_m > 0) {
+      int tmp = tmp_n;
+      tmp_n = tmp_m;
+      tmp_m = tmp%tmp_m;
+   }
+   return tmp_m;
+}
+
+void reduire(fraction* frac) {
+   if (0 == frac->num) { 
+      frac->den = 1;
+   } else {
+      int gcd = pgcd(abs(frac->num),frac->den);
+      frac->num /= gcd;
+      frac->den /= gcd;
+   }
+}
+
+fraction fraction_build(int num,int den) {
+   assert(den != 0);
+   int sign = den/abs(den);
+   fraction res = {sign*num,sign*den};
+   reduire(&res);
+   return res;
+}
+
+fraction add(fraction frac1,fraction frac2) {
+   return fraction_build(frac1.num*frac2.den+frac1.den*frac2.num,frac1.den*frac2.den);
+}
+
+fraction add1(int n,fraction frac) {
+   return add(fraction_build(n,1),frac);
+}
+
+fraction add2(fraction frac,int n,) {
+   return add1(n,frac);
+}
+
+void add_inplace(fraction* frac1,fraction frac2) {
+   *frac1 = add(*frac1,frac2);
+}
+
+fraction sub(fraction frac1,fraction frac2) {
+   return add(frac1,fraction_build(-frac2.num,frac2.den));
+}
+
+fraction sub1(int n,fraction frac) {
+   return sub(fraction_build(n,1),frac);
+}
+
+fraction sub2(fraction frac,int n,) {
+   return add(frac,-n);
+}
+
+void sub_inplace(fraction* frac1,fraction frac2) {
+   *frac1 = sub(*frac1,frac2);
+}
+
+fraction mult(fraction frac1,fraction frac2) {
+   return fraction_build(frac1.num*frac2.num,frac1.den*frac2.den);;
+}
+
+fraction mult1(int n,fraction frac) {
+   return mult(frac,fraction_build(n,1));
+}
+
+fraction mult2(fraction frac,int n) {
+   return mult1(n,frac);
+}
+
+void mult_inplace(fraction* frac1,fraction frac2) {
+   *frac1 = mult(*frac1,frac2);
+}
+
+fraction divide(fraction frac1,fraction frac2) {
+   assert(frac2.num != 0);
+   int sign = frac2.num/abs(frac2.num);
+   return mult(frac1,fraction_build(sign*frac2.den,abs(frac2.num)));
+}
+
+fraction div1(int n,fraction frac) {
+   return divide(fraction_build(n,1),frac);
+}
+
+fraction div2(fraction frac,int n) {
+   return divide(frac,fraction_build(n,1));
+}
+
+void divide_inplace(fraction* frac1,fraction frac2) {
+   *frac1 = divide(*frac1,frac2);
+}
+
+fraction puiss(fraction frac,int n) {
+   fraction prod = fraction_build(1,1); 
+   for (int i=1;i<=abs(n);i++) {
+      prod = mult(prod,frac);
+   }
+   if (n < 0) {
+      prod = div1(1,prod);
+   }
+   return prod;
+}
+
+float reel(fraction frac) {
+   return (float)frac.num/(float)frac.den;
+}
+
+fraction compute(fraction f1,fraction f2,char op) {     
+   fraction res;
+   switch(op) {
+      case 'x': res = mult(f1,f2);      break;     
+      case '+': res = add(f1,f2);       break;       
+      case '/': res = divide(f1,f2);    break;      
+      case '-': res = sub(f1,f2);       break;
+      case 'p': res = puiss(f1,f2.num); break;
+      default : printf("Pas implémenté\n");
+   }
+   return res;
+}
+  
+void main(int argc,char** argv) {
+   fraction f1,f2;
+   switch(argc) {
+      case 3:
+         printf("%d\n",pgcd(atoi(argv[1]),atoi(argv[2])));
+         break;
+      case 5:
+         // teste si le 2ème argument est un dénominateur (donc > 0)
+         if ('1' <= argv[2][0] && argv[2][0] <= '9') {
+            f1 = fraction_build(atoi(argv[1]),atoi(argv[2]));
+            f2 = fraction_build(atoi(argv[4]),1);
+            print(compute(f1,f2,argv[3][0]));
+         } else {
+            f1 = fraction_build(atoi(argv[1]),1);
+            f2 = fraction_build(atoi(argv[3]),atoi(argv[4]));
+            print(compute(f1,f2,argv[2][0]));
+         }
+         break;
+      case 6:
+         f1 = fraction_build(atoi(argv[1]),atoi(argv[2]));
+         print(f1); printf("\n");
+         f2 = fraction_build(atoi(argv[4]),atoi(argv[5]));
+         print(f2); printf("\n");
+         print(compute(f1,f2,argv[3][0]));
+         break;
+      default: printf("Pas implémenté\n");
+   }
+   printf("\n");
+}
+
diff --git a/source_codes/structures/fractions_part.c b/source_codes/structures/fractions_part.c
new file mode 100644
index 0000000..8c0095a
--- /dev/null
+++ b/source_codes/structures/fractions_part.c
@@ -0,0 +1,172 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+typedef struct _fraction {
+   int num;
+   int den;
+} fraction;
+
+void print(fraction frac) {
+   printf(" %d/%d ",frac.num,frac.den); 
+}
+
+int pgcd(int n,int m) {
+   assert(n > 0 && m > 0);
+   int tmp_n = n,tmp_m = m;
+   while (tmp_n%tmp_m > 0) {
+      int tmp = tmp_n;
+      tmp_n = tmp_m;
+      tmp_m = tmp%tmp_m;
+   }
+   return tmp_m;
+}
+
+void reduire(fraction* frac) {
+   if (0 == frac->num) { 
+      frac->den = 1;
+   } else {
+      int gcd = pgcd(abs(frac->num),frac->den);
+      frac->num /= gcd;
+      frac->den /= gcd;
+   }
+}
+
+fraction fraction_build(int num,int den) {
+   assert(den != 0);
+   int sign = den/abs(den);
+   fraction res = {sign*num,sign*den};
+   reduire(&res);
+   return res;
+}
+
+fraction add(fraction frac1,fraction frac2) {
+   return fraction_build(frac1.num*frac2.den+frac1.den*frac2.num,frac1.den*frac2.den);
+}
+
+fraction add1(int n,fraction frac) {
+   return add(fraction_build(n,1),frac);
+}
+
+fraction add2(fraction frac,int n,) {
+   return add1(n,frac);
+}
+
+void add_inplace(fraction* frac1,fraction frac2) {
+   *frac1 = add(*frac1,frac2);
+}
+
+fraction sub(fraction frac1,fraction frac2) {
+   return add(frac1,fraction_build(-frac2.num,frac2.den));
+}
+
+fraction sub1(int n,fraction frac) {
+   //à compléter
+   return fraction_build(0,1);
+}
+
+fraction sub2(fraction frac,int n,) {
+   //à compléter
+   return fraction_build(0,1);
+}
+
+void sub_inplace(fraction* frac1,fraction frac2) {
+   //à compléter
+}
+
+fraction mult(fraction frac1,fraction frac2) {
+   return fraction_build(frac1.num*frac2.num,frac1.den*frac2.den);
+}
+
+fraction mult1(int n,fraction frac) {
+   //à compléter
+   return fraction_build(0,1);
+}
+
+fraction mult2(fraction frac,int n) {
+   //à compléter
+   return fraction_build(0,1);
+}
+
+void mult_inplace(fraction* frac1,fraction frac2) {
+   //à compléter
+}
+
+fraction divide(fraction frac1,fraction frac2) {
+   assert(frac2.num != 0);
+   int sign = frac2.num/abs(frac2.num);
+   return mult(frac1,fraction_build(sign*frac2.den,abs(frac2.num)));
+}
+
+fraction div1(int n,fraction frac) {
+   //à compléter
+   return fraction_build(0,1);
+}
+
+fraction div2(fraction frac,int n) {
+   //à compléter
+   return fraction_build(0,1);
+}
+
+void divide_inplace(fraction* frac1,fraction frac2) {
+   //à compléter
+}
+
+fraction puiss(fraction frac,int n) {
+   fraction prod = fraction_build(1,1); 
+   for (int i=1;i<=abs(n);i++) {
+      prod = mult(prod,frac);
+   }
+   if (n < 0) {
+      prod = div1(1,prod);
+   }
+   return prod;
+}
+
+float reel(fraction frac) {
+   return (float)frac.num/(float)frac.den;
+}
+
+fraction compute(fraction f1,fraction f2,char op) {     
+   fraction res;
+   switch(op) {
+      case 'x': res = mult(f1,f2);      break;     
+      case '+': res = add(f1,f2);       break;       
+      case '/': res = divide(f1,f2);    break;      
+      case '-': res = sub(f1,f2);       break;
+      case 'p': res = puiss(f1,f2.num); break;
+      default : printf("Pas implémenté\n");
+   }
+   return res;
+}
+  
+void main(int argc,char** argv) {
+   fraction f1,f2;
+   switch(argc) {
+      case 3:
+         printf("%d\n",pgcd(atoi(argv[1]),atoi(argv[2])));
+         break;
+      case 5:
+         // teste si le 2ème argument est un dénominateur (donc > 0)
+         if ('1' <= argv[2][0] && argv[2][0] <= '9') {
+            f1 = fraction_build(atoi(argv[1]),atoi(argv[2]));
+            f2 = fraction_build(atoi(argv[4]),1);
+            print(compute(f1,f2,argv[3][0]));
+         } else {
+            f1 = fraction_build(atoi(argv[1]),1);
+            f2 = fraction_build(atoi(argv[3]),atoi(argv[4]));
+            print(compute(f1,f2,argv[2][0]));
+         }
+         break;
+      case 6:
+         f1 = fraction_build(atoi(argv[1]),atoi(argv[2]));
+         print(f1); printf("\n");
+         f2 = fraction_build(atoi(argv[4]),atoi(argv[5]));
+         print(f2); printf("\n");
+         print(compute(f1,f2,argv[3][0]));
+         break;
+      default: printf("Pas implémenté\n");
+   }
+   printf("\n");
+}
+
diff --git a/source_codes/tableaux_2d/calcul_matrix.c b/source_codes/tableaux_2d/calcul_matrix.c
new file mode 100644
index 0000000..4530051
--- /dev/null
+++ b/source_codes/tableaux_2d/calcul_matrix.c
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "matrix.h"
+
+int main(int argc, char** argv) {
+   m_double *matA,*matB,*res;
+   matA = from_file(argv[2]);
+   if (4 == argc) matB = from_file(argv[3]);
+   if (0 == strcmp(argv[1],"add")) res = add(matA,matB);
+   else if (0 == strcmp(argv[1],"mult")) res = mult(matA,matB);
+   else if (0 == strcmp(argv[1],"transpose")) res = transpose(matA);
+   print(res,NULL);
+   return 0;
+}
diff --git a/source_codes/tableaux_2d/matrix.c b/source_codes/tableaux_2d/matrix.c
new file mode 100644
index 0000000..e93e8d1
--- /dev/null
+++ b/source_codes/tableaux_2d/matrix.c
@@ -0,0 +1,187 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "matrix.h"
+
+m_double* new_matrix(int li,int co) {
+   m_double* mat = NULL;
+   if (li > 0 && co > 0) {
+      mat =(m_double*) malloc(sizeof(m_double));
+      mat->li = li; mat->co = co;
+      double* data = (double*) malloc(li*co*sizeof(double));
+      mat->content = (double**) malloc(li*sizeof(double*));
+      for (int i=0;i<li;i++) mat->content[i] = data+i*co;
+   }
+   return mat;
+}
+
+void resize_line(m_double* mat,int li) {
+   if (NULL != mat && li > 0) {
+      mat->content = realloc(mat->content,li*sizeof(double*));
+      mat->content[0] = realloc(mat->content[0],li*(mat->co)*sizeof(double));
+      for (int i=0;i<li;i++) { 
+         mat->content[i] = mat->content[0]+i*(mat->co);
+         for (int j=0;j<mat->co;j++) {
+            if (i >= mat->li) mat->content[i][j] = 0.0;
+         }
+      }               
+      mat->li = li;
+   }
+}
+
+void resize_column(m_double* mat,int co) {
+   if (NULL != mat && co > 0) {
+      int sign = (mat->co-co)/abs(mat->co-co);
+      int first = (1+sign)/2 + ((mat->li)-1)*(1-sign)/2;
+      int last  = (1-sign)/2 + ((mat->li)-1)*(1+sign)/2;
+      
+      if (co > mat->co) { //sign == -1
+         mat->content[0] = realloc(mat->content[0],(mat->li)*co*sizeof(double));
+         for (int i=1;i<mat->li;i++) mat->content[i] = mat->content[0]+i*co;
+      }
+      for (int i=first;sign*i<=sign*last;i+=sign) {
+         memmove(
+            mat->content[0]+i*co,
+            mat->content[0]+i*(mat->co),
+            (mat->co)*sizeof(double)
+         ); 
+      }        
+      if (co < mat->co) { //sign == +1
+         mat->content[0] = realloc(mat->content[0],(mat->li)*co*sizeof(double));
+         for (int i=1;i<mat->li;i++) mat->content[i] = mat->content[0]+i*co;
+      }
+      
+      for (int i=0;i<mat->li;i++)  
+         for (int j=mat->co;j<co;j++) 
+            mat->content[i][j] = 0.0; 
+      
+      mat->co = co;
+   }
+}
+
+void resize(m_double* mat,int li,int co) {
+   resize_column(mat,co);
+   resize_line(mat,li);
+}
+   
+m_double* transpose(m_double* m) {
+   m_double* transp = NULL;
+   if (NULL != m) {
+      transp = new_matrix(m->co,m->li);
+      for (int i=0;i<m->li;i++) 
+         for (int j=0;j<m->co;j++) 
+            transp->content[j][i] = m->content[i][j];
+   }
+   return transp;
+}
+
+m_double* rnd(int li,int co,
+              double inf,double sup) {
+   m_double* mat = new_matrix(li,co);
+   if (NULL != mat) {
+      for (int i=0;i<li;i++)
+         for (int j=0;j<co;j++)
+            mat->content[i][j] = inf+drand48()*(sup-inf);
+   }
+   return mat;
+}
+
+m_double* rnd_int(int li,int co,
+                 int inf,int sup) {
+   m_double* mat = new_matrix(li,co);
+   if (NULL != mat) {
+      for (int i=0;i<li;i++)
+         for (int j=0;j<co;j++)
+            mat->content[i][j] = inf+rand()%(sup-inf);
+   }
+   return mat;
+}
+
+m_double* add(m_double* m1,m_double* m2) {
+   m_double* res = NULL;
+   if (m1->li == m2->li && m1->co == m2->co) {
+      res = new_matrix(m1->li,m1->co);
+      for (int i=0;i<res->li;i++) 
+         for (int j=0;j<res->co;j++) 
+            res->content[i][j] = m1->content[i][j]+m2->content[i][j];
+   }
+   return res;
+}
+
+m_double* mult(m_double* m1,m_double* m2) {
+   m_double* res = NULL;
+   if (m1->co == m2->li) {
+      res = new_matrix(m1->li,m2->co);
+      for (int i=0;i<res->li;i++) 
+         for (int j=0;j<res->co;j++) {
+            res->content[i][j] = 0;
+            for (int k=0;k<m1->co;k++)
+               res->content[i][j] += m1->content[i][k]*m2->content[k][j];
+         }
+   }
+   return res;
+}
+
+void free_matrix(m_double* m) {
+   free(m->content[0]);
+   free(m->content);
+}
+
+void format(m_double* m) {
+   if (NULL != m) {
+      printf("[");
+      for (int i=0;i<m->li;i++) {
+         for (int j=0;j<m->co;j++) printf("%f ",m->content[i][j]);
+         if (i+1 == m->li) printf("]\n");
+         else printf("; ");
+      }
+   } else printf("\n");
+}
+
+m_double* from_file(const char* filename) {
+   FILE *fp = fopen(filename,"r+");
+   if (NULL == fp) {
+      fprintf(stderr,"%s, file not found\n",filename);
+      exit(1);
+   }
+   int li = 0, co = 0, nb = 0;
+   double* data = NULL;
+   char* line = NULL;
+   size_t n;
+	while (getline(&line,&n,fp) != -1) {
+	   char* ptr = line;
+	   int ret, old = -1, nb_car;
+	   float val;
+	   while (1 == (ret = sscanf(ptr,"%f%n",&val,&nb_car))) {
+         ptr += nb_car;   
+         if (li == 0) co++;           
+         data = (double*)realloc(data,(li+1)*co*sizeof(double));         
+         data[nb++] = val;
+         old = ret;
+      }
+      if (1 == ret || 1 == old) {
+         old = -1;
+         li++;
+      }      
+   }
+   free(line);
+   fclose(fp);
+   
+   m_double* mat = new_matrix(li,co);
+   memcpy(mat->content[0],data,li*co*sizeof(double));
+   free(data);
+   return mat;
+}
+
+void print(m_double* m,char* filename) {
+   FILE *fp = stdout;
+   if (NULL != filename) fp = fopen(filename,"w+");
+   if (NULL != m) { 
+      for (int i=0;i<m->li;i++) {
+         for (int j=0;j<m->co;j++) 
+            fprintf(fp,"%d ",(int)(m->content[i][j]));
+         fprintf(fp,"\n");
+      }
+   } else fprintf(fp,"\n");
+}
diff --git a/source_codes/tableaux_2d/matrix.h b/source_codes/tableaux_2d/matrix.h
new file mode 100644
index 0000000..5d847cf
--- /dev/null
+++ b/source_codes/tableaux_2d/matrix.h
@@ -0,0 +1,19 @@
+typedef struct m_double {
+	int li,co;   /* nombre de colonnes, lignes */
+	double** content;  /* permet d'accéder aux éléments */
+} m_double;
+
+void resize(m_double* mat,int li,int co);
+m_double* new_matrix(int li,int co);
+m_double* transpose(m_double* m);
+m_double* add(m_double* m1,m_double* m2);
+m_double* mult(m_double* m1,m_double* m2);
+void free_matrix(m_double* m);
+void print(m_double* m,char* filename);
+void format(m_double* m);
+m_double* rnd(int li,int co,
+              double inf,double sup);
+m_double* rnd_int(int li,int co,
+                 int inf,int sup);
+      
+m_double* from_file(const char* filename);
-- 
GitLab