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