source: git/Singular/LIB/equising.lib @ 09b9c1

spielwiese
Last change on this file since 09b9c1 was 09b9c1, checked in by Christoph Lossen <lossen@…>, 17 years ago
*lossen: Computation of I^s(f) (third entry of list returned by esIdeal) fixed git-svn-id: file:///usr/local/Singular/svn/trunk@9198 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 53.3 KB
Line 
1version="$Id: equising.lib,v 1.15 2006-06-12 12:12:27 lossen Exp $";
2category="Singularities";
3info="
4LIBRARY:  equising.lib  Equisingularity Stratum of a Family of Plane Curves
5AUTHOR:   Christoph Lossen, lossen@mathematik.uni-kl.de
6          Andrea Mindnich, mindnich@mathematik.uni-kl.de
7
8MAIN PROCEDURES:
9 tau_es(f);             codim of mu-const stratum in semi-universal def. base
10 esIdeal(f);            (Wahl's) equisingularity ideal of f
11 esStratum(F[,m,L]);    equisingularity stratum of a family F
12 isEquising(F[,m,L]);   tests if a given deformation is equisingular
13
14AUXILIARY PROCEDURE:
15 control_Matrix(M);     computes list of blowing-up data
16";
17
18LIB "hnoether.lib";
19LIB "poly.lib";
20LIB "elim.lib";
21LIB "deform.lib";
22LIB "sing.lib";
23
24////////////////////////////////////////////////////////////////////////////////
25//
26//  The following (static) procedures are used by esComputation
27//
28////////////////////////////////////////////////////////////////////////////////
29// COMPUTES  a weight vector. x and y get weight 1 and all other
30//           variables get weight 0.
31static proc xyVector()
32{
33  intvec iv ;
34  iv[nvars(basering)]=0 ;
35  iv[rvar(x)] =1;
36  iv[rvar(y)] =1;
37  return (iv);
38}
39
40////////////////////////////////////////////////////////////////////////////////
41// exchanges the variables x and y in the polynomial f
42static proc swapXY(poly f)
43{
44  def r_base = basering;
45  ideal MI = maxideal(1);
46  MI[rvar(x)]=y;
47  MI[rvar(y)]=x;
48  map phi = r_base, MI;
49  f=phi(f);
50  return (f);
51}
52
53////////////////////////////////////////////////////////////////////////////////
54// computes m-jet w.r.t. the variables x,y (other variables weighted 0
55static proc m_Jet(poly F,int m);
56{
57  intvec w=xyVector();
58  poly Fd=jet(F,m,w);
59  return(Fd);
60}
61
62
63////////////////////////////////////////////////////////////////////////////////
64// computes the 4 control matrices (input is multsequence(L))
65proc control_Matrix(list M);
66"USAGE:   control_Matrix(L); L list
67ASSUME:  L is the output of multsequence(hnexpansion(f)).
68RETURN:  list M of 4 intmat's:
69@format
70  M[1] contains the multiplicities at the respective infinitely near points
71       p[i,j] (i=step of blowup+1, j=branch) -- if branches j=k,...,k+m pass
72       through the same p[i,j] then the multiplicity is stored in M[1][k,j],
73       while M[1][k+1]=...=M[1][k+m]=0.
74  M[2] contains the number of branches meeting at p[i,j] (again, the information
75       is stored according to the above rule)
76  M[3] contains the information about the splitting of M[1][i,j] with respect to
77       different tangents of branches at p[i,j] (information is stored only for
78       minimal j>=k corresponding to a new tangent direction).
79       The entries are the sum of multiplicities of all branches with the
80       respective tangent.
81  M[4] contains the maximal sum of higher multiplicities for a branch passing
82       through p[i,j] ( = degree Bound for blowing up)
83@end format
84NOTE:    the branches are ordered in such a way that only consecutive branches
85         can meet at an infinitely near point. @*
86         the final rows of the matrices M[1],...,M[3] is (1,1,1,...,1), and
87         correspond to infinitely near points such that the strict transforms
88         of the branches are smooth and intersect the exceptional divisor
89         transversally.
90SEE ALSO: multsequence
91EXAMPLE: example control_Matrix; shows an example
92"
93{
94  int i,j,k,dummy;
95
96  dummy=0;
97  for (j=1;j<=ncols(M[2]);j++)
98  {
99    dummy=dummy+M[1][nrows(M[1])-1,j]-M[1][nrows(M[1]),j];
100  }
101  intmat S[nrows(M[1])+dummy][ncols(M[1])];
102  intmat T[nrows(M[1])+dummy][ncols(M[1])];
103  intmat U[nrows(M[1])+dummy][ncols(M[1])];
104  intmat maxDeg[nrows(M[1])+dummy][ncols(M[1])];
105
106  for (i=1;i<=nrows(M[2]);i++)
107  {
108    dummy=1;
109    for (j=1;j<=ncols(M[2]);j++)
110    {
111      for (k=dummy;k<dummy+M[2][i,j];k++)
112      {
113        T[i,dummy]=T[i,dummy]+1;
114        S[i,dummy]=S[i,dummy]+M[1][i,k];
115        if (i>1)
116        {
117          U[i-1,dummy]=U[i-1,dummy]+M[1][i-1,k];
118        }
119      }
120      dummy=k;
121    }
122  }
123
124  // adding an extra row (in some cases needed to control ES-Stratum
125  // computation)
126  for (i=nrows(M[1]);i<=nrows(S);i++)
127  {
128    for (j=1;j<=ncols(M[2]);j++)
129    {
130      S[i,j]=1;
131      T[i,j]=1;
132      U[i,j]=1;
133    }
134  }
135
136  // Computing the degree Bounds to be stored in M[4]:
137  for (i=1;i<=nrows(S);i++)
138  {
139    dummy=1;
140    for (j=1;j<=ncols(S);j++)
141    {
142      for (k=dummy;k<dummy+T[i,j];k++)
143      {
144        maxDeg[i,k]=S[i,dummy];  // multiplicity at i-th blowup
145      }
146      dummy=k;
147    }
148  }
149  // adding up multiplicities
150  for (i=nrows(S);i>=2;i--)
151  {
152    for (j=1;j<=ncols(S);j++)
153    {
154      maxDeg[i-1,j]=maxDeg[i-1,j]+maxDeg[i,j];
155    }
156  }
157
158  list L=S,T,U,maxDeg;
159  return(L);
160}
161
162
163////////////////////////////////////////////////////////////////////////////////
164//  matrix of higher tangent directions:
165//  returns list: 1) tangent directions
166//                2) swapping information (x <--> y)
167static proc inf_Tangents(list L,int s); // L aus hnexpansion,
168{
169  int nv=nvars(basering);
170  matrix M;
171  matrix B[s][size(L)];
172  intvec V;
173  intmat Mult=multsequence(L)[1];
174
175  int i,j,k,counter,e;
176  for (k=1;k<=size(L);k++)
177  {
178    V[k]=L[k][3];  // switch: 0 --> tangent 2nd parameter
179                   //         1 --> tangent 1st parameter
180    e=0;
181    M=L[k][1];
182    counter=1;
183    B[counter,k]=M[1,1];
184
185    for (i=1;i<=nrows(M);i++)
186    {
187      for (j=2;j<=ncols(M);j++)
188      {
189        counter=counter+1;
190        if (M[i,j]==var(nv-1))
191        {
192          if (i<>nrows(M))
193          {
194            B[counter,k]=M[i,j];
195            j=ncols(M)+1; // goto new row of HNmatrix...
196            if (counter<>s)
197            {
198              if (counter+1<=nrows(Mult))
199              {
200                e=Mult[counter-1,k]-Mult[counter,k]-Mult[counter+1,k];
201              }
202              else
203              {
204                e=Mult[counter-1,k]-Mult[counter,k]-1;
205              }
206            }
207          }
208          else
209          {
210            B[counter,k]=0;
211            j=ncols(M)+1; // goto new row of HNmatrix...
212          }
213        }
214        else
215        {
216          if (e<=0)
217          {
218            B[counter,k]=M[i,j];
219          }
220          else  // point is still proximate to an earlier point
221          {
222            B[counter,k]=y; // marking proximity (without swap....)
223            if (counter+1<=nrows(Mult))
224            {
225              e=e-Mult[counter+1,k];
226            }
227            else
228            {
229              e=e-1;
230            }
231          }
232        }
233
234        if (counter==s) // given number of points determined
235        {
236            j=ncols(M)+1;
237            i=nrows(M)+1;
238            // leave procedure
239        }
240      }
241    }
242  }
243  L=B,V;
244  return(L);
245}
246
247////////////////////////////////////////////////////////////////////////////////
248// compute "good" upper bound for needed number of help variables
249//
250static proc Determine_no_b(intmat U,matrix B)
251// U is assumed to be 3rd output of control_Matrix
252// B is assumed to be 1st output of inf_Tangents
253{
254  int nv=nvars(basering);
255  int i,j,counter;
256  for (j=1;j<=ncols(U);j++)
257  {
258    for (i=1;i<=nrows(U);i++)
259    {
260      if (U[i,j]>1)
261      {
262        if (B[i,j]<>var(nv-1) and B[i,j]<>var(nv))
263        {
264          counter=counter+1;
265        }
266      }
267
268    }
269  }
270  counter=counter+ncols(U);
271  return(counter);
272}
273
274////////////////////////////////////////////////////////////////////////////////
275// compute number of infinitely near free points corresponding to non-zero
276// entries in control_Matrix[1] (except first row)
277//
278static proc no_freePoints(intmat Mult,matrix B)
279// Mult is assumed to be 1st output of control_Matrix
280// U is assumed to be 3rd output of control_Matrix
281// B is assumed to be 1st output of inf_Tangents
282{
283  int i,j,k,counter;
284  for (j=1;j<=ncols(Mult);j++)
285  {
286    for (i=2;i<=nrows(Mult);i++)
287    {
288      if (Mult[i,j]>=1)
289      {
290        if (B[i-1,j]<>x and B[i-1,j]<>y)
291        {
292          counter=counter+1;
293        }
294      }
295    }
296  }
297  return(counter);
298}
299
300
301///////////////////////////////////////////////////////////////////////////////
302// COMPUTES string(minpoly) and substitutes the parameter by newParName
303static proc makeMinPolyString (string newParName)
304{
305  int i;
306  string parName = parstr(basering);
307  int parNameSize = size(parName);
308
309  string oldMinPolyStr = string (minpoly);
310  int minPolySize = size(oldMinPolyStr);
311
312  string newMinPolyStr = "";
313
314  for (i=1;i <= minPolySize; i++)
315  {
316    if (oldMinPolyStr[i,parNameSize] == parName)
317    {
318      newMinPolyStr = newMinPolyStr + newParName;
319      i = i + parNameSize-1;
320    }
321    else
322    {
323      newMinPolyStr = newMinPolyStr + oldMinPolyStr[i];
324    }
325  }
326
327  return(newMinPolyStr);
328}
329
330
331///////////////////////////////////////////////////////////////////////////////
332//
333// DEFINES: A new basering, "myRing",
334//          with new names for the parameters and variables.
335//          The new names for the parameters are a(1..k),
336//          and t(1..s),x,y for the variables
337//          The ring ordering is ordStr.
338// NOTE:    This proc uses 'execute'.
339static proc createMyRing_new(poly p_F, string ordStr,
340                                string minPolyStr, int no_b)
341{
342  def r_old = basering;
343
344  int chara = char(basering);
345  string charaStr;
346  int i;
347  string helpStr;
348  int nDefParams = nvars(r_old)-2;
349
350  ideal qIdeal = ideal(basering);
351
352  if ((npars(basering)==0) and (minPolyStr==""))
353  {
354    helpStr = "ring myRing1 ="
355              + string(chara)+ ", (t(1..nDefParams), x, y),("+ ordStr +");";
356    execute(helpStr);
357  }
358  else
359  {
360    charaStr = charstr(basering);
361    if (charaStr == string(chara) + "," + parstr(basering) or minPolyStr<>"")
362    {
363      if (minPolyStr<>"")
364      {
365        helpStr = "ring myRing1 =
366                 (" + string(chara) + ",a),
367                 (t(1..nDefParams), x, y),(" + ordStr + ");";
368        execute(helpStr);
369
370        execute (minPolyStr);
371      }
372      else // no minpoly given
373      {
374        helpStr = "ring myRing1 =
375                  (" + string(chara) + ",a(1..npars(basering)) ),
376                  (t(1..nDefParams), x, y),(" + ordStr + ");";
377        execute(helpStr);
378      }
379    }
380    else
381    {
382      // ground field is of type (p^k,a)....
383      i = find (charaStr,",");
384      helpStr = "ring myRing1 = (" + charaStr[1,i] + "a),
385              (t(1..nDefParams), x, y),(" + ordStr + ");";
386      execute (helpStr);
387    }
388  }
389
390  ideal mIdeal = maxideal(1);
391  ideal qIdeal = fetch(r_old, qIdeal);
392  poly p_F = fetch(r_old, p_F);
393  export p_F,mIdeal;
394
395  // Extension by no_b auxiliary variables
396  if (no_b>0)
397  {
398    if (npars(basering) == 0)
399    {
400      ordStr = "(dp("+string(no_b)+"),"+ordStr+")";
401      helpStr = "ring myRing ="
402                + string(chara)+ ", (b(1..no_b), t(1..nDefParams), x, y),"
403                + ordStr +";";
404      execute(helpStr);
405    }
406    else
407    {
408      charaStr = charstr(basering);
409      if (charaStr == string(chara) + "," + parstr(basering))
410      {
411        if (minpoly !=0)
412        {
413          ordStr = "(dp(" + string(no_b) + ")," + ordStr + ")";
414          minPolyStr = makeMinPolyString("a");
415          helpStr = "ring myRing =
416                   (" + string(chara) + ",a),
417                   (b(1..no_b), t(1..nDefParams), x, y)," + ordStr + ";";
418          execute(helpStr);
419
420          helpStr = "minpoly =" + minPolyStr + ";";
421          execute (helpStr);
422        }
423        else // no minpoly given
424        {
425          ordStr = "(dp(" + string(no_b) + ")," + ordStr + ")";
426          helpStr = "ring myRing =
427                    (" + string(chara) + ",a(1..npars(basering)) ),
428                    (b(1..no_b), t(1..nDefParams), x, y)," + ordStr + ";";
429          execute(helpStr);
430        }
431      }
432      else
433      {
434        i = find (charaStr,",");
435        ordStr = "(dp(" + string(no_b) + ")," + ordStr + ")";
436        helpStr = "ring myRing =
437                (" + charaStr[1,i] + "a),
438                (b(1..no_b), t(1..nDefParams), x, y)," + ordStr + ";";
439        execute (helpStr);
440      }
441    }
442    ideal qIdeal = imap(myRing1, qIdeal);
443
444    if(qIdeal != 0)
445    {
446      def r_base = basering;
447      setring r_base;
448      kill myRing;
449      qring myRing = std(qIdeal);
450    }
451
452    poly p_F = imap(myRing1, p_F);
453    ideal mIdeal = imap(myRing1, mIdeal);
454    export p_F,mIdeal;
455    kill myRing1;
456  }
457  else
458  {
459    if(qIdeal != 0)
460    {
461      def r_base = basering;
462      setring r_base;
463      kill myRing1;
464      qring myRing = std(qIdeal);
465      poly p_F = imap(myRing1, p_F);
466      ideal mIdeal = imap(myRing1, mIdeal);
467      export p_F,mIdeal;
468    }
469    else
470    {
471      def myRing=myRing1;
472    }
473    kill myRing1;
474  }
475
476  setring r_old;
477  return(myRing);
478}
479
480////////////////////////////////////////////////////////////////////////////////
481// returns list of coef, leadmonomial
482//
483static proc determine_coef (poly Fm)
484{
485  def r_base = basering; // is assumed to be the result of createMyRing
486
487  int chara = char(basering);
488  string charaStr;
489  int i;
490  string minPolyStr = "";
491  string helpStr = "";
492
493  if (npars(basering) == 0)
494  {
495    helpStr = "ring myRing1 ="
496              + string(chara)+ ", (y,x),ds;";
497    execute(helpStr);
498  }
499  else
500  {
501    charaStr = charstr(basering);
502    if (charaStr == string(chara) + "," + parstr(basering))
503    {
504      if (minpoly !=0)
505      {
506        minPolyStr = makeMinPolyString("a");
507        helpStr = "ring myRing1 = (" + string(chara) + ",a), (y,x),ds;";
508        execute(helpStr);
509
510        helpStr = "minpoly =" + minPolyStr + ";";
511        execute (helpStr);
512      }
513      else // no minpoly given
514      {
515        helpStr = "ring myRing1 =
516                  (" + string(chara) + ",a(1..npars(basering)) ), (y,x),ds;";
517        execute(helpStr);
518      }
519    }
520    else
521    {
522      i = find (charaStr,",");
523
524      helpStr = " ring myRing1 = (" + charaStr[1,i] + "a), (y,x),ds;";
525      execute (helpStr);
526    }
527  }
528  poly f=imap(r_base,Fm);
529  poly g=leadmonom(f);
530  setring r_base;
531  poly g=imap(myRing1,g);
532  kill myRing1;
533  def M=coef(Fm,xy);
534
535  for (i=1; i<=ncols(M); i++)
536  {
537    if (M[1,i]==g)
538    {
539      poly h=M[2,i];  // determine coefficient of leading monomial (in K[t])
540      i=ncols(M)+1;
541    }
542  }
543  return(list(h,g));
544}
545
546///////////////////////////////////////////////////////////////////////////////
547// RETURNS: 1, if p_f = 0 or char(basering) divides the order of p_f
548//             or p_f is not squarefree.
549//          0, otherwise
550static proc checkPoly (poly p_f)
551{
552  int i_print = printlevel - voice + 3;
553  int i_ord;
554
555  if (p_f == 0)
556  {
557    print("Input is a 'deformation'  of the zero polynomial!");
558    return(1);
559  }
560
561  i_ord = mindeg1(p_f);
562
563  if (number(i_ord) == 0)
564  {
565    print("Characteristic of coefficient field "
566            +"divides order of zero-fiber !");
567    return(1);
568  }
569
570  if (squarefree(p_f) != p_f)
571  {
572    print("Original polynomial (= zero-fiber) is not reduced!");
573    return(1);
574  }
575
576  return(0);
577}
578
579////////////////////////////////////////////////////////////////////////////////
580static proc make_ring_small(ideal J)
581// returns varstr for new ring, the map and the number of vars
582{
583  attrib(J,"isSB",1);
584  int counter=0;
585  ideal newmap;
586  string newvar="";
587  for (int i=1; i<=nvars(basering); i++)
588  {
589    if (reduce(var(i),J)<>0)
590    {
591      newmap[i]=var(i);
592
593      if (newvar=="")
594      {
595        newvar=newvar+string(var(i));
596        counter=counter+1;
597      }
598      else
599      {
600        newvar=newvar+","+string(var(i));
601        counter=counter+1;
602      }
603    }
604    else
605    {
606      newmap[i]=0;
607    }
608  }
609  list L=newvar,newmap,counter;
610  attrib(J,"isSB",0);
611  return(L);
612}
613
614///////////////////////////////////////////////////////////////////////////////
615//  The following procedure is called by esStratum (typ=0), resp. by
616//  isEquising (typ=1)
617///////////////////////////////////////////////////////////////////////////////
618
619static proc esComputation (int typ, poly p_F, list #)
620{
621  intvec ov=option(get);  // store options set at beginning
622  option(redSB);
623  // Initialize variables
624  int branch=1;
625  int blowup=1;
626  int auxVar=1;
627  int nVars;
628
629  intvec upper_bound, upper_bound_old, fertig, soll;
630  list blowup_string;
631  int i_print= printlevel-voice+2;
632
633  int no_b, number_of_branches, swapped;
634  int i,j,k,m, counter, dummy;
635  string helpStr = "";
636  string ordStr = "";
637  string MinPolyStr = "";
638
639  if (nvars(basering)<=2)
640  {
641    print("family is trivial (no deformation parameters)!");
642    if (typ==1) //isEquising
643    {
644      option(set,ov);
645      return(1);
646    }
647    else
648    {
649      option(set,ov);
650      return(list(ideal(0),0));
651    }
652  }
653
654  if (size(#)>0)
655  {
656    if (typeof(#[1])=="int")
657    {
658      def artin_bd=#[1];  // compute modulo maxideal(artin_bd)
659      if (artin_bd <= 1)
660      {
661        print("Do you really want to compute over Basering/maxideal("
662              +string(artin_bd)+") ?");
663        print("No computation performed !");
664        if (typ==1) //isEquising
665        {
666          option(set,ov);
667          return(1);
668        }
669        else
670        {
671          option(set,ov);
672          return(list(ideal(0),int(1)));
673        }
674      }
675      if (size(#)>1)
676      {
677        if (typeof(#[2])=="list")
678        {
679          def @L=#[2];  // is assumed to be the Hamburger-Noether matrix
680        }
681      }
682    }
683    else
684    {
685      if (typeof(#)=="list")
686      {
687        def @L=#;  // is assumed to be the Hamburger-Noether matrix
688      }
689    }
690  }
691  int ring_is_changed;
692  def old_ring=basering;
693  if(defined(@L)<=0)
694  {
695    // define a new ring without deformation-parameters and change to it:
696    string str;
697    string minpolyStr = string(minpoly);
698    str = " ring HNERing = (" + charstr(basering) + "), (x,y), ls;";
699    execute (str);
700    str = "minpoly ="+ minpolyStr+";";
701    execute(str);
702    ring_is_changed=1;
703    // Basering changed to HNERing (variables x,y, with ls ordering)
704
705    k=nvars(old_ring);
706    matrix Map_Phi[1][k];
707    Map_Phi[1,k-1]=x;
708    Map_Phi[1,k]=y;
709    map phi=old_ring,Map_Phi;
710    poly f=phi(p_F);
711
712    // Heuristics: if x,y are transversal parameters then computation of HNE
713    // can be much faster when exchanging variables...!
714    if (2*size(coeffs(f,x))<size(coeffs(f,y)))
715    {
716      swapped=1;
717      f=swapXY(f);
718    }
719
720    int error=checkPoly(f);
721    if (error)
722    {
723      setring old_ring;
724      if (typ==1) //isEquising
725      {
726        print("Return value (=0) has no meaning!");
727        option(set,ov);
728        return(0);
729      }
730      else
731      {
732        option(set,ov);
733        return(list( ideal(0),error));
734      }
735    }
736
737    dbprint(i_print,"// ");
738    dbprint(i_print,"// Compute HN expansion");
739    dbprint(i_print,"// ---------------------");
740    i=printlevel;
741    printlevel=printlevel-5;
742    list LLL=hnexpansion(f);
743
744    if (size(LLL)==0) { // empty list returned by hnexpansion
745      setring old_ring;
746      print(i_print,"Unable to compute HN expansion !");
747      if (typ==1) //isEquising
748      {
749        print("Return value (=0) has no meaning!");
750        option(set,ov);
751        return(0);
752      }
753      else
754      {
755        option(set,ov);
756        return(list(ideal(0),int(1)));
757      }
758      option(set,ov);
759      return(0);
760    }
761    else
762    {
763      if (typeof(LLL[1])=="ring") {
764        def HNering = LLL[1];
765        setring HNering;
766        def @L=stripHNE(hne);
767      }
768      else {
769        def @L=stripHNE(LLL);
770      }
771    }
772    printlevel=i;
773    dbprint(i_print,"// finished");
774    dbprint(i_print,"// ");
775  }
776  def HNEring=basering;
777  list M=multsequence(@L);
778  M=control_Matrix(M);     // this returns the 4 control matrices
779  def maxDeg=M[4];
780
781  list L1=inf_Tangents(@L,nrows(M[1]));
782  matrix B=L1[1];
783  intvec V=L1[2];
784  kill L1;
785
786  // if we have computed the HNE for f after swapping x and y, we have
787  // to reinterprete the (swap) matrix V:
788  if (swapped==1)
789  {
790    for (i=1;i<=size(V);i++) { V[i]=V[i]-1; } // turns 0 into -1, 1 into 0
791  }
792
793  // Determine maximal number of needed auxiliary parameters (free tangents):
794  no_b=Determine_no_b(M[3],B);
795
796  // test whether HNexpansion needed field extension....
797  string minPolyStr = "";
798  if (minpoly !=0)
799  {
800    minPolyStr = makeMinPolyString("a");
801    minPolyStr = "minpoly =" + minPolyStr + ";";
802  }
803
804  setring old_ring;
805
806  def myRing=createMyRing_new(p_F,"dp",minPolyStr,no_b);
807  setring myRing;  // comes with mIdeal
808  map hole=HNEring,mIdeal;
809  // basering has changed to myRing, in particular, the "old"
810  // variable names, e.g., A,B,C,z,y are replaced by t(1),t(2),t(3),x,y
811
812  ideal bNodes;
813
814  // Initialize some variables:
815  map phi;
816  poly G, F_save;
817  poly b_dummy;
818  ideal J,Jnew,final_Map;
819  number_of_branches=ncols(M[1]);
820  for (i=1;i<=number_of_branches;i++)
821  {
822    poly F(i);
823    ideal bl_Map(i);
824  }
825  upper_bound[number_of_branches]=0;
826  upper_bound[1]=number_of_branches;
827  upper_bound_old=upper_bound;
828  fertig[number_of_branches]=0;
829  for (i=1;i<=number_of_branches;i++){ soll[i]=1; }
830
831  // Hole:  B = matrix of blowup points
832  if (ring_is_changed==0) { matrix B=hole(B); }
833  else                    { matrix B=imap(HNEring,B); }
834  m=M[1][blowup,branch];    // multiplicity at 0
835
836  // now, we start by checking equimultiplicity along trivial section
837  poly Fm=m_Jet(p_F,m-1);
838
839  matrix coef_Mat = coef(Fm,xy);
840  Jnew=coef_Mat[2,1..ncols(coef_Mat)];
841  J=J,Jnew;
842
843  if (defined(artin_bd)) // the artin_bd-th power of the maxideal of
844                         // deformation parameters can be cutted off
845  {
846    J=jet(J,artin_bd-1);
847  }
848
849  J=interred(J);
850  if (defined(artin_bd)) { J=jet(J,artin_bd-1); }
851
852// J=std(J);
853
854  if (typ==1) // isEquising
855  {
856    if(ideal(nselect(J,1,no_b))<>0)
857    {
858      setring old_ring;
859      option(set,ov);
860      return(0);
861    }
862  }
863
864  F(1)=p_F;
865
866  // and reduce the remaining terms in F(1):
867  bl_Map(1)=maxideal(1);
868
869  attrib(J,"isSB",1);
870  bl_Map(1)=reduce(bl_Map(1),J);
871  attrib(J,"isSB",0);
872
873  phi=myRing,bl_Map(1);
874  F(1)=phi(F(1));
875
876  // simplify F(1)
877  attrib(J,"isSB",1);
878  F(1)=reduce(F(1),J);
879  attrib(J,"isSB",0);
880
881  // now we compute the m-jet:
882  Fm=m_Jet(F(1),m);
883
884  G=1;
885  counter=branch;
886  k=upper_bound[branch];
887
888  F_save=F(1);  // is truncated differently in the following loop
889
890  while(counter<=k)
891  {
892    F(counter)=m_Jet(F_save,maxDeg[blowup,counter]);
893    if (V[counter]==0) // 2nd ring variable is tangent to this branch
894    {
895      G=G*(y-(b(auxVar)+B[blowup,counter])*x)^(M[3][blowup,counter]);
896    }
897    else // 1st ring variable is tangent to this branch
898    {
899      G=G*(x-(b(auxVar)+B[blowup,counter])*y)^(M[3][blowup,counter]);
900      F(counter)=swapXY(F(counter));
901    }
902    bl_Map(counter)=maxideal(1);
903    bl_Map(counter)[nvars(basering)]=xy+(b(auxVar)+B[blowup,counter])*x;
904
905    bNodes[counter]=b(auxVar);
906
907    auxVar=auxVar+1;
908    upper_bound[counter]=counter+M[2][blowup+1,counter]-1;
909    counter=counter+M[2][blowup+1,counter];
910
911  }
912
913  list LeadDataFm=determine_coef(Fm);
914  def LeadDataG=coef(G,xy);
915
916  for (i=1; i<=ncols(LeadDataG); i++)
917  {
918    if (LeadDataG[1,i]==LeadDataFm[2])
919    {
920      poly LeadG = LeadDataG[2,i];  // determine the coefficient of G
921      i=ncols(LeadDataG)+1;
922    }
923  }
924
925  G=LeadDataFm[1]*G-LeadG*Fm;  // leading terms in y should cancel...
926
927  coef_Mat = coef(G,xy);
928  Jnew=coef_Mat[2,1..ncols(coef_Mat)];
929
930  // simplification of Jnew
931
932  if (defined(artin_bd)) // the artin_bd-th power of the maxideal of
933                         // deformation parameters can be cutted off
934  {
935    Jnew=jet(Jnew,artin_bd-1);
936  }
937  Jnew=interred(Jnew);
938  if (defined(artin_bd)) { Jnew=jet(Jnew,artin_bd-1); }
939  J=J,Jnew;
940
941  if (typ==1) // isEquising
942  {
943    if(ideal(nselect(J,1,no_b))<>0)
944    {
945      setring old_ring;
946      option(set,ov);
947      return(0);
948    }
949  }
950
951  while (fertig<>soll and blowup<nrows(M[3]))
952  {
953    upper_bound_old=upper_bound;
954    dbprint(i_print,"// Blowup Step "+string(blowup)+" completed");
955    blowup=blowup+1;
956
957    for (branch=1;branch<=number_of_branches;branch=branch+1)
958    {
959      Jnew=0;
960
961      // First we check if the branch still has to be considered:
962      if (branch==upper_bound_old[branch] and fertig[branch]<>1)
963      {
964        if (M[3][blowup-1,branch]==1 and
965               ((B[blowup,branch]<>x and B[blowup,branch]<>y)
966            or (blowup==nrows(M[3])) ))
967        {
968          fertig[branch]=1;
969          dbprint(i_print,"// 1 branch finished");
970        }
971      }
972
973      if (branch<=upper_bound_old[branch] and fertig[branch]<>1)
974      {
975        for (i=branch;i>=1;i--)
976        {
977          if (M[1][blowup-1,i]<>0)
978          {
979            m=M[1][blowup-1,i]; // multiplicity before blowup
980            i=0;
981          }
982        }
983
984        // we blow up the branch and take the strict transform:
985        attrib(J,"isSB",1);
986        bl_Map(branch)=reduce(bl_Map(branch),J);
987        attrib(J,"isSB",0);
988
989        phi=myRing,bl_Map(branch);
990        F(branch)=phi(F(branch))/x^m;
991
992        // simplify F
993        attrib(Jnew,"isSB",1);
994
995        F(branch)=reduce(F(branch),Jnew);
996        attrib(Jnew,"isSB",0);
997
998        m=M[1][blowup,branch]; // multiplicity after blowup
999        Fm=m_Jet(F(branch),m); // homogeneous part of lowest degree
1000
1001
1002        // we check for Fm=F[k]*...*F[k+s] where
1003        //
1004        //    F[j]=(y-b'(j)*x)^m(j), respectively F[j]=(-b'(j)*y+x)^m(j)
1005        //
1006        // according to the entries m(j)= M[3][blowup,j] and
1007        //                          b'(j) mod m_A = B[blowup,j]
1008        // computed from the HNE of the special fibre of the family:
1009        G=1;
1010        counter=branch;
1011        k=upper_bound[branch];
1012
1013        F_save=F(branch);
1014
1015        while(counter<=k)
1016        {
1017          F(counter)=m_Jet(F_save,maxDeg[blowup,counter]);
1018
1019          if (B[blowup,counter]<>x and B[blowup,counter]<>y)
1020          {
1021            G=G*(y-(b(auxVar)+B[blowup,counter])*x)^(M[3][blowup,counter]);
1022            bl_Map(counter)=maxideal(1);
1023            bl_Map(counter)[nvars(basering)]=
1024                                        xy+(b(auxVar)+B[blowup,counter])*x;
1025            bNodes[counter]=b(auxVar);
1026            auxVar=auxVar+1;
1027          }
1028          else
1029          {
1030            if (B[blowup,counter]==x)
1031            {
1032              G=G*x^(M[3][blowup,counter]);  // branch has tangent x !!
1033              F(counter)=swapXY(F(counter)); // will turn x to y for blow up
1034              bl_Map(counter)=maxideal(1);
1035              bl_Map(counter)[nvars(basering)]=xy;
1036            }
1037            else
1038            {
1039              G=G*y^(M[3][blowup,counter]); // tangent has to be y
1040              bl_Map(counter)=maxideal(1);
1041              bl_Map(counter)[nvars(basering)]=xy;
1042            }
1043          }
1044          upper_bound[counter]=counter+M[2][blowup+1,counter]-1;
1045          counter=counter+M[2][blowup+1,counter];
1046        }
1047        G=determine_coef(Fm)[1]*G-Fm;  // leading terms in y should cancel
1048        coef_Mat = coef(G,xy);
1049        Jnew=coef_Mat[2,1..ncols(coef_Mat)];
1050        if (defined(artin_bd)) // the artin_bd-th power of the maxideal of
1051                              // deformation parameters can be cutted off
1052        {
1053          Jnew=jet(Jnew,artin_bd-1);
1054        }
1055
1056        // simplification of J
1057        Jnew=interred(Jnew);
1058
1059        J=J,Jnew;
1060        if (typ==1) // isEquising
1061        {
1062          if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
1063          if(ideal(nselect(J,1,no_b))<>0)
1064          {
1065            setring old_ring;
1066            option(set,ov);
1067            return(0);
1068          }
1069        }
1070      }
1071    }
1072    if (number_of_branches>=2)
1073    {
1074      J=interred(J);
1075      if (typ==1) // isEquising
1076      {
1077        if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
1078        if(ideal(nselect(J,1,no_b))<>0)
1079        {
1080          setring old_ring;
1081          option(set,ov);
1082          return(0);
1083        }
1084      }
1085    }
1086  }
1087 
1088  // Computation for all equimultiple sections being trivial (I^s(f))
1089  ideal Jtriv=J;
1090  for (i=1;i<=no_b; i++)
1091  {
1092    if (reduce(b(i),std(bNodes))!=0){
1093      Jtriv=subst(Jtriv,b(i),0);
1094    }
1095  }
1096  Jtriv=std(Jtriv);
1097
1098
1099
1100  dbprint(i_print,"// ");
1101  dbprint(i_print,"// Elimination starts:");
1102  dbprint(i_print,"// -------------------");
1103
1104  poly gg;
1105  int b_left=no_b;
1106
1107  for (i=1;i<=no_b; i++)
1108  {
1109    attrib(J,"isSB",1);
1110    gg=reduce(b(i),J);
1111    if (gg==0)
1112    {
1113      b_left = b_left-1;  // another b(i) has to be 0
1114    }
1115    J = subst(J, b(i), gg);
1116    attrib(J,"isSB",0);
1117  }
1118  J=simplify(J,10);
1119  if (typ==1) // isEquising
1120  {
1121    if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
1122    if(ideal(nselect(J,1,no_b))<>0)
1123    {
1124      setring old_ring;
1125      option(set,ov);
1126      return(0);
1127    }
1128  }
1129
1130  //new CL 11/06:  check in which equations b(k) appears and remove those b(k)
1131  //               which appear in exactly one of the equations (by removing this
1132  //               equation)
1133  dbprint(i_print,"// ");
1134  dbprint(i_print,"// Remove superfluous equations:");
1135  dbprint(i_print,"// -----------------------------");
1136  int Z,App_in;
1137  ideal J_Tmp;
1138  int ncJ=ncols(J);
1139
1140  intmat Mdet[ncJ][1];
1141  for (Z=1;Z<=ncJ;Z++){ Mdet[Z,1]=Z; }
1142
1143  for (i=1;i<=no_b; i++)
1144  {
1145    ideal b_appears_in(i);            // Eintraege sind spaeter 1 oder 0
1146    intmat b_app_in(i)[1][ncJ];       // Eintraege sind spaeter 1 oder 0
1147    b_appears_in(i)[ncJ]=0; 
1148    J_Tmp = J-subst(J,b(i),0);
1149    for (Z=1; Z<=ncJ; Z++) {
1150      if (J_Tmp[Z]<>0) {      // b(i) appear in J_Tmp[Z]
1151        b_appears_in(i)[Z]=1;
1152        b_app_in(i)[1,Z]=1;
1153      }
1154    }
1155    if (size(b_appears_in(i))==1) { //b(i) appears only in one J_Tmp[Z]
1156      App_in = (b_app_in(i)*Mdet)[1,1];  // determines Z
1157      J[App_in]=0;
1158      b_appears_in(i)[App_in]=0;
1159      b_app_in(i)[1,App_in]=0;
1160    }
1161  }
1162
1163  for (i=1;i<=no_b; i++)
1164  {
1165    if (size(b_appears_in(i))==1) { //b(i) appears only in one J_Tmp[Z]
1166      App_in = (b_app_in(i)*Mdet)[1,1];  // determines Z
1167      J[App_in]=0;
1168      b_appears_in(i)[App_in]=0;
1169      b_app_in(i)[1,Z]=1;
1170      i=0;
1171    }
1172  }
1173
1174  Jtriv = nselect(Jtriv,1,no_b);
1175  ideal J_no_b = nselect(J,1,no_b);
1176  if (size(J) > size(J_no_b))
1177  {
1178    dbprint(i_print,"// std computation started");
1179    // some b(i) didn't appear in linear conditions and have to be eliminated
1180    if (defined(artin_bd))
1181    {
1182      // first we make the ring smaller (removing variables, which are
1183      // forced to 0 by J
1184      list LL=make_ring_small(J);
1185      ideal Shortmap=LL[2];
1186      minPolyStr = "";
1187      if (minpoly !=0)
1188      {
1189        minPolyStr = "minpoly = "+string(minpoly);
1190      }
1191      ordStr = "dp(" + string(b_left) + "),dp";
1192      ideal qId = ideal(basering);
1193
1194      helpStr = "ring Shortring = ("
1195                + charstr(basering) + "),("+ LL[1] +") , ("+ ordStr  +");";
1196      execute(helpStr);
1197      execute(minPolyStr);
1198      // ring has changed to "Shortring"
1199
1200      ideal MM=maxideal(artin_bd);
1201      MM=subst(MM,x,0);
1202      MM=subst(MM,y,0);
1203      MM=simplify(MM,2);
1204      dbprint(i_print-1,"// maxideal("+string(artin_bd)+") has "
1205                         +string(size(MM))+" elements");
1206      dbprint(i_print-1,"//");
1207
1208      // we change to the qring mod m^artin_bd
1209      // first, we have to check if we were in a qring when starting
1210      ideal qId = imap(myRing, qId);
1211      if (qId == 0)
1212      {
1213         attrib(MM,"isSB",1);
1214         qring QQ=MM;
1215      }
1216      else
1217      {
1218         qId=qId,MM;
1219         qring QQ = std(qId);
1220      }
1221
1222      ideal Shortmap=imap(myRing,Shortmap);
1223      map phiphi=myRing,Shortmap;
1224
1225      ideal J=phiphi(J);
1226      option(redSB);
1227      J=std(J);
1228      J=nselect(J,1,no_b);
1229
1230      setring myRing;
1231      // back to "myRing"
1232
1233      J=nselect(J,1,no_b);
1234      Jnew=imap(QQ,J);
1235
1236      J=J,Jnew;
1237      J=interred(J);
1238      if (defined(artin_bd)){ J=jet(J,artin_bd-1); }
1239    }
1240    else
1241    {
1242      J=std(J);
1243      J=nselect(J,1,no_b);
1244      if (defined(artin_bd)){ J=jet(J,artin_bd-1); }
1245    }
1246  }
1247
1248  dbprint(i_print,"// finished");
1249  dbprint(i_print,"// ");
1250
1251  minPolyStr = "";option(set,ov);
1252  if (minpoly !=0)
1253  {
1254   minPolyStr = "minpoly = "+string(minpoly);
1255  }
1256
1257  kill HNEring;
1258
1259  if (typ==1) // isEquising
1260  {
1261    if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
1262    if(J<>0)
1263    {
1264      setring old_ring;
1265      option(set,ov);
1266      return(0);
1267    }
1268    else
1269    {
1270      setring old_ring;
1271      option(set,ov);
1272      return(1);
1273    }
1274  }
1275
1276  setring old_ring;
1277  // we are back in the original ring
1278
1279  if (npars(myRing)<>0)
1280  {
1281    ideal qIdeal = ideal(basering);
1282    helpStr = "ring ESSring = ("
1283                 + string(char(basering))+ "," + parstr(myRing) +
1284                 ") , ("+ varstr(basering)+") , ("+ ordstr(basering) +");";
1285    execute(helpStr);
1286    execute(minPolyStr);
1287    // basering has changed to ESSring
1288
1289    ideal qIdeal = fetch(old_ring, qIdeal);
1290    if(qIdeal != 0)
1291    {
1292      def r_base = basering;
1293      kill ESSring;
1294      qring ESSring = std(qIdeal);
1295    }
1296    kill qIdeal;
1297
1298    ideal SSS;
1299    for (int ii=1;ii<=nvars(basering);ii++)
1300    {
1301      SSS[ii+no_b]=var(ii);
1302    }
1303    map phi=myRing,SSS;   // b(i) variables are mapped to zero
1304
1305    ideal ES=phi(J);
1306    ideal ES_all_triv=phi(Jtriv);
1307    kill phi;
1308
1309    if (defined(p_F)<=0)
1310    {
1311      poly p_F=fetch(old_ring,p_F);
1312      export(p_F);
1313    }
1314    export(ES);
1315    export(ES_all_triv);
1316    setring old_ring;
1317    dbprint(i_print+2,"
1318// 'esStratum' created a list M of a ring and an integer.
1319// To access the ideal defining the equisingularity stratum, type:
1320        def ESSring = M[1]; setring ESSring;  ES; ");
1321
1322    option(set,ov);
1323    return(list(ESSring,0));
1324  }
1325  else
1326  {
1327    // no new ring definition necessary
1328    ideal SSS;
1329    for (int ii=1;ii<=nvars(basering);ii++)
1330    {
1331      SSS[ii+no_b]=var(ii);
1332    }
1333    map phi=myRing,SSS;  // b(i) variables are mapped to zero
1334
1335    ideal ES=phi(J);
1336    ideal ES_all_triv=phi(Jtriv);
1337    kill phi;
1338
1339    setring old_ring;
1340    dbprint(i_print,"// output of 'esStratum' is a list consisting of:
1341//    _[1][1] = ideal defining the equisingularity stratum
1342//    _[1][2] = ideal defining the part of the equisingularity stratum
1343//              where all equimultiple sections are trivial
1344//    _[2] = 0");
1345
1346    option(set,ov);
1347    return(list(list(ES,ES_all_triv),0));
1348  }
1349
1350}
1351
1352////////////////////////////////////////////////////////////////////////////////
1353
1354proc tau_es (poly f,list #)
1355"USAGE:   tau_es(f); f poly
1356ASSUME:  f is a reduced bivariate polynomial, the basering has precisely
1357         two variables, is local and no qring.
1358RETURN:  int, the codimension of the mu-const stratum in the semi-universal
1359         deformation base.
1360NOTE:    printlevel>=1 displays additional information.
1361         When called with any additional parameter, the computation of the
1362         Milnor number is avoided (no check for NND).
1363SEE ALSO: esIdeal, tjurina, invariants
1364EXAMPLE: example tau_es; shows an example.
1365"
1366{
1367  int i,j,k,s;
1368  int slope_x, slope_y, upper;
1369  int i_print = printlevel - voice + 3;
1370  string MinPolyStr;
1371
1372  // some checks first
1373  if ( nvars(basering)<>2 )
1374  {
1375    print("// basering has not the correct number (two) of variables !");
1376    print("// computation stopped");
1377    return(0);
1378  }
1379  if ( mult(std(1+var(1)+var(2))) <> 0)
1380  {
1381    print("// basering is not local !");
1382    print("// computation stopped");
1383    return(0);
1384  }
1385
1386  if (mult(std(f))<=1)
1387  {
1388    // f is rigid
1389    return(0);
1390  }
1391
1392  if ( deg(squarefree(f))!=deg(f) )
1393  {
1394    print("// input polynomial was not reduced");
1395    print("// try    squarefree(f);   first");
1396    return(0);
1397  }
1398
1399  def old_ring=basering;
1400  execute("ring @myRing=("+charstr(basering)+"),("+varstr(basering)+"),ds;");
1401  poly f=imap(old_ring,f);
1402
1403  ideal Jacobi_Id = jacob(f);
1404
1405  // check for A_k singularity
1406  // ----------------------------------------
1407  if (mult(std(f))==2)
1408  {
1409    dbprint(i_print-1,"// ");
1410    dbprint(i_print-1,"// polynomial defined A_k singularity");
1411    dbprint(i_print-1,"// ");
1412    return( vdim(std(Jacobi_Id)) );
1413  }
1414
1415  // check for D_k singularity
1416  // ----------------------------------------
1417  if (mult(std(f))==3 and size(factorize(jet(f,3))[1])>=3)
1418  {
1419    dbprint(i_print,"// ");
1420    dbprint(i_print,"// polynomial defined D_k singularity");
1421    dbprint(i_print,"// ");
1422    ideal ES_Id = f, jacob(f);
1423    return( vdim(std(Jacobi_Id)));
1424  }
1425
1426
1427  if (size(#)==0)
1428  {
1429    // check if Newton polygon non-degenerate
1430    // ----------------------------------------
1431    Jacobi_Id=std(Jacobi_Id);
1432    int mu = vdim(Jacobi_Id);
1433    poly f_tilde=f+var(1)^mu+var(2)^mu;  //to obtain convenient Newton-polygon
1434
1435    list NP=newtonpoly(f_tilde);
1436    dbprint(i_print-1,"// Newton polygon:");
1437    dbprint(i_print-1,NP);
1438    dbprint(i_print-1,"");
1439
1440    if(is_NND(f,mu,NP))          // f is Newton non-degenerate
1441    {
1442      upper=NP[1][2];
1443      ideal ES_Id= x^k*y^upper;
1444      dbprint(i_print-1,"polynomial is Newton non-degenerate");
1445      dbprint(i_print-1,"");
1446      k=0;
1447      for (i=1;i<=size(NP)-1;i++)
1448      {
1449        slope_x=NP[i+1][1]-NP[i][1];
1450        slope_y=NP[i][2]-NP[i+1][2];
1451        for (k=NP[i][1]+1; k<=NP[i+1][1]; k++)
1452        {
1453          while ( slope_x*upper + slope_y*k >=
1454                  slope_x*NP[i][2] + slope_y*NP[i][1])
1455          {
1456            upper=upper-1;
1457          }
1458          upper=upper+1;
1459          ES_Id=ES_Id, x^k*y^upper;
1460        }
1461      }
1462      ES_Id=std(ES_Id);
1463      dbprint(i_print-2,"ideal of monomials above Newton bd. is generated by:");
1464      dbprint(i_print-2,ES_Id);
1465      ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
1466      ES_Id = ES_Id, Jacobi_Id;
1467      ES_Id = std(ES_Id);
1468      dbprint(i_print-1,"// ");
1469      dbprint(i_print-1,"// Equisingularity ideal is computed!");
1470      dbprint(i_print-1,"");
1471      return(vdim(ES_Id));
1472    }
1473    else
1474    {
1475      dbprint(i_print-1,"polynomial is Newton degenerate !");
1476      dbprint(i_print-1,"");
1477    }
1478  }
1479
1480  // for Newton degenerate polynomials, we compute the HN expansion, and
1481  // count the number of free points .....
1482
1483  dbprint(i_print-1,"// ");
1484  dbprint(i_print-1,"// Compute HN expansion");
1485  dbprint(i_print-1,"// ---------------------");
1486  i=printlevel;
1487  printlevel=printlevel-5;
1488  if (2*size(coeffs(f,x))<size(coeffs(f,y)))
1489  {
1490    f=swapXY(f);
1491  }
1492  list LLL=hnexpansion(f);
1493  if (size(LLL)==0) { // empty list returned by hnexpansion
1494    setring old_ring;
1495    ERROR("Unable to compute HN expansion !");
1496  }
1497  else
1498  {
1499    if (typeof(LLL[1])=="ring") {
1500      def HNering = LLL[1];
1501      setring HNering;
1502      def @L=hne;
1503    }
1504    else {
1505      def @L=LLL;
1506    }
1507  }
1508  def HNEring=basering;
1509
1510  printlevel=i;
1511  dbprint(i_print-1,"// finished");
1512  dbprint(i_print-1,"// ");
1513
1514  list M=multsequence(@L);
1515  M=control_Matrix(M);     // this returns the 4 control matrices
1516  intmat Mult=M[1];
1517
1518  list L1=inf_Tangents(@L,nrows(M[1]));
1519  matrix B=L1[1];
1520
1521  // determine sum_i m_i(m_i+1)/2 (over inf. near points)
1522  int conditions=0;
1523  for (i=1;i<=nrows(Mult);i++)
1524  {
1525    for (j=1;j<=ncols(Mult);j++)
1526    {
1527      conditions=conditions+(Mult[i,j]*(Mult[i,j]+1)/2);
1528    }
1529  }
1530  int freePts=no_freePoints(M[1],B);
1531  int taues=conditions-freePts-2;
1532
1533  setring old_ring;
1534  return(taues);
1535}
1536example
1537{
1538   "EXAMPLE:"; echo=2;
1539   ring r=32003,(x,y),ds;
1540   poly f=(x4-y4)^2-x10;
1541   tau_es(f);
1542}
1543
1544
1545////////////////////////////////////////////////////////////////////////////////
1546
1547proc esIdeal (poly f,list #)
1548"USAGE:   esIdeal(f[,any]]); f poly
1549ASSUME:  f is a reduced bivariate polynomial, the basering has precisely
1550         two variables, is local and no qring, and the characteristic of
1551         the ground field does not divide mult(f).
1552RETURN:  if called with only one parameter: list of two ideals,
1553@format
1554          _[1]:  equisingularity ideal of f (in sense of Wahl),
1555          _[2]:  ideal of equisingularity with fixed position of the
1556                 singularity;
1557@end format
1558         if called with more than one parameter: list of three ideals,
1559@format
1560          _[1]:  equisingularity ideal of f (in sense of Wahl)
1561          _[2]:  ideal of equisingularity with fixed position of the
1562                 singularity;
1563          _[3]:  ideal of all g such that the deformation defined by f+eg
1564                 (e^2=0) is isomorphic to an equisingular deformation
1565                 of V(f) with all equimultiple sections being trivial.
1566@end format
1567NOTE:    if some of the above condition is not satisfied then return
1568         value is list(0,0).
1569SEE ALSO: tau_es, esStratum
1570KEYWORDS: equisingularity ideal
1571EXAMPLE: example esIdeal; shows examples.
1572"
1573{
1574
1575  int typ;
1576  if (size(#)>0) { typ=1; }   // I^s is also computed
1577  int i,k,s;
1578  int slope_x, slope_y, upper;
1579  int i_print = printlevel - voice + 3;
1580  string MinPolyStr;
1581
1582  // some checks first
1583  if ( nvars(basering)<>2 )
1584  {
1585    print("// basering has not the correct number (two) of variables !");
1586    print("// computation stopped");
1587    return(list(0,0));
1588  }
1589  if ( mult(std(1+var(1)+var(2))) <> 0)
1590  {
1591    print("// basering is not local !");
1592    print("// computation stopped");
1593    return(list(0,0));
1594  }
1595
1596  if (mult(std(f))<=1)
1597  {
1598    // f is rigid
1599    if (typ==0)
1600    {
1601      return(list(ideal(1),ideal(1)));
1602    }
1603    else
1604    {
1605      return(list(ideal(1),ideal(1),ideal(1)));
1606    }
1607  }
1608
1609  if ( deg(squarefree(f))!=deg(f) )
1610  {
1611    print("// input polynomial was not squarefree");
1612    print("// try    squarefree(f);   first");
1613    return(list(0,0));
1614  }
1615
1616  if (char(basering)<>0)
1617  {
1618    if (mult(std(f)) mod char(basering)==0)
1619    {
1620      print("// characteristic of ground field divides "
1621            + "multiplicity of polynomial !");
1622      print("// computation stopped");
1623      return(list(0,0));
1624    }
1625  }
1626
1627  // check for A_k singularity
1628  // ----------------------------------------
1629  if (mult(std(f))==2)
1630  {
1631    dbprint(i_print,"// ");
1632    dbprint(i_print,"// polynomial defined A_k singularity");
1633    dbprint(i_print,"// ");
1634    ideal ES_Id = f, jacob(f);
1635    ES_Id = interred(ES_Id);
1636    ideal ESfix_Id = f, maxideal(1)*jacob(f);
1637    ESfix_Id= interred(ESfix_Id);
1638    if (typ==0) // only for computation of I^es and I^es_fix
1639    {
1640      return( list(ES_Id,ESfix_Id) );
1641    }
1642    else
1643    {
1644      return( list(ES_Id,ESfix_Id,ES_Id) );
1645    }
1646  }
1647
1648  // check for D_k singularity
1649  // ----------------------------------------
1650  if (mult(std(f))==3 and size(factorize(jet(f,3))[1])>=3)
1651  {
1652    dbprint(i_print,"// ");
1653    dbprint(i_print,"// polynomial defined D_k singularity");
1654    dbprint(i_print,"// ");
1655    ideal ES_Id = f, jacob(f);
1656    ES_Id = interred(ES_Id);
1657    ideal ESfix_Id = f, maxideal(1)*jacob(f);
1658    ESfix_Id= interred(ESfix_Id);
1659    if (typ==0) // only for computation of I^es and I^es_fix
1660    {
1661      return( list(ES_Id,ESfix_Id) );
1662    }
1663    else
1664    {
1665      return( list(ES_Id,ESfix_Id,ES_Id) );
1666    }
1667  }
1668
1669  // check if Newton polygon non-degenerate
1670  // ----------------------------------------
1671  int mu = milnor(f);
1672  poly f_tilde=f+var(1)^mu+var(2)^mu;  //to obtain a convenient Newton-polygon
1673
1674  list NP=newtonpoly(f_tilde);
1675  dbprint(i_print-1,"// Newton polygon:");
1676  dbprint(i_print-1,NP);
1677  dbprint(i_print-1,"");
1678
1679  if(is_NND(f,mu,NP))          // f is Newton non-degenerate
1680  {
1681    upper=NP[1][2];
1682    ideal ES_Id= x^k*y^upper;
1683    dbprint(i_print,"polynomial is Newton non-degenerate");
1684    dbprint(i_print,"");
1685    k=0;
1686    for (i=1;i<=size(NP)-1;i++)
1687    {
1688      slope_x=NP[i+1][1]-NP[i][1];
1689      slope_y=NP[i][2]-NP[i+1][2];
1690      for (k=NP[i][1]+1; k<=NP[i+1][1]; k++)
1691      {
1692        while ( slope_x*upper + slope_y*k >=
1693                slope_x*NP[i][2] + slope_y*NP[i][1])
1694        {
1695          upper=upper-1;
1696        }
1697        upper=upper+1;
1698        ES_Id=ES_Id, x^k*y^upper;
1699      }
1700    }
1701    ES_Id=std(ES_Id);
1702    dbprint(i_print-1,"ideal of monomials above Newton bd. is generated by:");
1703    dbprint(i_print-1,ES_Id);
1704    ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
1705    ES_Id = ES_Id, f, jacob(f);
1706    dbprint(i_print,"// ");
1707    dbprint(i_print,"// equisingularity ideal is computed!");
1708    if (typ==0)
1709    {
1710      return(list(ES_Id,ESfix_Id));
1711    }
1712    else
1713    {
1714      return(list(ES_Id,ESfix_Id,ES_Id));
1715    }
1716  }
1717  else
1718  {
1719    dbprint(i_print,"polynomial is Newton degenerate !");
1720    dbprint(i_print,"");
1721  }
1722
1723  def old_ring=basering;
1724
1725  dbprint(i_print,"// ");
1726  dbprint(i_print,"// versal deformation with triv. section");
1727  dbprint(i_print,"// =====================================");
1728  dbprint(i_print,"// ");
1729
1730  ideal JJ=maxideal(1)*jacob(f);
1731  ideal kbase_versal=kbase(std(JJ));
1732  s=size(kbase_versal);
1733  string ring_versal="ring @Px = ("+charstr(basering)+"),(t(1.."+string(s)+"),"
1734                        +varstr(basering)+"),(ds("+string(s)+"),"
1735                        +ordstr(basering)+");";
1736  MinPolyStr = string(minpoly);
1737
1738  execute(ring_versal);
1739  if (MinPolyStr<>"0")
1740  {
1741    MinPolyStr = "minpoly="+MinPolyStr;
1742    execute(MinPolyStr);
1743  }
1744  // basering has changed to @Px
1745
1746  poly F=imap(old_ring,f);
1747  ideal kbase_versal=imap(old_ring,kbase_versal);
1748  for (i=1; i<=s; i++)
1749  {
1750    F=F+var(i)*kbase_versal[i];
1751  }
1752  dbprint(i_print-1,F);
1753  dbprint(i_print-1,"");
1754
1755
1756  ideal ES_Id,ES_Id_all_triv;
1757  poly Ftriv=F;
1758
1759  dbprint(i_print,"// ");
1760  dbprint(i_print,"// Compute equisingularity Stratum over Spec(C[t]/t^2)");
1761  dbprint(i_print,"// ===================================================");
1762  dbprint(i_print,"// ");
1763  list M=esStratum(F,2);
1764  dbprint(i_print,"// finished");
1765  dbprint(i_print,"// ");
1766
1767  if (M[2]==1) // error occured during esStratum computation
1768  {
1769    print("Some error has occured during the computation");
1770    return(list(0,0));
1771  }
1772
1773  if ( typeof(M[1])=="list" )
1774  {
1775    int defpars = nvars(basering)-2;
1776    poly Fred,Ftrivred;
1777    poly g;
1778    F=reduce(F,std(M[1][1]));
1779    Ftriv=reduce(Ftriv,std(M[1][2]));
1780
1781    for (i=1; i<=defpars; i++)
1782    {
1783      Fred=reduce(F,std(var(i)));
1784      Ftrivred=reduce(Ftriv,std(var(i)));
1785
1786      g=subst(F-Fred,var(i),1);
1787      ES_Id=ES_Id, g;
1788      F=Fred;
1789
1790      g=subst(Ftriv-Ftrivred,var(i),1);
1791      ES_Id_all_triv=ES_Id_all_triv, g;
1792      Ftriv=Ftrivred;
1793    }
1794
1795    setring old_ring;
1796    // back to original ring
1797
1798    ideal ES_Id = imap(@Px,ES_Id);
1799    ES_Id = interred(ES_Id);
1800
1801    ideal ES_Id_all_triv = imap(@Px,ES_Id_all_triv);
1802    ES_Id_all_triv = interred(ES_Id_all_triv);
1803
1804    ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
1805    ES_Id = ES_Id, f, jacob(f);
1806    ES_Id_all_triv = ES_Id_all_triv, f, jacob(f);
1807
1808    if (typ==0)
1809    {
1810      return(list(ES_Id,ESfix_Id));
1811    }
1812    else
1813    {
1814      return(list(ES_Id,ESfix_Id,ES_Id_all_triv));
1815    }
1816  }
1817  else
1818  {
1819    def AuxRing=M[1];
1820
1821    dbprint(i_print,"// ");
1822    dbprint(i_print,"// change ring to ESSring");
1823
1824    setring AuxRing;  // contains p_F, ES
1825
1826    int defpars = nvars(basering)-2;
1827    poly Fred,Fredtriv;
1828    poly g;
1829    ideal ES_Id,ES_Id_all_triv;
1830
1831    poly p_Ftriv=p_F;
1832
1833    p_F=reduce(p_F,std(ES));
1834    p_Ftriv=reduce(p_Ftriv,std(ES_all_triv));
1835    for (i=1; i<=defpars; i++)
1836    {
1837      Fred=reduce(p_F,std(var(i)));
1838      Fredtriv=reduce(p_Ftriv,std(var(i)));
1839
1840      g=subst(p_F-Fred,var(i),1);
1841      ES_Id=ES_Id, g;
1842      p_F=Fred;
1843
1844      g=subst(p_Ftriv-Fredtriv,var(i),1);
1845      ES_Id_all_triv=ES_Id_all_triv, g;
1846      p_Ftriv=Fredtriv;
1847
1848    }
1849
1850    dbprint(i_print,"// ");
1851    dbprint(i_print,"// back to the original ring");
1852
1853    setring old_ring;
1854    // back to original ring
1855
1856    ideal ES_Id = imap(AuxRing,ES_Id);
1857    ES_Id = interred(ES_Id);
1858
1859    ideal ES_Id_all_triv = imap(AuxRing,ES_Id_all_triv);
1860    ES_Id_all_triv = interred(ES_Id_all_triv);
1861
1862    kill @Px;
1863    kill AuxRing;
1864
1865    ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
1866    ES_Id = ES_Id, f, jacob(f);
1867    ES_Id_all_triv = ES_Id_all_triv, f, jacob(f);
1868    dbprint(i_print,"// ");
1869    dbprint(i_print,"// equisingularity ideal is computed!");
1870    if (typ==0)
1871    {
1872      return(list(ES_Id,ESfix_Id));
1873    }
1874    else
1875    {
1876      return(list(ES_Id,ESfix_Id,ES_Id_all_triv));
1877    }
1878  }
1879}
1880example
1881{
1882  "EXAMPLE:"; echo=2;
1883  ring r=0,(x,y),ds;
1884  poly f=x7+y7+(x-y)^2*x2y2;
1885  list K=esIdeal(f);
1886  option(redSB);
1887  // Wahl's equisingularity ideal:
1888  std(K[1]);
1889
1890  ring rr=0,(x,y),ds;
1891  poly f=x4+4x3y+6x2y2+4xy3+y4+2x2y15+4xy16+2y17+xy23+y24+y30+y31;
1892  list K=esIdeal(f);
1893  vdim(std(K[1]));
1894  // the latter should be equal to:
1895  tau_es(f);
1896}
1897
1898///////////////////////////////////////////////////////////////////////////////
1899
1900proc esStratum (poly p_F, list #)
1901"USAGE:   esStratum(F[,m,L]); F poly, m int, L list
1902ASSUME:  F defines a deformation of a reduced bivariate polynomial f
1903         and the characteristic of the basering does not divide mult(f). @*
1904         If nv is the number of variables of the basering, then the first
1905         nv-2 variables are the deformation parameters. @*
1906         If the basering is a qring, ideal(basering) must only depend
1907         on the deformation parameters.
1908COMPUTE: equations for the stratum of equisingular deformations with
1909         fixed (trivial) section.
1910RETURN:  list l: either consisting of a list and an integer, where
1911@format
1912  l[1][1]=ideal defining the equisingularity stratum
1913  l[1][2]=ideal defining the part of the equisingularity stratum where all
1914          equimultiple sections through the non-nodes of the reduced total
1915          transform are trivial sections
1916  l[2]=1 if some error has occured,  l[2]=0 otherwise;
1917@end format
1918or consisting of a ring and an integer, where
1919@format
1920  l[1]=ESSring is a ring extension of basering containing the ideal ES
1921        (describing the ES-stratum), the ideal ES_all_triv (describing the
1922        part with trival equimultiple sections) and the poly p_F=F,
1923  l[2]=1 if some error has occured,  l[2]=0 otherwise.
1924@end format
1925NOTE:    L is supposed to be the output of hnexpansion (with the given ordering
1926         of the variables appearing in f). @*
1927         If m is given, the ES Stratum over A/maxideal(m) is computed. @*
1928         This procedure uses @code{execute} or calls a procedure using
1929         @code{execute}.
1930         printlevel>=2 displays additional information.
1931SEE ALSO: esIdeal, isEquising
1932KEYWORDS: equisingularity stratum
1933EXAMPLE: example esStratum; shows examples.
1934"
1935{
1936  list l=esComputation (0,p_F,#);
1937  return(l);
1938}
1939example
1940{
1941   "EXAMPLE:"; echo=2;
1942   int p=printlevel;
1943   printlevel=1;
1944   ring r = 0,(a,b,c,d,e,f,g,x,y),ds;
1945   poly F = (x2+2xy+y2+x5)+ax+by+cx2+dxy+ey2+fx3+gx4;
1946   list M = esStratum(F);
1947   M[1][1];
1948
1949   printlevel=3;     // displays additional information
1950   esStratum(F,2)  ; // ES-stratum over Q[a,b,c,d,e,f,g] / <a,b,c,d,e,f,g>^2
1951
1952   ideal I = f-fa,e+b;
1953   qring q = std(I);
1954   poly F = imap(r,F);
1955   esStratum(F);
1956   printlevel=p;
1957}
1958
1959///////////////////////////////////////////////////////////////////////////////
1960
1961proc isEquising (poly p_F, list #)
1962"USAGE:   isEquising(F[,m,L]); F poly, m int, L list
1963ASSUME:  F defines a deformation of a reduced bivariate polynomial f
1964         and the characteristic of the basering does not divide mult(f). @*
1965         If nv is the number of variables of the basering, then the first
1966         nv-2 variables are the deformation parameters. @*
1967         If the basering is a qring, ideal(basering) must only depend
1968         on the deformation parameters.
1969COMPUTE: tests if the given family is equisingular along the trivial
1970         section.
1971RETURN:  int: 1 if the family is equisingular, 0 otherwise.
1972NOTE:    L is supposed to be the output of hnexpansion (with the given ordering
1973         of the variables appearing in f). @*
1974         If m is given, the family is considered over A/maxideal(m). @*
1975         This procedure uses @code{execute} or calls a procedure using
1976         @code{execute}.
1977         printlevel>=2 displays additional information.
1978EXAMPLE: example isEquising; shows examples.
1979"
1980{
1981  int check=esComputation (1,p_F,#);
1982  return(check);
1983}
1984example
1985{
1986   "EXAMPLE:"; echo=2;
1987   ring r = 0,(a,b,x,y),ds;
1988   poly F = (x2+2xy+y2+x5)+ay3+bx5;
1989   isEquising(F);
1990   ideal I = ideal(a);
1991   qring q = std(I);
1992   poly F = imap(r,F);
1993   isEquising(F);
1994
1995   ring rr=0,(A,B,C,x,y),ls;
1996   poly f=x7+y7+(x-y)^2*x2y2;
1997   poly F=f+A*y*diff(f,x)+B*x*diff(f,x);
1998   isEquising(F);
1999   isEquising(F,2);    // computation over  Q[a,b] / <a,b>^2
2000}
2001
2002
2003
2004/*  Examples:
2005
2006LIB "equising.lib";
2007   ring r = 0,(x,y),ds;
2008   poly p1 = y^2+x^3;
2009   poly p2 = p1^2+x5y;
2010   poly p3 = p2^2+x^10*p1;
2011   poly p=p3^2+x^20*p2;
2012   p;
2013   list L=versal(p);
2014   def Px=L[1];
2015   setring Px;
2016   poly F=Fs[1,1];
2017   int t=timer;
2018   list M=esStratum(F);
2019   timer-t;  //-> 3
2020
2021LIB "equising.lib";
2022option(prot);
2023printlevel=2;
2024ring r=0,(x,y),ds;
2025poly f=(x-yx+y2)^2-(y+x)^31;
2026list L=versal(f);
2027def Px=L[1];
2028setring Px;
2029poly F=Fs[1,1];
2030int t=timer;
2031list M=esStratum(F);
2032timer-t;  //-> 233
2033
2034
2035LIB "equising.lib";
2036printlevel=2;
2037option(prot);
2038timer=1;
2039ring r=0,(x,y),ls;
2040poly f=(x4-y4)^2-x10;
2041list L=versal(f);
2042def Px=L[1];
2043setring Px;
2044poly F=Fs[1,1];
2045int t=timer;
2046list M=esStratum(F,3);
2047timer-t;  //-> 8
2048
2049LIB "equising.lib";
2050printlevel=2;
2051timer=1;
2052ring rr=0,(x,y),ls;
2053poly f=x7+y7+(x-y)^2*x2y2;
2054list K=esIdeal(f);
2055// tau_es
2056vdim(std(K[1])); //-> 22
2057// tau_es_fix
2058vdim(std(K[2])); //-> 24
2059
2060
2061LIB "equising.lib";
2062printlevel=2;
2063timer=1;
2064ring rr=0,(x,y),ls;
2065poly f=x7+y7+(x-y)^2*x2y2+x2y4; // Newton non-deg.
2066list K=esIdeal(f);
2067// tau_es
2068vdim(std(K[1])); //-> 21
2069// tau_es_fix
2070vdim(std(K[2])); //-> 23
2071
2072LIB "equising.lib";
2073ring r=0,(w,v),ds;
2074poly f=w2-v199;
2075list L=hnexpansion(f);
2076list LL=versal(f);
2077def Px=LL[1];
2078setring Px;
2079list L=imap(r,L);
2080poly F=Fs[1,1];
2081list M=esStratum(F,2,L);
2082
2083LIB "equising.lib";
2084printlevel=2;
2085timer=1;
2086ring rr=0,(A,B,C,x,y),ls;
2087poly f=x7+y7+(x-y)^2*x2y2;
2088poly F=f+A*y*diff(f,x)+B*x*diff(f,x)+C*diff(f,y);
2089list M=esStratum(F,6);
2090std(M[1][1]);  // standard basis of equisingularity ideal
2091
2092LIB "equising.lib";
2093printlevel=2;
2094timer=1;
2095ring rr=0,(x,y),ls;
2096poly f=x20+y7+(x-y)^2*x2y2+x2y4; // Newton non-degenerate
2097list K=esIdeal(f);
2098K;
2099
2100ring rr=0,(x,y),ls;
2101poly f=x6y-3x4y4-x4y5+3x2y7-x4y6+2x2y8-y10+2x2y9-y11+x2y10-y12-y13;
2102list K=esIdeal(f);
2103list L=versal(f);
2104def Px=L[1];
2105setring Px;
2106poly F=Fs[1,1];
2107list M=esStratum(F,2);
2108
2109LIB "equising.lib";
2110ring R=0,(A,B,C,D,x,y),ds;
2111poly f=x6y-3x4y4-x4y5+3x2y7-x4y6+2x2y8-y10+2x2y9-y11+x2y10-y12-y13;
2112poly F=f+Ax9+Bx7y2+Cx9y+Dx8y2;
2113list M=esStratum(F,2);
2114
2115
2116LIB "equising.lib";
2117printlevel=2;
2118ring rr=0,(x,y),ls;
2119poly f=x6y-3x4y4-x4y5+3x2y7-x4y6+2x2y8-y10+2x2y9-y11+x2y10-y12-y13;
2120list K=esIdeal(f);
2121vdim(std(K[1]));  //-> 51
2122tau_es(f);        //-> 51
2123
2124printlevel=3;
2125f=f*(y-x2)*(y2-x3)*(x-y5);
2126int t=timer;
2127list L=esIdeal(f);
2128vdim(std(L[1]));  //-> 99
2129timer-t;   //-> 42
2130t=timer;
2131tau_es(f);        //-> 99
2132timer-t;   //-> 23
2133
2134
2135LIB "equising.lib";
2136printlevel=3;
2137ring rr=0,(x,y),ds;
2138poly f=x4+4x3y+6x2y2+4xy3+y4+2x2y15+4xy16+2y17+xy23+y24+y30+y31;
2139list K=esIdeal(f);
2140vdim(std(K[1]));  //-> 68
2141tau_es(f);        //-> 68
2142
2143list L=versal(f);
2144def Px=L[1];
2145setring Px;
2146poly F=Fs[1,1];
2147list M=esStratum(F);
2148timer-t;          //-> 0
2149
2150
2151
2152*/
Note: See TracBrowser for help on using the repository browser.