source: git/Singular/LIB/sagbi.lib @ bf42f0

spielwiese
Last change on this file since bf42f0 was 2e937c, checked in by Hans Schoenemann <hannes@…>, 14 years ago
synatx fix git-svn-id: file:///usr/local/Singular/svn/trunk@13471 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 36.3 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id$";
3category="Commutative Algebra";
4info="
5LIBRARY: sagbi.lib  Compute SAGBI basis (subalgebra bases analogous to
6                    Groebner bases for ideals) of a subalgebra
7AUTHORS: Jan Hackfeld,     Jan.Hackfeld@rwth-aachen.de
8         Gerhard Pfister,  pfister@mathematik.uni-kl.de
9         Viktor Levandovskyy,     levandov@math.rwth-aachen.de
10
11OVERVIEW:
12SAGBI stands for 'subalgebra bases analogous to Groebner bases for ideals'.
13It is an important tool in working with finitely presented subalgebras,
14many properties of SAGBI bases are analogously important to Groebner bases
15of ideals. Note, that due to absence of Noetherian property, SAGBI basis
16of a finite number of generators of a subalgebra may be infinite.
17Hence we provide procedures, which perform a given number of steps in
18computations.
19
20Guide: new implementations of sagbi, sagbiPart, sagbiReduce, sagbiSPoly
21as well as algebraicDependence by Jan Hackfeld do not support computations
22over a quotient ring yet. On the contrary, sagbiReduction and sagbiNF do
23work over any ring.
24
25PROCEDURES:
26 sagbiSPoly(A [,r,m]);      computes SAGBI S-polynomials of A
27 sagbiNF(id,dom,k[,n]);     computes SAGBI normal form of id wrt dom
28 sagbiReduce(I,A [,t,mt]);  performs subalgebra reduction of I by A
29 sagbiReduction(I,A [,n]);  performs subalgebra reduction of I by A in a
30                            quotient ring
31 sagbi(A [,m,t]);           computes SAGBI basis for A
32 sagbiPart(A,k[,m]);        computes partial SAGBI basis for A
33 algebraicDependence(I,it); performs iterations of SAGBI for algebraic
34                            dependencies of I
35
36SEE ALSO: algebra_lib
37";
38
39
40//AUXILIARY PROCEDURES:
41//uniqueVariableName(s)              adds character "@" at the beginning of
42//                                   string s until this is a unique new
43//                                   variable name
44//extendRing(r, ...)                 creates a new ring, which is an extension
45//                                   of r
46//stdKernPhi(kernNew, kernOld,...)   computes Groebner basis of kernNew+kernOld
47//spolynomialsGB(A,...)              computes the SAGBI S-polynomials of the
48//                                   subalgebra defined by the generators in A
49//                                   using Groebner bases
50//spolynomialsToric(A)               computes the SAGBI S-polynomials of the
51//                                   subalgebra defined by the generators in A
52//                                   using toric.lib
53//reductionGB(ideal F, ideal A,....) performs subalgebra reduction of F by A
54//reduceByMonomials(A)               performs subalgebra reduction of all
55//                                   polynomials in A by the subset of
56//                                   monomials
57
58LIB "elim.lib"; //for nselect
59LIB "toric.lib"; //for toric_ideal
60LIB "algebra.lib";
61//////////////////////////////////////////////////////////////////////////////
62
63
64//static
65proc tst_sagbi()
66{
67  example sagbiSPoly;
68  example sagbiNF;
69  example sagbiReduce;
70  example sagbiReduction;
71  example sagbi;
72  example sagbiPart;
73  example algebraicDependence;
74}
75
76static proc assumeQring()
77{
78  if (ideal(basering) != 0)
79  {
80    ERROR("This function has not yet been implemented over qrings.");
81  }
82}
83
84
85static proc uniqueVariableName (string variableName)
86{
87  //Adds character "@" at the beginning of variableName until this name is
88  //unique (not contained in the names of the ring variables or description
89  //of the coefficient field)
90  string ringVars = charstr(basering) + "," + varstr(basering);
91  while (find(ringVars,variableName) <> 0)
92  {
93    variableName="@"+variableName;
94  }
95  return(variableName);
96}
97
98static proc extendRing(r, ideal leadTermsAlgebra, int method) {
99  /* Extends ring r with additional variables. If k=ncols(leadTermsAlgebra)
100   * and r contains already m additional variables @y, the procedure adds
101   * k-m variables @y(m+1)...@y(k) to the ring.
102   * The monomial ordering of the extended ring depends on method.
103   * Important: When calling this function, the basering (where algebra is
104   * defined) has to be active
105   */
106  def br=basering;
107  int i;
108  ideal varsBasering=maxideal(1);
109  int numTotalAdditionalVars=ncols(leadTermsAlgebra);
110  string variableName=uniqueVariableName("@y"); //get a variable name
111                                                //different from existing
112                                                //variables
113
114  //-------- extend current baserring r with new variables @y, one for each
115  //         new element in ideal algebra  -------------
116  list l = ringlist(r);
117  for (i=nvars(r)-nvars(br)+1; i<=numTotalAdditionalVars;i++)
118  {
119    l[2][i+nvars(br)]=string(variableName,"(",i,")");
120  }
121  if (method>=0 && method<=1)
122  {
123    if (nvars(r)==nvars(br))
124    {        //first run of spolynomialGB in sagbi construction algorithms
125      l[3][size(l[3])+1]=l[3][size(l[3])]; //save module ordering
126      l[3][size(l[3])-1]=list("dp",intvec(1:numTotalAdditionalVars));
127    }
128    else
129    {        //overwrite existing order for @y(i) to only get one block for
130             //the @y
131      l[3][size(l[3])-1]=list("dp",intvec(1:numTotalAdditionalVars));
132    }
133  }
134  // VL : todo noncomm case: correctly use l[5] and l[6]
135  // that is update matrices
136  // at the moment this is troublesome, so use nc_algebra call
137  // see how it done in algebraicDependence proc // VL
138  def rNew=ring(l);
139  setring br;
140  return(rNew);
141}
142
143
144static proc stdKernPhi(ideal kernNew, ideal kernOld, ideal leadTermsAlgebra,
145                       int method)
146{
147  /* Computes Groebner basis of kernNew+kernOld, where kernOld already is a
148   * Groebner basis and kernNew contains elements of the form
149   * @y(i)-leadTermsAlgebra[i] added to it.
150   * The techniques chosen is specified by the integer method
151   */
152  ideal kern;
153  attrib(kernOld,"isSB",1);
154  if (method==0)
155  {
156    kernNew=reduce(kernNew,kernOld);
157    kern=kernOld+kernNew;
158    kern=std(kern);
159    //kern=std(kernOld,kernNew); //Found bug using this method. TODO Change
160    //if bug is removed
161    //this call of std return Groebner Basis of ideal kernNew+kernOld given
162    //that kernOld is a Groebner basis
163  }
164  if (method==1)
165  {
166    kernNew=reduce(kernNew,kernOld);
167    kern=slimgb(kernNew+kernOld);
168  }
169  return(kern);
170}
171
172
173static proc spolynomialsGB(ideal algebra,r,int method)
174{
175  /* This procedure does the actual S-polynomial calculation using Groebner
176   * basis methods and is called by the procedures sagbiSPoly, sagbi and
177   * sagbiPart. As this procedure is called at each step of the SAGBI
178   * construction algorithm, we can reuse the information already calculated
179   * which is contained in the ring r. This is done in the following order
180   * 1. If r already contain m additional variables and m'=number of elements
181   *    in algebra, extend r with variables @y(m+1),...,@y(m')
182   * 2. Transfer all objects to this ring, kernOld=kern is the Groebnerbasis
183   *    already computed
184   * 3. Define ideal kernNew containing elements of the form
185   *    leadTermsAlgebra(m+1)-@y(m+1),...,leadTermsAlgebra(m')-@y(m')
186   * 4. Compute Groebnerbasis of kernOld+kernNew
187   * 5. Compute the new algebraic relations
188   */
189  def br=basering;
190  ideal varsBasering=maxideal(1);
191  ideal leadTermsAlgebra=lead(algebra);
192  //save leading terms as ordering in ring extension may not be compatible
193  //with ordering in basering
194  int numGenerators=ncols(algebra);
195
196  def rNew=extendRing(r,leadTermsAlgebra,method); // important: br has to be
197                                                  // active here
198  setring r;
199  if (!defined(kern)) // only true for first run of spolynomialGB in sagbi
200                      // construction algorithms
201  {
202    ideal kern=0;
203    ideal algebraicRelations=0;
204  }
205  setring rNew;
206  //-------------------------- transfer object to new ring rNew ---------------
207  ideal varsBasering=fetch(br,varsBasering);
208  ideal kernOld,algebraicRelationsOld;
209  kernOld=fetch(r,kern); //kern is Groebner basis of the kernel of the map
210                         //Phi:r->K[x_1,...,x_n], x(i)->x(i),@y(i)
211                         //       ->leadTermsAlgebra(i)
212  algebraicRelationsOld=fetch(r,algebraicRelations);
213  ideal leadTermsAlgebra=fetch(br,leadTermsAlgebra);
214  ideal listOfVariables=maxideal(1);
215  //-----------------------define kernNew containing elements to be added to
216  //                       the ideal kern -------------
217  ideal kernNew;
218  for (int i=nvars(r)-nvars(br)+1; i<=numGenerators; i++)
219  {
220    kernNew[i-nvars(r)+nvars(br)]=
221      leadTermsAlgebra[i]-listOfVariables[i+nvars(br)];
222  }
223  //-------------------------- calulate kernel of Phi depending on method
224  //                           choosen -----------------------
225
226  attrib(kernOld,"isSB",1);
227  ideal kern=stdKernPhi(kernNew,kernOld,leadTermsAlgebra,method);
228  //-------------------------- calulate algebraic relations -------------------
229  ideal algebraicRelations=nselect(kern,1..nvars(br));
230  attrib(algebraicRelationsOld,"isSB",1);
231  ideal algebraicRelationsNew=reduce(algebraicRelations,algebraicRelationsOld);
232  /*        algebraicRelationsOld is a groebner basis by construction (as
233   *        variable ordering is block ordering we have an elemination
234   *        ordering for the varsBasering)
235   *        Therefore, to only get the new algebraic relations, calculate
236   *        <algebraicRelations>\<algebraicRelationsOld> using groebner
237   *        reduction
238   */
239  kill kernOld,kernNew,algebraicRelationsOld,listOfVariables;
240  export algebraicRelationsNew,algebraicRelations,kern;
241  setring br;
242  return(rNew);
243}
244
245static proc spolynomialsToric(ideal algebra) {
246  /* This procedure does the actual S-polynomial calculation using toric.lib
247   * for computation of a Groebner basis for the toric ideal kern(phi), where
248   * phi:K[y_1,...,y_m]->K[x_1,...,x_n], y_i->leadmonom(algebra[i])
249   * By suitable substitutions we obtain the kernel of the map
250   * K[y_1,...,y_m]->K[x_1,...,x_n], x(i)->x(i), @y(i)->leadterm(algebra[i])
251   */
252  def br=basering;
253  int m=ncols(algebra);
254  int n=nvars(basering);
255  intvec tempVec;
256  int i,j;
257  ideal leadCoefficients;
258  for (i=1;i<=m; i++)
259  {
260    leadCoefficients[i]=leadcoef(algebra[i]);
261  }
262  int k=1;
263  for (i=1;i<=n;i++)
264  {
265    for (j=1; j<=m; j++)
266    {
267      tempVec[k]=leadexp(algebra[j])[i];
268      k++;
269    }
270  }
271  //The columns of the matrix A are now the exponent vectors of the leadings
272  //monomials in algebra.
273  intmat A[n][m]=intmat(tempVec,n,m);
274  //Create the preimage ring K[@y(1),...,@y(m)], where m=ncols(algebra).
275  string variableName=uniqueVariableName("@y");
276  list l = ringlist(basering);
277  for (i=1; i<=m;i++)
278  {
279    l[2][i]=string(variableName,"(",i,")");
280  }
281  l[3][2]=l[3][size(l[3])];
282  l[3][1]=list("dp",intvec(1:m));
283  def rNew=ring(l);
284  setring rNew;
285  //Use toric_ideal to compute the kernel
286  ideal algebraicRelations=toric_ideal(A,"ect");
287  //Suitable substitution
288  ideal leadCoefficients=fetch(br,leadCoefficients);
289  for (i=1; i<=m; i++)
290  {
291    if (leadCoefficients[i]!=0)
292    {
293      algebraicRelations=subst(algebraicRelations,var(i),
294                               1/leadCoefficients[i]*var(i));
295    }
296  }
297  export algebraicRelations;
298  return(rNew);
299}
300
301
302static proc reductionGB(ideal F, ideal algebra,r, int tailreduction,
303                        int method,int parRed)
304{
305  /* This procedure does the actual SAGBI/subalgebra reduction using Groebner
306   * basis methods and is called by the procedures sagbiReduce, sagbi and
307   * sagbiPart
308   * If r already is an extension of the basering and contains the ideal kern
309   * needed for the subalgebra reduction, the reduction can be started
310   * directly, at each reduction step using the fact that
311   * p=reduce(leadF,kern) in K[@y(1),...,@y(m)] <=> leadF in K[lead(algebra)]
312   * Otherwise some precomputation has to be done, outlined below.
313   */
314  def br=basering;
315  int numVarsBasering=nvars(br);
316  ideal varsBasering=maxideal(1);
317  int i;
318
319  if (numVarsBasering==nvars(r))
320  {
321    /* Case that ring r is the same ring as the basering. Using proc
322     * extendRing, stdKernPhi one construct the extension of the current
323     * baserring with new variables @y, one for each element in ideal algebra
324     * and calculates the kernel of Phi, where
325     * Phi: r---->br, x_i-->x_i, y_i-->f_i, algebra={f_1,...f_m},
326     * br=K[x1,...,x_n] und r=K[x1,...x_n,@y1,...@y_m]
327     * This is similarly done (however step by step for each run of the
328     * SAGBI construction algorithm) in the procedure spolynomialsGB
329     */
330    ideal leadTermsAlgebra=lead(algebra);
331    kill r;
332    def r=extendRing(br,leadTermsAlgebra,method);
333    setring r;
334    ideal listOfVariables=maxideal(1);
335    ideal leadTermsAlgebra=fetch(br,leadTermsAlgebra);
336    ideal kern;
337    for (i=1; i<=ncols(leadTermsAlgebra); i++)
338    {
339      kern[i]=leadTermsAlgebra[i]-listOfVariables[numVarsBasering+i];
340    }
341    kern=stdKernPhi(kern,0,leadTermsAlgebra,method);
342  }
343  setring r;
344  poly p,leadF;
345  ideal varsBasering=fetch(br,varsBasering);
346  setring br;
347  map phi=r,varsBasering,algebra;
348  poly p,normalform,leadF;
349  intvec tempExp;
350  //------------------algebraic reduction for each polynomial F[i] ------------
351  for (i=1; i<=ncols(F);i++)
352  {
353    normalform=0;
354    while (F[i]!=0)
355    {
356      leadF=lead(F[i]);
357      if(leadmonom(leadF)==1) { //K is always contained in the subalgebra,
358                                //thus the remainder is zero in this case
359        if (parRed) { break; }
360        else { F[i]=0; break; }
361      }
362      //note: as the ordering in br and r might not be compatible it can be
363      //that lead(F[i]) in r is different from lead(F[i]) in br. To take the
364      //"correct" leading term therefore take lead(F[i]) in br and transfer
365      //it to the extension r
366      setring r;
367      leadF=fetch(br,leadF);
368      p=reduce(leadF,kern);
369      if (leadmonom(p)<varsBasering[numVarsBasering])
370      {        //as choosen ordering is a block ordering,
371               //lm(p) in K[y_1...y_m] is equivalent to lm(p)<x_n
372        //Needs to be changed, if no block ordering is used!
373        setring br;
374        F[i]=F[i]-phi(p);
375      }
376      else
377      {
378        if (tailreduction)
379        {
380          setring br;
381          normalform=normalform+lead(F[i]);
382          F[i]=F[i]-lead(F[i]);
383        }
384        else
385        {
386          setring br;
387          break;
388        }
389      }
390    }
391    if (tailreduction)
392    {
393      F[i] = normalform;
394    }
395  }
396  return(F);
397}
398
399static proc reduceByMonomials(ideal algebra)
400/* This procedures uses the sagbiReduce procedure to reduce all polynomials
401 * in algebra, which are not monomials, by the subset of all monomials.
402 */
403{
404  ideal monomials;
405  int i;
406  for (i=1; i<=ncols(algebra);i++)
407  {
408    if(size(algebra[i])==1)
409    {
410      monomials[i]=algebra[i];
411      algebra[i]=0;
412    }
413    else
414    {
415      monomials[i]=0;
416    }
417  }
418  //Monomials now contains the subset of all monomials in algebra, algebra
419  //contains the non-monomials.
420  if(size(monomials)>0)
421  {
422    algebra=sagbiReduce(algebra,monomials,1);
423    for (i=1; i<=ncols(algebra);i++)
424    {
425      if(size(monomials[i])==1)
426      {
427        //Put back monomials into algebra.
428        algebra[i]=monomials[i];
429      }
430    }
431  }
432  return(algebra);
433}
434
435
436static proc sagbiConstruction(ideal algebra, int iterations, int tailreduction, int method,int parRed)
437/* This procedure is the SAGBI construction algorithm and does the actual
438 * computation both for the procedure sagbi and sagbiPart.
439 * - If the sagbi procedure calls this procedure, iterations==-1 and this
440 *   procedure only stops if all S-Polynomials reduce to zero (criterion for
441 *   termination of SAGBI construction algorithm).
442 * - If the sagbiPart procedure calls this procedure, iterations>=0 and
443 *   iterations specifies the number of iterations. A degree boundary is not
444 *   used here.
445 * Note that parRed is used for testing a special modification and can be
446 * ignored (assume parRed==0).
447 */
448{
449  def br=basering;
450  int i=1;
451
452  ideal reducedParameters;
453  int numReducedParameters=1;
454  int j;
455  if (parRed==0)
456  {
457    algebra=reduceByMonomials(algebra);
458    algebra=simplify(simplify(algebra,3),4);
459  }
460  int step=1;
461  if (iterations==-1) //case: infintitly many iterations
462  {
463    step=0;
464    iterations=1;
465  }
466  ideal P=1; //note: P is initialized this way, so that the while loop is
467             //entered. P gets overriden there, anyhow.
468  ideal varsBasering=maxideal(1);
469  map phi;
470  ideal spolynomialsNew;
471  def r=br;
472  while (size(P)>0 && i<=iterations)
473  {
474    def rNew=spolynomialsGB(algebra,r,method);
475    kill r;
476    def r=rNew;
477    kill rNew;
478    phi=r,varsBasering,algebra;
479    spolynomialsNew=simplify(phi(algebraicRelationsNew),6);
480    //By construction spolynomialsNew only contains the spolynomials, that
481    //have not already been calculated in the steps before.
482    P=reductionGB(spolynomialsNew,algebra,r,tailreduction,method,parRed);
483    if (parRed)
484    {
485      for(j=1; j<=ncols(P); j++)
486      {
487        if (leadmonom(P[j])==1)
488        {
489          reducedParameters[numReducedParameters]=P[j];
490          P[j]=0;
491          numReducedParameters++;
492        }
493      }
494    }
495    if (parRed==0)
496    {
497      P=reduceByMonomials(P);  //Reducing with monomials is cheap and can
498                               //only result in less terms
499      P=simplify(simplify(P,3),4); //Avoid that zeros are added to the bases
500                                   //or one element in P more than once
501    }
502    else
503    {
504      P=simplify(P,6);
505    }
506    algebra=algebra,P;         //Note that elements and order of elements must
507                               //in algebra must not be changed, otherwise the
508                               //already calculated
509    //ideal in r will give wrong results. Thus it is important to use a komma
510    //here.
511    i=i+step;
512  }
513  if (step==1)
514  { //case that sagbiPart called this procedure
515    if (size(P)==0)
516    {
517      dbprint(4-voice,
518              "//SAGBI construction algorithm terminated after "
519              +string(i-1)+" iterations, as all SAGBI S-polynomials reduced"
520              +" to 0. //Returned generators therefore are a SAGBI basis.");
521    }
522    else
523    {
524      dbprint(4-voice,
525              "//SAGBI construction algorithm stopped as it reached the limit"
526              +" of "+string(iterations)+" iterations. //In general the"
527              +" returned generators are no SAGBI basis for the given"
528              +" algebra.");
529    }
530  }
531  kill r;
532  if (parRed)
533  {
534    algebra=algebra,reducedParameters;
535  }
536  algebra=simplify(algebra,6);
537  return(algebra);
538}
539
540
541proc sagbiSPoly(ideal algebra,list #)
542"USAGE:   sagbiSPoly(A[, returnRing, meth]);  A is an ideal, returnRing and
543                                              meth are integers.
544RETURN:   ideal or ring
545ASSUME: basering is not a qring
546PURPOSE: Returns SAGBI S-polynomials of the leading terms of given ideal A if
547         returnRing=0.
548@*       Otherwise returns a new ring containing the ideals algebraicRelations
549@*       and spolynomials, where these objects are explained by their name.
550@*       See the example on how to access these objects.
551@format     The other optional argument meth determines which method is
552            used for computing the algebraic relations.
553            - If meth=0 (default), the procedure std is used.
554            - If meth=1, the procedure slimgb is used.
555            - If meth=2, the prodecure uses toric_ideal.
556@end format
557EXAMPLE:  example sagbiSPoly; shows an example"
558{
559  assumeQring();
560  int returnRing;
561  int method=0;
562  def br=basering;
563  ideal spolynomials;
564  if (size(#)>=1)
565  {
566    if (typeof(#[1])=="int")
567    {
568      returnRing=#[1];
569    }
570    else
571    {
572      ERROR("Type of first optional argument needs to be int.");
573    }
574  }
575  if (size(#)==2)
576  {
577    if (typeof(#[2])=="int")
578    {
579      if (#[2]<0 || #[2]>2)
580      {
581        ERROR("Type of second optional argument needs to be 0,1 or 2.");
582      }
583      else
584      {
585        method=#[2];
586      }
587    }
588    else
589    {
590      ERROR("Type of second optional argument needs to be int.");
591    }
592  }
593  if (method>=0 and method<=1)
594  {
595    ideal varsBasering=maxideal(1);
596    def rNew=spolynomialsGB(algebra,br,method);
597    map phi=rNew,varsBasering,algebra;
598    spolynomials=simplify(phi(algebraicRelationsNew),7);
599  }
600  if(method==2)
601  {
602    def r2=spolynomialsToric(algebra);
603    map phi=r2,algebra;
604    spolynomials=simplify(phi(algebraicRelations),7);
605    def rNew=extendRing(br,lead(algebra),0);
606    setring rNew;
607    ideal algebraicRelations=imap(r2,algebraicRelations);
608    export algebraicRelations;
609    setring br;
610  }
611
612  if (returnRing==0)
613  {
614    return(spolynomials);
615  }
616  else
617  {
618    setring rNew;
619    ideal spolynomials=fetch(br,spolynomials);
620    export spolynomials;
621    setring br;
622    return(rNew);
623  }
624}
625example
626{ "EXAMPLE:"; echo = 2;
627  ring r= 0,(x,y),dp;
628  ideal A=x*y+x,x*y^2,y^2+y,x^2+x;
629  //------------------ Compute the SAGBI S-polynomials only
630  sagbiSPoly(A);
631  //------------------ Extended ring is to be returned, which contains
632  // the ideal of algebraic relations and the ideal of the S-polynomials
633  def rNew=sagbiSPoly(A,1);  setring rNew;
634  spolynomials;
635  algebraicRelations;
636  //----------------- Now we verify that the substitution of A[i] into @y(i)
637  // results in the spolynomials listed above
638  ideal A=fetch(r,A);
639  map phi=rNew,x,y,A;
640  ideal spolynomials2=simplify(phi(algebraicRelations),1);
641  spolynomials2;
642}
643
644
645proc sagbiReduce(idealORpoly, ideal algebra, list #)
646"USAGE: sagbiReduce(I, A[, tr, mt]); I, A ideals, tr, mt optional integers
647RETURN: ideal of remainders of I after SAGBI reduction by A
648ASSUME: basering is not a qring
649PURPOSE:
650@format
651    The optional argument tr=tailred determines whether tail reduction will
652    be performed.
653     - If (tailred=0), no tail reduction is done.
654     - If (tailred<>0), tail reduction is done.
655     The other optional argument meth determines which method is
656         used for Groebner basis computations.
657         - If mt=0 (default), the procedure std is used.
658         - If mt=1, the procedure slimgb is used.
659@end format
660EXAMPLE:  example sagbiReduce; shows an example"
661{
662  assumeQring();
663  int tailreduction=0; //Default
664  int method=0; //Default
665  ideal I;
666  if(typeof(idealORpoly)=="ideal")
667  {
668    I=idealORpoly;
669  }
670  else
671  {
672    if(typeof(idealORpoly)=="poly")
673    {
674      I[1]=idealORpoly;
675    }
676    else
677    {
678      ERROR("Type of first argument needs to be an ideal or polynomial.");
679    }
680  }
681  if (size(#)>=1)
682  {
683    if (typeof(#[1])=="int")
684    {
685      tailreduction=#[1];
686    }
687    else
688    {
689      ERROR("Type of optional argument needs to be int.");
690    }
691  }
692  if (size(#)>=2 )
693  {
694    if (typeof(#[2])=="int")
695    {
696      if (#[2]<0 || #[2]>1)
697      {
698        ERROR("Type of second optional argument needs to be 0 or 1.");
699      }
700      else
701      {
702        method=#[2];
703      }
704    }
705    else
706    {
707      ERROR("Type of optional arguments needs to be int.");
708    }
709  }
710
711  def r=basering;
712  I=simplify(reductionGB(I,algebra,r,tailreduction,method,0),1);
713
714  if(typeof(idealORpoly)=="ideal")
715  {
716    return(I);
717  }
718  else
719  {
720    if(typeof(idealORpoly)=="poly")
721    {
722      return(I[1]);
723    }
724  }
725}
726example
727{ "EXAMPLE:"; echo = 2;
728  ring r=0,(x,y,z),dp;
729  ideal A=x2,2*x2y+y,x3y2;
730  poly p1=x^5+x2y+y;
731  poly p2=x^16+x^12*y^5+6*x^8*y^4+x^6+y^4+3;
732  ideal P=p1,p2;
733  //---------------------------------------------
734  //SAGBI reduction of polynomial p1 by algebra A. Default call, that is, no
735  //tail-reduction is done.
736  sagbiReduce(p1,A);
737  //---------------------------------------------
738  //SAGBI reduction of set of polynomials P by algebra A, now tail-reduction
739  //is done.
740  sagbiReduce(P,A,1);
741}
742
743proc sagbi(ideal algebra, list #)
744"USAGE:   sagbi(A[, tr, mt]); A ideal, tr, mt optional integers
745RETURN: ideal, a SAGBI basis for A
746ASSUME: basering is not a qring
747PURPOSE: Computes a SAGBI basis for the subalgebra given by the generators
748         in A.
749@format
750    The optional argument tr=tailred determines whether tail reduction will
751    be performed.
752     - If (tailred=0), no tail reduction is performed,
753     - If (tailred<>0), tail reduction is performed.
754     The other optional argument meth determines which method is
755         used for Groebner basis computations.
756         - If mt=0 (default), the procedure std is used.
757         - If mt=1, the procedure slimgb is used.
758@end format
759EXAMPLE:  example sagbi; shows an example"
760{
761  assumeQring();
762  int tailreduction=0; //default value
763  int method=0; //default value
764  if (size(#)>=1)
765  {
766    if (typeof(#[1])=="int")
767    {
768      tailreduction=#[1];
769    }
770    else
771    {
772      ERROR("Type of optional argument needs to be int.");
773    }
774  }
775  if (size(#)>=2 )
776  {
777    if (typeof(#[2])=="int")
778    {
779      if (#[2]<0 || #[2]>1)
780      {
781        ERROR("Type of second optional argument needs to be 0 or 1.");
782      }
783      else
784      {
785        method=#[2];
786      }
787    }
788    else
789    {
790      ERROR("Type of optional arguments needs to be int.");
791    }
792  }
793  ideal a;
794  a=sagbiConstruction(algebra,-1,tailreduction,method,0);
795  a=simplify(a,7);
796  a=interreduced(a);
797  return(a);
798}
799example
800{ "EXAMPLE:"; echo = 2;
801  ring r= 0,(x,y,z),dp;
802  ideal A=x2,y2,xy+y;
803  //Default call, no tail-reduction is done.
804  sagbi(A);
805  //---------------------------------------------
806  //Call with tail-reduction and method specified.
807  sagbi(A,1,0);
808}
809
810proc sagbiPart(ideal algebra, int iterations, list #)
811"USAGE: sagbiPart(A, k,[tr, mt]); A is an ideal, k, tr and mt are integers
812RETURN: ideal
813ASSUME: basering is not a qring
814PURPOSE: Performs k iterations of the SAGBI construction algorithm for the
815         subalgebra given by the generators given by A.
816@format
817     The optional argument tr=tailred determines if tail reduction will be
818     performed.
819     - If (tailred=0), no tail reduction is performed,
820     - If (tailred<>0), tail reduction is performed.
821     The other optional argument meth determines which method is
822         used for Groebner basis computations.
823         - If mt=0 (default), the procedure std is used.
824         - If mt=1, the procedure slimgb is used.
825@end format
826EXAMPLE:  example sagbiPart; shows an example"
827{
828  assumeQring();
829  int tailreduction=0; //default value
830  int method=0; //default value
831  if (size(#)>=1)
832  {
833    if (typeof(#[1])=="int")
834    {
835      tailreduction=#[1];
836    }
837    else
838    {
839      ERROR("Type of optional argument needs to be int.");
840    }
841  }
842  if (size(#)>=2 )
843  {
844    if (typeof(#[2])=="int")
845    {
846      if (#[2]<0 || #[2]>3)
847      {
848        ERROR("Type of second optional argument needs to be 0 or 1.");
849      }
850      else
851      {
852        method=#[2];
853      }
854    }
855    else
856    {
857      ERROR("Type of optional arguments needs to be int.");
858    }
859  }
860  if (iterations<0)
861  {
862    ERROR("Number of iterations needs to be non-negative.");
863  }
864  ideal a;
865  a=sagbiConstruction(algebra,iterations,tailreduction,method,0);
866  a=simplify(a,7);
867  a=interreduced(a);
868  return(a);
869}
870example
871{ "EXAMPLE:"; echo = 2;
872  ring r= 0,(x,y,z),dp;
873  //The following algebra does not have a finite SAGBI basis.
874  ideal A=x,xy-y2,xy2;
875  //---------------------------------------------------
876  //Call with two iterations, no tail-reduction is done.
877  sagbiPart(A,2);
878  //---------------------------------------------------
879  //Call with three iterations, tail-reduction and method 0.
880  sagbiPart(A,3,1,0);
881}
882
883
884
885// VL: finished the documentation
886// TO compare with algDependent from algebra_lib
887// TODO : remove constants from algebraic dependencies
888proc algebraicDependence(ideal I,int iterations)
889"USAGE: algebraicDependence(I,it); I an an ideal, it is an integer
890RETURN: ring
891ASSUME: basering is not a qring
892PURPOSE: In @code{it} iterations, compute algebraic dependencies between
893         elements of I
894EXAMPLE: example algebraicDependence; shows an example"
895{
896  assumeQring();
897  def br=basering;
898  int i;
899
900  string parameterName=uniqueVariableName("@c");
901  list l = ringlist(basering);
902  list parList;
903  for (i=1; i<=ncols(I);i++)
904  {
905    parList[i]=string(parameterName,"(",i,")");
906  }
907  l[1]=list(l[1],parList,list(list("dp",1:ncols(I))));
908  ideal temp=0;
909  l[1][4]=temp;
910  // addition VL: noncomm case
911  int isNCcase = 0; // default for comm
912  //         if (size(l)>4)
913  //         {
914  //           // that is we're in the noncomm algebra
915  //           isNCcase = 1; // noncomm
916  //           matrix @C@ = l[5];
917  //           matrix @D@ = l[6];
918  //           l = l[1],l[2],l[3],l[4];
919  //         }
920  def parameterRing=ring(l);
921
922  string extendVarName=uniqueVariableName("@c");
923  list l2 = ringlist(basering);
924  for (i=1; i<=ncols(I);i++)
925  {
926    l2[2][i+nvars(br)]=string(extendVarName,"(",i,")");
927  }
928  l2[3][size(l2[3])+1]=l2[3][size(l2[3])];
929  l2[3][size(l2[3])-1]=list("dp",intvec(1:ncols(I)));
930  //         if (isNCcase)
931  //         {
932  //           // that is we're in the noncomm algebra
933  //           matrix @C@2 = l2[5];
934  //           matrix @D@2 = l2[6];
935  //           l2 = l2[1],l2[2],l2[3],l2[4];
936  //         }
937
938  def extendVarRing=ring(l2);
939  setring extendVarRing;
940  // VL : this requires extended matrices
941  // let's forget it for the moment
942  // since this holds only for showing the answer
943  //         if (isNCcase)
944  //         {
945  //           matrix C2=imap(br,@C@2);
946  //           matrix D2=imap(br,@D@2);
947  //           def er2 = nc_algebra(C2,D2);
948  //           setring er2;
949  //           def extendVarRing=er2;
950  //         }
951
952  setring parameterRing;
953
954  //         if (isNCcase)
955  //         {
956  //           matrix C=imap(br,@C@);
957  //           matrix D=imap(br,@D@);
958  //           def pr = nc_algebra(C,D);
959  //           setring pr;
960  //           def parameterRing=pr;
961  //         }
962
963
964  ideal I=fetch(br,I);
965  ideal algebra;
966  for (i=1; i<=ncols(I);i++)
967  {
968    algebra[i]=I[i]-par(i);
969  }
970  algebra=sagbiConstruction(algebra, iterations,0,0,1);
971  int j=1;
972  ideal algDep;
973  for (i=1; i<= ncols(algebra); i++)
974  {
975    if (leadmonom(algebra[i])==1)
976    {
977      algDep[j]=algebra[i];
978      j++;
979    }
980  }
981  setring extendVarRing;
982  ideal algDep=imap(parameterRing,algDep);
983  ideal algebra=imap(parameterRing,algebra);
984  export algDep,algebra;
985  //print(algDep);
986  setring br;
987  return(extendVarRing);
988}
989example
990{ "EXAMPLE:"; echo = 2;
991  ring r= 0,(x,y),dp;
992  //The following algebra does not have a finite SAGBI basis.
993  ideal I=x^2, xy-y2, xy2;
994  //---------------------------------------------------
995  //Call with two iterations
996  def DI = algebraicDependence(I,2);
997  setring DI; algDep;
998  // we see that no dependency has been seen so far
999  //---------------------------------------------------
1000  //Call with two iterations
1001  setring r; kill DI;
1002  def DI = algebraicDependence(I,3);
1003  setring DI; algDep;
1004  map F = DI,x,y,x^2, xy-y2, xy2;
1005  F(algDep); // we see that it is a dependence indeed
1006}
1007
1008static proc interreduced(ideal I)
1009{
1010  ideal J,B;
1011  int i,j,k;
1012  poly f;
1013  for(k=1;k<=ncols(I);k++)
1014  {
1015    f=I[k];
1016    I[k]=0;
1017    f=sagbiReduce(f,I,1);
1018    I[k]=f;
1019  }
1020  I=simplify(I,2);
1021  return(I);
1022}
1023///////////////////////////////////////////////////////////////////////////////
1024
1025proc sagbiReduction(poly p,ideal dom,list #)
1026"USAGE: sagbiReduction(p,dom[,n]); p poly , dom  ideal
1027RETURN: polynomial, after one step of subalgebra reduction
1028PURPOSE:
1029@format
1030    Three algorithm variants are used to perform subalgebra reduction.
1031    The positive interger n determines which variant should be used.
1032    n may take the values 0 (default), 1 or 2.
1033@end format
1034NOTE: works over both polynomial rings and their quotients
1035EXAMPLE: example sagbiReduction; shows an example"
1036{
1037  def bsr=basering;
1038  ideal B=ideal(bsr);//When the basering is quotient ring  this type casting
1039                     // gives the quotient ideal.
1040  int b=size(B);
1041  int n=nvars(bsr);
1042
1043  //In quotient rings, SINGULAR, usually does not reduce polynomials w.r.t the
1044  //quotient ideal,therefore we should first  reduce ,when it is necessary for
1045  //computations, to have a uniquely determined representant for each
1046  //equivalent class, which is the case of this algorithm.
1047
1048  if(b !=0) //means that the basering is a quotient ring
1049  {
1050    p=reduce(p,std(0));
1051    dom=reduce(dom,std(0));
1052  }
1053
1054  int i,choose;
1055  int z=ncols(dom);
1056
1057  if((size(#)>0) && (typeof(#[1])=="int"))
1058  {
1059    choose = #[1];
1060  }
1061  if (size(#)>1)
1062  {
1063    choose =#[2];
1064  }
1065
1066  //=======================first algorithm(default)=========================
1067  if ( choose == 0 )
1068  {
1069    list L = algebra_containment(lead(p),lead(dom),1);
1070    if( L[1]==1 )
1071    {
1072      // the ring L[2] = char(bsr),(x(1..nvars(bsr)),y(1..z)),(dp(n),dp(m)),
1073      // contains poly check s.t. LT(p) is of the form check(LT(f1),...,LT(fr))
1074      def s1 = L[2];
1075      map psi = s1,maxideal(1),dom;
1076      poly re = p - psi(check);
1077      // divide by the maximal power of #[1]
1078      if ( (size(#)>0) && (typeof(#[1])=="poly") )
1079      {
1080        while ((re!=0) && (re!=#[1]) &&(subst(re,#[1],0)==0))
1081        {
1082          re=re/#[1];
1083        }
1084      }
1085      return(re);
1086    }
1087    return(p);
1088  }
1089  //======================2end variant of algorithm=========================
1090  //It uses two different commands for elimaination.
1091  //if(choose==1):"elimainate"command.
1092  //if (choose==2):"nselect" command.
1093  else
1094  {
1095    poly v=product(maxideal(1));
1096
1097    //------------- change the basering bsr to bsr[@(0),...,@(z)] ----------
1098    execute("ring s=("+charstr(basering)+"),("+varstr(basering)
1099            +",@(0..z)),dp;");
1100    // Ev hier die Reihenfolge der Vars aendern. Dazu muss unten aber
1101    // entsprechend geaendert werden:
1102    //  execute("ring s="+charstr(basering)+",(@(0..z),"
1103    //          +varstr(basering)+"),dp;");
1104
1105    //constructs the leading ideal of dom=(p-@(0),dom[1]-@(1),...,dom[z]-@(z))
1106    ideal dom=imap(bsr,dom);
1107    for (i=1;i<=z;i++)
1108    {
1109      dom[i]=lead(dom[i])-var(nvars(bsr)+i+1);
1110    }
1111    dom=lead(imap(bsr,p))-@(0),dom;
1112
1113    //---------- eliminate the variables of the basering bsr --------------
1114    //i.e. computes dom intersected with K[@(0),...,@(z)].
1115
1116    if(choose==1)
1117    {
1118      ideal kern=eliminate(dom,imap(bsr,v));//eliminate does not need a
1119                                            //standard basis as input.
1120    }
1121    if(choose==2)
1122    {
1123      ideal kern= nselect(groebner(dom),1..n);//"nselect" is combinatorial
1124                                         //command which uses the internal
1125                                         //command "simplify"
1126    }
1127
1128    //---------  test wether @(0)-h(@(1),...,@(z)) is in ker ---------------
1129    // for some poly h and divide by maximal power of q=#[1]
1130    poly h;
1131    z=size(kern);
1132    for (i=1;i<=z;i++)
1133    {
1134      h=kern[i]/@(0);
1135      if (deg(h)==0)
1136      {
1137        h=(1/h)*kern[i];
1138        // define the map psi : s ---> bsr defined by @(i) ---> p,dom[i]
1139        setring bsr;
1140        map psi=s,maxideal(1),p,dom;
1141        poly re=psi(h);
1142        // divide by the maximal power of #[1]
1143        if ((size(#)>0) && (typeof(#[1])== "poly") )
1144        {
1145          while ((re!=0) && (re!=#[1]) &&(subst(re,#[1],0)==0))
1146          {
1147            re=re/#[1];
1148          }
1149        }
1150        return(re);
1151      }
1152    }
1153    setring bsr;
1154    return(p);
1155  }
1156}
1157example
1158{"EXAMPLE:"; echo = 2;
1159  ring r= 0,(x,y),dp;
1160  ideal dom =x2,y2,xy-y;
1161  poly p=x4+x3y+xy2-y2;
1162  sagbiReduction(p,dom);
1163  sagbiReduction(p,dom,2);
1164  // now let us see the action over quotient ring
1165  ideal I = xy;
1166  qring Q = std(I);
1167  ideal dom = imap(r,dom); poly p = imap(r,p);
1168  sagbiReduction(p,dom,1);
1169}
1170
1171proc sagbiNF(id,ideal dom,int k,list#)
1172"USAGE: sagbiNF(id,dom,k[,n]); id either poly or ideal,dom ideal, k and n
1173        positive intergers.
1174RETURN: same as type of id; ideal or polynomial.
1175PURPOSE:
1176@format
1177    The integer k determines what kind of s-reduction is performed:
1178    - if (k=0) no tail s-reduction is performed.
1179    - if (k=1) tail s-reduction is performed.
1180    Three Algorithm variants are used to perform subalgebra reduction.
1181    The positive integer n determines which variant should be used.
1182    n may take the values (0 or default),1 or 2.
1183@end format
1184NOTE: sagbiNF works over both rings and quotient rings
1185EXAMPLE: example sagbiNF; show example "
1186{
1187  ideal rs;
1188  if (ideal(basering) == 0)
1189  {
1190    rs = sagbiReduce(id,dom,k) ;
1191  }
1192  else
1193  {
1194    rs = sagbiReduction(id,dom,k) ;
1195  }
1196  return(rs);
1197}
1198example
1199{"EXAMPLE:"; echo = 2;
1200 ring r=0,(x,y),dp;
1201 poly p=x4+x2y+y;
1202 ideal dom =x2,x2y+y,x3y2;
1203 sagbiNF(p,dom,1);
1204 ideal I= x2-xy;
1205 qring Q=std(I); // we go to the quotient ring
1206 poly p=imap(r,p);
1207 NF(p,std(0)); // the representative of p has changed
1208 ideal dom = imap(r,dom);
1209 print(matrix(NF(dom,std(0)))); // dom has changed as well
1210 sagbiNF(p,dom,0); // no tail reduction
1211 sagbiNF(p,dom,1);// tail subalgebra reduction is performed
1212}
1213
1214/*
1215  ring r= 0,(x,y),dp;
1216  //The following algebra does not have a finite SAGBI basis.
1217  ideal J=x^2, xy-y2, xy2, x^2*(x*y-y^2)^2 - (x*y^2)^2*x^4 + 11;
1218  //---------------------------------------------------
1219  //Call with two iterations
1220  def DI = algebraicDependence(J,2);
1221  setring DI; algDep;
1222*/
Note: See TracBrowser for help on using the repository browser.