Changeset 969224 in git for Singular/LIB/normal.lib
- Timestamp:
- Apr 19, 2004, 5:15:34 PM (20 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- 49b2c8d253853920428dbbe2b38e18b87952e0bd
- Parents:
- 3a8dcadcb2b64d9b9db3416a310c9a32d157e00c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/LIB/normal.lib
r3a8dcad r969224 1 1 /////////////////////////////////////////////////////////////////////////////// 2 version="$Id: normal.lib,v 1.3 8 2004-02-23 10:19:11Singular Exp $";2 version="$Id: normal.lib,v 1.39 2004-04-19 15:15:34 Singular Exp $"; 3 3 category="Commutative Algebra"; 4 4 info=" … … 51 51 { 52 52 //---------- initialisation --------------------------------------------------- 53 54 53 int isIso,isPr,isCo,isRe,isEq,oSAZ,ii,jj,q,y; 55 54 intvec rw,rw1; … … 118 117 119 118 rf = interred(reduce(f,f2)); // represents p*Hom(J,J)/p*R = Hom(J,J)/R 120 121 119 if ( size(rf) == 0 ) 122 120 { … … 350 348 351 349 proc 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\" 353 351 if choose=1 the normalization of the associated primes is computed 354 352 (which is sometimes more efficient); … … 356 354 simultaneously; this may take much more time in the reducible case, 357 355 since the factorizing standard basis algorithm cannot be used. 356 if @code{choose=\"g\"} the generators of the integral closure 357 are computed. 358 358 ASSUME: The ideal must be radical, for non-radical ideals the output may 359 359 be wrong (i=radical(i); makes i radical) 360 360 RETURN: a list of rings, say nor and in case of @code{choose=\"wd\"} an 361 361 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. 362 365 Each ring @code{nor[i]} contains two ideals with given names 363 366 @code{norid} and @code{normap} such that@* … … 375 378 " 376 379 { 377 int i,j,y,withdelta ;380 int i,j,y,withdelta,withgens; 378 381 string sr; 379 382 list result,prim,keepresult; … … 383 386 if(typeof(#[1])=="string") 384 387 { 388 if(#[1]=="g") 389 { 390 withgens=1; 391 } 392 else 393 { 394 withdelta=1; 395 } 385 396 kill #; 386 397 list #; 387 withdelta=1;388 398 } 389 399 } … … 395 405 "// please change to global ordering!"; 396 406 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); 397 432 } 398 433 if( typeof(attrib(id,"isCompleteIntersection"))=="int" ) … … 559 594 nor=normal(i,"wd"); 560 595 //the delta-invariant 596 nor[size(nor)]; 597 nor=normal(i,"g"); 561 598 nor[size(nor)]; 562 599 } … … 831 868 } 832 869 } 833 834 870 //compute the singular locus 835 871 if((attrib(SM[2],"onlySingularAtZero")==0)&&(size(#)==0)) … … 1025 1061 "// radical computation of singular locus"; 1026 1062 } 1027 1028 1063 J=radical(JM[2]); //the singular locus 1029 1064 JM=mstd(J); … … 1039 1074 ""; 1040 1075 } 1041 1042 1076 if(deg(SL[1])>deg(J[1])) 1043 1077 { … … 1191 1225 } 1192 1226 /////////////////////////////////////////////////////////////////////////////// 1193 staticproc substpart(ideal endid, ideal endphi, int homo, intvec rw)1227 proc substpart(ideal endid, ideal endphi, int homo, intvec rw) 1194 1228 1195 1229 "//Repeated application of elimpart to endid, until no variables can be … … 1306 1340 } 1307 1341 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))) 1309 1343 { 1310 1344 ERROR("This is not a curve"); … … 1349 1383 K=eliminate(K,m,v); 1350 1384 if(size(K)==1){de=deg(K[1]);} 1351 if( i==5)1385 if((i==5)&&(d!=de)) 1352 1386 { 1353 1387 K=reduce(equidimMax(J),J); … … 1364 1398 if(nvars(basering)==2) 1365 1399 { 1400 if(p==0) { return(0); } 1366 1401 if(deg(squarefree(p))<deg(p)){ERROR("Curve is not reduced");} 1367 1402 return(-deg(p)+1); … … 1617 1652 map phi=R,x,y; 1618 1653 ideal singL=phi(singL); 1619 singL=std(singL); 1654 singL=simplify(std(singL),1); 1655 attrib(singL,"isSB",1); 1620 1656 int d=vdim(singL); 1621 1657 poly f=phi(f); … … 1626 1662 map alpha=S,var(1)-singL[2][2],var(2)-singL[1][2]; 1627 1663 f=alpha(f); 1628 1629 1664 execute("ring C=("+charstr(S)+"),("+varstr(S)+"),ds;"); 1630 1665 poly f=imap(S,f); … … 1666 1701 singL=psi(singL); 1667 1702 p=singL[2]; 1668 c=singL[1]-lead(singL[1]); ;1703 c=singL[1]-lead(singL[1]); 1669 1704 co=leadcoef(singL[1]); 1670 1705 } … … 1678 1713 1679 1714 minpoly=p; 1680 //number c=number(imap(S,c));1681 1715 map iota=S,a,a; 1682 1716 number c=number(iota(c)); … … 1829 1863 //} 1830 1864 1865 1866 ////////////////////////////////////////////////////////////////////////////// 1867 1868 proc 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 1871 RETURN: 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. 1881 NOTE: - 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. 1886 EXAMPLE: 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 } 2063 example 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 2084 proc closureRingtower(list L) 2085 "USAGE: closureRingtower(list L); L a list of rings 2086 CREATE: rings R(1),...,R(n) such that R(i)=L[i] for all i 2087 EXAMPLE: 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 } 2100 example 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 2114 proc closureFrac(list L); 2115 "USAGE: closureFrac (L); L a list as in the result of primeClosure, L[n] 2116 containing an additional poly f 2117 CREATE: 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]. 2119 EXAMPLE: 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 } 2225 example 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 2247 static 2248 proc 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 } 1831 2352 /////////////////////////////////////////////////////////////////////////// 1832 2353
Note: See TracChangeset
for help on using the changeset viewer.