diff --git a/Makefile b/Makefile
index 803ab991aa7dd7d172da46c1bb10650b484cc58c..3a7f943df664ce6aa46ab5052fcfd89e73a56649 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ CFLAGS = -Iinclude -Wall -g3
 LDFLAGS = -lm
 LIBHQR=src/libhqr.a
 
-default: testing_pivgen testing_treedraw
+default: testing_pivgen testing_treedraw testing_tileinit
 
 src/queue.o:           include/queue.h include/common.h
 src/libhqr.o:          include/common.h include/libhqr.h
@@ -24,6 +24,9 @@ testing_pivgen : testings/testing_pivgen.o ${LIBHQR}
 testing_treedraw : testings/testing_treedraw.o ${LIBHQR}
 	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
+testing_tileinit : testings/testing_tileinit.o ${LIBHQR}
+	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
+
 clean :
 	rm -f include/*~
 	rm -f src/*.o src/*~
@@ -31,4 +34,4 @@ clean :
 
 cleanall: clean
 	rm -f ${LIBHQR}
-	rm -f testing_pivgen testing_treedraw tree.svg
+	rm -f testing_pivgen testing_treedraw testing_tileinit tree.svg
diff --git a/include/libhqr.h b/include/libhqr.h
index 9e8baa03fdacdcab59a0fc56461a0bf2bbed2a8c..5be6d282152952ceeda0d5b6f1433d3aff2fd8f6 100644
--- a/include/libhqr.h
+++ b/include/libhqr.h
@@ -89,6 +89,19 @@ typedef struct libhqr_tiledesc_s{
     int p;     /**< The number of nodes per column in the data distribution */
 } libhqr_tiledesc_t;
 
+
+/**
+ * @brief Minimal structure to stock the information for each tile
+ */
+typedef struct libhqr_tileinfo_s{
+    int type;          /**< The type of the tile                             */
+    int currpiv;       /**< Number of the time annihilating the current tile */
+    int nextpiv;       /**< The next tile killed by the tile                 */
+    int prevpiv;       /**< The previous tile killed by the tile             */
+    int first_nextpiv; /**< The first next tile killed                       */
+    int first_prevpiv; /**< The first previous tile killed                   */
+} libhqr_tileinfo_t;
+
 struct libhqr_tree_s;
 typedef struct libhqr_tree_s libhqr_tree_t;
 
@@ -172,6 +185,7 @@ struct libhqr_tree_s {
     int a;
     /** Size of highest level tree (distributed one) */
     int p;
+    int domino;
     void *args;
 };
 
@@ -190,6 +204,14 @@ int  libhqr_hqr_init( libhqr_tree_t *qrtree,
                       int a, int p, int domino, int tsrr );
 void libhqr_hqr_finalize( libhqr_tree_t *qrtree );
 
+
+void libhqr_matrix_init(libhqr_tree_t *qrtree, const libhqr_tree_t *qrtree_init);
+int rdmtx_gettype(const libhqr_tree_t *qrtree, int k, int m);
+int rdmtx_currpiv(const libhqr_tree_t *qrtree, int k, int m);
+int rdmtx_nextpiv(const libhqr_tree_t *qrtree, int k, int p, int m);
+int rdmtx_prevpiv(const libhqr_tree_t *qrtree, int k, int p, int m);
+void libhqr_matrix_finalize(libhqr_tree_t *qrtree);
+
 /*
  * function for drawing the tree
  */
diff --git a/src/libhqr.c b/src/libhqr.c
index 434bf2fb4e9cdca5237def9ce60e89086a119cdc..2750739839116e72aefb4d3cf31563e6cb0344a4 100644
--- a/src/libhqr.c
+++ b/src/libhqr.c
@@ -170,6 +170,73 @@ static void hqr_low_greedy_init(   hqr_subpiv_t *arg, int minMN);
 static void hqr_low_binary_init(   hqr_subpiv_t *arg);
 static void hqr_low_fibonacci_init(hqr_subpiv_t *arg, int minMN);
 
+
+/****************************************************
+ * Reading functions
+ **************************************************
+ *
+ * Common parameters for the following functions
+ *    qrtree - tree used for the factorization
+ *    k      - Step k of the QR factorization
+ *    m      - line anhilated
+ */
+
+int  rdmtx_gettype(const libhqr_tree_t *qrtree, int k, int m){
+    int id;
+    libhqr_tileinfo_t *arg = (libhqr_tileinfo_t*)(qrtree->args);
+    id = (k * qrtree->mt) + m;
+    return arg[id].type;
+}
+
+int rdmtx_currpiv(const libhqr_tree_t *qrtree, int k, int m){
+    int id, perm_m, p, a;
+    libhqr_tileinfo_t *arg = (libhqr_tileinfo_t*)(qrtree->args);
+    perm_m = m;
+    p = qrtree->p;
+    a = qrtree->a;
+    myassert( (p==1) || (perm_m / (p*a)) == (m / (p*a)) );
+    myassert( (p==1) || (perm_m % p) == (m % p) );
+    id = (k * qrtree->mt) + m;
+    return arg[id].currpiv;
+}
+
+/*
+ * Extra parameter:
+ *    p - line used as pivot
+ */
+
+int rdmtx_nextpiv(const libhqr_tree_t *qrtree, int k, int p, int m){
+    int id;
+    libhqr_tileinfo_t *arg = (libhqr_tileinfo_t*)(qrtree->args);
+    int gmt = qrtree->mt;
+    myassert( m > p && p >= k );
+    myassert( m == gmt || p == rdmtx_currpiv( qrtree, k, m ) );
+    if(m == qrtree->mt){
+        id = (k * qrtree->mt) + p;
+        return arg[id].first_nextpiv;
+    }
+    else{
+        id = (k * qrtree->mt) + m;
+        return arg[id].nextpiv;
+    }
+}
+
+int rdmtx_prevpiv(const libhqr_tree_t *qrtree, int k, int p, int m){
+    int id;
+    libhqr_tileinfo_t *arg = (libhqr_tileinfo_t*)(qrtree->args);
+    int gmt = qrtree->mt;
+    myassert( m >= p && p >= k && m < gmt );
+    myassert( m == p || p == rdmtx_currpiv( qrtree, k, m ) );
+
+    if(m == p){
+        id = (k * qrtree->mt) + p;
+        return arg[id].first_prevpiv;
+    }
+    else{
+        id = (k * qrtree->mt) + m;
+        return arg[id].prevpiv;
+    }
+}
 /****************************************************
  *             Common ipiv
  ***************************************************
@@ -189,11 +256,10 @@ static void hqr_low_fibonacci_init(hqr_subpiv_t *arg, int minMN);
  *    The number of geqrt to execute in the panel k
  */
 static int hqr_getnbgeqrf( const libhqr_tree_t *qrtree, int k ) {
-    hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
     int a = qrtree->a;
     int p = qrtree->p;
     int gmt = qrtree->mt;
-    int domino = arg->domino;
+    int domino = qrtree->domino;
     int pa = p * a;
     int nb_1, nb_2, nb_3;
     int nb_11, nb_12;
@@ -236,12 +302,9 @@ static int hqr_getnbgeqrf( const libhqr_tree_t *qrtree, int k ) {
  */
 static int hqr_getm( const libhqr_tree_t *qrtree, int k, int i )
 {
-    hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
     int a = qrtree->a;
     int p = qrtree->p;
-    int gmt = qrtree->mt + 1;
-    int domino = arg->domino;
-    int *perm  = arg->perm + gmt * k;
+    int domino = qrtree->domino;
 
     int pos1, j, pa = p * a;
     int nbextra1 = nbextra1_formula;
@@ -258,7 +321,7 @@ static int hqr_getm( const libhqr_tree_t *qrtree, int k, int i )
           pos1 = ( ( (p * (k+1)) + pa - 1 ) / pa ) * pa;
         else
           pos1 = ( ( (p + k    ) + pa - 1 ) / pa ) * pa;
-        return perm[ pos1 + (j/p) * pa + j%p ];
+        return pos1 + (j/p) * pa + j%p;
     }
 }
 
@@ -270,11 +333,10 @@ static int hqr_getm( const libhqr_tree_t *qrtree, int k, int i )
  */
 static int hqr_geti( const libhqr_tree_t *qrtree, int k, int m )
 {
-    hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
     int a = qrtree->a;
     int p = qrtree->p;
-    int domino = arg->domino;
-    int lm = hqr_getinvperm( qrtree, k, m );
+    int domino = qrtree->domino;
+    int lm = m;
 
     int pos1, j, pa = p * a;
     int nbextra1 = nbextra1_formula;
@@ -306,12 +368,11 @@ static int hqr_geti( const libhqr_tree_t *qrtree, int k, int m )
  *      3 - if m is reduced in distributed
  */
 static int hqr_gettype( const libhqr_tree_t *qrtree, int k, int m ) {
-    hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
     int a = qrtree->a;
     int p = qrtree->p;
-    int domino = arg->domino;
+    int domino = qrtree->domino;
 
-    int lm = hqr_getinvperm( qrtree, k, m );
+    int lm = m;
     myassert( lm >= k );
 
     /* Element to be reduce in distributed */
@@ -1267,20 +1328,15 @@ static void hqr_high_greedy_init(hqr_subpiv_t *arg, int minMN){
 static int hqr_currpiv(const libhqr_tree_t *qrtree, int k, int m)
 {
     hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
-    int tmp, tmpk, perm_m;
-    int lm, rank, *perm;
+    int tmp, tmpk;
+    int lm, rank;
     int a = qrtree->a;
     int p = qrtree->p;
-    int domino = arg->domino;
+    int domino = qrtree->domino;
     int gmt = qrtree->mt;
 
-    perm_m = hqr_getinvperm( qrtree, k, m );
-    lm   = perm_m / p; /* Local index in the distribution over p domains */
-    rank = perm_m % p; /* Staring index in this distribution             */
-    perm = arg->perm + (gmt+1) * k;
-
-    myassert( (p==1) || (perm_m / (p*a)) == (m / (p*a)) );
-    myassert( (p==1) || (perm_m % p) == (m % p) );
+    lm   = m / p; /* Local index in the distribution over p domains */
+    rank = m % p; /* Staring index in this distribution             */
 
     /* TS level common to every case */
     if ( domino ) {
@@ -1289,20 +1345,20 @@ static int hqr_currpiv(const libhqr_tree_t *qrtree, int k, int m)
         case 0:
             tmp = lm / a;
             if ( tmp == k / a )
-                return perm[       k * p + rank ]; /* Below to the first bloc including the diagonal */
+                return        k * p + rank ; /* Below to the first bloc including the diagonal */
             else
-                return perm[ tmp * a * p + rank ];
+                return  tmp * a * p + rank ;
             break;
         case 1:
-            tmp = arg->llvl->currpiv(arg->llvl, k, perm_m);
-            return perm[ ( tmp == k / a ) ? k * p + rank : tmp * a * p + rank ];
+            tmp = arg->llvl->currpiv(arg->llvl, k, m);
+            return  ( tmp == k / a ) ? k * p + rank : tmp * a * p + rank;
             break;
         case 2:
             return m - p;
             break;
         case 3:
             if ( arg->hlvl != NULL )
-                return arg->hlvl->currpiv(arg->hlvl, k, perm_m);
+                return arg->hlvl->currpiv(arg->hlvl, k, m);
         default:
             return gmt;
         }
@@ -1314,20 +1370,20 @@ static int hqr_currpiv(const libhqr_tree_t *qrtree, int k, int m)
             tmp = lm / a;
             /* tmpk = (k + p - 1 - m%p) / p / a;  */
             tmpk = k / (p * a);
-            return perm[ ( tmp == tmpk ) ? k + (perm_m-k)%p : tmp * a * p + rank ];
+            return  ( tmp == tmpk ) ? k + (m-k)%p : tmp * a * p + rank ;
             break;
         case 1:
-            tmp = arg->llvl->currpiv(arg->llvl, k, perm_m);
+            tmp = arg->llvl->currpiv(arg->llvl, k, m);
             /* tmpk = (k + p - 1 - m%p) / p / a; */
             tmpk = k / (p * a);
-            return perm[ ( tmp == tmpk ) ? k + (perm_m-k)%p : tmp * a * p + rank ];
+            return  ( tmp == tmpk ) ? k + (m-k)%p : tmp * a * p + rank ;
             break;
         case 2:
-            return perm[ perm_m - p];
+            return  m - p;
             break;
         case 3:
             if ( arg->hlvl != NULL )
-                return perm[arg->hlvl->currpiv(arg->hlvl, k, perm_m)];
+                return arg->hlvl->currpiv(arg->hlvl, k, m);
         default:
             return gmt;
         }
@@ -1357,31 +1413,23 @@ static int hqr_nextpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
 {
     hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
     int tmp, ls, lp, nextp;
-    int opivot, ostart; /* original values before permutation */
-    int lpivot, rpivot, lstart, *perm;
+    int lpivot, rpivot, lstart;
     int a = qrtree->a;
     int p = qrtree->p;
     int gmt = qrtree->mt;
 
-    ostart = start;
-    opivot = pivot;
-    start = hqr_getinvperm( qrtree, k, ostart);
-    pivot = hqr_getinvperm( qrtree, k, opivot);
-
     lpivot = pivot / p; /* Local index in the distribution over p domains */
     rpivot = pivot % p; /* Staring index in this distribution             */
 
     /* Local index in the distribution over p domains */
     lstart = ( start == gmt ) ? arg->llvl->ldd * a : start / p;
 
-    perm = arg->perm + (gmt+1) * k;
-
     myassert( start > pivot && pivot >= k );
-    myassert( start == gmt || opivot == hqr_currpiv( qrtree, k, ostart ) );
+    myassert( start == gmt || pivot == hqr_currpiv( qrtree, k, start ) );
 
     /* TS level common to every case */
-    ls = (start < gmt) ? hqr_gettype( qrtree, k, ostart ) : -1;
-    lp = hqr_gettype( qrtree, k, opivot );
+    ls = (start < gmt) ? hqr_gettype( qrtree, k, start ) : -1;
+    lp = hqr_gettype( qrtree, k, pivot );
 
     switch( ls )
         {
@@ -1406,7 +1454,7 @@ static int hqr_nextpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
             if ( ( nextp < gmt ) &&
                  ( nextp < pivot + a*p ) &&
                  ( (nextp/p)%a != 0 ) )
-                return perm[nextp];
+                return nextp;
             start = gmt;
             lstart = arg->llvl->ldd * a;
 
@@ -1424,7 +1472,7 @@ static int hqr_nextpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
                 tmp = arg->llvl->nextpiv(arg->llvl, k, pivot, tmp);
 
             if ( tmp != arg->llvl->ldd )
-                return perm[tmp * a * p + rpivot];
+                return tmp * a * p + rpivot;
 
         next_2:
             /* no next of type 1, we reset start to search the next 2 */
@@ -1442,7 +1490,7 @@ static int hqr_nextpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
                  (start == gmt) &&
                  (lpivot < k)             &&
                  (pivot+p < gmt) ) {
-                return perm[pivot+p];
+                return pivot+p;
             }
 
             /* no next of type 2, we reset start to search the next 3 */
@@ -1458,7 +1506,7 @@ static int hqr_nextpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
             if( arg->hlvl != NULL ) {
                 tmp = arg->hlvl->nextpiv( arg->hlvl, k, pivot, start );
                 if ( tmp != gmt )
-                    return perm[tmp];
+                    return tmp;
             }
 
         default:
@@ -1489,28 +1537,21 @@ hqr_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
 {
     hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
     int tmp, ls, lp, nextp;
-    int opivot, ostart; /* original values before permutation */
-    int lpivot, rpivot, lstart, *perm;
+    int lpivot, rpivot, lstart;
     int a = qrtree->a;
     int p = qrtree->p;
     int gmt = qrtree->mt;
 
-    ostart = start;
-    opivot = pivot;
-    start = hqr_getinvperm( qrtree, k, ostart );
-    pivot = hqr_getinvperm( qrtree, k, opivot );
-
     lpivot = pivot / p; /* Local index in the distribution over p domains */
     rpivot = pivot % p; /* Staring index in this distribution             */
     lstart = start / p; /* Local index in the distribution over p domains */
-    perm = arg->perm + (gmt+1) * k;
 
     myassert( start >= pivot && pivot >= k && start < gmt );
-    myassert( start == pivot || opivot == hqr_currpiv( qrtree, k, ostart ) );
+    myassert( start == pivot || pivot == hqr_currpiv( qrtree, k, start ) );
 
     /* T Slevel common to every case */
-    ls = hqr_gettype( qrtree, k, ostart );
-    lp = hqr_gettype( qrtree, k, opivot );
+    ls = hqr_gettype( qrtree, k, start );
+    lp = hqr_gettype( qrtree, k, pivot );
 
     if ( lp == LIBHQR_KILLED_BY_TS )
       return gmt;
@@ -1522,7 +1563,7 @@ hqr_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
             if( arg->hlvl != NULL ) {
                 tmp = arg->hlvl->prevpiv( arg->hlvl, k, pivot, start );
                 if ( tmp != gmt )
-                    return perm[tmp];
+                    return tmp;
             }
 
             start = pivot;
@@ -1534,7 +1575,7 @@ hqr_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
 
                 if ( ( start == pivot ) &&
                      (start+p < gmt ) )
-                    return perm[start+p];
+                    return start+p;
 
                 if ( lp > LIBHQR_KILLED_BY_LOCALTREE )
                     return gmt;
@@ -1558,7 +1599,7 @@ hqr_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
                 tmp = arg->llvl->prevpiv(arg->llvl, k, pivot, tmp);
 
             if ( tmp != arg->llvl->ldd )
-                return perm[tmp * a * p + rpivot];
+                return tmp * a * p + rpivot;
 
             start = pivot;
 
@@ -1566,7 +1607,7 @@ hqr_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
             /* Search for predecessor in TS tree */
             /* if ( ( start+p < gmt ) &&  */
             /*      ( (((start+p) / p) % a) != 0 ) ) */
-            /*     return perm[start + p]; */
+            /*     return start + p; */
 
             if ( start == pivot ) {
                 tmp = lpivot + a - 1 - lpivot%a;
@@ -1579,7 +1620,7 @@ hqr_prevpiv(const libhqr_tree_t *qrtree, int k, int pivot, int start)
             }
             assert(nextp < gmt);
             if ( pivot < nextp )
-                return perm[nextp];
+                return nextp;
 
         default:
             return gmt;
@@ -1665,21 +1706,20 @@ hqr_genperm( libhqr_tree_t *qrtree )
 static int
 hqr_getinvperm( const libhqr_tree_t *qrtree, int k, int m )
 {
-    hqr_args_t *arg = (hqr_args_t*)(qrtree->args);
     int gmt = qrtree->mt + 1;
     int a = qrtree->a;
     int p = qrtree->p;
     int pa = p * a;
     int start = m / pa * pa;
     int stop  = libhqr_imin( start + pa, gmt ) - start;
-    int *perm = arg->perm + gmt * k + start;
     int i;
 
     if (a == 1)
         return m;
 
     for ( i=m%p; i < stop; i+=p ) {
-        if( perm[i] == m )
+        //if( perm[i] == m )
+        if( i == m )
             return i+start;
     }
 
@@ -1812,6 +1852,7 @@ libhqr_hqr_init( libhqr_tree_t *qrtree,
 		 int a, int p,
 		 int domino, int tsrr )
 {
+    libhqr_tree_t qrtree_init;
     double ratio = 0.0;
     int low_mt, minMN;
     hqr_args_t *arg;
@@ -1822,7 +1863,7 @@ libhqr_hqr_init( libhqr_tree_t *qrtree,
     }
     if ((trans != LIBHQR_QR) &&
         (trans != LIBHQR_LQ)) {
-      fprintf(stderr, "libhqr_hqr_ini, illegal value of trans");
+      fprintf(stderr, "libhqr_hqr_init, illegal value of trans");
       return -2;
     }
     if (A == NULL) {
@@ -1851,94 +1892,116 @@ libhqr_hqr_init( libhqr_tree_t *qrtree,
         }
     }
 
-    qrtree->getnbgeqrf = hqr_getnbgeqrf;
-    qrtree->getm       = hqr_getm;
-    qrtree->geti       = hqr_geti;
-    qrtree->gettype    = hqr_gettype;
-    qrtree->currpiv    = hqr_currpiv;
-    qrtree->nextpiv    = hqr_nextpiv;
-    qrtree->prevpiv    = hqr_prevpiv;
+    minMN = libhqr_imin(A->mt, A->nt);
 
-    qrtree->mt   = (trans == LIBHQR_QR) ? A->mt : A->nt;
-    qrtree->nt   = (trans == LIBHQR_QR) ? A->nt : A->mt;
+    /* Create a temporary qrtree structure based on the functions */
+    {
+        qrtree_init.domino     = domino;
+        qrtree_init.getnbgeqrf = hqr_getnbgeqrf;
+        qrtree_init.getm       = hqr_getm;
+        qrtree_init.geti       = hqr_geti;
+        qrtree_init.gettype    = hqr_gettype;
+        qrtree_init.currpiv    = hqr_currpiv;
+        qrtree_init.nextpiv    = hqr_nextpiv;
+        qrtree_init.prevpiv    = hqr_prevpiv;
 
-    a = libhqr_imin( a, qrtree->mt );
+        qrtree_init.mt = (trans == LIBHQR_QR) ? A->mt : A->nt;
+        qrtree_init.nt = minMN;
 
-    qrtree->a    = a;
-    qrtree->p    = p;
-    qrtree->args = NULL;
+        a = libhqr_imin( a, qrtree_init.mt );
 
-    arg = (hqr_args_t*) malloc( sizeof(hqr_args_t) );
-    arg->domino = domino;
-    arg->tsrr = tsrr;
-    arg->perm = NULL;
+        qrtree_init.a    = a;
+        qrtree_init.p    = p;
+        qrtree_init.args = NULL;
 
-    arg->llvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
-    arg->hlvl = NULL;
+        arg = (hqr_args_t*) malloc( sizeof(hqr_args_t) );
+        arg->domino = domino;
+        arg->tsrr = tsrr;
+        arg->perm = NULL;
 
-    minMN = libhqr_imin(A->mt, A->nt);
-    low_mt = (qrtree->mt + p * a - 1) / ( p * a );
+        arg->llvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
+        arg->hlvl = NULL;
 
-    arg->llvl->minMN  = minMN;
-    arg->llvl->ldd    = low_mt;
-    arg->llvl->a      = a;
-    arg->llvl->p      = p;
-    arg->llvl->domino = domino;
-
-    switch( type_llvl ) {
-    case LIBHQR_FLAT_TREE :
-        hqr_low_flat_init(arg->llvl);
-        break;
-    case LIBHQR_FIBONACCI_TREE :
-        hqr_low_fibonacci_init(arg->llvl, minMN);
-        break;
-    case LIBHQR_BINARY_TREE :
-        hqr_low_binary_init(arg->llvl);
-        break;
-    case LIBHQR_GREEDY1P_TREE :
-        hqr_low_greedy1p_init(arg->llvl, minMN);
-        break;
-    case LIBHQR_GREEDY_TREE :
-    default:
-        hqr_low_greedy_init(arg->llvl, minMN);
-    }
-
-    if ( p > 1 ) {
-        arg->hlvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
+        low_mt = (qrtree_init.mt + p * a - 1) / ( p * a );
 
         arg->llvl->minMN  = minMN;
-        arg->hlvl->ldd    = qrtree->mt;
-        arg->hlvl->a      = a;
-        arg->hlvl->p      = p;
-        arg->hlvl->domino = domino;
+        arg->llvl->ldd    = low_mt;
+        arg->llvl->a      = a;
+        arg->llvl->p      = p;
+        arg->llvl->domino = domino;
 
-        switch( type_hlvl ) {
+        switch( type_llvl ) {
         case LIBHQR_FLAT_TREE :
-            hqr_high_flat_init(arg->hlvl);
-            break;
-        case LIBHQR_GREEDY_TREE :
-            hqr_high_greedy_init(arg->hlvl, minMN);
+            hqr_low_flat_init(arg->llvl);
             break;
-        case LIBHQR_GREEDY1P_TREE :
-            hqr_high_greedy1p_init(arg->hlvl);
+        case LIBHQR_FIBONACCI_TREE :
+            hqr_low_fibonacci_init(arg->llvl, minMN);
             break;
         case LIBHQR_BINARY_TREE :
-            hqr_high_binary_init(arg->hlvl);
+            hqr_low_binary_init(arg->llvl);
             break;
-        case LIBHQR_FIBONACCI_TREE :
-            hqr_high_fibonacci_init(arg->hlvl);
+        case LIBHQR_GREEDY1P_TREE :
+            hqr_low_greedy1p_init(arg->llvl, minMN);
             break;
+        case LIBHQR_GREEDY_TREE :
         default:
-            if ( ratio >= 0.5 ) {
+            hqr_low_greedy_init(arg->llvl, minMN);
+        }
+
+        if ( p > 1 ) {
+            arg->hlvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
+
+            arg->llvl->minMN  = minMN;
+            arg->hlvl->ldd    = qrtree_init.mt;
+            arg->hlvl->a      = a;
+            arg->hlvl->p      = p;
+            arg->hlvl->domino = domino;
+
+            switch( type_hlvl ) {
+            case LIBHQR_FLAT_TREE :
                 hqr_high_flat_init(arg->hlvl);
-            } else {
+                break;
+            case LIBHQR_GREEDY_TREE :
+                hqr_high_greedy_init(arg->hlvl, minMN);
+                break;
+            case LIBHQR_GREEDY1P_TREE :
+                hqr_high_greedy1p_init(arg->hlvl);
+                break;
+            case LIBHQR_BINARY_TREE :
+                hqr_high_binary_init(arg->hlvl);
+                break;
+            case LIBHQR_FIBONACCI_TREE :
                 hqr_high_fibonacci_init(arg->hlvl);
+                break;
+            default:
+                if ( ratio >= 0.5 ) {
+                    hqr_high_flat_init(arg->hlvl);
+                } else {
+                    hqr_high_fibonacci_init(arg->hlvl);
+                }
             }
         }
+
+        qrtree_init.args = (void*)arg;
+        hqr_genperm( &qrtree_init );
     }
 
-    qrtree->args = (void*)arg;
-    hqr_genperm( qrtree );
+    /* Initialize the final QR tree */
+    memcpy( qrtree, &qrtree_init, sizeof(libhqr_tree_t) );
+    qrtree->getnbgeqrf = hqr_getnbgeqrf;
+    qrtree->getm       = hqr_getm;
+    qrtree->geti       = hqr_geti;
+    qrtree->gettype    = rdmtx_gettype;
+    qrtree->currpiv    = rdmtx_currpiv;
+    qrtree->nextpiv    = rdmtx_nextpiv;
+    qrtree->prevpiv    = rdmtx_prevpiv;
+    qrtree->args       = malloc( qrtree->mt * qrtree->nt * sizeof(libhqr_tileinfo_t) );
+
+    /* Initialize the matrix */
+    libhqr_matrix_init(qrtree, &qrtree_init);
+
+    /* Free the initial qrtree */
+    libhqr_hqr_finalize( &qrtree_init );
 
     return 0;
 }
@@ -2652,6 +2715,7 @@ libhqr_svd_init( libhqr_tree_t *qrtree,
 {
     int low_mt, minMN, a = -1;
     hqr_args_t *arg;
+    libhqr_tree_t qrtree_init;
 
     if (qrtree == NULL) {
         fprintf(stderr,"libhqr_svd_init, illegal value of qrtree");
@@ -2670,73 +2734,123 @@ libhqr_svd_init( libhqr_tree_t *qrtree,
     /* Compute parameters */
     p = libhqr_imax( p, 1 );
 
-    qrtree->getnbgeqrf = svd_getnbgeqrf;
-    qrtree->getm       = svd_getm;
-    qrtree->geti       = svd_geti;
-    qrtree->gettype    = svd_gettype;
-    qrtree->currpiv    = svd_currpiv;
-    qrtree->nextpiv    = svd_nextpiv;
-    qrtree->prevpiv    = svd_prevpiv;
+    /* Create a temporary qrtree structure based on the functions */
+    {
+        qrtree_init.getnbgeqrf = svd_getnbgeqrf;
+        qrtree_init.getm       = svd_getm;
+        qrtree_init.geti       = svd_geti;
+        qrtree_init.gettype    = svd_gettype;
+        qrtree_init.currpiv    = svd_currpiv;
+        qrtree_init.nextpiv    = svd_nextpiv;
+        qrtree_init.prevpiv    = svd_prevpiv;
 
-    qrtree->mt   = (trans == LIBHQR_QR) ? A->mt : A->nt;
-    qrtree->nt   = (trans == LIBHQR_QR) ? A->nt : A->mt;
+        qrtree_init.mt   = (trans == LIBHQR_QR) ? A->mt : A->nt;
+        qrtree_init.nt   = (trans == LIBHQR_QR) ? A->nt : A->mt;
 
-    qrtree->a    = a;
-    qrtree->p    = p;
-    qrtree->args = NULL;
+        qrtree_init.a    = a;
+        qrtree_init.p    = p;
+        qrtree_init.args = NULL;
 
-    arg = (hqr_args_t*) malloc( sizeof(hqr_args_t) );
-    arg->domino = 0;
-    arg->tsrr = 0;
-    arg->perm = NULL;
+        arg = (hqr_args_t*) malloc( sizeof(hqr_args_t) );
+        arg->domino = 0;
+        arg->tsrr = 0;
+        arg->perm = NULL;
 
-    arg->llvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
-    arg->hlvl = NULL;
+        arg->llvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
+        arg->hlvl = NULL;
 
-    minMN = libhqr_imin(A->mt, A->nt);
-    low_mt = (qrtree->mt + p - 1) / ( p );
+        minMN = libhqr_imin(A->mt, A->nt);
+        low_mt = (qrtree_init.mt + p - 1) / ( p );
 
-    arg->llvl->minMN  = minMN;
-    arg->llvl->ldd    = low_mt;
-    arg->llvl->a      = a;
-    arg->llvl->p      = p;
-    arg->llvl->domino = 0;
+        arg->llvl->minMN  = minMN;
+        arg->llvl->ldd    = low_mt;
+        arg->llvl->a      = a;
+        arg->llvl->p      = p;
+        arg->llvl->domino = 0;
 
-    svd_low_adaptiv_init(arg->llvl, qrtree->mt, qrtree->nt,
-                         nbthread_per_node * (A->nodes / p), ratio );
+        svd_low_adaptiv_init(arg->llvl, qrtree_init.mt, qrtree_init.nt,
+                             nbthread_per_node * (A->nodes / p), ratio );
 
-    if ( p > 1 ) {
-        arg->hlvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
+        if ( p > 1 ) {
+            arg->hlvl = (hqr_subpiv_t*) malloc( sizeof(hqr_subpiv_t) );
 
-        arg->llvl->minMN  = minMN;
-        arg->hlvl->ldd    = qrtree->mt;
-        arg->hlvl->a      = a;
-        arg->hlvl->p      = p;
-        arg->hlvl->domino = 0;
+            arg->llvl->minMN  = minMN;
+            arg->hlvl->ldd    = qrtree_init.mt;
+            arg->hlvl->a      = a;
+            arg->hlvl->p      = p;
+            arg->hlvl->domino = 0;
 
-        switch( type_hlvl ) {
-        case LIBHQR_FLAT_TREE :
-            hqr_high_flat_init(arg->hlvl);
-            break;
-        case LIBHQR_GREEDY_TREE :
-            hqr_high_greedy_init(arg->hlvl, minMN);
-            break;
-        case LIBHQR_GREEDY1P_TREE :
-            hqr_high_greedy1p_init(arg->hlvl);
-            break;
-        case LIBHQR_BINARY_TREE :
-            hqr_high_binary_init(arg->hlvl);
-            break;
-        case LIBHQR_FIBONACCI_TREE :
-            hqr_high_fibonacci_init(arg->hlvl);
-            break;
-        default:
-            hqr_high_fibonacci_init(arg->hlvl);
+            switch( type_hlvl ) {
+            case LIBHQR_FLAT_TREE :
+                hqr_high_flat_init(arg->hlvl);
+                break;
+            case LIBHQR_GREEDY_TREE :
+                hqr_high_greedy_init(arg->hlvl, minMN);
+                break;
+            case LIBHQR_GREEDY1P_TREE :
+                hqr_high_greedy1p_init(arg->hlvl);
+                break;
+            case LIBHQR_BINARY_TREE :
+                hqr_high_binary_init(arg->hlvl);
+                break;
+            case LIBHQR_FIBONACCI_TREE :
+                hqr_high_fibonacci_init(arg->hlvl);
+                break;
+            default:
+                hqr_high_fibonacci_init(arg->hlvl);
+            }
         }
+
+        qrtree_init.args = (void*)arg;
+        hqr_genperm( &qrtree_init );
     }
 
-    qrtree->args = (void*)arg;
+    /* Initialize the final QR tree */
+    memcpy( qrtree, &qrtree_init, sizeof(libhqr_tree_t) );
+    qrtree->getnbgeqrf = svd_getnbgeqrf;
+    qrtree->getm       = svd_getm;
+    qrtree->geti       = svd_geti;
+    qrtree->gettype    = rdmtx_gettype;
+    qrtree->currpiv    = rdmtx_currpiv;
+    qrtree->nextpiv    = rdmtx_nextpiv;
+    qrtree->prevpiv    = rdmtx_prevpiv;
+    qrtree->args       = malloc( qrtree->mt * qrtree->nt * sizeof(libhqr_tileinfo_t) );
+
+    /* Initialize the matrix */
+    libhqr_matrix_init(qrtree, &qrtree_init);
+
+    /* Free the initial qrtree */
+    libhqr_hqr_finalize( &qrtree_init );
 
     return 0;
 }
 
+void libhqr_matrix_init(libhqr_tree_t *qrtree, const libhqr_tree_t *qrtree_init){
+    int i, minMN, tile_id, p, k;
+    libhqr_tileinfo_t *arg = (libhqr_tileinfo_t*)(qrtree->args);
+    minMN = libhqr_imin(qrtree->nt, qrtree->mt);
+    for (k = 0; k < minMN; k++){
+        for (i = 0; i < qrtree->mt; i++){
+            tile_id = (k * qrtree->mt) + i;
+
+            arg[tile_id].type    = qrtree_init->gettype(qrtree_init, k, i);
+            assert( (i < k) || (arg[tile_id].type >= 0) );
+            arg[tile_id].currpiv = qrtree_init->currpiv(qrtree_init, k, i);
+            p = arg[tile_id].currpiv;
+            arg[tile_id].first_nextpiv = qrtree_init->nextpiv(qrtree_init, k, i, qrtree->mt);
+            arg[tile_id].first_prevpiv = qrtree_init->prevpiv(qrtree_init, k, i, i);
+            arg[tile_id].nextpiv = qrtree_init->nextpiv(qrtree_init, k, p, i);
+            arg[tile_id].prevpiv = qrtree_init->prevpiv(qrtree_init, k, p, i);
+            assert( (arg[tile_id].nextpiv <= qrtree->mt && arg[tile_id].nextpiv >= k) || arg[tile_id].nextpiv==-1  );
+            assert( (arg[tile_id].prevpiv <= qrtree->mt && arg[tile_id].prevpiv >= k) || arg[tile_id].prevpiv==-1  );
+            assert( (arg[tile_id].first_nextpiv <= qrtree->mt && arg[tile_id].first_nextpiv >= k) || arg[tile_id].first_nextpiv==-1  );
+            assert( (arg[tile_id].first_prevpiv <= qrtree->mt && arg[tile_id].first_prevpiv >= k) || arg[tile_id].first_prevpiv==-1  );
+        }
+    }
+    qrtree->args = (void*)arg;
+}
+
+void libhqr_matrix_finalize(libhqr_tree_t *qrtree){
+     libhqr_tileinfo_t *arg = (libhqr_tileinfo_t*)(qrtree->args);
+     free(arg);
+}
diff --git a/src/libhqr_dbg.c b/src/libhqr_dbg.c
index 46d82ef0a7e92db340cc4ab08271813c3cbd97cd..cc333f41fbafe64b3061bd13356f7dfc53c8f959 100644
--- a/src/libhqr_dbg.c
+++ b/src/libhqr_dbg.c
@@ -19,13 +19,16 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 /* static int libhqr_qrtree_getinon0( const qr_piv_t *arg,  */
 /*                                 const int k, int i, int mt ); */
 
 #define ENDCHECK( test, ret )                   \
-    if ( !test )                                \
-	return ret;
+    if ( !test ) {                              \
+        assert( ret == 0 );                     \
+        return ret;                             \
+    }
 
 int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree)
 {
@@ -152,7 +155,7 @@ int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree)
 			   a, p, A->mt, A->nt,
 			   m, k);
 		    check = 0;
-		    return 3;
+                    ENDCHECK( check, 3 );
 		}
 	    }
 	}
@@ -195,7 +198,7 @@ int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree)
 			   a, p, A->mt, A->nt,
 			   m, k);
 		    check = 0;
-		    return 3;
+                    ENDCHECK( check, 3 );
 		}
 	    }
 	}
@@ -227,11 +230,11 @@ int libhqr_tree_check( libhqr_tiledesc_t *A, libhqr_tree_t *qrtree)
 			printf(" ----------------------------------------------------\n"
 			       "  - a = %d, p = %d, M = %d, N = %d\n"
 			       "     Check next/prev:\n"
-			       "       next( m=%d, k=%d, start=%d ) => %d && prev( m=%d, k=%d, start=%d ) => %d\n ( %d != %d )",
+			       "       next( k=%d, m=%d, start=%d ) => %d && prev( k=%d, m=%d, start=%d ) => %d (instead of %d)\n",
 			       a, p, A->mt, A->nt,
-			       m, k, start, next, m, k, next, prev, start, prev);
-			check = 0;
-			return 3;
+			       k, m, start, next, k, m, next, prev, start);
+                        check = 0;
+			ENDCHECK( check, 3 );
 		    }
 		    start = next;
 		} while ( start != A->mt );
diff --git a/src/libhqr_systolic.c b/src/libhqr_systolic.c
index 66153a3b0e66ccefdbc371c6aef8167cb8e87da9..d66d3bb9666b06bd142ad055f2e7f84d1b665248 100644
--- a/src/libhqr_systolic.c
+++ b/src/libhqr_systolic.c
@@ -19,6 +19,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #define PRINT_PIVGEN 0
 #ifdef PRINT_PIVGEN
@@ -352,6 +353,8 @@ libhqr_systolic_init( libhqr_tree_t *qrtree,
 		       libhqr_typefacto_e trans, libhqr_tiledesc_t *A,
 		       int p, int q )
 {
+    libhqr_tree_t qrtree_init;
+
     if (qrtree == NULL) {
 	fprintf(stderr, "libhqr_systolic_init, illegal value of qrtree");
 	return -1;
@@ -374,20 +377,39 @@ libhqr_systolic_init( libhqr_tree_t *qrtree,
 	return -5;
     }
 
+    /* Create a temporary qrtree structure based on the functions */
+    {
+        qrtree_init.getnbgeqrf = systolic_getnbgeqrf;
+        qrtree_init.getm       = systolic_getm;
+        qrtree_init.geti       = systolic_geti;
+        qrtree_init.gettype    = systolic_gettype;
+        qrtree_init.currpiv    = systolic_currpiv;
+        qrtree_init.nextpiv    = systolic_nextpiv;
+        qrtree_init.prevpiv    = systolic_prevpiv;
+
+        qrtree_init.mt   = (trans == LIBHQR_QR) ? A->mt : A->nt;
+        qrtree_init.nt   = (trans == LIBHQR_QR) ? A->nt : A->mt;
+
+        qrtree_init.a    = libhqr_imax( q, 1 );
+        qrtree_init.p    = libhqr_imax( p, 1 );
+        qrtree_init.args = NULL;
+    }
+
+    memcpy( qrtree, &qrtree_init, sizeof(libhqr_tree_t) );
     qrtree->getnbgeqrf = systolic_getnbgeqrf;
     qrtree->getm       = systolic_getm;
     qrtree->geti       = systolic_geti;
-    qrtree->gettype    = systolic_gettype;
-    qrtree->currpiv    = systolic_currpiv;
-    qrtree->nextpiv    = systolic_nextpiv;
-    qrtree->prevpiv    = systolic_prevpiv;
+    qrtree->gettype    = rdmtx_gettype;
+    qrtree->currpiv    = rdmtx_currpiv;
+    qrtree->nextpiv    = rdmtx_nextpiv;
+    qrtree->prevpiv    = rdmtx_prevpiv;
+    qrtree->args       = malloc( qrtree->mt * qrtree->nt * sizeof(libhqr_tileinfo_t) );
 
-    qrtree->mt   = (trans == LIBHQR_QR) ? A->mt : A->nt;
-    qrtree->nt   = (trans == LIBHQR_QR) ? A->nt : A->mt;
+    /*Initialize the matrix */
+    libhqr_matrix_init(qrtree, &qrtree_init);
 
-    qrtree->a    = libhqr_imax( q, 1 );
-    qrtree->p    = libhqr_imax( p, 1 );
-    qrtree->args = NULL;
+    /* Free the initial qrtree */
+    libhqr_systolic_finalize( &qrtree_init );
 
     return 0;
 }
diff --git a/testings/testing_pivgen.c b/testings/testing_pivgen.c
index 3fa5adde0a311b8dbcc183520723ca87cd2b784e..3b805735395defff14c665540cc4f458a6c0f216 100644
--- a/testings/testing_pivgen.c
+++ b/testings/testing_pivgen.c
@@ -76,8 +76,10 @@ int main(int argc, char ** argv)
 		fprintf(stderr, "-M %d -N %d --treel=%d --qr_a=%d --tsrr=%d                                   FAILED(%d)\n",
 			allM[m], allN[n], alltreel[l], allA[a], r, rc);
 		ret |= 1;
+                libhqr_matrix_finalize( &qrtree );
+                return 0;
 	      }
-	      libhqr_hqr_finalize( &qrtree );
+	      libhqr_matrix_finalize( &qrtree );
 
 	      done++;
 	      printf("\r%6d / %6d", done, todo);
@@ -110,7 +112,7 @@ int main(int argc, char ** argv)
 		      ret |= 1;
 		    }
 
-		    libhqr_hqr_finalize( &qrtree );
+		    libhqr_matrix_finalize( &qrtree );
 
 		    done++;
 		    printf("\r%6d / %6d", done, todo);
@@ -145,7 +147,7 @@ int main(int argc, char ** argv)
 	      ret |= 1;
 	    }
 
-	    libhqr_systolic_finalize( &qrtree );
+	    libhqr_matrix_finalize( &qrtree );
 
 	    done++;
 	    printf("\r%6d / %6d", done, todo);
diff --git a/testings/testing_tileinit.c b/testings/testing_tileinit.c
new file mode 100644
index 0000000000000000000000000000000000000000..895aa63781f4c5a173e1c8b0f688f60a2b981bc5
--- /dev/null
+++ b/testings/testing_tileinit.c
@@ -0,0 +1,40 @@
+/**
+ *
+ * @file testting_tileinit.c
+ *
+ * Testing file for the functions stocking the informations of the tiles
+ *
+ * @copyright 2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ * @version 1.0.0
+ * @author Raphael Boucherie
+ * @author Mathieu Faverge
+ * @date 2017-04-18
+ *
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "libhqr.h"
+
+int
+main(int argc, char ** argv)
+{
+    int rc;
+    libhqr_tree_t qrtree;
+    libhqr_tiledesc_t matrix;
+
+    memset( &qrtree, 0xdeadbeef, sizeof(libhqr_tree_t) );
+    matrix.nodes = 1;
+    matrix.p     = 3;
+    matrix.mt    = 1;
+    matrix.nt    = 1;
+    libhqr_hqr_init( &qrtree, LIBHQR_QR, &matrix, 0, 0, 1, 3, 0, 0);
+    rc = libhqr_tree_check( &matrix, &qrtree );
+    libhqr_hqr_finalize( &qrtree );
+    return 1;
+}