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’écart­type
 // est inférieur à <seuil>
 
-void compress(node *arbre, double seuil);
+void compress(node *tree, double seuil);
 
 bool leaf(node *nd);
 
-- 
GitLab