[MN-dev] [mndiff]: r134 - trunk/noe/ldpc.c

michael subversion at mplayerhq.hu
Fri Apr 10 12:56:45 CEST 2009


Author: michael
Date: Fri Apr 10 12:56:45 2009
New Revision: 134

Log:
Solve matrix only partially and use sparse vectors during correction.
about twice as fast

Modified:
   trunk/noe/ldpc.c

Modified: trunk/noe/ldpc.c
==============================================================================
--- trunk/noe/ldpc.c	Wed Apr  1 11:16:50 2009	(r133)
+++ trunk/noe/ldpc.c	Fri Apr 10 12:56:45 2009	(r134)
@@ -35,7 +35,7 @@
 
 typedef struct LDPCContext{
     unsigned int (*parity_matrix)[2][MAX_NZC];
-    GFF4Element *inv_matrix;
+    GFF4Element (*inv_matrix)[2];
     int parity_len;
     int data_len;
     int nzc;
@@ -69,17 +69,7 @@ int inverse(ELEM *matrix, int width, int
             }
         }
     }
-    for(i=p-1; i>0; i--){
-        for(m=i; m<width; m++)
-            logline[m]= EXT(log)[matrix[m + i*width]];
-        for(k=0; k<i; k++){
-            if(matrix[i + k*width]){
-                unsigned int factor= EXT(log)[neg(matrix[i + k*width])];
-                for(m=i; m<width; m++)
-                    matrix[m + k*width] = sum(matrix[m + k*width], EXT(exp)[logline[m] + factor]);
-            }
-        }
-    }
+
     return p;
 }
 
@@ -104,7 +94,8 @@ LDPCContext *EXT(initLDPC)(int data_len,
     init_random(&kiss, seed);
 
     c->parity_matrix= malloc(code_len * sizeof(*c->parity_matrix));
-    c->   inv_matrix= malloc(parity_len*parity_len * sizeof(*c->inv_matrix));
+    c->   inv_matrix= malloc(parity_len*(parity_len+1) * sizeof(*c->inv_matrix)*2);
+//FIXME could we in theory need more space?
 
     memset(row, 0, sizeof(row));
     for(i=0; i<code_len; i++){
@@ -187,9 +178,16 @@ int EXT(init_matrixLDPC)(LDPCContext *c,
     }
 
     rank= inverse(inv_matrix, 2*parity_len, parity_len, erasure_count);
-    for(j=0; j<erasure_count; j++)
-        for(i=0; i<parity_len; i++)
-            c->inv_matrix[i + j*parity_len]= EXT(log)[inv_matrix[i + j*2*parity_len + parity_len]];
+    x=0;
+    for(j=erasure_count-1; j>=0; j--){
+        for(i=0; i<parity_len*2; i++){
+            if(i != j && inv_matrix[i + j*2*parity_len]){
+                c->inv_matrix[x  ][0]= i;
+                c->inv_matrix[x++][1]= EXT(log)[inv_matrix[i + j*2*parity_len]];
+            }
+        }
+        c->inv_matrix[x++][0]= 2*parity_len;
+    }
 
     free(inv_matrix);
     return rank - erasure_count;
@@ -199,7 +197,7 @@ int EXT(decodeLDPC)(LDPCContext *c, uint
     int i,j;
     int parity_len= c->parity_len;
     int   code_len= c->data_len + parity_len;
-    GFF4Element syndrom[c->parity_len];
+    GFF4Element syndrom[2*c->parity_len];
     memset(syndrom, 0, sizeof(syndrom));
 
     for(i=0; i<erasure_count; i++)
@@ -208,20 +206,25 @@ int EXT(decodeLDPC)(LDPCContext *c, uint
     for(i=0; i<code_len; i++){
         GFF4Element v= EXT(log)[ code[i] ];
         for(j=0; j<c->nzc; j++){
-            int y= c->parity_matrix[i][0][j];
+            int y= c->parity_matrix[i][0][j] + c->parity_len;
             int p= c->parity_matrix[i][1][j];
             syndrom[y]= sum(syndrom[y], EXT(exp)[p + v]);
         }
     }
 
-    for(i=0; i<parity_len; i++)
+    for(i=parity_len; i<2*parity_len; i++)
         syndrom[i]= EXT(log)[ syndrom[i] ];
 
-    for(i=0; i<erasure_count; i++){
+    j=0;
+    for(i=erasure_count-1; i>=0; i--){
         GFF4Element v=0;
-        for(j=0; j<parity_len; j++){
-            v= sum(v, EXT(exp)[syndrom[j] + c->inv_matrix[j + i*parity_len]]);
+        int idx= c->inv_matrix[j][0];
+        while(idx<2*parity_len){
+            v= sum(v, EXT(exp)[syndrom[idx] + c->inv_matrix[j++][1]]);
+            idx= c->inv_matrix[j][0];
         }
+        j++;
+        syndrom[i] = EXT(log)[ v ];
         code[ erasure_pos[i] ]= v;
     }
 



More information about the Mndiff-dev mailing list