From 2a43e77032642152c1d94b2802c3a6d46984f78c Mon Sep 17 00:00:00 2001 From: "thibault.chatillo" <thibault.chatillon@etu.hesge.ch> Date: Wed, 12 May 2021 15:55:42 +0200 Subject: [PATCH] compress --- quadTree/Makefile | 2 +- quadTree/main.c | 12 +++-- quadTree/quadTree.c | 124 ++++++++++++++++++++++++++++++++++---------- quadTree/quadTree.h | 8 ++- 4 files changed, 113 insertions(+), 33 deletions(-) diff --git a/quadTree/Makefile b/quadTree/Makefile index 26a69cf..b34469e 100644 --- a/quadTree/Makefile +++ b/quadTree/Makefile @@ -3,7 +3,7 @@ CFLAGS=-Wextra -Wall -g -fsanitize=address -fsanitize=leak LFLAGS= -lm main: main.x - ./main.x + ./main.x 5 main.x: quadTree.o main.o PGM.o matrix.o $(cc) -o $@ $^ $(CFLAGS) $(LFLAGS) diff --git a/quadTree/main.c b/quadTree/main.c index 439bdc3..33c92ae 100644 --- a/quadTree/main.c +++ b/quadTree/main.c @@ -1,9 +1,15 @@ #include "quadTree.h" -int main() { +int main(int argc,char **argv) { - node* tree=tree_from_file("pgm/buzz_octets.pgm"); - tree_to_file(tree, "test2.pgm"); + node* tree=tree_from_file("pgm/buzz_octets.pgm"); + printf("matrix size %d\n",(int)pow(4,depth(tree))*sizeof(double)); + average(tree); + printf("%d size\n",sizeOfTree(tree)); + compress(tree,atoi(argv[1])); + printf("%d size\n",sizeOfTree(tree)); + // print(tree,2,"--"); + tree_to_file(tree, "test2.pgm"); tree_destroy(tree); } \ No newline at end of file diff --git a/quadTree/quadTree.c b/quadTree/quadTree.c index d6f2d53..4ca661c 100644 --- a/quadTree/quadTree.c +++ b/quadTree/quadTree.c @@ -29,7 +29,7 @@ int tree_max(node *tree) { int m = INT_MIN; if (!is_leaf(tree)) { for (int i = 0; i < CHILDREN; i++) { - m = max(m, tree->child[i]->value); + m = max(m, tree->child[i]->ave); m = max(m, tree_max(tree->child[i])); } } @@ -48,12 +48,22 @@ int depth(node *a) { } } +int nb_nodes(node* tree){ + int sum=1; + if(!is_leaf(tree)){ + for(int i =0;i<CHILDREN;i++){ + sum+=nb_nodes(tree->child[i]); + } + } + return sum; +} + void print(node *arbre, int decal, char *sep) { if (NULL != arbre) { for (int i = 0; i < decal; i++) { printf("%s", sep); } - printf("%d\n", arbre->value); + printf("%d\n", (int)arbre->ave); decal++; if (!is_leaf(arbre)) { for (int i = 0; i < CHILDREN; i++) { @@ -76,7 +86,7 @@ void sum(node *arbre) { sum(arbre->child[i]); } for (int i = 0; i < CHILDREN; i++) { - arbre->value += arbre->child[i]->value; + arbre->ave += arbre->child[i]->ave; } } } @@ -86,7 +96,8 @@ node *tree_create(int depth) { if (depth > 0) { for (int i = 0; i < CHILDREN; i++) { a->child[i] = tree_create(depth - 1); - a->value = 0; + a->ave = -1; + a->ave_sq=-1; } } return a; @@ -114,50 +125,76 @@ void tree_destroy(node *tree) { // } // } +// node *position(int li, int col, node *a, int d) { +// node *crt = a; +// do { +// int size = pow(2, d); +// int half = size / 2; +// int i; + +// li %= size; +// col %= size; + +// if (li < half && col < half) { +// i = 0; +// } else if (li < half && col >= half) { +// i = 1; +// } else if (li >= half && col < half) { +// i = 2; +// } else if (li >= half && col >= half) { +// i = 3; +// } + +// crt = crt->child[i]; +// d--; +// } while (!is_leaf(crt)); +// return crt; +// } + node *position(int li, int col, node *a, int d) { node *crt = a; do { - int size = pow(2, d); - int half = size / 2; - int i; - li %= size; - col %= size; - - if (li < half && col < half) { - i = 0; - } else if (li < half && col >= half) { - i = 1; - } else if (li >= half && col < half) { - i = 2; - } else if (li >= half && col >= half) { - i = 3; - } - crt = crt->child[i]; + int i=(li>>d)&1; + int j=(col>>d)&1; + int index=(i<<1) + j; + crt = crt->child[index]; d--; } while (!is_leaf(crt)); return crt; } -// à compléter: tant qu’on n’est pas sur une feuille, déplacer -// <crt> sur un enfant selon valeur du dième bit de <li> et <col> + +void average(node * tree){ + if(!is_leaf(tree)){ + tree->ave=0; + tree->ave_sq=0; + for(int i=0;i<CHILDREN;i++){ + average(tree->child[i]); + tree->ave+=tree->child[i]->ave; + tree->ave_sq+=tree->child[i]->ave_sq; + } + tree->ave/=CHILDREN; + tree->ave_sq/=CHILDREN; + } +} void matrix2tree(matrix *mat, node *arbre) { - int d = depth(arbre); + int d = depth(arbre)-1; for (int m = 0; m < mat->m; m++) { for (int n = 0; n < mat->n; n++) { node *crt = position(m, n, arbre, d); - crt->value = mat->data[m][n]; + crt->ave = mat->data[m][n]; + crt->ave_sq = (crt->ave) * (crt->ave); // crt->ave = mat->data[m][n]; - // crt->ave_sq = (crt->ave) * (crt->ave); } } } void tree2matrix(node *arbre, matrix *mat) { - int d = depth(arbre); + int d = depth(arbre)-1; for (int m = 0; m < mat->m; m++) { for (int n = 0; n < mat->n; n++) { node *crt = position(m, n, arbre, d); - mat->data[m][n] = crt->value; + mat->data[m][n] = crt->ave; // crt->ave = mat->data[m][n]; // crt->ave_sq = (crt->ave) * (crt->ave); } @@ -185,4 +222,37 @@ void tree_to_file(node *tree, char *filename) { out.pixels = mx; pmg_write_to_file(&out, filename); matrix_destroy(&mx); +} + +void compress(node *tree, double seuil){ + if(!is_leaf(tree)){ + for(int i=0;i<CHILDREN;i++){ + compress(tree->child[i],seuil); + } + + bool isLastBranch=true; + for(int i=0;i<CHILDREN;i++){ + if(!is_leaf(tree->child[i])){ + isLastBranch=false; + } + } + + if(isLastBranch){ + double var=sqrt(tree->ave_sq-tree->ave*tree->ave); + if(var<=seuil){ + // printf("var %d \n",(int)var); + for(int i=0;i<CHILDREN;i++){ + free(tree->child[i]); + tree->child[i]=NULL; + } + } + } + + } +} + +int sizeOfTree(node* tree){ + + return nb_nodes(tree)*(sizeof(double)+4*sizeof(node*)); + } \ No newline at end of file diff --git a/quadTree/quadTree.h b/quadTree/quadTree.h index 58c2b46..8062802 100644 --- a/quadTree/quadTree.h +++ b/quadTree/quadTree.h @@ -14,13 +14,13 @@ typedef struct _node { - int value; double ave; // moyenne des valeurs des enfants double ave_sq; // moyenne des carrés des valeurs des enfants struct _node *child[CHILDREN]; } node; // typedef node* arbre; +void average(node * tree); bool is_leaf(node *nd); @@ -32,6 +32,10 @@ int depth(node *a); void print(node *arbre, int decal, char *sep); +int nb_nodes(node* tree); + +int sizeOfTree(node* tree); + // Fonction utile pour les symétries void swap(void **ptr1, void **ptr2); @@ -60,7 +64,7 @@ void average(node *arbre); // et on supprime les enfants en remontant si l’écarttype // est inférieur à <seuil> -void compress(node *arbre, double seuil); +void compress(node *tree, double seuil); bool leaf(node *nd); -- GitLab