source: git/Singular/LIB/equising.lib @ 558eb2

spielwiese
Last change on this file since 558eb2 was 558eb2, checked in by Gert-Martin Greuel <greuel@…>, 23 years ago
* GMG: Kosmetik git-svn-id: file:///usr/local/Singular/svn/trunk@4980 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 28.0 KB
Line 
1version="$Id: equising.lib,v 1.5 2000-12-22 13:44:24 greuel Exp $";
2category="Singularities";
3info="
4LIBRARY:  equising.lib  Equisingularity Stratum of a Family of Plane Curves
5AUTHOR:   Andrea Mindnich, e-mail:mindnich@mathematik.uni-kl.de
6
7PROCEDURES:
8 esStratum   computes the equisingularity stratum of a deformation
9 isEquising  tests, whether a given deformation is equisingular
10"
11
12LIB "poly.lib";
13LIB "elim.lib";
14LIB "hnoether.lib";
15
16///////////////////////////////////////////////////////////////////////////////
17// COMPUTES  a weight vector. x and y get weight 1 and all other
18//           variables get weight 0.
19static proc xyVector()
20{
21  intvec iv ;
22  iv[nvars(basering)]=0 ;
23  iv[rvar(x)] =1;
24  iv[rvar(y)] =1;
25  return (iv);
26}
27///////////////////////////////////////////////////////////////////////////////
28// exchanges the variables x and y in the polynomial p_f
29static proc swapXY(poly f)
30{
31  def r_base = basering;
32  ideal MI = maxideal(1);
33  MI[rvar(x)]=y;
34  MI[rvar(y)]=x;
35  map phi = r_base, MI;
36  f=phi(f);
37  return (f);
38}
39///////////////////////////////////////////////////////////////////////////////
40// ASSUME:   p_mon is a monomial
41//            and p_g is the product of the variables in p_mon.
42// COMPUTES the coefficient of p_mon in p_h.
43static proc coefficient(poly p_h, poly p_mon, poly p_g)
44{
45  matrix coefMatrix = coef(p_h,p_g);
46  int nc = ncols(coefMatrix);
47  int ii=1;
48  poly p_c=0;
49  while(ii<=nc)
50  {
51    if (coefMatrix[1,ii] == p_mon)
52    {
53      p_c = coefMatrix[2,ii];
54      break;
55    }
56    ii++;
57  }
58  return (p_c);
59}
60///////////////////////////////////////////////////////////////////////////////
61// in p_F the variable p_vari is substituted by the polynomial p_g.
62static proc eSubst(poly p_F, poly p_vari, poly p_g)
63{
64  def r_base = basering;
65  ideal MI;
66  map phi;
67  int ii = rvar(p_vari);
68  if (ii != 0)
69  {
70    MI = maxideal(1);
71    MI[ii] = p_g;
72    phi = r_base, MI;
73    p_F = phi(p_F);
74  }
75  return (p_F);
76}
77///////////////////////////////////////////////////////////////////////////////
78// All ring variables of p_F which occur in (the set of generators of) the
79// ideal  Id, are substituted by 0
80static proc SimplifyF(poly p_F, ideal Id)
81{
82  int i=1;
83  int si = size(Id);
84  for (i=1; i <= si; i++)
85  {
86    if (rvar(Id[i]))
87    {
88      p_F = subst(p_F, Id[i], 0);
89    }
90  }
91  return(p_F);
92}
93
94
95///////////////////////////////////////////////////////////////////////////////
96
97
98// Checks, if the basering is admissible.
99static proc checkBasering ()
100{
101  int error = 0;
102  if(find(charstr(basering),"real"))
103  {
104    ERROR ("cannot compute esStratum with 'real' as coefficient field");
105  }
106  if (nvars(basering) <= 2)
107  {
108   ERROR ("there are to less ringvariables to compute esStratum")
109  }
110  error = checkQIdeal(ideal(basering));
111  return(error);
112}
113///////////////////////////////////////////////////////////////////////////////
114static  proc getInput (list #)
115{
116  def r_base = basering;
117
118  int maxStep = -1;
119
120  if (size(#) >= 1)
121  {
122    if (typeof(#[1]) == "int")
123    {
124      maxStep = #[1];
125    }
126
127    else
128    {
129      ERROR("expected esStratum('poly', 'int') ");
130    }
131  }
132
133  return(maxStep);
134}
135//////////////////////////////////////////////////////////////////////////////
136// RETURNS: 0, if the ideal cond only depends on the deformation parameters
137//          1, otherwise.
138static proc checkQIdeal (ideal cond)
139{
140  def r_base = basering;
141
142  int i_print = printlevel-voice + 4;
143  int i_nvars = nvars(basering);
144
145  ideal id_help = subst(cond,var(i_nvars),0,var(i_nvars-1),0) - cond;
146
147  // cond depends only on the first i_nvars-2 variables <=>
148  //  id_help == <0>
149  if ( simplify(id_help, 2) != 0)
150  {
151    dbprint(i_print,
152    "ideal(basering) must only depend on the deformation parameters");
153    return(1);
154  }
155
156  return(0);
157}
158
159
160///////////////////////////////////////////////////////////////////////////////
161// COMPUTES string(minpoly) and substitutes the parameter by newParName
162static proc makeMinPolyString (string newParName)
163{
164  int i;
165  string parName = parstr(basering);
166  int parNameSize = size(parName);
167
168  string oldMinPolyStr = string (minpoly);
169  int minPolySize = size(oldMinPolyStr);
170
171  string newMinPolyStr = "";
172
173  for (i=1;i <= minPolySize; i++)
174  {
175    if (oldMinPolyStr[i,parNameSize] == parName)
176    {
177      newMinPolyStr = newMinPolyStr + newParName;
178      i = i + parNameSize-1;
179    }
180    else
181    {
182      newMinPolyStr = newMinPolyStr + oldMinPolyStr[i];
183    }
184  }
185
186  return(newMinPolyStr);
187}
188
189
190///////////////////////////////////////////////////////////////////////////////
191// Defines a new ring without deformation-parameters.
192static proc createHNERing()
193{
194  string str;
195  string minpolyStr = string(minpoly);
196
197  str = " ring HNERing = (" + charstr(basering) + "), (x,y), ls;";
198  execute (str);
199
200  str = "minpoly ="+ minpolyStr+";";
201  execute(str);
202
203  keepring(HNERing);
204}
205///////////////////////////////////////////////////////////////////////////////
206// RETURNS: 1, if p_f = 0 or char(basering) divides the order of p_f
207//             or p_f is not squarefree.
208//          0, otherwise
209static proc checkPoly (poly p_f)
210{
211  int i_print = printlevel - voice + 3;
212  int i_ord;
213
214  if (p_f == 0)
215  {
216    dbprint(i_print,"The Input is a 'deformation'  of the zero polynomial");
217    return(1);
218  }
219
220  i_ord = mindeg1(p_f);
221
222  if (number(i_ord) == 0)
223  {
224    dbprint(i_print,
225            "The characteristic of the coefficient field
226             divides the order of the equation");
227    return(1);
228  }
229
230  if (squarefree(p_f) != p_f)
231  {
232    dbprint(i_print, "The curve is reducible");
233    return(1);
234  }
235
236  return(0);
237}
238///////////////////////////////////////////////////////////////////////////////
239// COMPUTES  the multiplicity sequence of p_f
240static proc calcMultSequence (poly p_f)
241{
242  int i_print = printlevel-voice + 3;
243  intvec multSeq=0;
244  list hneList;
245  int xNotTransversal;
246  int fIrreducible = 1;
247
248  // if basering =  (p,a) or (p,a(1..s)),
249  //            p prime, a algebraic, a(1..s) transcendent use reddevelop
250  // otherwise use develop
251  if (char(basering) != 0
252      && npars(basering) !=0
253      && charstr(basering) == string(char(basering)) + "," + parstr(basering))
254  {
255    hneList = reddevelop(p_f, -1);
256    if ( size(hneList)>=2)
257    {
258      fIrreducible = 0;
259      dbprint(i_print, "The curve is reducible");
260      return(multSeq, xNotTransversal, fIrreducible);
261    }
262
263    hneList = hneList[1];
264
265    xNotTransversal= hneList[3];
266  }
267  else
268  {
269    hneList = develop(p_f, -1);
270
271    xNotTransversal= hneList[3];
272    fIrreducible = hneList[5];
273  }
274
275  if ( ! fIrreducible)
276  {
277    dbprint(i_print, "The curve is reducible");
278    return(multSeq, xNotTransversal, fIrreducible);
279  }
280
281  multSeq = multsequence (hneList);
282  return(multSeq, xNotTransversal, fIrreducible);
283}
284///////////////////////////////////////////////////////////////////////////////
285// ASSUME:  The basering is no qring and has at least 3 variables
286// DEFINES: A new basering, "myRing",
287//          with new names for the parameters and variables.
288//          The new names for the parameters are a(1..k),
289//          and t(1..s),x,y for the variables
290//          The ring ordering is ordStr.
291// NOTE:    This proc uses 'execute'.
292static proc createMyRing(poly p_F, string ordStr )
293{
294  def r_old = basering;
295
296  int chara = char(basering);
297  string charaStr;
298  int i;
299  string minPolyStr = "";
300  string helpStr;
301  int nDefParams = nvars(r_old)-2;
302
303
304  ideal qIdeal = ideal(basering);
305
306  if (npars(basering) == 0)
307  {
308    helpStr = "ring myRing ="
309              + string(chara)+ ", (t(1..nDefParams), x, y),"+ ordStr +";";
310    execute(helpStr);
311  }
312
313  else
314  {
315    charaStr = charstr(basering);
316    if (charaStr == string(chara) + "," + parstr(basering))
317    {
318      if (minpoly !=0)
319      {
320        minPolyStr = makeMinPolyString("a");
321
322        helpStr = "ring myRing =
323                 (" + string(chara) + ",a),
324                 (t(1..nDefParams), x, y)," + ordStr + ";";
325        execute(helpStr);
326
327        helpStr = "minpoly =" + minPolyStr + ";";
328        execute (helpStr);
329      }
330      else
331      {
332        helpStr = "ring myRing =
333                  (" + string(chara) + ",a(1..npars(basering)) ),
334                  (t(1..nDefParams), x, y)," + ordStr + ";";
335        execute(helpStr);
336      }
337    }
338    else
339    {
340      i = find (charaStr,",");
341
342      helpStr = " ring myRing =
343              (" + charaStr[1,i] + "a),
344              (t(1..nDefParams), x, y)," + ordStr + ";";
345
346      execute (helpStr);
347    }
348  }
349
350  ideal qIdeal = fetch(r_old, qIdeal);
351
352  if(qIdeal != 0)
353  {
354    def r_base = basering;
355    kill myRing;
356    qring myRing = std(qIdeal);
357  }
358
359  poly p_F = fetch(r_old, p_F);
360  ideal ES;
361
362  keepring(myRing);
363}
364
365///////////////////////////////////////////////////////////////////////////////
366/////////// procedures to compute the equisingularity stratum /////////////////
367///////////////////////////////////////////////////////////////////////////////
368// DEFINES a new basering, myRing,  which has one variable
369//         more than the old ring.
370//         The name for the new variable is "H(nhelpV)".
371//         p_F and ES are "imaped" into the new ring.
372static proc extendRing (poly p_F,  ideal ES, int nHelpV, ideal HCond)
373{
374  def r_old = basering;
375
376  string helpStr;
377  string minPolyStr = "";
378
379  ideal qIdeal = ideal(basering);
380
381  if (minpoly != 0)
382  {
383    if (charstr(basering) == string(char(basering)) + "," + parstr(basering))
384    {
385      minPolyStr = string(minpoly);
386    }
387  }
388
389  string str =
390 "ring myRing = (" + charstr(r_old) + "),
391                (H(" + string(nHelpV)+ ")," + string(maxideal(1)) + "),
392                (dp(" + string(nHelpV) + "),dp);";
393  execute (str);
394
395  if (minPolyStr != "")
396  {
397    helpStr = "minpoly =" + minPolyStr + ";";
398    execute(helpStr);
399  }
400
401  ideal qIdeal = imap(r_old, qIdeal);
402  if(qIdeal != 0)
403  {
404    def r_base = basering;
405
406    kill myRing;
407
408    attrib(qIdeal,"isSB",1);
409    qring myRing = qIdeal;
410  }
411
412
413  poly p_F = imap(r_old, p_F);
414  ideal ES = imap(r_old, ES);
415  ideal HCond = imap(r_old, HCond);
416
417  keepring(myRing);
418}
419///////////////////////////////////////////////////////////////////////////////
420// COMPUTES an ideal equimultCond, such that F_(n-1) mod equimultCond =0,
421//          where F_(n-1) is the (nNew-1)-jet of p_F with respect to x,y.
422static proc calcEquimultCond(poly p_F, int nNew)
423{
424  ideal equimultCond = 0;
425  poly p_FnMinus1;
426  matrix coefMatrix;
427  int nc;
428  int ii = 1;
429
430  p_FnMinus1 = jet(p_F, nNew-1, xyVector());
431
432  coefMatrix = coef(p_FnMinus1, xy);
433
434  nc = ncols(coefMatrix);
435
436  for (ii=1; ii<=nc; ii++)
437  {
438    equimultCond[ii] = NF(coefMatrix[2,ii],std(0));
439  }
440
441  p_F = p_F - p_FnMinus1;
442  p_F = SimplifyF(p_F, equimultCond);
443
444  return(equimultCond, p_F);
445}
446///////////////////////////////////////////////////////////////////////////////
447// COMPUTES smallest integer >= nNew/nOld -1
448static proc calcNZeroSteps (int nOld,int nNew)
449{
450 int nZeroSteps;
451
452 if (nOld mod nNew == 0)
453 {
454   nZeroSteps = nOld div nNew -1;
455 }
456
457 else
458 {
459  nZeroSteps  = nOld div nNew;
460 }
461
462 return(nZeroSteps);
463}
464///////////////////////////////////////////////////////////////////////////////
465// ASSUME: ord_(X,Y)(F)=nNew
466// COMPUTES an ideal I such that (p_F mod I)_nNew  = p_c*y^nNew.
467static proc purePowerOfY (poly p_F, int nNew)
468{
469  ideal id_help = 0;
470  poly  p_Fn;
471  matrix coefMatrix;
472  int nc;
473  poly p_c;
474  int ii=1;
475
476  p_Fn = jet(p_F, nNew, xyVector());
477
478  coefMatrix = coef(p_Fn, xy);
479  nc = ncols(coefMatrix);
480
481  p_c = coefMatrix[2,nc];
482
483  for (ii=1; ii <= nc-1; ii++)
484  {
485    id_help[ii] = NF(coefMatrix[2,ii],std(0));
486  }
487
488  p_F = p_F - p_Fn + p_c*y^nNew;
489
490  p_F = SimplifyF(p_F, id_help);
491
492  return(id_help, p_F, p_c);
493}
494///////////////////////////////////////////////////////////////////////////////
495// ASSUME: ord_(X,Y)(F)=nNew
496// COMPUTES an ideal I such that p_Fn mod I = p_c*(y-p_a*x)^nNew,
497//          where p_Fn is the homogeneous part of p_F of order nNew.
498static proc purePowerOfLin (poly p_F, ideal HCond, int nNew, int nHelpV)
499{
500  ideal id_help = 0;
501  poly p_Fn;
502  matrix coefMatrix;
503  poly p_c;
504  poly p_ca;
505  poly p_help;
506  poly p_a;
507  int ii;
508  int jj;
509  int bico;
510
511  p_Fn = jet(p_F, nNew, xyVector());
512
513  coefMatrix = coeffs(subst(p_Fn,x,1),y);
514
515  p_c = coefMatrix[nNew+1,1];
516  p_ca = coefMatrix[nNew,1]/(-nNew);
517
518  if (npars(basering)==1 && charstr(basering) != string(char(basering)) + "," + parstr(basering))
519  {
520    p_a = H(nHelpV);
521    HCond = HCond + ideal(p_ca - p_a*p_c);
522  }
523  else
524  {
525    p_help = p_ca/p_c;
526    if (p_help * p_c == p_ca)
527    {
528      p_a = p_help;
529    }
530    else
531    {
532      p_a = H(nHelpV);
533      HCond = HCond + ideal(p_ca - p_a*p_c);
534    }
535  }
536
537  bico = (nNew*(nNew-1))/2;
538
539  for (ii = 2; ii <= nNew ; ii++)
540  {
541
542    if (coefMatrix[nNew+1-ii,1] == 0)
543    {
544      if (number(bico) != 0)
545      // Then a^i=0 since c is a unit
546      {
547        id_help = id_help + ideal(NF(p_a^(ii),std(0)));
548        for (jj = ii+1; jj <= nNew; jj++)
549        // the remaining coefficients (of y^(nnew-k)*x^k with k>i)
550        // are also zero.
551        {
552          id_help = id_help
553                    + ideal(NF(coefMatrix[nNew+1-jj,1],std(0)));
554        }
555        break;
556      }
557    }
558
559    else
560    {
561      id_help = id_help +
562            ideal(NF(coefMatrix[nNew+1-ii,1] - bico*p_c*(-p_a)^ii,std(0)));
563    }
564
565    bico = (bico*(nNew-ii))/(ii+1);
566  }
567
568  p_F = SimplifyF(p_F, id_help);
569
570  return(id_help, HCond, p_F, p_c, p_a);
571}
572///////////////////////////////////////////////////////////////////////////////
573// eliminates the variables H(1),..,H(nHelpV) from the ideal ES + HCond
574static proc helpVarElim(ideal ES, ideal HCond, int nHelpV)
575{
576  ES = ES + HCond;
577  ES = std(ES);
578  ES = nselect(ES,1,nHelpV);
579
580  return(ES);
581}
582///////////////////////////////////////////////////////////////////////////////
583// ASSUME:   ord(F)=nNew and p_c(y-p_a*x)^n is the nNew-jet of F with respect
584//           to X,Y
585// COMPUTES  F(x,yx+a*x)/x^n
586static proc formalBlowUp(poly p_F, poly p_c, poly p_a, int nNew)
587{
588
589  p_F = p_F - jet(p_F, nNew, xyVector());
590
591  if (p_a != 0)
592  {
593    p_F = eSubst(p_F, y , yx + p_a*x);
594  }
595  else
596  {
597    p_F = subst(p_F, y, xy);
598  }
599
600  p_F = p_F/(x^nNew);
601
602  p_F = p_F + p_c * y^nNew;
603
604  return (p_F);
605}
606///////////////////////////////////////////////////////////////////////////////
607// ASSUME:  p_F in K[t(1)..t(s),x,y]
608// COMPUTES the minimal ideal ES, such that the deformation p_F mod ES is
609//          equisingular.
610//          The computation is done up to iteration step 'maxstep'.
611// RETURNS: list l, such that
612//          l[1]=1 if some error has occured,
613//          l[1]=0 otherwise and then l[2] = es_cond.
614static proc calcEsCond(poly p_F, intvec multSeq, int maxStep)
615{
616  def r_old = basering;
617
618  ideal ES = 0;
619
620  int ii;
621  int step = 1;
622  int nNew = multSeq[step];
623  int nOld = nNew;
624  int nZeroSteps;
625  int nHelpV = 1;
626  ideal HCond = 0;
627  int maxDeg = 0;
628  int z = printlevel - voice + 3;
629  string str;
630
631  extendRing(p_F, ES, nHelpV, HCond);
632
633  poly p_c;
634  poly p_a;
635  ideal I;
636
637  for (ii = 1; ii <= size(multSeq); ii++)
638  {
639    maxDeg = maxDeg + multSeq[ii];
640  }
641
642  while (step <= maxStep)
643  {
644
645    nOld = nNew;
646    nNew = multSeq[step];
647
648    p_F = jet(p_F, maxDeg, xyVector());
649    maxDeg = maxDeg - nNew;
650
651    if (nNew<nOld)
652    //start a new line in the HNE of F
653    //               _            _
654    // for the next | nold/nnew -1 | iteration steps the coefficient 'a'
655    // in the leading form Fn = c(y-ax)^n should  be zero.
656    {
657      p_F = swapXY(p_F);
658      nZeroSteps = calcNZeroSteps (nOld, nNew);
659    }
660
661    I, p_F = calcEquimultCond (p_F, nNew);
662    ES = ES + I;
663
664    if (z>1)
665    {
666      "// conditions for equimultiplicity in step:", step;
667      I;
668      if (nHelpV >1)
669      {
670        str = string(nHelpV);
671        "// conditions for help variables H(1),..,H("+str+"):";
672        HCond;
673      }
674      pause("press <return> to continue");
675    }
676
677    if (nZeroSteps > 0)
678    {
679      nZeroSteps--;
680
681      // compute conditions, s.th. Fn = c*y^nnew ?
682      I, p_F, p_c = purePowerOfY (p_F, nNew);
683      ES = ES + I;
684
685      if (z>1)
686      {
687        "// conditions for pure power in step:", step;
688        I;
689        if (nHelpV > 1)
690        {
691          str = string(nHelpV);
692          "// conditions for help variables H(1),..,H("+str+"):";
693          HCond;
694        }
695        pause("press <return> to continue");
696      }
697      p_a =0;
698    }
699
700    else
701    {
702      I, HCond, p_F, p_c, p_a = purePowerOfLin (p_F, HCond, nNew, nHelpV);
703
704      ES = ES + I;
705
706      if (z>1)
707      {
708        "// conditions for pure power in step:", step;
709        I;
710        str = string(nHelpV);
711        "// conditions for help variables H(1),..,H("+str+"):";
712        HCond;
713        pause("press <return> to continue");
714      }
715    }
716
717    p_F = formalBlowUp (p_F, p_c, p_a, nNew);
718
719    if (p_a == H(nHelpV))
720    {
721      nHelpV++;
722
723      def r_base = basering;
724      kill myRing;
725
726      extendRing(p_F, ES, nHelpV, HCond);
727
728      kill r_base;
729
730      poly p_a;
731      poly p_c;
732      ideal I;
733    }
734    step++;
735  }
736  if (nHelpV > 1)
737  {
738    ES = helpVarElim(ES, HCond, nHelpV);
739  }
740
741  if (nameof(basering)=="myRing")
742  {
743    setring r_old;
744    ES = imap(myRing, ES);
745  }
746
747  return(ES);
748}
749
750///////////////////////////////////////////////////////////////////////////////
751//                           main procedure
752///////////////////////////////////////////////////////////////////////////////
753
754proc esStratum (poly p_F, list #)
755"USAGE:   esStratum(F[,m]); F a polynomial, m an integer
756ASSUME:  F defines a deformation of an irreducible bivariate polynomial f
757         and that char(basering) does not divide mult(f).
758         If nv is the number of variables of the basering, then the first nv-2
759         ringvariables are the deformation parameters.
760         If the basering is a qring, ideal(basering) must only depend
761         on the deformation parameters.
762RETURN:  A list l of an ideal and an integer, where
763         l[1] is the ideal in the deformation parameters, defining the
764         equisingularity stratum of F,
765         l[2] = 1 if some error has occured, l[2] = 0 otherwise.
766         If m is given, the computation stops after m steps of the iteration.
767NOTE:    printlevel > 0 displays comments and pauses after intermediate
768         computations (default: printlevel=0)
769         This proc uses 'execute' or calls a procedure using 'execute'.
770EXAMPLE: example esStratum; shows an example
771"
772{
773  def r_user = basering;
774
775  int ii = 1;
776  int i_nvars = nvars(basering);
777  int error = 0;
778  int xNotTransversal;
779  int fIrreducible;
780  int maxStep;
781  int userMaxStep;
782  ideal cond;
783  intvec multSeq;
784  ideal ES = 0;
785
786  error = checkBasering();
787  if (error)
788  {
789    return(list(ES,error));
790  }
791
792  userMaxStep = getInput(#);
793
794  // define a new basering "myRing" with new names for parameters
795  // and variables.
796  // The new names are 'a(1)', ..., 'a(npars)' for the parameters
797  // and 't(1)', ..., 't(nvars-2)', 'x', 'y' for the variables.
798  createMyRing(p_F, "dp");
799
800  // define a ring without deformation parameters, to compute the HNE
801  // of F mod <t_1,..,t_s>
802  createHNERing();
803
804  poly p_f = imap(myRing,p_F);
805
806  error = checkPoly(p_f);
807  if (error)
808  {
809    setring r_user;
810    return(list( ideal(0),error));
811  }
812
813  // compute the multiplicitysequence of p_f.
814  multSeq, xNotTransversal, fIrreducible = calcMultSequence(p_f);
815
816  if ( ! fIrreducible)
817  {
818    setring r_user;
819    return(list(ideal(0),1));
820  }
821
822  setring myRing;
823
824  if (xNotTransversal)
825  {
826    p_F = swapXY(p_F);
827  }
828
829  if (userMaxStep != -1 && userMaxStep <  size(multSeq)-1)
830  {
831    maxStep = userMaxStep;
832  }
833  else
834  {
835    maxStep = size(multSeq)-1;
836  }
837
838  ES = calcEsCond(p_F, multSeq, maxStep);
839
840  setring r_user;
841  ES = fetch(myRing, ES);
842
843  return(list(ES, error));
844}
845
846example
847{
848   "EXAMPLE:"; echo=2;
849   ring r = 11,(a,b,c,d,e,f,g,x,y),ds;
850   poly F =
851   xa+yb+x2+2xy+y2c+y^2+y3d+y4e+y5f+y6g+x^7;
852   esStratum(F);
853   esStratum(F,2);
854   ideal I  = f-fa,e+b;
855   qring q = std(I);
856   poly F = imap(r,F);
857   esStratum(F);
858}
859
860///////////////////////////////////////////////////////////////////////////////
861//                  procedures for equisingularity test
862///////////////////////////////////////////////////////////////////////////////
863
864// DEFINES a new basering, myRing,  which has one variable
865//         more than the old ring.
866//         The name for the new variable is "H(nhelpV)".
867static proc T_extendRing(poly p_F, int nHelpV, ideal HCond)
868{
869  def r_old = basering;
870
871  ideal qIdeal = ideal(basering);
872
873  string helpStr;
874  string minPolyStr = "";
875
876  if(minpoly != 0)
877  {
878    if (charstr(basering) == string(char(basering)) + "," + parstr(basering))
879    {
880      minPolyStr = string(minpoly);
881    }
882  }
883
884  string str = "ring myRing =
885               (" + charstr(r_old) + "),
886               (H(" + string( nHelpV)+ ")," + string(maxideal(1)) + "),
887               (dp(" + string( nHelpV) + "), ds);";
888  execute (str);
889
890  if (minPolyStr != "")
891  {
892    helpStr = "minpoly =" + minPolyStr + ";";
893    execute(helpStr);
894  }
895
896  ideal qIdeal = imap(r_old, qIdeal);
897  if(qIdeal != 0)
898  {
899    def r_base = basering;
900    kill myRing;
901    qring myRing = std(qIdeal);
902  }
903
904  poly p_F =imap(r_old, p_F);
905  ideal HCond = imap(r_old, HCond);
906
907  keepring(myRing);
908}
909///////////////////////////////////////////////////////////////////////////////
910// tests, if ord p_F = nNew.
911static proc equimultTest (poly p_F, int nHelpV, int nNew, ideal HCond)
912{
913  poly p_FnMinus1;
914  ideal id_help;
915  matrix coefMatrix;
916  int i;
917  int nc;
918
919  p_FnMinus1 = jet(p_F, nNew-1, xyVector());
920
921  coefMatrix = coef(p_FnMinus1, xy);
922  nc = ncols(coefMatrix);
923
924  for (i=1; i<=nc; i++)
925  {
926    id_help[i] = coefMatrix[2,i];
927  }
928
929  id_help = T_helpVarElim(id_help, HCond, nHelpV);
930
931  if (reduce(id_help, std(0)) !=0 )
932  {
933    return(0, p_F);
934  }
935
936  p_F = p_F - p_FnMinus1;
937
938  return(1, p_F);
939}
940///////////////////////////////////////////////////////////////////////////////
941// ASSUME: ord(p_F)=nNew
942// tests, if p_F =  p_c*y^nNew for some p_c.
943static proc pPOfYTest (poly p_F, int nHelpV, int nNew, ideal HCond)
944{
945  poly  p_Fn;
946  poly p_c;
947  ideal id_help;
948  int nc;
949  int i=1;
950  matrix coefMatrix;
951
952  p_Fn = jet(p_F, nNew, xyVector());
953
954  coefMatrix = coef(p_Fn, xy);
955  nc = ncols(coefMatrix);
956
957  p_c = coefMatrix[2,1];
958
959  for (i = 2; i <= nc; i++)
960  {
961    id_help[i] = coefMatrix[2,i];
962  }
963
964  id_help = T_helpVarElim(id_help, HCond, nHelpV);
965
966  if (reduce(id_help, std(0)) !=0 )
967  {
968    return(0, p_c);
969  }
970
971  return(1, p_c);
972}
973///////////////////////////////////////////////////////////////////////////////
974// ASSUME: ord(p_F)=nNew
975// tests, if p_F =  p_c*(y - p_a*x)^nNew for some p_a, p_c.
976static proc pPOfLinTest(poly p_F, int nNew, int nHelpV, ideal HCond)
977{
978  poly p_Fn;
979  poly p_c;
980  poly p_ca;
981  poly p_help;
982  poly p_a;
983  ideal id_help;
984
985  p_Fn = jet(p_F, nNew, xyVector());
986
987  p_c  = coefficient(p_Fn,y^nNew,y);
988  p_ca = coefficient(p_Fn,y^(nNew-1)*x,xy)/-nNew;
989
990  if (npars(basering)==1
991  && charstr(basering) != string(char(basering)) + "," + parstr(basering))
992  {
993    p_a = H(nHelpV);
994    HCond = HCond + ideal(p_ca - p_a*p_c);
995  }
996  else
997  {
998    p_help = p_ca/p_c;
999    if (p_help * p_c == p_ca)
1000    {
1001      p_a = p_help;
1002    }
1003    else
1004    {
1005      p_a = H(nHelpV);
1006      HCond = HCond + ideal(p_ca - p_a*p_c);
1007    }
1008  }
1009
1010  id_help = ideal(p_Fn - p_c *(y - p_a *x)^nNew);
1011  id_help = T_helpVarElim(id_help, HCond, nHelpV);
1012
1013  if (reduce(id_help, std(0)) != 0 )
1014  {
1015    return(0, p_F, p_c, p_a, HCond);
1016  }
1017
1018  return(1, p_F, p_c, p_a, HCond);
1019}
1020//////////////////////////////////////////////////////////////////////////////
1021// eliminates the variables H(1),..,H(nHelpV) from the ideal ES + HCond
1022static proc T_helpVarElim(ideal ES, ideal HCond, int nHelpV)
1023{
1024
1025  def r_old = basering;
1026
1027  ideal qIdeal = ideal(basering);
1028
1029  string helpStr;
1030  string minPolyStr = "";
1031
1032  if(minpoly != 0)
1033  {
1034    if (charstr(basering) == string(char(basering)) + "," + parstr(basering))
1035    {
1036      minPolyStr = string(minpoly);
1037    }
1038  }
1039
1040  string str = "ring myRing =
1041               (" + charstr(r_old) + "),(" + string(maxideal(1)) + "),
1042               (dp(" + string( nHelpV) + "), dp);";
1043  execute (str);
1044
1045  if (minPolyStr != "")
1046  {
1047    helpStr = "minpoly =" + minPolyStr + ";";
1048    execute(helpStr);
1049  }
1050
1051  ideal qIdeal = imap(r_old, qIdeal);
1052  if(qIdeal != 0)
1053  {
1054    def r_base = basering;
1055    kill myRing;
1056    qring myRing = std(qIdeal);
1057  }
1058
1059  ideal ES = imap(r_old, ES);
1060  ideal HCond = imap(r_old, HCond);
1061
1062  ES = ES + HCond;
1063  ES = std(ES);
1064  ES = nselect(ES,1,nHelpV);
1065
1066  setring r_old;
1067  ES = imap (myRing,ES);
1068
1069  return(ES);
1070}
1071///////////////////////////////////////////////////////////////////////////////
1072// ASSUME:  F in K[t(1)..t(s),x,y],
1073//          the ringordering is ds
1074// RETURNS: list l, such that
1075//          l[1]=1 if some error has occured,
1076//          l[1]=0 otherwise and then
1077//          l[2] = 1, if the deformation is equisingular and
1078//          l[2] = 0 otherwise.
1079static proc equisingTest (poly p_F, intvec multSeq, int maxStep)
1080{
1081  def r_old = basering;
1082
1083  ideal id_Es = 0;
1084
1085  int isES = 1;
1086  int step = 1;
1087  int nNew = multSeq[step];
1088  int nOld = nNew;
1089  int zeroSteps;
1090  ideal  HCond = 0;
1091  int  nHelpV = 1;
1092
1093  T_extendRing (p_F, nHelpV, HCond);
1094
1095  poly p_c;
1096  poly p_a;
1097
1098  while (step <= maxStep)
1099  {
1100    nOld = nNew;
1101    nNew = multSeq[step];
1102
1103    if (nNew < nOld)
1104    //start a new line in the HNE of F
1105    //               _            _
1106    // for the next | nold/nnew -1 | iteration steps the coefficient 'a'
1107    // in the leading form Fn = c(y-ax) should  be zero
1108    {
1109      p_F = swapXY(p_F);
1110      zeroSteps = calcNZeroSteps (nOld, nNew);
1111    }
1112
1113    isES, p_F = equimultTest (p_F, nHelpV, nNew, HCond);
1114
1115    if (! isES)
1116    {
1117      return(0);
1118    }
1119
1120    if (zeroSteps > 0)
1121    {
1122      zeroSteps--;
1123
1124      isES, p_c = pPOfYTest (p_F,  nHelpV, nNew, HCond);
1125      p_a = 0;
1126    }
1127    else
1128    {
1129      isES, p_F, p_c, p_a, HCond = pPOfLinTest (p_F, nNew, nHelpV, HCond);
1130    }
1131
1132    if (! isES)
1133    {
1134      return(0);
1135    }
1136
1137    p_F = formalBlowUp (p_F, p_c, p_a, nNew);
1138
1139    if (p_a == H(nHelpV))
1140    {
1141      nHelpV++;
1142
1143      def r_base = basering;
1144      kill myRing;
1145
1146      T_extendRing(p_F, nHelpV, HCond);
1147
1148      kill r_base;
1149
1150      poly p_a;
1151      poly p_c;
1152    }
1153
1154    step++;
1155  }
1156
1157  return(1);
1158}
1159///////////////////////////////////////////////////////////////////////////////
1160
1161proc isEquising (poly p_F, list #)
1162"USAGE:   esStratum(F[,m]); F a polynomial, m an integer
1163ASSUME:  F defines a deformation of an irreducible bivariate polynomial f
1164         and that char(basering) does not divide mult(f).
1165         If nv is the number of variables of the basering, then the first nv-2
1166         ringvariables are the deformation parameters.
1167         If the basering is a qring, ideal(basering) must only depend
1168         on the deformation parameters.
1169RETURN:  A list l of two integers, where
1170         l[1] = 1 if F is an equisingular deformation,l[1] = 0 otherwise.
1171         l[2] = 1 if some error has occured, l[2] = 0 otherwise.
1172         If m is given, the computation stops after m steps of the iteration.
1173NOTE:    This proc uses 'execute' or calls a procedure using 'execute'.
1174EXAMPLE: example isEquising; shows an example
1175"
1176{
1177  def r_user = basering;
1178
1179  int ii = 1;
1180  int i_nvars = nvars(basering);
1181  int error = 0;
1182  int maxStep;
1183  int userMaxStep;
1184  int xNotTransversal = 0;
1185  int fIrreducible = 1;
1186  intvec multSeq;
1187  ideal isES = 1;
1188
1189  error = checkBasering();
1190  if (error)
1191  {
1192    return(0,1);
1193  }
1194
1195  userMaxStep = getInput(#);
1196
1197  // define a new basering "myRing" with new names for parameters
1198  // and variables.
1199  // The new names are 'a(1)', ..., 'a(npars)' for the parameters
1200  // and 't(1)', ..., 't(nvars-2)', 'x', 'y' for the variables.
1201  createMyRing(p_F, "ds");
1202
1203  createHNERing();
1204
1205  poly p_f = imap(myRing,p_F);
1206
1207  error = checkPoly(p_f);
1208  if (error)
1209  {
1210    return(0,1);
1211  }
1212
1213  // compute the multiplicity sequence of p_f.
1214  multSeq, xNotTransversal, fIrreducible = calcMultSequence(p_f);
1215
1216   if ( ! fIrreducible)
1217   {
1218     return(list(0,1));
1219   }
1220
1221  setring myRing;
1222
1223  if (xNotTransversal)
1224  {
1225    p_F = swapXY(p_F);
1226  }
1227
1228  if (userMaxStep != -1 && userMaxStep <  size(multSeq)-1)
1229  {
1230    maxStep = userMaxStep;
1231  }
1232  else
1233  {
1234    maxStep = size(multSeq)-1;
1235  }
1236
1237  int isES = equisingTest(p_F, multSeq, maxStep);
1238
1239  return(list(isES, error));
1240}
1241
1242example
1243{
1244   "EXAMPLE:"; echo=2;
1245   ring r = 11,(T,x,y),ds;
1246   poly F = (x+y)^2+y^3*T+x^7;
1247   isEquising(F);
1248   isEquising(F,1);
1249   isEquising(F,2);
1250   ideal I  = ideal(T);
1251   qring q = std(I);
1252   poly F = imap(r,F);
1253   isEquising(F,2);
1254}
1255///////////////////////////////////////////////////////////////////////////////
1256/*
1257  Weiter Beispiele aus Dipl. von A. Mindnich einfuegen
1258*/
Note: See TracBrowser for help on using the repository browser.