source: git/Singular/LIB/equising.lib @ 341696

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