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

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