source: git/Singular/LIB/decodegb.lib @ 288382

spielwiese
Last change on this file since 288382 was 288382, checked in by Stanislav Bulygin <bulygin@…>, 16 years ago
name agreement implemented git-svn-id: file:///usr/local/Singular/svn/trunk@10991 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 43.2 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: decodegb.lib,v 1.1 2008-08-13 15:44:20 bulygin Exp $";
3category="Coding theory";
4info="
5LIBRARY:   decodedistGB.lib     Generating and solving systems of polynomial equations for decoding and finding the minimum distance of linear codes
6AUTHORS:   Stanislav Bulygin,   bulygin@mathematik.uni-kl.de                     
7
8OVERVIEW:
9 In this library we generate several systems used for decoding cyclic codes. And finding the minimum distance
10 Namely, we work with the Cooper's philosophy and generalized Newton identities.
11 The original method of quadratic equations is worked out here as well.
12 We also (for comparison) enable to work with the system of Fitzgerald-Lax.
13 We provide also some auxiliary functions for further manipulations and decoding.
14 For an overview of the methods mentioned above, cf. Stanislav Bulygin, Ruud Pellikaan: 'Decoding and finding the minimum distance with
15 Groebner bases: history and new insights', in 'Selected Topics in Information and Coding Theory', World Scientific (2008) (to appear) (*).
16
17MAIN PROCEDURES:
18 sysCRHT(n,defset,e,q,m,#); generates the CRHT-ideal that follows Cooper's philosophy, Sala's extentions are available
19 sysCRHTMindistBinary(n,defset,w); generates the ideal from Cooper's philosophy to find the minimum distance in the binary case
20 sysNewton(n,defset,t,q,m,#); generates the ideal with the Generalized Newton identities
21 sysBin(v,Q,n,#);  generates Bin system as in the work of Augot et.al, cf. [*] for a reference
22 encode(x,g);  encodes given message with a given generator matrix
23 syndrome(h, c);  computes a syndroem w.r.t. a given check matrix
24 sysQE(check,y,t,fieldeq,formal); generates the system of quadratic equations as in the method of Pellikaan and Bulygin
25 error(y,pos,val);  inserts errors in a word
26 errorRand(y,num,e);  inserts random errors in a word
27 randomCheck(m,n,e);  generates a random check matrix
28 genMDSMat(n,a);  generates an MDS (actually an RS) matrix
29 mindist(check);   computes the minimum distance of the code via solving systems of quadratic equations
30 decode(rec);  decoding of a word using the systems of quadratic equations
31 solveForRandom(redun,ncodes,ntrials,#);  a procedure for manipulation with random codes
32 solveForCode(check,ntrials,#); a procedure for manipulation with a given codes
33 vanishId(points); computes the vanishing ideal for the given set of points. The algorithm of Farr and Gao is implemented
34 sysFL(check,y,t,e,s); generates the Fitzgerald-Lax system
35 FLSolveForRandom(n,redun,p,e,t,ncodes,ntrials,minpol); a procedure for manipulation with random codes via Fitzgerald-Lax
36 
37
38KEYWORDS:  Cyclic code; Linear code; Decoding;
39           Minimum distance; Groebner bases
40";
41
42LIB "linalg.lib";
43LIB "brnoeth.lib";
44
45///////////////////////////////////////////////////////////////////////////////
46
47static proc lis (int n)
48{
49 list result;
50 if (n<=0) {print("ERRORlis");}
51 for (int i=1; i<=n; i++)
52 {
53  result=result+list(i);
54 }
55 return(result);
56}
57
58static proc combinations (int m, int n)
59{
60 list result;
61 if (m>n) {print("ERRORcombinations");}
62 if (m==n) {result[size(result)+1]=lis(m);return(result);}
63 if (m==0) {result[size(result)+1]=list();return(result);}
64 list temp=combinations(m-1,n-1);
65 for (int i=1; i<=size(temp); i++)
66 {
67  temp[i]=temp[i]+list(n);
68 }
69 result=combinations(m,n-1)+temp;
70 return(result);
71}
72
73static proc combinsert (list temp, int i)
74{
75 list result;
76 list tmp;
77 int j,k;
78 for (j=1; j<=size(temp); j++)
79 {
80  result[j]=tmp;
81 }
82 for (j=1; j<=size(temp); j++)
83 {
84  for (k=1; k<=size(temp[j]); k++)
85  {
86   if (temp[j][k]<i) {result[j][k]=temp[j][k];}
87   else {result[j][k]=temp[j][k]+1;}
88  }
89 }
90 return(result);   
91}
92
93static proc p_poly(int n, int a, int b)
94{
95  poly f;
96  for (int i=0; i<=n-1; i++)
97  {
98    f=f+Z(a)^i*Z(b)^(n-1-i);
99  }
100  return(f);
101}
102
103proc sysCRHT (int n, list defset, int e, int q, int m, int #)
104"USAGE:   sysCRHT(n,defset,e,q,m,#);  n length of the cyclic code, defset is a list representing the defining set,
105          e the error-correcting capacity, m degree extension of the splitting field, if #>0 additional equations
106          representing the fact that every two error positions are either different or at least one of them is zero
107RETURN:   a ring to work with the CRHT-ideal (with Sala's additions), the ideal itself is exported with the name 'crht'
108EXAMPLE:  example sysCRHT; shows an example
109"
110{
111  int r=size(defset); 
112  ring @crht=(q,a),(Y(e..1),Z(1..e),X(r..1)),lp;
113  ideal crht;
114  int i,j;
115  poly sum;
116 
117  // check equations
118  for (i=1; i<=r; i++)
119  {
120    sum=0;
121    for (j=1; j<=e; j++)
122    {
123      sum=sum+Y(j)*Z(j)^defset[i];
124    }
125    crht[i]=sum-X(i);
126  }
127 
128  // restrictions on syndromes
129  for (i=1; i<=r; i++)
130  {
131    crht=crht,X(i)^(q^m)-X(i);
132  }
133 
134  // n-th roots of unity
135  for (i=1; i<=e; i++)
136  {
137    crht=crht,Z(i)^(n+1)-Z(i);
138  }
139 
140  for (i=1; i<=e; i++)
141  {
142    crht=crht,Y(i)^(q-1)-1;
143  } 
144 
145  if (#)
146  {
147    for (i=1; i<=e; i++)
148    {
149      for (j=i+1; j<=e; j++)
150      {
151        crht=crht,Z(i)*Z(j)*p_poly(n,i,j);
152      }
153    }
154  } 
155  export crht; 
156  return(@crht);   
157} example
158{
159  "EXAMPLE:"; echo=2;
160  // binary cyclic [15,7,5] code with defining set (1,3)
161 
162  list defset=1,3; // defining set
163 
164  int n=15; // length
165  int e=2; // error-correcting capacity
166  int q=2; // basefield size
167  int m=4; // degree extension of the splitting field
168  int sala=1; // indicator to add additional equations
169   
170  def A=sysCRHT(n,defset,e,q,m);
171  setring A;
172  A; // shows the ring we are working in
173  print(crht); // the CRHT-ideal
174  option(redSB);
175  ideal red_crht=std(crht);
176  // reduced Groebner basis
177  print(red_crht);
178 
179  //============================
180  A=sysCRHT(n,defset,e,q,m,sala);
181  setring A; 
182  print(crht); // the CRHT-ideal with additional equations from Sala
183  option(redSB);
184  ideal red_crht=std(crht);
185  // reduced Groebner basis
186  print(red_crht);
187  // general error-locator polynomial for this code
188  red_crht[5];
189}
190
191
192proc sysCRHTMindistBinary (int n, list defset, int w)
193"USAGE:  sysCRHTMindistBinary(n,defset,w);  n length of the cyclic code, defset is a list representing the defining set,
194         w is a candidate for the minimum distance
195RETURN:  a ring to work with the Sala's ideal for mindist, the ideal itself is exported with the name 'crht_md'
196EXAMPLE: example sysCRHTMindistBinary; shows an example
197"
198{
199  int r=size(defset); 
200  ring @crht_md=2,Z(1..w),lp;
201  ideal crht_md;
202  int i,j;
203  poly sum;
204 
205  // check equations
206  for (i=1; i<=r; i++)
207  {
208    sum=0;
209    for (j=1; j<=w; j++)
210    {
211      sum=sum+Z(j)^defset[i];
212    }
213    crht_md[i]=sum;
214  } 
215 
216 
217  // n-th roots of unity
218  for (i=1; i<=w; i++)
219  {
220    crht_md=crht_md,Z(i)^n-1;
221  } 
222 
223 
224  for (i=1; i<=w; i++)
225  {
226    for (j=i+1; j<=w; j++)
227    {
228      crht_md=crht_md,Z(i)*Z(j)*p_poly(n,i,j);
229    }
230  }
231   
232  export crht_md; 
233  return(@crht_md);   
234} example
235{
236  "EXAMPLE:"; echo=2;
237  // binary cyclic [15,7,5] code with defining set (1,3)
238 
239  list defset=1,3; // defining set
240 
241  int n=15; // length
242  int d=5; // candidate for the minimum distance 
243     
244  def A=sysCRHTMindistBinary(n,defset,d);
245  setring A;
246  A; // shows the ring we are working in
247  print(crht_md); // the Sala's ideal for mindist
248  option(redSB);
249  ideal red_crht_md=std(crht_md);
250  // reduced Groebner basis
251  print(red_crht_md); 
252}
253
254static proc mod_ (int n, int m)
255{
256  if (n mod m==0) {return(m);}
257  if (n mod m!=0) {return(n mod m);}
258}
259
260proc sysNewton (int n, list defset, int t, int q, int m, int #)
261"USAGE:   sysNewton (n, defset, t, q, m, #);  n is length, defset is the defining set,
262          t is the number of errors, q is basefield size, m is degree extension of the splitting field
263          if triangular>0 it indicates that Newton identities in triangular form should be constructed
264RETURN:   a ring to work with the generalized Newton identities (in triangular form if applicable),
265          the ideal itself is exported with the name 'newton'
266EXAMPLE:  example sysNewton; shows an example
267"
268
269 string s="ring @newton=("+string(q)+",a),(";
270 int i,j;
271 int flag;
272 for (i=n; i>=1; i--)
273 {
274  for (j=1; j<=size(defset); j++)
275  {
276    flag=1;
277    if (i==defset[j])
278    {
279      flag=0;
280      break;     
281    }
282  }
283  if (flag)
284  {
285    s=s+"S("+string(i)+"),";
286  }
287 }
288 s=s+"sigma(1.."+string(t)+"),";
289 for (i=size(defset); i>=2; i--)
290 {
291  s=s+"S("+string(defset[i])+"),";
292 }
293 s=s+"S("+string(defset[1])+")),lp;";
294 
295 execute(s);
296 
297 ideal newton;
298 poly sum;
299 
300 
301 // generate generalized Newton identities
302 if (#)
303 {
304  for (i=1; i<=t; i++)
305  {
306    sum=0;
307    for (j=1; j<=i-1; j++)
308    {
309      sum=sum+sigma(j)*S(i-j);
310    }
311    newton=newton,S(i)+sum+number(i)*sigma(i);
312  }
313 } else
314 {
315  for (i=1; i<=t; i++)
316  {
317    sum=0;
318    for (j=1; j<=t; j++)
319    {
320      sum=sum+sigma(j)*S(mod_(i-j,n));
321    }
322    newton=newton,S(i)+sum;
323  }
324 }
325 for (i=1; i<=n-t; i++)
326 {
327  sum=0;
328  for (j=1; j<=t; j++)
329  {
330    sum=sum+sigma(j)*S(t+i-j);
331  }
332  newton=newton,S(t+i)+sum;
333 }
334 
335 // field equations on sigma's
336 for (i=1; i<=t; i++)
337 {
338  newton=newton,sigma(i)^(q^m)-sigma(i);
339 }
340 
341 // conjugacy relations
342 for (i=1; i<=n; i++)
343 {
344  newton=newton,S(i)^q-S(mod_(q*i,n));
345 }
346 newton=simplify(newton,2);
347 export newton;
348 return(@newton);
349} example
350{
351     "EXAMPLE:";  echo = 2;
352     // Newton identities for a binary 3-error-correcting cyclic code of length 31 with defining set (1,5,7)
353     
354     int n=31; // length
355     list defset=1,5,7; //defining set
356     int t=3; // number of errors
357     int q=2; // basefield size
358     int m=5; // degree extension of the splitting field
359     int triangular=1; // indicator of triangular form of Newton identities       
360     
361     def A=sysNewton(n,defset,t,q,m);
362     setring A;
363     A; // shows the ring we are working in
364     print(newton); // generalized Newton identities
365     
366     //===============================
367     A=sysNewton(n,defset,t,q,m,triangular);
368     setring A;     
369     print(newton); // generalized Newton identities in triangular form
370}
371
372static proc combinations_sum (int m, int n)
373{
374 list result;
375 list comb=combinations(m-1,n+m-1);
376 int i,j,flag,count;
377 list interm=comb;
378 for (i=1; i<=size(comb); i++)
379 {
380  interm[i][1]=comb[i][1]-1;
381  for (j=2; j<=m-1; j++)
382  {
383   interm[i][j]=comb[i][j]-comb[i][j-1]-1;
384  }
385  interm[i][m]=n+m-comb[i][m-1]-1;
386  flag=1;
387  count=2;
388  while ((flag)&&(count<=m))
389  {
390   if (interm[i][count] mod count != 0) {flag=0;}
391   count++;
392  }
393  if (flag)
394  {
395   for (j=2; j<=m; j++)
396   {
397    interm[i][j]=interm[i][j] div j;
398   }
399   result[size(result)+1]=interm[i]; 
400  }
401 }
402 return(result);
403}
404
405static proc exp_count (int n, int q)
406{
407 int flag=1;
408 int result=0;
409 while(flag)
410 {
411  if (n mod q != 0) {flag=0;}
412   else {n=n div q; result++;}
413 }
414 return(result);
415}
416
417
418proc sysBin (int v, list Q, int n, int#)
419"USAGE:    sysBin (v, Q, n, #);  v a number if errors, Q is a generating set of the code, n the length, # is additional parameter is
420           set to 1, then the generating set is enlarged by odd elements, which are 2^(some power)*(some elment in the gen.set) mod n
421RETURN:    keeps a ring with the resulting system, which ideal is called 'bin'
422EXAMPLE:   example sysBin; shows an example
423"
424{
425 //ring r=2,(sigma(1..v),S(1..n)),(lp(v),dp(n));
426 ring r=2,(S(1..n),sigma(1..v)),lp;
427 list cyclot;
428 ideal result;
429 int i,j,k,s;
430 list comb;
431 poly sum_, mon;
432 int count1, count2, upper, coef_, flag, gener;
433 list Q_update;
434 if (#==1)
435 {
436  for (i=1; i<=n; i++)
437  {
438   cyclot[i]=0;
439  }
440  for (i=1; i<=size(Q); i++)
441  {
442   flag=1;
443   gener=Q[i];
444   while(flag)
445   {
446    cyclot[gener]=1;
447    gener=2*gener mod n;
448    if (gener == Q[i]) {flag=0;}
449   }
450  }
451  for (i=1; i<=n; i++)
452  {
453   if ((cyclot[i] == 1)&&(i mod 2 == 1)) {Q_update[size(Q_update)+1]=i;}
454  }
455 }
456 else
457 {
458  Q_update=Q;
459 }
460   
461 for (i=1; i<=size(Q_update); i++)
462 {
463  comb=combinations_sum(v,Q_update[i]);
464  sum_=0;
465  for (k=1; k<=size(comb); k++)
466  {
467   upper=0;
468   for (j=1; j<=v; j++)
469   {
470    upper=upper+comb[k][j];
471   }
472   count1=0;
473   for (j=2; j<=upper-1; j++)
474   {
475    count1=count1+exp_count(j,2);
476   }
477   count1=count1+exp_count(Q_update[i],2);
478   count2=0;
479   for (j=1; j<=v; j++)
480   {
481    for (s=2; s<=comb[k][j]; s++)
482    {
483     count2=count2+exp_count(s,2);
484    }
485   }
486   if (count1<count2) {print("ERRORsysBin");}
487   if (count1>count2) {coef_=0;}
488   if (count1 == count2) {coef_=1;}
489   mon=1;
490   for (j=1; j<=v; j++)
491   {
492    mon=mon*sigma(j)^(comb[k][j]);
493   }
494   sum_=sum_+coef_*mon;
495  }
496  result=result,S(Q_update[i])-sum_; 
497 }
498 ideal bin=simplify(result,2);
499 export bin;
500 return(r);
501} example
502{
503     "EXAMPLE:";  echo = 2;
504     // [31,16,7] quadratic residue code
505     list l=1,5,7,9,19,25;
506     // we do not need even synromes here
507     def A=sysBin(3,l,31);
508     setring A;
509     print(bin);
510}
511
512proc encode (matrix x, matrix g)
513"USAGE:  encode (x, g);  x a row vector (message), and g a generator matrix
514RETURN:  corresponding codeword
515EXAMPLE: example encode; shows an example
516"
517{
518 if (nrows(x)>1) {print("ERRORencode1!");}
519 if (ncols(x)!=nrows(g)) {print("ERRORencode2!");}
520 return(x*g);
521} example
522{
523     "EXAMPLE:";  echo = 2;
524     ring r=2,x,dp;
525     matrix x[1][4]=1,0,1,0;
526     matrix g[4][7]=1,0,0,0,0,1,1,
527                    0,1,0,0,1,0,1,
528                    0,0,1,0,1,1,1,
529                    0,0,0,1,1,1,0;
530     //encode x with the generator matrix g
531     print(encode(x,g));
532}
533
534proc syndrome (matrix h, matrix c)
535"USAGE:  syndrome (h, c);  h a check matrix, c a row vector (codeword)
536RETURN:  corresponding syndrome
537EXAMPLE: example syndrome; shows an example
538"
539{
540 if (nrows(c)>1) {print("ERRORsyndrome1!");}
541 if (ncols(c)!=ncols(h)) {print("ERRORsyndrome2!");}
542 return(h*transpose(c)); 
543} example
544{
545     "EXAMPLE:";  echo = 2;
546     ring r=2,x,dp;
547     matrix x[1][4]=1,0,1,0;
548     matrix g[4][7]=1,0,0,0,0,1,1,
549                    0,1,0,0,1,0,1,
550                    0,0,1,0,1,1,1,
551                    0,0,0,1,1,1,0;
552     //encode x with the generator matrix g
553     matrix c=encode(x,g);
554     // disturb
555     c[1,3]=0;
556     //compute syndrome
557     //corresponding check matrix
558     matrix check[3][7]=1,0,0,1,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,1;
559     print(syndrome(check,c));
560     c[1,3]=1;
561     //now c is a codeword
562     print(syndrome(check,c));
563}
564
565static proc star(matrix m, int i, int j)
566{
567 matrix result[ncols(m)][1];
568 for (int k=1; k<=ncols(m); k++)
569 {
570  result[k,1]=m[i,k]*m[j,k];
571 }
572 return(result);
573}
574
575proc sysQE(matrix check, matrix y, int t, int fieldeq, int formal)
576"USAGE:   sysQE(check, y, t, fieldeq, formal); check is the check matrix of the code   
577          y is a received word, t the number of errors to be corrected,
578          if fieldeq=1, then field equations are added; if formal=0, fields equations on (known) syndrome variables
579          are not added, in order to add them (note that the exponent should be as a number of elements in the INITIAL alphabet) one
580          needs to set formal>0 for the exponent
581RETURN:   the ring to work with together with the resulting system
582EXAMPLE:  example sysQE; shows an example
583"
584{
585 def br=basering;
586 list rl=ringlist(br);
587 
588 int red=nrows(check);
589 int n=ncols(check);
590 int q=rl[1][1];
591 
592 if (formal==0)
593 {
594  ring work=(q,a),(V(1..t),U(1..n)),dp;
595 } else
596 {
597  ring work=(q,a),(V(1..t),U(1..n),s(1..red)),(dp(t),lp(n),dp(red));
598 }
599 
600 matrix check=imap(br,check);
601 matrix y=imap(br,y);
602 
603 matrix h_full=genMDSMat(n,a);
604 matrix h=submat(h_full,1..red,1..n);
605 if (nrows(y)!=1) {print("ERROR1Pell");}
606 if (ncols(y)!=n) {print("ERROR2Pell");}
607 
608 ideal result;
609 
610 list c;
611 list a;
612 list tmp,tmp2;
613 int i,j,l,k;
614 number sum,prod,sig;
615        poly sum1,sum2,sum3;
616 for (i=1; i<=n; i++)
617 {
618  c[i]=tmp;
619 }
620 
621 int tim=rtimer;
622 matrix transf=inverse(transpose(h_full));
623 
624 tim=rtimer;
625 for (i=1; i<=red ; i++)
626 {
627  a[i]=transpose(submat(check,i..i,1..n));
628  a[i]=transf*a[i];
629 }
630 
631 tim=rtimer;
632 matrix te[n][1];
633 for (i=1; i<=n; i++)
634 {
635  for (j=1; j<=t+1; j++)
636  {
637   if ((j<i)&&(i<=t+1)) {c[i][j]=c[j][i];}
638   else
639   {
640    if (i+j<=n+1)
641    {
642     c[i][j]=te;
643     c[i][j][i+j-1,1]=1;
644    }
645    else
646    {
647     c[i][j]=star(h_full,i,j);
648     c[i][j]=transf*c[i][j];
649    }   
650   }
651  }
652 }
653 
654 
655 tim=rtimer;
656 if (formal==0)
657 {
658  matrix s[red][1]=syndrome(check,y);
659  for (j=1; j<=red; j++)
660  {
661   sum1=0;
662   for (l=1; l<=n; l++)
663   {
664    sum1=sum1+a[j][l,1]*U(l);
665   }
666   result=result,sum1-s[j,1];
667  }
668 } else
669 {
670  for (j=1; j<=red; j++)
671  {
672   sum1=0;
673   for (l=1; l<=n; l++)
674   {
675    sum1=sum1+a[j][l,1]*U(l);
676   }
677   result=result,sum1-s(j);
678  }
679  for (j=1; j<=red; j++)
680  {
681     result=result,s(j)^(formal)-s(j);
682  }
683 }
684 if (fieldeq)
685 {
686  for (i=1; i<=n; i++)
687  {
688   result=result,U(i)^q-U(i);
689  }
690  for (j=1; j<=t; j++)
691  {
692     result=result,V(j)^q-V(j);
693  }
694 }
695 for (i=1; i<=n; i++)
696 {
697  sum1=0;
698  for (j=1; j<=t; j++)
699  {
700   sum2=0;
701   for (l=1; l<=n; l++)
702   {
703    sum2=sum2+c[i][j][l,1]*U(l);
704   }
705   sum1=sum1+sum2*V(j);
706  }
707  sum3=0;
708  for (l=1; l<=n; l++)
709  {
710   sum3=sum3+c[i][t+1][l,1]*U(l);
711  }
712  result=result,sum1-sum3;
713 }
714 
715 result=simplify(result,2);
716 
717 ideal qe=result;
718 export qe;
719 return(work);
720 //exportto(Top,h_full);   
721} example
722{
723     "EXAMPLE:";  echo = 2;
724     //correct 2 errors in [7,3] 8-ary code RS code
725     int t=2; int q=8; int n=7; int redun=4;
726     ring r=(q,a),x,dp;
727     matrix h_full=genMDSMat(n,a);
728     matrix h=submat(h_full,1..redun,1..n);
729     matrix g=dual_code(h);
730     matrix x[1][3]=0,0,1,0;
731     matrix y[1][7]=encode(x,g);
732     //disturb with 2 errors
733     matrix rec[1][7]=error(y,list(2,4),list(1,a));
734     //generate the system
735     def A=sysQE(h,rec,t,0,0);
736     setring A;
737     print(qe);
738     //let us decode
739     option(redSB);
740     ideal sys_qe=std(qe);
741     print(sys_qe);     
742}
743
744proc error(matrix y, list pos, list val)
745"USAGE:  error(y, pos, val); y is a (code) word, pos = positions where errors occured, val = their corresponding values
746RETURN:  corresponding received word
747EXAMPLE: example error; shows an example
748"
749{
750 matrix result[1][ncols(y)]=y;
751 if (size(pos)!=size(val)) {print("ERRORerror");}
752 for (int i=1; i<=size(pos); i++)
753 {
754  result[1,pos[i]]=y[1,pos[i]]+val[i];
755 }
756 return(result);
757} example
758{
759     "EXAMPLE:";  echo = 2;
760     //correct 2 errors in [7,3] 8-ary code RS code
761     int t=2; int q=8; int n=7; int redun=4;
762     ring r=(q,a),x,dp;
763     matrix h_full=genMDSMat(n,a);
764     matrix h=submat(h_full,1..redun,1..n);
765     matrix g=dual_code(h);
766     matrix x[1][3]=0,0,1,0;
767     matrix y[1][7]=encode(x,g);
768     print(y);
769     
770     //disturb with 2 errors
771     matrix rec[1][7]=error(y,list(2,4),list(1,a));
772     print(rec);
773     print(rec-y);
774}
775
776proc errorRand(matrix y, int num, int e)
777"USAGE:    errorRand(y, num, e); y is a (code) word, num is the number of errors, e is an extension degree (if one wants values to
778           be from GF(p^e)
779RETURN:    corresponding received word
780EXAMPLE:   example errorRand; shows an example
781"
782{
783 matrix result[1][ncols(y)]=y;
784 int i,j, flag, temp;
785 list pos, val;
786 matrix tempnum;
787
788 for (i=1; i<=num; i++)
789 {
790  while(1)
791  {
792   temp=random(1,ncols(y));
793   flag=1;
794   for (j=1; j<=size(pos); j++)
795   {
796    if (temp==pos[j]) {flag=0;}
797   }
798   if (flag) {pos[i]=temp;break;}
799  }
800 }
801 
802 for (i=1; i<=num; i++)
803 {
804  flag=1;
805  while(flag)
806  {   
807   tempnum=randomvector(1,e);   
808   if (tempnum!=0) {flag=0;}   
809  }
810  val[i]=tempnum;
811 }
812 
813 for (i=1; i<=size(pos); i++)
814 {
815  result[1,pos[i]]=y[1,pos[i]]+val[i];
816 }
817 return(result);
818} example
819{
820  "EXAMPLE:";  echo = 2;
821     //correct 2 errors in [7,3] 8-ary code RS code
822     int t=2; int q=8; int n=7; int redun=4;
823     ring r=(q,a),x,dp;
824     matrix h_full=genMDSMat(n,a);
825     matrix h=submat(h_full,1..redun,1..n);
826     matrix g=dual_code(h);
827     matrix x[1][3]=0,0,1,0;
828     matrix y[1][7]=encode(x,g);
829     
830     //disturb with 2 random errors
831     matrix rec[1][7]=errorRand(y,2,3);
832     print(rec);
833     print(rec-y);     
834}
835
836proc randomCheck(int m, int n, int e, int #)
837"USAGE:    randomCheck(m, n, e); m x n are dimensions of the matrix, e is an extension degree (if one wants values to
838           be from GF(p^e)
839RETURN:    random check matrix
840EXAMPLE:   example randomCheck; shows an example
841"
842{
843 matrix result[m][n];
844 matrix rand[m][n-m];
845 int i,j;
846 matrix temp;
847 for (i=1; i<=m; i++)
848 {
849  temp=randomvector(n-m,e,#); 
850  for (j=1; j<=n-m; j++)
851  {
852   rand[i,j]=temp[j,1];
853  }
854 }
855 result=concat(rand,unitmat(m));
856 return(result);
857} example
858{
859  "EXAMPLE:";  echo = 2;     
860     int redun=5; int n=15;
861     ring r=2,x,dp;
862     
863     //generate random check matrix for a [15,5] binary code
864     matrix h=randomCheck(redun,n,1);
865     print(h);
866     
867     //corresponding generator matrix
868     matrix g=dual_code(h);
869     print(g);     
870}
871
872proc genMDSMat(int n, number a)
873"USAGE:   genMDSMat(n, a); n x n are dimensions of the matrix, a is a primitive element of the field
874          An MDS matrix is constructed in the following way. We take a to be a generator of the multiplicative group of the field.
875          Then we construct the Vandermonde matrix with this a.
876ASSUME:   extension field should already be defined
877RETURN:   a matrix with the MDS property
878EXAMPLE:  example genMDSMat; shows an example 
879"
880{
881 int i,j;
882 matrix result[n][n];
883 for (i=0; i<=n-1; i++)
884 {
885  for (j=0; j<=n-1; j++)
886  {
887   result[j+1,i+1]=(a^i)^j;
888  }
889 }
890 return(result);
891} example
892{
893     "EXAMPLE:";  echo = 2;
894     int q=16; int n=15;
895     ring r=(q,a),x,dp;
896     
897     //generate an MDS (Vandermonde) matrix
898     matrix h_full=genMDSMat(n,a);
899     print(h_full);     
900}
901
902
903proc mindist (matrix check)
904"USAGE:  mindist (check, q); check is a check matrix, q = field size
905RETURN:  minimum distance of the code together with the time needed for its calculation
906EXAMPLE: example mindist; shows an example
907"
908{
909 int n=ncols(check); int redun=nrows(check); int t=redun+1;
910 
911 def br=basering;
912 list rl=ringlist(br);
913 int q=rl[1][1];
914 
915 ring work=(q,a),(V(1..t),U(1..n)),dp; 
916 matrix check=imap(br,check);
917 
918 ideal temp;
919 int count=1;
920 int flag=1;
921 int flag2;
922 int i, tim, timsolve;
923 matrix z[1][n];
924 option(redSB);
925 def A=sysQE(check,z,count,0,0);
926 while (flag)
927 {
928    A=sysQE(check,z,count,0,0);
929    setring A;
930    ideal temp=qe;
931    tim=rtimer;
932    temp=std(temp);
933    timsolve=timsolve+rtimer-tim; 
934    flag2=1;
935    setring work;
936    temp=imap(A,temp);   
937    for (i=1; i<=n; i++)
938    {
939      if
940        (temp[i]!=U(n-i+1))
941        {
942          flag2=0;
943        }
944    }
945    if (!flag2)
946    {
947      flag=0;
948    }
949    else
950    {
951      count++;
952    }
953 }
954 list result=list(count,timsolve);
955 return(result);
956} example
957{
958     "EXAMPLE:";  echo = 2;
959     //determine a minimum distance for a [7,3] binary code
960     int q=8; int n=7; int redun=4; int t=redun+1;
961     ring r=(q,a),x,dp;     
962               
963     //generate random check matrix
964     matrix h=randomCheck(redun,n,1);
965     print(h);
966     list l=mindist(h);     
967     print(l[1]); 
968     //time for the comutation in secs   
969     print(l[2]);     
970}
971
972proc decode(matrix check, matrix rec)
973"USAGE:    decode(check, rec, t); check is the check matrix of the code
974           rec is a received word, t is an upper bound for the number of errors one wants to correct
975ASSUME:    Errors in rec should be correctable, otherwise the output is unpredictable
976RETURN:    a codeword that is closest to rec
977EXAMPLE:   example decode; shows an example
978"
979{
980 def br=basering;
981 int n=ncols(check);
982 
983 int count=1;
984 def A=sysQE(check,rec,count,0,0);
985 while(1)
986 {
987  A=sysQE(check,rec,count,0,0);
988  setring A;     
989  matrix h_full=genMDSMat(n,a);
990  matrix rec=imap(br,rec);
991  option(redSB);
992  ideal qe_red=std(qe);   
993  if (qe_red[1]!=1)
994  {
995    break;
996  }
997  else
998  {
999    count++;
1000  }
1001  setring br;
1002 }
1003 
1004 setring A;
1005     
1006 //obtain a codeword
1007 //this works only if our code is indeed can correct these errors
1008 matrix syn[n][1];
1009 for (int i=1; i<=n; i++)
1010 {
1011  syn[i,1]=-qe_red[n-i+1]+lead(qe_red[n-i+1]);
1012 }   
1013 
1014 matrix real_syn=inverse(h_full)*syn; 
1015 setring br;
1016 matrix real_syn=imap(A,real_syn);
1017 return(rec-transpose(real_syn));     
1018} example
1019{
1020     "EXAMPLE:";  echo = 2;     
1021     //correct 1 error in [15,7] binary code
1022     int t=1; int q=16; int n=15; int redun=10;
1023     ring r=(q,a),x,dp;     
1024             
1025     //generate random check matrix
1026     matrix h=randomCheck(redun,n,1);     
1027     matrix g=dual_code(h);
1028     matrix x[1][n-redun]=0,0,1,0,1,0,1;
1029     matrix y[1][n]=encode(x,g);
1030     print(y);
1031     
1032     // find out the minimum distance of the code
1033     list l=mindist(h);
1034     
1035     //disturb with errors
1036     "Correct ",(l[1]-1) div 2," errors";
1037     matrix rec[1][n]=errorRand(y,(l[1]-1) div 2,1);
1038     print(rec);     
1039     
1040     //let us decode
1041     matrix dec_word=decode(h,rec);
1042     print(dec_word);     
1043}
1044
1045
1046proc solveForRandom(int n, int redun, int ncodes, int ntrials, int #)
1047"USAGE:    solveForRandom(redun, q, ncodes, ntrials); redun is a redundabcy of a (random) code,
1048           q = field size, ncodes = number of random codes to be processed
1049           ntrials = number of received vectors per code to be corrected
1050           if # is given it sets the correction capacity explicitly. It should be used in case one expexts some lower bound,
1051           otherwise the procedure tries to compute the real minimum distance to find out the error-correction capacity
1052RETURN:    nothing;
1053EXAMPLE:   example solveForRandom; shows an example
1054"
1055{
1056 int i,j;
1057 matrix h;
1058 int dist, t, tim, tim2, tim3, timdist, timdec, timdist2, timdec2, timdec3;
1059 ideal sys;
1060 list tmp;
1061
1062 option(redSB);
1063 def br=basering;
1064 matrix h_full=genMDSMat(n,a);
1065 matrix z[1][ncols(h_full)];
1066 int n=ncols(h_full);
1067 for (i=1; i<=ncodes; i++)
1068 {
1069  setring br;
1070  h=randomCheck(redun,n,1);
1071  print(h);
1072  if (#>0)
1073  {
1074     t=#;
1075  } else {
1076     tim=rtimer;
1077     tmp=mindist(h);
1078     timdist=timdist+rtimer-tim;
1079     timdist2=timdist2+tmp[2];
1080     dist=tmp[1];
1081     printf("d= %p",dist);
1082     t=(dist-1) div 2;
1083  }     
1084  tim2=rtimer; 
1085  tim3=rtimer;
1086  def A=sysQE(h,z,t,0,0);
1087  setring A;
1088  matrix word,y,rec;
1089  ideal sys2,sys3;
1090  matrix h=imap(br,h);
1091  matrix g=dual_code(h); 
1092  ideal sys=qe;
1093  print("The system is generated");
1094  timdec3=timdec3+rtimer-tim3; 
1095  for (j=1; j<=ntrials; j++)
1096  {
1097   word=randomvector(n-redun,1);   
1098   y=encode(transpose(word),g);
1099   rec=errorRand(y,t,1);   
1100   sys2=add_synd(rec,h,redun,sys);
1101 
1102   tim=rtimer;
1103   sys3=std(sys2);         
1104   sys3;
1105   timdec=timdec+rtimer-tim;   
1106  }
1107  timdec2=timdec2+rtimer-tim2; 
1108 }
1109 printf("Time for mindist: %p", timdist);
1110 printf("Time for GB in mindist: %p", timdist);
1111 printf("Time for decoding: %p", timdec2);
1112 printf("Time for GB in decoding: %p", timdec);
1113 printf("Time for sysQE in decoding: %p", timdec3);
1114} example
1115{
1116     "EXAMPLE:";  echo = 2;
1117     int q=32; int n=25; int redun=n-11; int t=redun+1;
1118     ring r=(q,a),x,dp;
1119     
1120     // correct 2 errors in 5 random binary codes, 50 trials each
1121     solveForRandom(n,redun,5,50,2);
1122}
1123
1124
1125proc solveForCode(matrix check, int ntrials, int #)
1126"USAGE:     solveForCode(check, ntrials);
1127            check is a check matrix for the code, ntrials = number of received vectors per code to be corrected
1128            if # is given it sets the correction cpacity explicitly. It should be used in case one expexts some lower bound
1129            otherwise the procedure tries to compute the real minimum distance to find out the error-correction capacity
1130RETURN:     nothing; 
1131EXAMPLE:    example solveForCode; shows an example
1132"
1133{
1134 int n=ncols(check);
1135 int redun=nrows(check);
1136 int i,j;
1137 matrix h;
1138 int dist, t, tim, tim2, tim3, timdist, timdec, timdist2, timdec2, timdec3;
1139 ideal sys;
1140 list tmp;
1141
1142 option(redSB);
1143 def br=basering;
1144 matrix h_full=genMDSMat(n,a);
1145 matrix z[1][ncols(h_full)];
1146 int n=ncols(h_full);
1147 setring br;
1148 h=check;
1149 print(h);
1150 if (#>0)
1151 {
1152    t=#;
1153 } else {
1154   tim=rtimer;
1155   tmp=mindist(h);
1156   timdist=timdist+rtimer-tim;
1157   timdist2=timdist2+tmp[2];
1158   dist=tmp[1];
1159   printf("d= %p",dist);
1160   t=(dist-1) div 2;
1161 }     
1162 tim2=rtimer; 
1163 tim3=rtimer;
1164 def A=sysQE(h,z,t,0,0);
1165 setring A;
1166 matrix word,y,rec;
1167 ideal sys2,sys3;
1168 matrix h=imap(br,h);
1169 matrix g=dual_code(h); 
1170 ideal sys=qe;
1171 print("The system is generated");
1172 timdec3=timdec3+rtimer-tim3; 
1173 for (j=1; j<=ntrials; j++)
1174 {
1175   word=randomvector(n-redun,1);   
1176   y=encode(transpose(word),g);
1177   rec=errorRand(y,t,1);   
1178   sys2=add_synd(rec,h,redun,sys);
1179   
1180   tim=rtimer;
1181   sys3=std(sys2);         
1182   sys3;
1183   timdec=timdec+rtimer-tim;   
1184 }
1185 timdec2=timdec2+rtimer-tim2; 
1186 
1187 printf("Time for mindist: %p", timdist);
1188 printf("Time for GB in mindist: %p", timdist);
1189 printf("Time for decoding: %p", timdec2);
1190 printf("Time for GB in decoding: %p", timdec);
1191 printf("Time for sysQE in decoding: %p", timdec3);
1192} example
1193{
1194     "EXAMPLE:";  echo = 2;
1195     int q=32; int n=25; int redun=n-11; int t=redun+1;
1196     ring r=(q,a),x,dp;
1197     matrix check=randomCheck(redun,n,1);
1198     
1199     // correct 2 errors in using the code above, 50 trials
1200     solveForCode(check,50,2);
1201}
1202
1203
1204static proc list2intvec (list l)
1205{
1206 intvec result;
1207 for (int i=1; i<=size(l); i++)
1208 {
1209  result[i]=l[i];
1210 }
1211 return(result);
1212}
1213   
1214
1215static proc add_synd (matrix rec, matrix check, int redun, ideal sys)
1216{
1217     ideal result=sys;
1218     matrix s[redun][1]=syndrome(check,rec);
1219     for (int i=1; i<=redun; i++)
1220     
1221     {
1222          result[i]=result[i]-s[i,1];         
1223     }
1224     return(result);
1225}
1226
1227static proc ev (poly f, matrix p)
1228{
1229     if (ncols(p)>1) {ERROR("not a column vector");};
1230     int m=size(p);
1231     poly temp=f;
1232     for (int i=1; i<=m; i++)
1233     {
1234          temp=subst(temp,x(i),p[i,1]);
1235     }
1236     return(number(temp));
1237}
1238
1239static proc find_index (ideal G, matrix p)
1240{
1241     if (ncols(p)>1) {ERROR("not a column vector");};
1242     int i=1;
1243     int n=size(G);
1244     while(i<=n)
1245     {
1246          if (ev(G[i],p)!=0) {return(i);}
1247          i++;
1248     }
1249     return(-1);
1250}
1251
1252static proc ideal2list (ideal id)
1253{
1254     list l;
1255     for (int i=1; i<=size(id); i++)
1256     {
1257          l[i]=id[i];
1258     }
1259     return(l);
1260}
1261
1262static proc list2ideal (list l)
1263{
1264     ideal id;
1265     for (int i=1; i<=size(l); i++)
1266     {
1267          id[i]=l[i];
1268     }
1269     return(id);
1270}
1271
1272static proc divisible (poly m, ideal G)
1273{
1274     for (int i=1; i<=size(G); i++)
1275     {
1276          if (m/leadmonom(G[i])!=0) {return(1);}         
1277     }
1278     return(0);
1279}
1280
1281proc vanishId (list points)
1282"USAGE:  vanishId (points,e); points is a list of point that define, where polynomials from the vanishing ideal will vanish,
1283RETURN:  Vanishing ideal corresponding to the given set of points
1284EXAMPLE: example vanishId; shows an example
1285"
1286{
1287     int m=size(points[1]);
1288     int n=size(points);
1289     
1290     ideal G=1;
1291     int i,k,j;
1292     list temp;
1293     poly h,cur;
1294     for (k=1; k<=n; k++)
1295     {         
1296          i=find_index(G,points[k]);
1297          cur=G[i];         
1298          for(j=i+1; j<=size(G); j++)
1299          {
1300               G[j]=G[j]-ev(G[j],points[k])/ev(G[i],points[k])*G[i];
1301          }
1302          G=simplify(G,2);
1303          temp=ideal2list(G);
1304          temp=delete(temp,i);
1305          G=list2ideal(temp);         
1306          for (j=1; j<=m; j++)
1307          {
1308               if (!divisible(x(j)*leadmonom(cur),G))
1309               {
1310                    attrib(G,"isSB",1);
1311                    h=NF((x(j)-points[k][j,1])*cur,G);                   
1312                    temp=ideal2list(G);
1313                    temp=insert(temp,h);
1314                    G=list2ideal(temp);
1315                    G=sort(G)[1];     
1316               }
1317          }
1318     }
1319     attrib(G,"isSB",1);
1320     return(G);
1321} example
1322{
1323     "EXAMPLE:";  echo = 2;
1324      ring r=3,(x(1..3)),dp;
1325     
1326     //generate all 3-vectors over GF(3)
1327     list points=points_gen(3,1);
1328     
1329     list points2=conv_points(points);
1330     
1331     //grasps the first 11 points
1332     list p=grasp_list(points2,1,11);
1333     print(p);
1334     
1335     //construct the vanishing ideal
1336     ideal id=vanishId(p);
1337     print(id);
1338}
1339
1340proc points_gen (int m, int e)
1341{
1342     if (e>1)
1343     {
1344     list result;
1345     int count=1;
1346     int i,j;
1347     list l=ringlist(basering);
1348     int charac=l[1][1];
1349     number a=par(1);
1350     list tmp;
1351     for (i=1; i<=charac^(e*m); i++)
1352     {
1353          result[i]=tmp;
1354     }
1355     if (m==1)
1356     {
1357          result[count][m]=0;
1358          count++;
1359          for (j=1; j<=charac^(e)-1; j++)
1360          {               
1361               result[count][m]=a^j;
1362               count++;
1363          }
1364          return(result);
1365     }
1366     list prev=points_gen(m-1,e);     
1367     for (i=1; i<=size(prev); i++)
1368     {
1369          result[count]=prev[i];
1370          result[count][m]=0;
1371          count++;
1372          for (j=1; j<=charac^(e)-1; j++)
1373          {
1374               result[count]=prev[i];
1375               result[count][m]=a^j;
1376               count++;
1377          }
1378     }
1379     return(result);
1380     }
1381     
1382     if (e==1)
1383     {
1384     list result;
1385     int count=1;
1386     int i,j;
1387     list l=ringlist(basering);
1388     int charac=l[1][1];     
1389     list tmp;
1390     for (i=1; i<=charac^m; i++)
1391     {
1392          result[i]=tmp;
1393     }
1394     if (m==1)
1395     {
1396          for (j=0; j<=charac-1; j++)
1397          {               
1398               result[count][m]=number(j);
1399               count++;
1400          }
1401          return(result);
1402     }
1403     list prev=points_gen(m-1,e);     
1404     for (i=1; i<=size(prev); i++)
1405     {
1406          for (j=0; j<=charac-1; j++)
1407          {
1408               result[count]=prev[i];
1409               result[count][m]=number(j);
1410               count++;
1411          }
1412     }
1413     return(result);
1414     }
1415     
1416}
1417
1418static proc list2vec (list l)
1419{
1420     matrix m[size(l)][1];
1421     for (int i=1; i<=size(l); i++)
1422     {
1423          m[i,1]=l[i];
1424     }
1425     return(m);
1426}
1427
1428proc conv_points (list points)
1429{
1430     for (int i=1; i<=size(points); i++)
1431     {
1432          points[i]=list2vec(points[i]);
1433     }
1434     return(points);
1435}
1436
1437proc grasp_list (list l, int m, int n)
1438{
1439     list result;
1440     int count=1;
1441     for (int i=m; i<=n; i++)
1442     {
1443          result[count]=l[i];
1444          count++;
1445     }
1446     return(result);
1447}
1448
1449static proc xi_gen (matrix p, int e, int s)
1450{
1451     poly prod=1;
1452     list rl=ringlist(basering);     
1453     int charac=rl[1][1];
1454     int l;
1455     for (l=1; l<=s; l++)
1456     {
1457          prod=prod*(1-(x(l)-p[l,1])^(charac^e-1));
1458     }
1459     return(prod);
1460}
1461
1462static proc gener_funcs (matrix check, list points, int e, ideal id, int s)
1463{
1464     int n=ncols(check);
1465     if (n!=size(points)) {ERROR("Incompatible sizes of check and points");}
1466     ideal xi;
1467     int i,j;
1468     for (i=1; i<=n; i++)
1469     {
1470          xi[i]=xi_gen(points[i],e,s);
1471     }
1472     ideal result;
1473     int m=nrows(check);
1474     poly sum;
1475     for (i=1; i<=m; i++)
1476     {
1477          sum=0;
1478          for (j=1; j<=n; j++)
1479          {
1480               sum=sum+check[i,j]*xi[j];
1481          }
1482          result[i]=NF(sum,id);
1483     }
1484     return(result);
1485}
1486
1487proc sysFL (matrix check, matrix y, int t, int e, int s)
1488"USAGE:    sysFL (check,y,t,e,s); check is a check matrix of the code, y is a received word, t the number of errors to correct,
1489           e is the extension degree, s is the dimension of the point for the vanishing ideal
1490RETURN:    the system of Fitzgerald-Lax for the given decoding problem
1491EXAMPLE:   example sysFL; shows an example
1492"
1493{
1494     list rl=ringlist(basering);       
1495     int charac=rl[1][1];     
1496     int n=ncols(check);
1497     int m=nrows(check);         
1498     list points=points_gen(s,e);
1499     list points2=conv_points(points);
1500     list p=grasp_list(points2,1,n);     
1501     ideal id=vanishId(p,e);     
1502     ideal funcs=gener_funcs(check,p,e,id,s);         
1503     
1504     ideal result;
1505     poly temp;
1506     int i,j,k;
1507     
1508     //vanishing realtions     
1509     for (i=1; i<=t; i++)
1510     {         
1511          for (j=1; j<=size(id); j++)
1512          {
1513               temp=id[j];               
1514               for (k=1; k<=s; k++)
1515               {
1516                    temp=subst(temp,x(k),x_var(i,k,s));
1517               }               
1518               result=result,temp;
1519          }
1520     }         
1521     
1522     //field equations
1523     for (i=1; i<=t; i++)
1524     {
1525          for (k=1; k<=s; k++)
1526          {
1527               result=result,x_var(i,k,s)^(charac^e)-x_var(i,k,s);
1528          }
1529     }
1530     for (i=1; i<=t; i++)
1531     {
1532          result=result,e(i)^(charac^e-1)-1;
1533     }
1534     
1535     result=simplify(result,8);
1536     
1537     //check realtions
1538     poly sum;
1539     matrix syn[m][1]=syndrome(check,y);         
1540     for (i=1; i<=size(funcs); i++)
1541     {         
1542          sum=0;
1543          for (j=1; j<=t; j++)
1544          {
1545               temp=funcs[i];
1546               for (k=1; k<=s; k++)
1547               {
1548                    temp=subst(temp,x(k),x_var(j,k,s));
1549               }
1550               sum=sum+temp*e(j);         
1551          }
1552          result=result,sum-syn[i,1];
1553     }
1554     
1555     result=simplify(result,2);
1556     
1557     points=points2;
1558     export points;     
1559     return(result);
1560} example
1561{
1562     "EXAMPLE:";  echo = 2;
1563     
1564     list l=FLpreprocess(3,1,11,2,"");
1565     def r=l[1];
1566     setring r;
1567     int s_work=l[2];     
1568     
1569     //the check matrix of [11,6,5] ternary code
1570     matrix h[5][11]=1,0,0,0,0,1,1,1,-1,-1,0,
1571          0,1,0,0,0,1,1,-1,1,0,-1,
1572          0,0,1,0,0,1,-1,1,0,1,-1,
1573          0,0,0,1,0,1,-1,0,1,-1,1,
1574          0,0,0,0,1,1,0,-1,-1,1,1;
1575     matrix g=dual_code(h);
1576     matrix x[1][6];
1577     matrix y[1][11]=encode(x,g);
1578     //disturb with 2 errors
1579     matrix rec[1][11]=error(y,list(2,4),list(1,-1));
1580
1581     //the Fitzgerald-Lax system     
1582     ideal sys=sysFL(h,rec,2,1,s_work);
1583     print(sys);
1584     option(redSB);
1585     ideal red_sys=std(sys);
1586     red_sys; // read the solutions from this redGB
1587     // the points are (0,0,1) and (0,1,0) with error values 1 and -1 resp.
1588     // use list points to find error positions;
1589     points;     
1590}
1591
1592proc FLpreprocess (int p, int e, int n, int t, string minp)
1593{
1594     ring r1=p,x,dp;
1595     int s=1;
1596     while(p^(s*e)<n)
1597     {
1598          s++;
1599     }     
1600     list var_ord;
1601     int i,j;
1602     int count=1;
1603     for (i=s; i>=1; i--)
1604     {
1605          var_ord[count]=string("x("+string(i)+")");
1606          count++;
1607     }
1608     for (i=t; i>=1; i--)
1609     {
1610          var_ord[count]=string("e("+string(i)+")");
1611          count++;
1612          for (j=s; j>=1; j--)
1613          {
1614               var_ord[count]=string("x1("+string(s*(i-1)+j)+")");
1615               count++;
1616          }
1617     }     
1618     
1619     list rl;
1620     list tmp;
1621     
1622     if (e>1)
1623     {
1624          rl[1]=tmp;
1625          rl[1][1]=p;
1626          rl[1][2]=tmp;
1627          rl[1][2][1]=string("a");
1628          rl[1][3]=tmp;
1629          rl[1][3][1]=tmp;
1630          //rl[1][3][1][1]=string("dp("+string((t-1)*(s+1)+s)+"),lp("+string(s+1)+")");
1631          rl[1][3][1][1]=string("lp");
1632          rl[1][3][1][2]=1;
1633          rl[1][4]=ideal(0);
1634     } else {
1635          rl[1]=p;
1636     }
1637     
1638     rl[2]=var_ord;
1639     
1640     rl[3]=tmp;
1641     rl[3][1]=tmp;     
1642     //rl[3][1][1]=string("dp("+string((t-1)*(s+1)+s)+"),lp("+string(s+1)+")");
1643     rl[3][1][1]=string("lp");
1644     intvec v=1;
1645     for (i=1; i<=size(var_ord)-1; i++)
1646     {
1647          v=v,1;
1648     }
1649     rl[3][1][2]=v;
1650     rl[3][2]=tmp;
1651     rl[3][2][1]=string("C");   
1652     rl[3][2][2]=intvec(0);
1653     
1654     rl[4]=ideal(0);     
1655     
1656     def r2=ring(rl);
1657     setring r2;
1658     list l=ringlist(r2);     
1659     if (e>1)
1660     {
1661          execute(string("poly f="+minp));     
1662          ideal id=f;     
1663          l[1][4]=id;
1664     }
1665     
1666     def r=ring(l);
1667     setring r;     
1668     
1669     return(list(r,s));
1670}
1671
1672static proc x_var (int i, int j, int s)
1673{     
1674     return(x1(s*(i-1)+j));
1675}
1676
1677static proc randomvector(int n, int e, int #)
1678{     
1679    int i;
1680    matrix result[n][1];
1681    for (i=1; i<=n; i++)
1682    {
1683        result[i,1]=asElement(random_prime_vector(e,#));
1684    }
1685    return(result);       
1686}
1687
1688static proc asElement(list l)
1689{
1690  number s;
1691  int i;
1692  number w=1;
1693  if (size(l)>1) {w=par(1);} 
1694  for (i=0; i<=size(l)-1; i++)
1695  {
1696    s=s+w^i*l[i+1];
1697  }
1698  return(s);
1699}
1700
1701proc random_prime_vector (int n, int #)
1702{
1703  if (#==1)
1704  {
1705     list rl=ringlist(basering);     
1706     int charac=rl[1][1];
1707  } else {
1708     int charac=2;
1709  }
1710  list l;
1711  int i;
1712  for (i=1; i<=n; i++)
1713  {
1714    l=l+list(random(0,charac-1));
1715  }
1716  return(l);
1717}
1718
1719proc FLSolveForRandom(int n, int redun, int p, int e, int t, int ncodes, int ntrials, string minpol)
1720"USAGE:    FLSolveForRandom(redun,p,e,n,t,ncodes,ntrials,minpol); n = length of codes generated, redun = redundancy of codes generated,
1721           p = characteristics, e is the extension degree,
1722           q = number of errors to correct, ncodes = number of random codes to be processed
1723           ntrials = number of received vectors per code to be corrected
1724           due to some pecularities of SINGULAR one needs to provide minimal polynomial for the extension explicitly
1725RETURN:    nothing
1726EXAMPLE:   example FLSolveForRandom; shows an example
1727{
1728 list l=FLpreprocess(p,e,n,t,minpol);
1729 
1730 def r=l[1];
1731 int s_work=l[2];
1732 export(s_work);
1733 setring r;
1734 
1735 int i,j;
1736 matrix h, g, word, y, rec;
1737 list l;
1738 int dist, tim, tim2, tim3, timdist, timdec, timdist2, timdec2, timdec3;
1739 ideal sys, sys2, sys3;
1740 list tmp;
1741
1742 option(redSB);
1743 matrix z[1][n];
1744 
1745 for (i=1; i<=ncodes; i++)
1746 {
1747     h=randomCheck(redun,n,e,1);           
1748     g=dual_code(h);
1749     tim2=rtimer;       
1750     tim3=rtimer;               
1751     sys=sysFL(h,z,t,e,s_work);     
1752     timdec3=timdec3+rtimer-tim3;
1753   
1754     for (j=1; j<=ntrials; j++)
1755     {
1756          word=randomvector(n-redun,1);
1757          y=encode(transpose(word),g);
1758          rec=errorRand(y,t,e);
1759          sys2=LF_add_synd(rec,h,sys);   
1760          tim=rtimer;
1761          sys3=std(sys2);
1762          timdec=timdec+rtimer-tim;
1763     }           
1764     timdec2=timdec2+rtimer-tim2;
1765 }
1766 
1767 printf("Time for decoding: %p", timdec2);
1768 printf("Time for GB in decoding: %p", timdec);
1769 printf("Time for generating Fitzgerald-Lax system during decoding: %p", timdec3);
1770} example
1771{
1772     "EXAMPLE:";  echo = 2;
1773     
1774     // decoding for one random binary code of length 25, redundancy 14; 300 words are processed
1775     FLSolveForRandom(25,14,2,1,1,1,300,"");
1776}
1777
1778static proc LF_add_synd (matrix rec, matrix check, ideal sys)
1779{
1780     int redun=nrows(check);
1781     ideal result=sys;
1782     matrix s[redun][1]=syndrome(check,rec);
1783     for (int i=size(sys)-redun+1; i<=size(sys); i++)
1784     {
1785          result[i]=result[i]-s[i-size(sys)+redun,1];
1786     }
1787     return(result);
1788}
1789
1790
1791/*
1792//////////////     SOME HARD EXAMPLES    //////////////////////
1793//////      THAT MAYBE WILL BE DOABLE LATER     ///////////////
1794
17951.) These random instances are not doable in <=1000 sec.
1796
1797"EXAMPLE:";  echo = 2;
1798int q=128; int n=120; int redun=n-40;
1799ring r=(q,a),x,dp;
1800solveForRandom(n,redun,1,1,6);
1801
1802redun=n-30;
1803solveForRandom(n,redun,1,1,8);
1804
1805redun=n-20;
1806solveForRandom(n,redun,1,1,12);
1807
1808redun=n-10;
1809solveForRandom(n,redun,1,1,24);
1810
1811int q=256; int n=150; int redun=n-10;
1812ring r=(q,a),x,dp;
1813solveForRandom(n,redun,1,1,26);
1814
1815
18162.) Generic decoding is hard!
1817
1818int q=32; int n=31; int redun=n-16; int t=3;
1819ring r=(q,a),(V(1..n),U(n..1),s(redun..1)),(dp(n),lp(n),dp(redun));
1820matrix check[redun][n]= 1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,
18210,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,
18220,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
18230,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,
18240,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,
18250,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
18260,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,
18270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
18280,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,
18290,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,
18300,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,
18311,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,
18320,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,
18331,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
18341,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,
18350,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,
18360,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
18370,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,
18380,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,
18390,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
18400,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,
18410,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,
18420,1,0,1,0,0,1,0,0,1;
1843matrix rec[1][n];
1844
1845def A=sysQE(check,rec,t,1,2);
1846setring A;
1847print(qe);
1848ideal red_qe=stdfglm(qe);
1849
1850*/
Note: See TracBrowser for help on using the repository browser.