Changeset 969224 in git for Singular/LIB/normal.lib


Ignore:
Timestamp:
Apr 19, 2004, 5:15:34 PM (20 years ago)
Author:
Hans Schönemann <hannes@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
49b2c8d253853920428dbbe2b38e18b87952e0bd
Parents:
3a8dcadcb2b64d9b9db3416a310c9a32d157e00c
Message:
*pfister: genus fixed


git-svn-id: file:///usr/local/Singular/svn/trunk@7136 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/LIB/normal.lib

    r3a8dcad r969224  
    11///////////////////////////////////////////////////////////////////////////////
    2 version="$Id: normal.lib,v 1.38 2004-02-23 10:19:11 Singular Exp $";
     2version="$Id: normal.lib,v 1.39 2004-04-19 15:15:34 Singular Exp $";
    33category="Commutative Algebra";
    44info="
     
    5151{
    5252//---------- initialisation ---------------------------------------------------
    53 
    5453   int isIso,isPr,isCo,isRe,isEq,oSAZ,ii,jj,q,y;
    5554   intvec rw,rw1;
     
    118117
    119118   rf = interred(reduce(f,f2));       // represents p*Hom(J,J)/p*R = Hom(J,J)/R
    120 
    121119   if ( size(rf) == 0 )
    122120   {
     
    350348
    351349proc normal(ideal id, list #)
    352 "USAGE:   normal(i [,choose]);  i a radical ideal, choose empty, 1 or \"wd\"
     350"USAGE:   normal(i [,choose]);  i a radical ideal, choose empty, 1 ,\"g\" \"wd\"
    353351         if choose=1 the normalization of the associated primes is computed
    354352         (which is sometimes more efficient);
     
    356354         simultaneously; this may take much more time in the reducible case,
    357355         since the factorizing standard basis algorithm cannot be used.
     356         if @code{choose=\"g\"} the generators of the integral closure
     357         are computed.
    358358ASSUME:  The ideal must be radical, for non-radical ideals the output may
    359359         be wrong (i=radical(i); makes i radical)
    360360RETURN:  a list of rings, say nor and in case of @code{choose=\"wd\"} an
    361361         integer at the end of the list.
     362         In case of @code{choose=\"g\"} it returns a list of polynomials
     363         g_1,...,g_k+1 at the end of the list such that g_1/g_k+1,...
     364         g_k/g_k+1 generate the integral closure.
    362365         Each ring @code{nor[i]} contains two ideals with given names
    363366         @code{norid} and @code{normap} such that@*
     
    375378"
    376379{
    377    int i,j,y,withdelta;
     380   int i,j,y,withdelta,withgens;
    378381   string sr;
    379382   list result,prim,keepresult;
     
    383386     if(typeof(#[1])=="string")
    384387     {
     388       if(#[1]=="g")
     389       {
     390          withgens=1;
     391       }
     392       else
     393       {
     394          withdelta=1;
     395       }
    385396       kill #;
    386397       list #;
    387        withdelta=1;
    388398     }
    389399   }
     
    395405     "// please change to global ordering!";
    396406     return(result);
     407   }
     408   if(withgens)
     409   {
     410      list pr=minAssGTZ(id);
     411      if(size(pr)>1){ERROR("ideal is not prime");}
     412      def R=basering;
     413      if(defined(ker)){kill ker;}
     414      ideal ker=id;
     415      export(ker);
     416      list l=R;
     417      l=primeClosure(l);
     418      list gens=closureGenerators(l);
     419      list resu=l[size(l)],gens;
     420      dbprint(y+1,"
     421// 'normal' created a list of one ring.
     422// nor[2] is a list of elements of the basering such that
     423// nor[2][i]/nor[2][size(nor[2])] generate the integral closure.
     424// To see the rings, type (if the name of your list is nor):
     425     show( nor);
     426// To access the 1-st ring and map (similar for the others), type:
     427     def R = nor[1]; setring R;  norid; normap;
     428// R/norid is the 1-st ring of the normalization and
     429// normap the map from the original basering to R/norid");
     430
     431      return(resu);
    397432   }
    398433   if( typeof(attrib(id,"isCompleteIntersection"))=="int" )
     
    559594   nor=normal(i,"wd");
    560595   //the delta-invariant
     596   nor[size(nor)];
     597   nor=normal(i,"g");
    561598   nor[size(nor)];
    562599}
     
    831868      }
    832869   }
    833 
    834870   //compute the singular locus
    835871   if((attrib(SM[2],"onlySingularAtZero")==0)&&(size(#)==0))
     
    10251061         "// radical computation of singular locus";
    10261062      }
    1027 
    10281063      J=radical(JM[2]);   //the singular locus
    10291064      JM=mstd(J);
     
    10391074        "";
    10401075      }
    1041 
    10421076      if(deg(SL[1])>deg(J[1]))
    10431077      {
     
    11911225}
    11921226///////////////////////////////////////////////////////////////////////////////
    1193 static proc substpart(ideal endid, ideal endphi, int homo, intvec rw)
     1227proc substpart(ideal endid, ideal endphi, int homo, intvec rw)
    11941228
    11951229"//Repeated application of elimpart to endid, until no variables can be
     
    13061340   }
    13071341   ideal J=std(I);
    1308    if((dim(J)!=2)||((nvars(basering)==2)&&(dim(J)!=1)))
     1342   if((dim(J)!=2)||((nvars(basering)==2)&&(dim(J)<1)))
    13091343   {
    13101344      ERROR("This is not a curve");
     
    13491383         K=eliminate(K,m,v);
    13501384         if(size(K)==1){de=deg(K[1]);}
    1351          if(i==5)
     1385         if((i==5)&&(d!=de))   
    13521386         {
    13531387            K=reduce(equidimMax(J),J);
     
    13641398   if(nvars(basering)==2)
    13651399   {
     1400      if(p==0) { return(0); }
    13661401      if(deg(squarefree(p))<deg(p)){ERROR("Curve is not reduced");}
    13671402      return(-deg(p)+1);
     
    16171652   map phi=R,x,y;
    16181653   ideal singL=phi(singL);
    1619    singL=std(singL);
     1654   singL=simplify(std(singL),1);
     1655   attrib(singL,"isSB",1);
    16201656   int d=vdim(singL);
    16211657   poly f=phi(f);
     
    16261662      map alpha=S,var(1)-singL[2][2],var(2)-singL[1][2];
    16271663      f=alpha(f);
    1628 
    16291664      execute("ring C=("+charstr(S)+"),("+varstr(S)+"),ds;");
    16301665      poly f=imap(S,f);
     
    16661701         singL=psi(singL);
    16671702         p=singL[2];
    1668          c=singL[1]-lead(singL[1]);;
     1703         c=singL[1]-lead(singL[1]);
    16691704         co=leadcoef(singL[1]);
    16701705      }
     
    16781713     
    16791714      minpoly=p;
    1680       //number c=number(imap(S,c));
    16811715      map iota=S,a,a;
    16821716      number c=number(iota(c));
     
    18291863//}
    18301864
     1865
     1866//////////////////////////////////////////////////////////////////////////////
     1867
     1868proc primeClosure (list L, list #)
     1869"USAGE:    primeClosure(L [,c]); L a list of a ring containing a prime ideal
     1870                                 ker, c an optional integer
     1871RETURN:   a list L consisting of rings L[1],...,L[n] such that
     1872          - L[1] is a copy of (not a reference to!) the input ring L[1]
     1873          - all rings L[i] contain ideals ker, L[2],...,L[n] contain ideals phi
     1874            such that
     1875                    L[1]/ker --> ... --> L[n]/ker
     1876            are injections given by the corresponding ideals phi, and L[n]/ker
     1877            is the integral closure of L[1]/ker in its quotient field.
     1878          - all rings L[i] contain a polynomial nzd such that elements of
     1879            L[i]/ker are quotients of elements of L[i-1]/ker with denominator
     1880            nzd via the injection phi.
     1881NOTE:     - L is constructed by recursive calls of primeClosure itself.
     1882          - c determines the choice of nzd:
     1883               - c not given or equal to 0: first generator of the ideal SL,
     1884                 the singular locus of Spec(L[i]/ker)
     1885               - c<>0: the generator of SL with least number of monomials.
     1886EXAMPLE:  example primeClosure; shows an example
     1887"
     1888{
     1889// Start with a consistency check:
     1890
     1891  if (!(typeof(L[1])=="ring"))
     1892    {
     1893      "// Parameter must be a ring or a list containing a ring!";
     1894      return(-1);
     1895    }
     1896
     1897  int dblvl=printlevel-voice+2;
     1898
     1899
     1900// Some auxiliary variables:
     1901
     1902  int n=size(L);
     1903
     1904// How to choose the non-zerodivisor later on?
     1905
     1906  int nzdoption=0;
     1907  if (size(#)>0)
     1908    {
     1909      nzdoption=#[1];
     1910    }
     1911
     1912// R0 is the ring to work with, if we are in step one, make a copy of the
     1913// input ring, so that all objects are created in the copy, not in the original
     1914// ring (therefore a copy, not a reference is defined).
     1915
     1916  if (n==1)
     1917    {
     1918      def R=L[1];
     1919      def BAS=basering;
     1920      setring R;
     1921      if (!(typeof(ker)=="ideal"))
     1922        {
     1923          "// No ideal ker in the input ring!";
     1924          return (-1);
     1925        }
     1926      ker=simplify(interred(ker),15);
     1927      execute ("ring R0="+charstr(R)+",("+varstr(R)+"),("+ordstr(R)+");");
     1928      ideal ker=fetch(R,ker);
     1929       
     1930      // check whether we compute the normalization of the blow up of
     1931      // an isolated singularity at the origin (checked in normalI)
     1932
     1933      if (typeof(attrib(L[1],"iso_sing_Rees"))=="int")
     1934      {
     1935        attrib(R0,"iso_sing_Rees",attrib(L[1],"iso_sing_Rees"));
     1936      }
     1937      L=R0;
     1938    }
     1939  else
     1940    {
     1941      def R0=L[n];
     1942      setring R0;
     1943    }
     1944
     1945
     1946// In order to apply HomJJ from normal.lib, we need the radical of the singular
     1947// locus of ker, J:=rad(ker):
     1948
     1949//  if (homog(ker)==1)
     1950//    {
     1951      list SM=mstd(ker);
     1952//    }
     1953/*  else
     1954    {
     1955      list SM=groebner(ker),ker;
     1956    }*/
     1957
     1958// In the first iteration, we have to compute the singular locus "from
     1959// scratch". In further iterations, we can fetch it from the previous one but
     1960// have to compute its radical.
     1961
     1962  if (n==1)
     1963    {
     1964      if (typeof(attrib(R0,"iso_sing_Rees"))=="int")
     1965      {
     1966        ideal J;
     1967        for (int s=1;s<=attrib(R0,"iso_sing_Rees");s++)
     1968        {
     1969          J=J,var(s);
     1970        }
     1971      }
     1972      else
     1973      {
     1974        ideal J=minor(jacob(SM[2]),nvars(basering)-dim(SM[1]));
     1975      }
     1976      J=J+SM[2];
     1977      if (homog(J)==1)
     1978        {
     1979          J=mstd(J)[2];                 
     1980        }
     1981      J=radical(interred(J));                   
     1982    }
     1983  else
     1984    {
     1985      J=radical(interred(J));   
     1986    }
     1987
     1988  // having computed the radical J of the ideal of the singular locus,
     1989  // we now need to pick an element nzd of J
     1990
     1991  poly nzd=J[1];
     1992  if (nzdoption)
     1993  {
     1994    for (int ii=2;ii<=ncols(J);ii++)
     1995    {
     1996      if ( (deg(nzd)>=deg(J[ii])) && (size(nzd)>size(J[ii])) )
     1997      {
     1998        nzd=J[ii];
     1999      }
     2000    }
     2001  }
     2002
     2003  export nzd;
     2004  list RR=SM[1],SM[2],J,nzd;
     2005  list RS=HomJJ(RR); 
     2006
     2007
     2008//////////////////////////////////////////////////////////////////////////////
     2009
     2010
     2011// If we've reached the integral closure (as determined by the result of
     2012// HomJJ), then we are done, otherwise we have to prepare the next iteration.
     2013
     2014  if (RS[2]==1)               // we've reached the integral closure
     2015    {
     2016      kill(J);
     2017      return(L);
     2018    }
     2019  else                        // prepare the next iteration
     2020    {
     2021      if (n==1)               // In the first iteration: keep only the data
     2022        {                     // needed later on.
     2023          kill (RR,SM);
     2024
     2025          export(ker);
     2026        }
     2027
     2028      def R1=RS[1];           // The data of the next ring R1:
     2029      setring R1;             // keep only what is necessary and kill
     2030      ideal ker=endid;        // everything else.
     2031      export(ker);
     2032      ideal norid=endid;
     2033      export(norid);
     2034      kill(endid);
     2035
     2036      map phi=R0,endphi;      // fetch the singular locus
     2037      ideal J=mstd(simplify(phi(J)+ker,4))[2]; 
     2038      export(J);
     2039      if(n>1)
     2040      {
     2041         ideal normap=phi(normap);
     2042      }
     2043      else
     2044      {
     2045         ideal normap=endphi;
     2046      }
     2047      export(normap);
     2048      kill(phi);              // we save phi as ideal, not as map, so that
     2049      ideal phi=endphi;       // we have more flexibility in the ring names
     2050      kill(endphi);           // later on.
     2051      export(phi);
     2052      L=insert(L,R1,n);       // Add the new ring R1 and go on with the
     2053      if (size(#)>0)
     2054        {
     2055          return (primeClosure(L,#));
     2056        }
     2057      else
     2058        {
     2059          return(primeClosure(L));         // next iteration.
     2060        }
     2061    }
     2062}
     2063example
     2064{
     2065  "EXAMPLE:"; echo=2;
     2066  ring R=0,(x,y),dp;
     2067  ideal I=x4,y4;
     2068  def K=ReesAlgebra(I)[1];        // K contains ker such that K/ker=R[It]
     2069  list L=primeClosure(K);
     2070  def R(1)=L[1];                  // L[4] contains ker, L[4]/ker is the
     2071  def R(4)=L[4];                  // integral closure of L[1]/ker
     2072  setring R(1);
     2073  R(1);
     2074  ker;
     2075  setring R(4);
     2076  R(4);
     2077  ker;
     2078}
     2079
     2080
     2081//////////////////////////////////////////////////////////////////////////////
     2082//////////////////////////////////////////////////////////////////////////////
     2083
     2084proc closureRingtower(list L)
     2085"USAGE:    closureRingtower(list L); L a list of rings
     2086CREATE:   rings R(1),...,R(n) such that R(i)=L[i] for all i
     2087EXAMPLE:  example closureRingtower; shows an example
     2088"
     2089{
     2090  int n=size(L);
     2091
     2092  for (int i=1;i<=n;i++)
     2093    {
     2094      def R(i)=L[i];
     2095      keepring (R(i));
     2096    }
     2097
     2098  return();
     2099}
     2100example
     2101{
     2102  "EXAMPLE:"; echo=2;
     2103  ring R=0,(x,y),dp;
     2104  ideal I=x4,y4;
     2105  list L=primeClosure(ReesAlgebra(I)[1]);
     2106  closureRingtower(L);
     2107  R(1);
     2108  R(4);
     2109}
     2110
     2111//////////////////////////////////////////////////////////////////////////////
     2112//////////////////////////////////////////////////////////////////////////////
     2113
     2114proc closureFrac(list L);
     2115"USAGE:    closureFrac (L); L a list as in the result of primeClosure, L[n]
     2116                           containing an additional poly f
     2117CREATE:   a list fraction of two elements of L[1], such that
     2118          f=fraction[1]/fraction[2] via the injections phi L[i]-->L[i+1].
     2119EXAMPLE:  example closureFrac; shows an example
     2120"
     2121{
     2122// Define some auxiliary variables:
     2123
     2124  int n=size(L);
     2125  int j,k,l;
     2126  string mapstr;
     2127
     2128  closureRingtower(L);         // The rings of L get names R[1],...,R[n]
     2129
     2130// The quotient representing f is computed as in 'closureGenerators' with
     2131// the differences that
     2132//   - the loop is done twice: for the numerator and for the denominator;
     2133//   - the result is stored in the list fraction and
     2134//   - we have to make sure that no more objects of the rings R(i) survive.
     2135
     2136  for (j=1;j<=2;j++)
     2137    {
     2138      setring R(n);
     2139      if (j==1)
     2140        {
     2141          poly p=f;
     2142        }
     2143      else
     2144        {
     2145          p=1;
     2146        }
     2147
     2148      for (k=n;k>1;k--)
     2149        {
     2150
     2151          if (j==1)
     2152            {
     2153              map phimap=R(k-1),phi;
     2154            }
     2155
     2156          p=p*phimap(nzd);
     2157
     2158          if (j==2)
     2159            {
     2160              kill(phimap);
     2161            }
     2162
     2163          if (j==1)
     2164            {
     2165              execute ("ring S(k) = "+charstr(R(k))+",("+varstr(R(k))+",
     2166                       Z(1.."+string(ncols(phi))+")),(dp("+string(nvars(R(k)))
     2167                       +"),dp("+string(ncols(phi))+"));");
     2168              ideal phi = imap(R(k),phi);
     2169              ideal J= imap (R(k),ker);
     2170              for (l=1;l<=ncols(phi);l++)
     2171                {
     2172                  J=J+(Z(l)-phi[l]);
     2173                }
     2174              J=groebner(J);
     2175              poly h=NF(imap(R(k),p),J);
     2176            }
     2177          else
     2178            {
     2179              setring S(k);
     2180              h=NF(imap(R(k),p),J);
     2181              setring R(k);
     2182              kill(p);
     2183            }
     2184
     2185          setring R(k-1);
     2186
     2187          if (j==1)
     2188            {
     2189              mapstr=" map backmap = S(k),";
     2190              for (l=1;l<=nvars(R(k));l++)
     2191                {
     2192                  mapstr=mapstr+"0,";
     2193                }
     2194              execute (mapstr+"maxideal(1);");
     2195
     2196              poly p;
     2197            }
     2198          p=NF(backmap(h),std(ker));
     2199          if (j==2)
     2200            {
     2201              kill(backmap);
     2202            }
     2203        }
     2204
     2205      if (j==1)
     2206        {
     2207          if (defined(fraction))
     2208            {
     2209              kill(fraction);
     2210              list fraction=p;
     2211            }
     2212          else
     2213            {
     2214              list fraction=p;
     2215            }
     2216        }
     2217      else
     2218        {
     2219          fraction=insert(fraction,p,1);
     2220        }
     2221    }
     2222  export(fraction);
     2223  return ();
     2224}
     2225example
     2226{
     2227  "EXAMPLE:"; echo=2;
     2228  ring R=0,(x,y),dp;
     2229  ideal ker=x2+y2;
     2230  export R;
     2231  list L=primeClosure(R);          // We normalize R/ker
     2232  closureRingtower(L);             // Now R/ker=R(1) with normalization R(2)
     2233  setring R(2);
     2234  kill(R);
     2235  phi;                             // The map R(1)-->R(2)
     2236  poly f=T(1)*T(2);                // We will get a representation of f
     2237  export R(2);
     2238  closureFrac(L);
     2239  setring R(1);
     2240  kill (R(2));
     2241  fraction;                        // f=fraction[1]/fraction[2] via phi
     2242}
     2243
     2244//////////////////////////////////////////////////////////////////////////////
     2245//////////////////////////////////////////////////////////////////////////////
     2246
     2247static
     2248proc closureGenerators(list L);    // called inside normalI
     2249{
     2250  // In the list L of rings R(1),...,R(n), compute representations of the ring
     2251  // ring variables of the last ring R(n) as fractions of elements of R(1).
     2252
     2253  def Rees=basering;              // when called inside normalI, the Rees
     2254                                  // Algebra is the current basering.
     2255
     2256  // First of all we need some variable declarations...
     2257
     2258  list preimages;
     2259  int n=size(L);                  // the number of rings R(1)-->...-->R(n)
     2260  int j,k,l;
     2261  int length=nvars(L[n]);         // the number of variables of the last ring
     2262  string mapstr;
     2263
     2264  closureRingtower(L);            // ...and the rings R(1),...,R(n) out of L.
     2265
     2266  // For each variable (counter j) and for each intermediate ring (counter k):
     2267  // Find a preimage of var_j*phi(nzd(k-1)) in R(k-1).
     2268  // Finally, do the same for nzd.
     2269
     2270  for (j=1;j<=length+1;j++)
     2271    {
     2272      setring R(n);
     2273
     2274      if (j==1)
     2275        {
     2276          poly p;
     2277        }
     2278
     2279      if (j<=nvars(R(n)))
     2280        {
     2281          p=var(j);
     2282        }
     2283      else
     2284        {
     2285          p=1;
     2286        }
     2287
     2288      for (k=n;k>1;k--)
     2289        {
     2290
     2291          if (j==1)
     2292            {
     2293              map phimap=R(k-1),phi;      // phimap is the map corresponding
     2294            }                             // to phi
     2295
     2296          p=p*phimap(nzd);
     2297
     2298          // Compute the preimage of [p mod ker(k)] under phi in R(k-1):
     2299          // As p is an element of Image(phi), there is a polynomial h such
     2300          // that h is mapped to [p mod ker(k)], and h can be computed as the
     2301          // normal form of p w.r.t. a Gröbner basis of
     2302          // J(k):=<ker(k),Z(l)-phi(k)(l)> in R(k)[Z]=:S(k)
     2303
     2304          if (j==1)   // In the first iteration: Create S(k), fetch phi and
     2305                      // ker(k) and construct the ideal J(k).
     2306            {
     2307              execute ("ring S(k) = "+charstr(R(k))+",("+varstr(R(k))+",
     2308                       Z(1.."+string(ncols(phi))+")),(dp("+string(nvars(R(k)))
     2309                       +"),dp("+string(ncols(phi))+"));");
     2310              ideal phi=imap(R(k),phi);
     2311              ideal J=imap (R(k),ker);
     2312              for (l=1;l<=ncols(phi);l++)
     2313                {
     2314                  J=J+(Z(l)-phi[l]);
     2315                }
     2316              J=groebner(J);
     2317              poly h=NF(imap(R(k),p),J);
     2318            }
     2319          else
     2320            {
     2321              setring S(k);
     2322              h=NF(imap(R(k),p),J);
     2323            }
     2324
     2325          setring R(k-1);
     2326
     2327          if (j==1)  // In the first iteration: Compute backmap:S(k)-->R(k-1)
     2328            {
     2329              mapstr=" map backmap = S(k),";
     2330              for (l=1;l<=nvars(R(k));l++)
     2331                {
     2332                  mapstr=mapstr+"0,";
     2333                }
     2334              execute (mapstr+"maxideal(1);");
     2335
     2336              poly p;
     2337            }
     2338          p=NF(backmap(h),std(ker));
     2339        }
     2340
     2341      // When down to R(1), store the result in the list preimages
     2342
     2343      preimages = insert(preimages,p,j-1);
     2344    }
     2345
     2346  // R(1) was a copy of Rees, so we have to get back to the basering Rees from
     2347  // the beginning and fetch the result (the list preimages) to this ring.
     2348
     2349  setring Rees;
     2350  return (fetch(R(1),preimages));
     2351}
    18312352///////////////////////////////////////////////////////////////////////////
    18322353
Note: See TracChangeset for help on using the changeset viewer.