[MN-dev] [mndiff]: r80 - in trunk/noe: filerw.c galois.c noe.c rs.c rw.c test.c

michael subversion at mplayerhq.hu
Tue Jul 10 00:42:52 CEST 2007


Author: michael
Date: Tue Jul 10 00:42:52 2007
New Revision: 80

Log:
version from unknown date but definitly before 2006-06-16 20:48


Modified:
   trunk/noe/filerw.c
   trunk/noe/galois.c
   trunk/noe/noe.c
   trunk/noe/rs.c
   trunk/noe/rw.c
   trunk/noe/test.c

Modified: trunk/noe/filerw.c
==============================================================================
--- trunk/noe/filerw.c	(original)
+++ trunk/noe/filerw.c	Tue Jul 10 00:42:52 2007
@@ -45,7 +45,10 @@ static int fileIO(noe_RwContext *c, uint
             uint64_t currentLen= pos - p->end[i];
             if(currentLen > len) currentLen= len;
             if(currentLen <= 0) return -1;
-            
+
+            if(fseek(p->file[i], pos - (i ? p->end[i-1] : 0), SEEK_SET))
+                return -1;
+
             if(write)
                 e= fwrite(data, currentLen, 1, p->file[i]);
             else

Modified: trunk/noe/galois.c
==============================================================================
--- trunk/noe/galois.c	(original)
+++ trunk/noe/galois.c	Tue Jul 10 00:42:52 2007
@@ -48,11 +48,21 @@ void noe_init(){
 /**
  * ...
  */
-int noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
+void noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+    const int order1= *src1++;
+    const int order2= *src2++;
     int order= order1 + order2;
     int i;
 
-    if(order1*order2 < (order1+order2)*64){
+    if((order1==0 && src1[0]==0) || 
+       (order2==0 && src2[0]==0)){
+        SET_POLY0(dst, 0);
+        return;
+    }
+
+    *dst++= order;
+
+    if(order1*order2 <= (order1+order2)*64){
         for(i=order; i>=0; i--){
             unsigned int acc=0;
             int j, end;
@@ -87,19 +97,23 @@ int noe_prodPoly(GFF4Element *dst, GFF4E
         noe_igfft(temp[0], temp[0], logSize);
         memcpy(dst, temp[0], sizeof(GFF4Element)*(order+1));
     }
-
-    return order;
 }
 
 /**
  * returns the first order2 coefficients of the product of the 2 polynoms.
  * Note dst must be at least 2^log2(order1+order2) big FIXME benchmark if its worth it
  */
-int noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
-    const int order= order2;
+void noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order){
+    int order1= *src1++;
+    int order2= *src2++;
     int i;
-    
-    if(order1*order2 < (order1+order2)*64){
+
+    *dst++= order;
+
+    if(order < order1) order1= order;
+    if(order < order2) order2= order;
+
+    if(order1*order2 <= (order1+order2)*64){
         for(i=order; i>=0; i--){
             unsigned int acc=0;
             int j, end;
@@ -113,7 +127,7 @@ int noe_partialProdPoly(GFF4Element *dst
             dst[i]= reduce(acc);
         }
     }else{
-        const int logSize= noe_log2(order2 + order1)+1;
+        const int logSize= noe_log2(order1+order2)+1;
         const int size= 1<<logSize;
         GFF4Element temp[size]; //FIXME is this fast?
         const GFF4Element scale= inv(size);
@@ -134,14 +148,14 @@ int noe_partialProdPoly(GFF4Element *dst
         noe_igfft(dst, dst, logSize);
     }
 
-    return order;
+    noe_getOrder(dst-1);
 }
 
-void noe_printPoly(GFF4Element *src, int order){
+void noe_printPoly(GFF4Element *src){
     int i;
     
-    for(i=order; i>=0; i--){
-        printf(" + %X*x^%d", src[i], i);
+    for(i=src[0]+1; i>0; i--){
+        printf(" + %X*x^%d", src[i], i-1);
     }
     printf("\n");
 }
@@ -149,25 +163,24 @@ void noe_printPoly(GFF4Element *src, int
 /**
  * Evaluates the src polynom at x.
  */
-GFF4Element noe_evalPoly(GFF4Element *src, int order, GFF4Element x){
+GFF4Element noe_evalPoly(GFF4Element *src, GFF4Element x){
     unsigned int acc=0;
     int j;
 
-    for(j=order; j>=0; j--){
+    for(j=src[0]+1; j>0; j--){
         acc = sum(prod(acc, x), src[j]);
     }
 
     return acc;
 }
 
-int noe_getDerivative(GFF4Element *dst, GFF4Element *src, int order){
+void noe_getDerivative(GFF4Element *dst, GFF4Element *src){
     int i;
-    
-    for(i=0; i<order; i++){
-        dst[i  ]= prod(src[i+1], i+1);
-    }
 
-    return order-1;
+    for(i=1; i<=src[0]; i++){
+        dst[i  ]= prod(src[i+1], i);
+    }
+    dst[0]= src[0]-1;
 }
 
 /**
@@ -177,10 +190,11 @@ void noe_synthPoly(GFF4Element *dst, GFF
     if(count<20){
         int i;
 
-        dst[0]= 1;
+        SET_POLY0(dst, 1);
 
         for(i=0; i<count; i++){
-            noe_prodPoly(dst, dst, src+2*i, i, 1);
+            assert(src[3*i] == 1);
+            noe_prodPoly(dst, dst, src+3*i);
         }
     }else{
         int pass, i, countLeft;
@@ -195,11 +209,10 @@ void noe_synthPoly(GFF4Element *dst, GFF
     //  noe_printPoly(src+2, 1);
 
         for(i=0; i<(count>>1); i++){
-            noe_prodPoly(temp[0]+4*i, src+4*i, src+4*i+2, 1, 1);
+            noe_prodPoly(temp[0]+4*i, src+6*i, src+6*i+3);
         }
         if(count&1){
-            memcpy(temp[0]+4*i, src+4*i, 2*sizeof(GFF4Element));
-            temp[0][4*i+2]= 0;
+            memcpy(temp[0]+4*i, src+6*i, 3*sizeof(GFF4Element));
             countLeft++;
         }
         countLeft>>=1;
@@ -212,13 +225,11 @@ void noe_synthPoly(GFF4Element *dst, GFF
             GFF4Element *temp2= temp[(pass&1)^1];
 
             for(i=0; i<(countLeft>>1); i++){
-                noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step, step>>1, step>>1);
+                noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step);
             }
 
             if(countLeft&1){
-                int len= (step>>1) + 1;
-                memcpy(temp1+2*step*i       , temp2+2*step*i, len*sizeof(GFF4Element));
-                memset(temp1+2*step*i + len , 0, step*sizeof(GFF4Element));
+                memcpy(temp1+2*step*i, temp2+2*step*i, step*sizeof(GFF4Element));
                 countLeft++;
             }
             countLeft>>=1;
@@ -228,31 +239,34 @@ void noe_synthPoly(GFF4Element *dst, GFF
 
     //  noe_printPoly(temp[0], count);
 
-        memcpy(dst, temp[(pass&1)^1], (count+1)*sizeof(GFF4Element));
+        memcpy(dst, temp[(pass&1)^1], (count+2)*sizeof(GFF4Element));
     //  noe_printPoly(dst, count);
     }
 }
 
-int noe_getOrder(GFF4Element *src, int maxOrder){
-    while(maxOrder && src[maxOrder]==0) 
-        maxOrder--;
-
-    return maxOrder;
+void noe_getOrder(GFF4Element *src){
+    while(src[0] && src[ src[0] + 1 ]==0) 
+        src[0]--;
 }
 
 /**
  * ...
  * Note: rem can be identical to nom
  */
-int noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom, int nomOrder, int denomOrder){
+void noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom){
+    const int nomOrder= *nom++;
+    const int denomOrder= *denom++;
     int i;
     int remOrder= nomOrder;
-    int quotOrder= 0;
+
+    *rem++= nomOrder;
+    *quot++= remOrder - denomOrder;
 
     if(rem != nom)
         memcpy(rem, nom, (nomOrder+1)*sizeof(GFF4Element));
 
-    denomOrder= noe_getOrder(denom, denomOrder);
+    assert(  nom[  nomOrder]);
+    assert(denom[denomOrder]);
 
     quot[0]=0;
 
@@ -269,34 +283,85 @@ int noe_divPoly(GFF4Element *quot, GFF4E
         }
 
         quot[remOrder - denomOrder]= scale;
-        if(quotOrder==0)
-            quotOrder= remOrder - denomOrder;
     }
-    
-    return noe_getOrder(rem, remOrder);
+
+    noe_getOrder(rem-1);
 }
 
-int noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
+void noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+    const int order1= *src1++;
+    const int order2= *src2++;
     int i;
     int minOrder= NOE_MIN(order1, order2);
 
+    *dst++= order1;
+
     for(i=0; i<=minOrder; i++){
         dst[i]= sum(src1[i], SIZE - src2[i]);
     }
     
     if(order1==order2){
-        return noe_getOrder(dst, order1);
+        noe_getOrder(dst-1);
     }else{
-        if(dst!=src1){
-            for(; i<=order1; i++){
-                dst[i]= src1[i];
-            }
-        }
+        if(dst!=src1)
+            memcpy(dst+i, src1+i, (i-1-order1)*sizeof(GFF4Element));
 
         for(; i<=order2; i++){
             dst[i]= SIZE - src2[i];
         }
 
-        return NOE_MAX(order1, order2);;
+        dst[-1]= NOE_MAX(order1, order2);
+    }
+}
+
+void noe_sumPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+    const int order1= *src1++;
+    const int order2= *src2++;
+    int i;
+    int minOrder= NOE_MIN(order1, order2);
+
+    *dst++= order1;
+
+    for(i=0; i<=minOrder; i++){
+        dst[i]= sum(src1[i], src2[i]);
+    }
+    
+    if(order1==order2){
+        noe_getOrder(dst-1);
+    }else if(order1 < order2){
+        dst[-1]= order2;
+        if(dst!=src2)
+            memcpy(dst+i, src2+i, (order2 - order1)*sizeof(GFF4Element));
+    }else{
+        if(dst!=src1)
+            memcpy(dst+i, src1+i, (order1 - order2)*sizeof(GFF4Element));
+    }
+}
+
+void noe_scaledSumPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, GFF4Element f, int s){
+    const int order1= *src1++;
+    const int order2= *src2++; //FIXME +s
+    int i;
+    int minOrder= NOE_MIN(order1, order2+s);
+
+    *dst++= order1;
+
+    for(i=0; i<s; i++)
+        dst[i]= src1[i];
+    for(   ; i<=minOrder; i++)
+        dst[i]= sum(src1[i], prod(src2[i-s], f));
+
+    if(order1==order2 + s){
+        noe_getOrder(dst-1);
+    }else{
+        if(dst!=src1)
+            memcpy(dst+i, src1+i, (order1+1-i)*sizeof(GFF4Element));
+
+        for(; i<=order2+s; i++){
+            dst[i]= prod(src2[i-s], f);
+        }
+
+        dst[-1]= NOE_MAX(order1, order2+s);
+        noe_getOrder(dst-1); //FIXME we need this due to src2= 0
     }
 }

Modified: trunk/noe/noe.c
==============================================================================
--- trunk/noe/noe.c	(original)
+++ trunk/noe/noe.c	Tue Jul 10 00:42:52 2007
@@ -46,6 +46,9 @@ typedef struct NoeContext{
     int dataSize;
     int fileIdThreshold;
     int version;
+    int interleave;
+    int parity_per_header;              ///< number of parity symbols (16bit) per header
+    int cw_per_pass;
 //    uint8_t header[HEADER_LENGTH];
     int header[HEADER_LENGTH][256];
     uint32_t *fingerprint;
@@ -113,12 +116,12 @@ static int decode_header(NoeContext *n, 
     const int k= SIZE - 1 - HEADER_PARITY_LENGTH;
     GFF4Element erased[HEADER_PARITY_LENGTH];
     GFF4Element code[nn];
-    int i,j;
+    int i,j,dataword_size, file_parity_size;
 
     for(j=0; j<8; j++){
         buffer[j] = startcode[j];
     }
-    
+
     for(i=12; i<HEADER_DATA_LENGTH; i++){
         int best=0;
         int bestScore=0;
@@ -137,7 +140,7 @@ static int decode_header(NoeContext *n, 
 
     memset(code, 0, sizeof(GFF4Element)*nn);
     for(i=0; 2*i<HEADER_DATA_LENGTH; i++){
-        code[i  ]= get_c(&bs, 2);
+        code[i  ]= get_c(&bs, 2); //FIXME change to 1
     }
     for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
         code[k+i]= get_c(&bs, 2);
@@ -186,6 +189,11 @@ static int decode_header(NoeContext *n, 
     n->fingerprintCount= get_c(&bs, 2);
     n->dataSize= get_c(&bs, 8);
 
+    dataword_size= 2*(65535 - n->parityCount);
+    n->interleave= (n->dataSize + dataword_size - 1)/dataword_size;
+    file_parity_size= n->interleave * n->parityCount;
+    n->parity_per_header= (file_parity_size + n->headerCount - 1)/n->headerCount;
+
     for(i=12; i<HEADER_DATA_LENGTH; i++){
         n->header[i][ buffer[i] ]= INT_MAX/2;
     }
@@ -199,14 +207,13 @@ static int decode_header(NoeContext *n, 
  * @return -1 if not found
  */
 static int find_and_decode_global_header(NoeContext *n, noe_RwContext *rw){
-    int length= BUFFER_LENGTH;
     uint64_t i;
-    uint8_t buffer[length];
+    uint8_t buffer[BUFFER_LENGTH];
 
-    for(i=rw->size; i>=0; i-= length - HEADER_LENGTH){
+    for(i=rw->size; i>=0; i-= BUFFER_LENGTH - HEADER_LENGTH){
+        int length= MIN(BUFFER_LENGTH, i);
         int pos;
 
-        if(i < length) length= i;
         rw->io(rw, buffer, i - length, length, 0);
 
         for(pos=0; ; pos++){
@@ -222,7 +229,6 @@ static int find_and_decode_global_header
             if( decode_header(n, buffer + pos) >= 0)
                 return 0;
         }
-        length= BUFFER_LENGTH;
     }
 
     return -1;
@@ -247,7 +253,7 @@ static int decode_fingerprints(NoeContex
         const int index= n->seqNum + i*n->headerCount;
         const int expectedChecksum= getChecksum(c, index);
 
-        if(expectedChecksum == checksum){
+        if(expectedChecksum == checksum && !n->fingerprintOk[index]){
             n->fingerprintOk[index]= 1;
             n->fingerprint[index]= c;
             n->fingerprintOk_count++;
@@ -261,19 +267,18 @@ static int decode_fingerprints(NoeContex
  * @return -1 if not found
  */
 static int find_and_decode_packets(NoeContext *n, noe_RwContext *rw){
-    int length= BUFFER_LENGTH;
     const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
     uint64_t i;
-    uint8_t buffer[length];
+    uint8_t buffer[BUFFER_LENGTH];
 
     n->fingerprint  = malloc(n->fingerprintCount*n->headerCount * sizeof(int));
     n->fingerprintOk= malloc(n->fingerprintCount*n->headerCount);
     memset(n->fingerprintOk, 0, n->fingerprintCount*n->headerCount);
 
-    for(i=rw->size; i>=0; i-= length - packetLength){
+    for(i=rw->size; i>=0; i-= BUFFER_LENGTH - packetLength){
+        int length= MIN(BUFFER_LENGTH, i);
         int pos;
 
-        if(i < length) length= i;
         rw->io(rw, buffer, i - length, length, 0);
 
         for(pos=0; ; pos++){
@@ -287,9 +292,8 @@ static int find_and_decode_packets(NoeCo
 
             decode_fingerprints(n, buffer + pos, length - pos);
         }
-        length= BUFFER_LENGTH;
 
-        if(n->fingerprintOk_count >= n->fingerprintCount*n->headerCount*15/16)
+        if(n->fingerprintOk_count >= n->fingerprintCount*n->headerCount*15/16) //FIXME
             break;
     }
 
@@ -300,7 +304,7 @@ static int match_fingerprints(NoeContext
     int length= BUFFER_LENGTH;
 //    const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
     uint64_t i;
-    uint8_t buffer[length];
+    uint8_t buffer[BUFFER_LENGTH];
 
     for(i=0; i<n->fingerprintCount*n->headerCount; i++){
         if(!n->fingerprintOk[i])
@@ -322,4 +326,81 @@ static int match_fingerprints(NoeContext
 //    setup remap table
 }
 
-//decode data into another file
+//reorder data based on fingerprint matches
+
+static int correct(NoeContext *n, noe_RwContext *out, noe_RwContext *in){
+    uint8_t buffer[BUFFER_LENGTH];
+    int passes, pass, i;
+    const int nn= SIZE - 1;
+//    const int k= SIZE - 1 - HEADER_PARITY_LENGTH;
+    GFF4Element erased[/*HEADER_PARITY_LENGTH*/nn];
+    const int erasedCount=0;
+    GFF4Element (*code)[nn];
+    const int packet_size= HEADER_LENGTH + 5*n->fingerprintCount + 2*n->parity_per_header;
+    int uncorrectable=0;
+
+    assert(2*packet_size <= BUFFER_LENGTH);
+
+    n->cw_per_pass= 32; //4mb storege
+
+    code= malloc(n->cw_per_pass*nn*sizeof(GFF4Element));
+    passes= (n->interleave + n->cw_per_pass - 1) / n->cw_per_pass;
+
+    for(pass=0; pass<passes; pass++){
+        int first_cw= n->interleave* pass    / passes;
+        int  next_cw= n->interleave*(pass+1) / passes;
+
+        memset(code, 0, n->cw_per_pass*nn*sizeof(GFF4Element));
+
+        for(i=0; i<in->size; i+= BUFFER_LENGTH - packet_size){
+            int length= MIN(BUFFER_LENGTH, in->size - i);
+            int pos;
+
+            in->io(in, buffer, i, length, 0);
+
+            for(pos=0; ; pos++){
+                int j;
+                pos += find_header(n, buffer + pos, length - pos);
+                if(pos + packet_size > length) break;
+
+                if( decode_header(n, buffer + pos) < 0 )
+                    continue;
+                pos += HEADER_LENGTH + 5*n->fingerprintCount;
+
+                for(j=0; j<n->parity_per_header; pos+=2, j++){
+                    int j2= j + n->seqNum*n->parity_per_header;
+                    int cw_id = j2 % n->interleave;//FIXME optimize
+                    int cw_pos= j2 / n->interleave;
+                    if(cw_id < first_cw || cw_id >= next_cw)
+                        continue;
+                    code[cw_id - first_cw][cw_pos]= 256*buffer[pos] + buffer[pos+1];
+                }
+            }
+
+            assert(i%2==0);
+            for(pos=0; pos<length; pos+=2){
+                int cw_id = ((i+pos)/2) % n->interleave; //FIXME optimize
+                int cw_pos= ((i+pos)/2) / n->interleave; //FIXME optimize
+                if(i+pos >= n->dataSize)
+                    break;
+                if(cw_id < first_cw || cw_id >= next_cw)
+                    continue;
+                code[cw_id - first_cw][cw_pos]= 256*buffer[pos] + buffer[pos+1];
+            }
+        }
+        if(noe_rsDecode(code, NULL/*erased*/, erasedCount, n->parityCount) < 0)
+            uncorrectable++;
+
+//        write data
+    }
+
+    av_free(code);
+    return uncorrectable;
+}
+
+//main
+
+//encode mainheader
+//encode fingerprints
+//encoder parity
+

Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c	(original)
+++ trunk/noe/rs.c	Tue Jul 10 00:42:52 2007
@@ -28,25 +28,25 @@
 #include "gfft.h"
 
 
+#undef NDEBUG
+#include <assert.h>
+
 /**
  * 
  */
 void noe_getRsGenerator(GFF4Element *dst, int first, int order){
     int i;
-    GFF4Element factor[2*order];
-
-    factor[0]= SIZE - noe_exp[first];
-    factor[1]= 1;
+    GFF4Element factor[3*order];
 
-    for(i=1; i<order; i++){
-        factor[2*i+0]= prod(factor[2*i-2], PRIMITIVE_ELEMENT);
-        factor[2*i+1]= 1;
+    for(i=0; i<order; i++){
+        SET_POLY1(factor+3*i, SIZE - noe_exp[ first + i ], 1);
     }
     
     noe_synthPoly(dst, factor, order);
 }
 
 void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int order){
+    *syn++= order;
     noe_gfft(syn, src, 16);
     noe_permute(syn, syn, order+1);
 
@@ -62,22 +62,19 @@ noe_RsEncoder *noe_getRsEncoder(int pari
     const int dataCount= SIZE - parityCount - 1;
     int i;  
     GFF4Element *locator, *factor;
-    GFF4Element locatorDerivative[parityCount];
+    GFF4Element locatorDerivative[parityCount+1];
     noe_RsEncoder *encoder= memalign(16, sizeof(noe_RsEncoder));
+    GFF4Element locationFactor[3*parityCount];
     
-    locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+1));
+    locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+2));
     factor=  encoder->parityFactor = memalign(16, sizeof(GFF4Element)* parityCount   );
 
     encoder->parityCount= parityCount;
     
-    locator[0]= 1;
     for(i=0; i<parityCount; i++){
-        GFF4Element locationFactor[2];
-            
-        locationFactor[0] = 1;
-        locationFactor[1] = SIZE - noe_exp[dataCount + i];
-        noe_prodPoly(locator, locator, locationFactor, i, 1); //FIXME use synthPoly
+        SET_POLY1(locationFactor+3*i, 1, SIZE - noe_exp[dataCount + i]);
     }
+    noe_synthPoly(locator, locationFactor, parityCount);
 #if 0
 for(i=0; i<parityCount; i++){
     if(noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount + i]))){
@@ -87,8 +84,8 @@ for(i=0; i<parityCount; i++){
 if(!noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount - 1])))
     printf("Internal Error 2\n");
 #endif
-    i= noe_getDerivative(locatorDerivative, locator, parityCount);
-    assert(i==parityCount-1);
+    noe_getDerivative(locatorDerivative, locator);
+    assert(locatorDerivative[0] == parityCount-1);
 
     for(i=0; i<parityCount; i++){
         GFF4Element X= noe_exp[dataCount + i];
@@ -97,7 +94,7 @@ if(!noe_evalPoly(locator, parityCount, i
         
         assert(X == inv(invX));
 
-        denom= noe_evalPoly(locatorDerivative, parityCount-1, invX); //FIXME do in freq domain if parityCount>1000
+        denom= noe_evalPoly(locatorDerivative, invX); //FIXME do in freq domain if parityCount>1000
         factor[i]= prod(SIZE - X, inv(denom));
     }
     
@@ -123,8 +120,8 @@ void noe_rsEncode(noe_RsEncoder *encoder
     int i;
     const int parityCount= encoder->parityCount;
     const int dataCount= SIZE - parityCount - 1;
-    GFF4Element syn[SIZE - 1];
-    GFF4Element omega[SIZE - 1];
+    GFF4Element syn[SIZE];
+    GFF4Element omega[SIZE];
     GFF4Element *locator= encoder->parityLocator;
     GFF4Element *factor= encoder->parityFactor;
 
@@ -132,13 +129,13 @@ void noe_rsEncode(noe_RsEncoder *encoder
     
     noe_getSyndrom(syn, data, parityCount);
 
-    noe_partialProdPoly(omega, locator, syn, parityCount, parityCount);
+    noe_partialProdPoly(omega, locator, syn, syn[0]);
     
     if(parityCount < 1000){
         for(i=0; i<parityCount; i++){
             GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
             
-            GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
+            GFF4Element parity= prod(noe_evalPoly(omega, invX), factor[i]);
             
             data[dataCount + i]= SIZE - parity;
         }
@@ -153,12 +150,12 @@ void noe_rsEncode(noe_RsEncoder *encoder
             data[dataCount + i]= SIZE - parity;
         }
 #else
-        memset(omega + parityCount + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
-        noe_gfft(omega, omega, 16);
+        memset(omega + parityCount + 1 + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
+        noe_gfft(omega+1, omega+1, 16);
         for(i=0; i<parityCount; i++){
             int index= SIZE - dataCount - i - 1;
             
-            GFF4Element parity= prod(omega[noe_bitReverse(index)], factor[i]);
+            GFF4Element parity= prod(omega[noe_bitReverse(index)+1], factor[i]);
             
             data[dataCount + i]= SIZE - parity;
         }
@@ -168,66 +165,269 @@ void noe_rsEncode(noe_RsEncoder *encoder
 }
 #endif
 
+#define XCHG(a,b) {void *tmp= a; a= b; b= tmp;}
+
+static void lehmer(GFF4Element *ma[2], GFF4Element *mb[2], GFF4Element *a, GFF4Element *b, int len){
+    int j;
+    int end= a[0] + b[0] - len;
+    assert(a[0] >= b[0]);
+
+//    assert(len);
+//printf("In %d %d %d len=%d\n", level, a[0], b[0], len);
+    if(len > 256){
+        int max;
+        int len2= len>>1;
+        GFF4Element a_tmp[4*len];
+        GFF4Element b_tmp[4*len];
+        GFF4Element m2[4][2*len];
+        GFF4Element *ma2[2]= {m2[0], m2[1]};
+        GFF4Element *mb2[2]= {m2[2], m2[3]};
+        assert(len-1 <= a[0]);
+        assert(len-1 <= b[0]);
+        a_tmp[0]= a[0] - b[0] + len2-1;
+        b_tmp[0]=               len2-1;
+        max= a[0] - a_tmp[0];
+        memcpy(a_tmp+1, a+1+a[0]-a_tmp[0], (a_tmp[0]+1)*sizeof(GFF4Element));
+        memcpy(b_tmp+1, b+1+b[0]-b_tmp[0], (b_tmp[0]+1)*sizeof(GFF4Element));
+        lehmer(ma, mb, a_tmp, b_tmp, len2);
+
+        max+= NOE_MAX(a_tmp[0], b_tmp[0]);
+
+        noe_partialProdPoly(a_tmp, b, ma[1], max);
+        noe_partialProdPoly(b_tmp, a, mb[0], max);
+        noe_partialProdPoly(a    , a, ma[0], max);
+        noe_partialProdPoly(b    , b, mb[1], max);
+        noe_sumPoly(a, a, a_tmp);
+        noe_sumPoly(b, b, b_tmp);
+        len2= a[0] + b[0] - end;
+//printf("Mid %d %d %d len2=%d\n", level, a[0], b[0], len2);
+        if(len2 == 0)
+            return;
+            
+        assert(len2>0);
+        assert(len2 <= a[0]+1);
+        assert(len2 <= b[0]+1);
+
+        if(a[0] < b[0]){
+            XCHG(a,b);
+            XCHG(ma,mb);
+        }
+        j= b[0] + 1 - len2;
+        a[j]= a[0] - j;
+        b[j]= b[0] - j;
+        lehmer(ma2, mb2, a + j, b + j, len2);
+
+//printf("End %d %d %d\n", level, a[0], b[0]);
+
+        noe_prodPoly(a_tmp, ma[0], mb2[0]);
+        noe_prodPoly(ma[0], ma[0], ma2[0]);
+        noe_prodPoly(b_tmp, mb[0], ma2[1]);
+        noe_prodPoly(mb[0], mb[0], mb2[1]);
+        noe_sumPoly(ma[0], ma[0], b_tmp);
+        noe_sumPoly(mb[0], mb[0], a_tmp);
+
+        noe_prodPoly(a_tmp, ma[1], mb2[0]);
+        noe_prodPoly(ma[1], ma[1], ma2[0]);
+        noe_prodPoly(b_tmp, mb[1], ma2[1]);
+        noe_prodPoly(mb[1], mb[1], mb2[1]);
+        noe_sumPoly(ma[1], ma[1], b_tmp);
+        noe_sumPoly(mb[1], mb[1], a_tmp);
+    }else{
+        SET_POLY0(ma[0], 1);
+        SET_POLY0(ma[1], 0);
+        SET_POLY0(mb[0], 0);
+        SET_POLY0(mb[1], 1);
+
+        for(;;){
+            GFF4Element q= SIZE - prod(a[ a[0]+1 ], inv(b[ b[0]+1 ]));
+            int s= a[0] - b[0];
+
+            assert(s >= 0);
+            assert(a[ a[0]+1 ]);
+            assert(b[ b[0]+1 ]);
+
+            for(j=end - b[0] + 2; j<=a[0]; j++){
+                a[ j ] = sum(a[ j ], prod(q, b[ j-s ]));
+            }
+            a[0]--;
+
+            noe_scaledSumPoly(ma[0], ma[0], mb[0], q, s);
+            noe_scaledSumPoly(ma[1], ma[1], mb[1], q, s);
+
+            noe_getOrder(a);
+            if(a[0] + b[0] <= end)
+                return;
+            assert(a[0]!=0 || a[1]!=0);
+
+            if(a[0] < b[0]){
+                XCHG(a,b)
+                XCHG(ma,mb)
+            }
+        }
+    }
+}
+
+int noe_rsEuclid2(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+    int i;
+    GFF4Element quot[parityCount+2]; //FIXME size ok?
+
+    omega[0][0]= parityCount+1;
+    memset(omega[0]+1, 0, (parityCount+1)*sizeof(GFF4Element));
+    omega[0][parityCount+1+1]= 1;
+    SET_POLY0(locator[0], 0);
+    SET_POLY0(locator[1], 1);
+    
+    for(i=0; 1; i++){
+        GFF4Element a_tmp[SIZE];
+        GFF4Element b_tmp[SIZE];
+        GFF4Element m[4][SIZE];
+        GFF4Element *ma[2]= {m[0], m[1]};
+        GFF4Element *mb[2]= {m[2], m[3]};
+        int max;
+
+        const int di= i&1;
+        const int si= 1-di;
+        int len= 2*omega[si][0] - parityCount - erasureCount;
+//printf("%d %d\n", omega[si][0], omega[di][0]);
+        if(2*omega[si][0] <= parityCount + erasureCount)
+            return si;
+
+        if(len > omega[si][0]+1) len=omega[si][0]+1;
+        if(len>128 && omega[si][0]/2 < len) len= omega[si][0]/2;
+
+        assert(omega[si][ omega[si][0]+1 ]);
+
+        a_tmp[0]= omega[di][0] - omega[si][0] + len-1;
+        b_tmp[0]=                               len-1;
+        memcpy(a_tmp+1, omega[di]+1+omega[di][0]-a_tmp[0], (a_tmp[0]+1)*sizeof(GFF4Element));
+        memcpy(b_tmp+1, omega[si]+1+omega[si][0]-b_tmp[0], (b_tmp[0]+1)*sizeof(GFF4Element));
+        assert(b_tmp[ b_tmp[0]+1 ]);
+//printf("In 0 %d %d\n", omega[di][0], omega[si][0]);
+        lehmer(ma, mb, a_tmp, b_tmp, len);
+        max= omega[si][0] - (len-1) + NOE_MAX(a_tmp[0], b_tmp[0]);
+
+        noe_partialProdPoly(a_tmp, omega[si], ma[1], max);
+        noe_partialProdPoly(b_tmp, omega[di], mb[0], max);
+        noe_partialProdPoly(omega[di], omega[di], ma[0], max);
+        noe_partialProdPoly(omega[si], omega[si], mb[1], max);
+        noe_sumPoly(omega[di], omega[di], a_tmp);
+        noe_sumPoly(omega[si], omega[si], b_tmp);
+
+        noe_prodPoly(a_tmp, locator[si], ma[1]);
+        noe_prodPoly(b_tmp, locator[di], mb[0]);
+        noe_prodPoly(locator[di], locator[di], ma[0]);
+        noe_prodPoly(locator[si], locator[si], mb[1]);
+        noe_sumPoly(locator[di], locator[di], a_tmp);
+        noe_sumPoly(locator[si], locator[si], b_tmp);
+
+        if(omega[si][0] < omega[di][0])
+            i++;
+    }
+}
+
 /**
  * ...
  * @param omega must be parityCount+2 big
  */
-int noe_rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount, int *locatorOrderP, int *omegaOrderP){
-    int i, quotOrder;
-    int locatorOrder[2]= {0,0};
-    int omegaOrder[2]= {parityCount+1, -1};
+int noe_rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+    int i;
     GFF4Element quot[parityCount+2]; //FIXME size ok?
 
-    memset(omega[0], 0, (parityCount+1)*sizeof(GFF4Element));
-    omega[0][parityCount+1]= 1;
-    locator[0][0]=0;
-    locator[1][0]=1;
-    omegaOrder[1]= noe_getOrder(omega[1], parityCount);
+    omega[0][0]= parityCount+1;
+    memset(omega[0]+1, 0, (parityCount+1)*sizeof(GFF4Element));
+    omega[0][parityCount+1+1]= 1;
+    SET_POLY0(locator[0], 0);
+    SET_POLY0(locator[1], 1);
     
     for(i=0; 1; i++){
         const int di= i&1;
         const int si= 1-di;
-#ifdef DEBUG_EUCLID
-printf("Locator0:");noe_printPoly(locator[di], locatorOrder[di]);
-printf("Omega0:");noe_printPoly(omega[di], omegaOrder[di]);
-printf("Locator1:");noe_printPoly(locator[si], locatorOrder[si]);
-printf("Omega1:");noe_printPoly(omega[si], omegaOrder[si]);
-#endif
-        if(2*omegaOrder[si] <= parityCount + erasureCount)
-            break;
 
-        quotOrder= omegaOrder[di] - omegaOrder[si];
+        if(2*omega[si][0] <= parityCount + erasureCount)
+            return si;
 
-        omegaOrder[di]= noe_divPoly(quot, omega[di], omega[di], omega[si], omegaOrder[di], omegaOrder[si]);
+        noe_divPoly(quot, omega[di], omega[di], omega[si]);
 
-        quotOrder= noe_prodPoly(quot, quot, locator[si], quotOrder, locatorOrder[si]);
-        locatorOrder[di]= noe_diffPoly(locator[di], locator[di], quot, locatorOrder[di], quotOrder);
-#ifdef DEBUG_EUCLID
-printf("quot:");noe_printPoly(quot, quotOrder);
-printf("Locator:");noe_printPoly(locator[di], locatorOrder[di]);
-printf("Omega:");noe_printPoly(omega[di], omegaOrder[di]);
-#endif
+        noe_prodPoly(quot, quot, locator[si]);
+        noe_diffPoly(locator[di], locator[di], quot);
     }
+}
 
-    i++;
-    
-    *locatorOrderP= locatorOrder[i&1];
-    *omegaOrderP= omegaOrder[i&1];
+/**
+ * ...
+ * @param omega must be parityCount+2 big
+ */
+int noe_rsBerlekampMassey(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+    GFF4Element *syn= omega[1]+1; //yeah maybe we should clean this ...
+    int k, j;
+    GFF4Element oldDelta=0x10000;
+    GFF4Element *Tix= locator[0]+1;
+    GFF4Element *Lix= locator[1]+1;
+    GFF4Element *temp;
+    int Tshift= 1;
 
-    return i&1;
+    Tix[-1]=1;
+    Tix[ 0]=1;
+    SET_POLY0(Lix-1, 1);
+
+    for(k=1+erasureCount; k<=parityCount; k++){
+        const int k2= k - erasureCount;
+        GFF4Element delta= syn[k];
+
+        for(j=1; j<=Lix[-1]; j++)
+            delta+= prod(Lix[j], syn[k-j]);
+        delta= reduce(delta);
+
+        if(delta){
+            GFF4Element factor= prod(delta, oldDelta);
+            if(Lix[-1] >= k2 - Lix[-1]){
+                for(j=Tshift; j<=Tix[-1]; j++)
+                    Lix[j]= sum(Lix[j], prod(factor, Tix[j-Tshift]));
+            }else{
+                //Lix[-1] >= Tshift-1 has always been true during tests
+                //Tshift == 2 true in >99% of the cases
+                if(Tshift == 2 && Lix[-1]>0){
+                    for(j=Tix[-1]; j>Lix[-1]; j--)
+                        Tix[j]=             prod(factor, Tix[j-2]);
+                    for(; j>=2; j--)
+                        Tix[j]= sum(Lix[j], prod(factor, Tix[j-2]));
+                }else{
+                    for(j=Tix[-1]; j>NOE_MAX(Lix[-1], Tshift-1); j--)
+                        Tix[j]=             prod(factor, Tix[j-Tshift]);
+                    for(; j>=Tshift; j--)
+                        Tix[j]= sum(Lix[j], prod(factor, Tix[j-Tshift]));
+                }
+                for(; j>0; j--)
+                    Tix[j]= Lix[j];
+                Tshift=0;
+                temp= Tix; Tix= Lix; Lix= temp;
+                oldDelta= SIZE - inv(delta);
+                Lix[-1]= k2 - Tix[-1];
+            }
+        }
+        Tix[-1]++;
+        Tshift++;
+    }
+
+    assert(Lix[0]==1);
+
+    k= Tix-1 == locator[0];
+    noe_partialProdPoly(omega[k], Lix-1, syn-1, syn[-1]);
+
+    return k;
 }
 
 int noe_rsDecode(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
     int i;
-    int errorCount, psiOrder, gfftEval, omegaOrder, phantomErrorCount;
+    int errorCount, gfftEval, phantomErrorCount;
     const int dataCount= SIZE - 1 - parityCount;
     GFF4Element erasureLocator[erasureCount + 1];
-    GFF4Element erasureSynthSrc[erasureCount*2 + 1];
-    GFF4Element locator0[parityCount + 1];
-    GFF4Element locator1[parityCount + 1];
+    GFF4Element erasureSynthSrc[erasureCount*3 + 1];
+    GFF4Element locator0[parityCount + 1 + 1];
+    GFF4Element locator1[parityCount + 1 + 1];
     GFF4Element *locators[2]={locator0, locator1};
-    GFF4Element omega0[SIZE - 1];
-    GFF4Element omega1[SIZE - 1];
+    GFF4Element omega0[SIZE - 1 + 1];
+    GFF4Element omega1[SIZE - 1 + 1];
     GFF4Element *omegas[2]={omega0, omega1}; //FIXME clean this shit up
     GFF4Element *fErrorLocator, *errorLocator, *omega, *syn, *psi;
 
@@ -241,7 +441,7 @@ int noe_rsDecode(GFF4Element *data, int 
 
     noe_getSyndrom(syn, data, parityCount);
     for(i=1; i<=parityCount; i++){
-        if(syn[i]) break;
+        if(syn[i+1]) break;
     }
     if(i>parityCount)
         return 0;
@@ -250,8 +450,7 @@ int noe_rsDecode(GFF4Element *data, int 
     //FIXME check truncated symbols syndrom
 
     for(i=0; i<erasureCount; i++){
-        erasureSynthSrc[2*i + 0] = 1;
-        erasureSynthSrc[2*i + 1] = SIZE - noe_exp[erasure[i]];
+        SET_POLY1(erasureSynthSrc + 3*i, 1, SIZE - noe_exp[erasure[i]]);
     }
     noe_synthPoly(erasureLocator, erasureSynthSrc, erasureCount);
 //  noe_printPoly(erasureLocator, erasureCount);
@@ -261,13 +460,15 @@ for(i=0; i<erasureCount; i++){
     assert( eval==0);
 }
 #endif
-    noe_partialProdPoly(syn, erasureLocator, syn, erasureCount, parityCount);
-
-
-    i= noe_rsEuclid(locators, omegas, parityCount, erasureCount, &errorCount, &omegaOrder);
+    noe_partialProdPoly(syn, erasureLocator, syn, syn[0]);
+START_TIMER
+//    i= noe_rsBerlekampMassey(locators, omegas, parityCount, erasureCount);
+    i= noe_rsEuclid2(locators, omegas, parityCount, erasureCount);
+STOP_TIMER
 //printf("errorCount %d \n", errorCount);
 
     if(i<0) return -1;
+    errorCount= locators[i][0];
 
     omega= omegas[i];
     errorLocator= locators[i];
@@ -276,13 +477,13 @@ for(i=0; i<erasureCount; i++){
 
     gfftEval= errorCount>20;
     if(gfftEval && errorCount){
-        memcpy(fErrorLocator, errorLocator, (errorCount+1)*sizeof(GFF4Element));
+        memcpy(fErrorLocator, errorLocator+1, (errorCount+1)*sizeof(GFF4Element));
         memset(fErrorLocator + errorCount+1, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
         noe_gfft(fErrorLocator, fErrorLocator, 16);
     }
 
-    psiOrder= noe_prodPoly(psi, errorLocator, erasureLocator, errorCount, erasureCount);
-    psiOrder= noe_getDerivative(psi, psi, psiOrder);
+    noe_prodPoly(psi, errorLocator, erasureLocator);
+    noe_getDerivative(psi, psi);
 
     if(errorCount){
         for(i=0; i<SIZE-1; i++){
@@ -295,7 +496,7 @@ for(i=0; i<erasureCount; i++){
                     
                 r= (- noe_bitReverse(i))&0xFFFF;
             }else{
-                if(noe_evalPoly(errorLocator, errorCount, noe_exp[i]))
+                if(noe_evalPoly(errorLocator, noe_exp[i]))
                     continue;
                     
                 r= (-i)&0xFFFF;
@@ -304,8 +505,8 @@ for(i=0; i<erasureCount; i++){
 
             X   = noe_exp[r];
             invX= noe_exp[SIZE - r - 1];
-            nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
-            denom= noe_evalPoly(psi, psiOrder, invX);
+            nom= prod(X, noe_evalPoly(omega, invX));
+            denom= noe_evalPoly(psi, invX);
 
             assert(r>=0 && r<=SIZE-2);
             e= prod(nom, inv(denom));
@@ -328,8 +529,8 @@ for(i=0; i<erasureCount; i++){
         assert(r>=0 && r<0x10000);
         assert(prod(X, invX)==1);
         
-        nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
-        denom= noe_evalPoly(psi, psiOrder, invX);
+        nom= prod(X, noe_evalPoly(omega, invX));
+        denom= noe_evalPoly(psi, invX);
 
         assert(data[r]==0);
         data[r]= prod(nom, inv(denom));

Modified: trunk/noe/rw.c
==============================================================================
--- trunk/noe/rw.c	(original)
+++ trunk/noe/rw.c	Tue Jul 10 00:42:52 2007
@@ -19,7 +19,6 @@
 #include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
 
 #include "rw.h"
 
@@ -82,44 +81,3 @@ noe_RwContext *noe_getRemapRwContext(noe
 
     return c;
 }
-
-static void update_buf(noe_RwContext *c, uint64_t pos, int len){
-    assert(len>0 && len<=64);
-//    assert(pos < 8*c->size);
-
-    if(pos<8*c->pos || pos + len > 8*c->pos + 8*RW_SIZE){
-        if(c->flush){
-            c->io(c, c->buffer, c->pos, RW_SIZE, 1);
-            c->flush=0;
-        }
-        c->pos= pos/8 - RW_SIZE/2;
-        if(c->pos<0) c->pos=0;
-        //FIXME memmove the old to avoid redundant io
-        c->io(c, c->buffer, c->pos, RW_SIZE, 0);
-    }
-}
-
-uint64_t noe_read(noe_RwContext *c, uint64_t pos, int len){
-    int i;
-    uint64_t v=0;
-
-    update_buf(c, pos, len);
-
-    for(i=0; i<len; i++){
-        v += v + (c->buffer[(pos+i)/8 - c->pos] >> (8-((pos+i)&7)));
-    }
-    return v;
-}
-
-void noe_write(noe_RwContext *c, uint64_t pos, int len, uint64_t v){
-    int i;
-
-    update_buf(c, pos, len);
-
-    for(i=0; i<len; i++){
-        int bit= (v>>(len-i))&1;
-        c->buffer[(pos+i)/8 - c->pos] &= ~(1  <<(8-((pos+i)&7)));
-        c->buffer[(pos+i)/8 - c->pos] |=  (bit<<(8-((pos+i)&7)));
-    }
-    c->flush=1;
-}

Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c	(original)
+++ trunk/noe/test.c	Tue Jul 10 00:42:52 2007
@@ -86,7 +86,7 @@ int main(){
     }
 #endif
     srand (31415);
-
+#if 0
     printf("Testing GFFT");
     for(i=1; i<20; i++){
         int n= SIZE - 1;
@@ -127,25 +127,26 @@ int main(){
     for(i=1; i<100; i+=5){
         int n= SIZE - 1;
         int k= SIZE - 1 - i;
-        GFF4Element syn[n];
-        GFF4Element gen[i+1];
-        GFF4Element data[k];
-        GFF4Element code[n];
-        
+        GFF4Element syn[n+1];
+        GFF4Element gen[i+1+1];
+        GFF4Element data[k+1];
+        GFF4Element code[n+1];
+
+        data[0]= k-1;
         for(j=0; j<k; j++)
-            data[j]= rand() & 0xFFFF;
+            data[j+1]= rand() & 0xFFFF;
         
         noe_getRsGenerator(gen, 1, i);
-        j=noe_prodPoly(code, gen, data, i, k-1);
-        assert(j==n-1);
+        noe_prodPoly(code, gen, data);
+        assert(code[0]==n-1);
         
-        noe_getSyndrom(syn, code, i);
+        noe_getSyndrom(syn, code+1, i);
         
 //      noe_printPoly(gen, i);
 //      noe_printPoly(syn, i-1);
         
         for(j=0; j<i; j++){
-            if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
+            if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
         }
         printf("."); fflush(stdout);
     }
@@ -154,7 +155,7 @@ int main(){
     for(i=1; i<1000; i+=200){
         int n= SIZE - 1;
         int k= SIZE - 1 - i;
-        GFF4Element syn[n];
+        GFF4Element syn[n+1];
 //      GFF4Element gen[i+1];
         GFF4Element data[k];
         GFF4Element code[n];
@@ -178,15 +179,15 @@ int main(){
     //      noe_printPoly(syn, i-1);
 
             for(j=0; j<i; j++){
-                if(syn[j+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
+                if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
             }
             printf("."); fflush(stdout);
         }
         noe_freeRsEncoder(encoder);
     }
-    
+#endif
     printf("\nTesting decoder");
-    for(i=1; i<2000; i+=100){
+    for(i=1; i<5000; i+=100){
         int n= SIZE - 1;
         int k= SIZE - 1 - i;
 //      GFF4Element syn[n];
@@ -280,44 +281,42 @@ int main(){
 #endif
     printf("\n");
 return 0;
-    
     printf("Testing erasure decoding\n");
     for(i=1; i<20; i++){
         int n= SIZE - 1;
         int k= SIZE - 1 - i;
-        GFF4Element syn[n];
-        GFF4Element gen[i+1];
-        GFF4Element data[k];
-        GFF4Element code[n];
-        GFF4Element locator[i+1];
-        GFF4Element omega[2*i];
+        GFF4Element syn[n+1];
+        GFF4Element gen[i+1+1];
+        GFF4Element data[k+1];
+        GFF4Element code[n+1];
+        GFF4Element locator[i+1+1];
+        GFF4Element omega[2*i+1];
 
-        int locatorOrder=0;
-        
+        data[0]= k-1;
         for(j=0; j<k; j++)
-            data[j]= rand() & 0xFFFF;
+            data[j+1]= rand() & 0xFFFF;
         
         noe_getRsGenerator(gen, 1, i);
-        j=noe_prodPoly(code, gen, data, i, k);
-        assert(j==n);
+        noe_prodPoly(code, gen, data);
+        assert(code[0]==n);
         
-        locator[0] = 1;
+        locator[0] = 0;
+        locator[1] = 1;
         for(j=0; j<i; j++){
             int index;
-            GFF4Element locationFactor[2];
+            GFF4Element locationFactor[3];
             
             if((rand()&7)==0 && j) continue;
             
             index= rand()%0xFFFF;
-            locationFactor[0] = 1;
-            locationFactor[1] = inv(noe_exp[index]);
-            locatorOrder= noe_prodPoly(locator, locator, locationFactor, j, 1);
+            SET_POLY1(locationFactor, 1, inv(noe_exp[index]));
+            noe_prodPoly(locator, locator, locationFactor);
             
             code[index] = 0;
         }
         
-        noe_getSyndrom(syn, code, i);
-        noe_prodPoly(omega, syn, locator, i-1, locatorOrder);
+        noe_getSyndrom(syn, code+1, i);
+        noe_prodPoly(omega, syn, locator);
 //      noe_getDeriative(locator, locator, locatorOrder);
         
 
@@ -325,8 +324,9 @@ return 0;
 //      noe_printPoly(syn, i-1);
         
         for(j=0; j<i; j++){
-            if(syn[j]) printf("FAIL generator:%d coefficient:%d\n", i, j);
+            if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
         }
     }
+
     return 0;
 }



More information about the Mndiff-dev mailing list