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

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