Changeset 7c871e in git
- Timestamp:
- Sep 6, 2023, 12:34:53 PM (9 months ago)
- Branches:
- (u'spielwiese', 'c7af8613769b29c741d6c338945669719f1fc4f8')
- Children:
- 52f69966ea5a90890641163cbd32e35badcc23f8
- Parents:
- 8e0ad00ce244dfd0756200662572aef8402f13d5
- Location:
- Singular/LIB
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/LIB/locnormal.lib
r8e0ad0 r7c871e 264 264 ""; 265 265 } 266 ideal nor = changeDenom(norT, denomT, condu, I);266 ideal nor = normal::changeDenominator(norT, denomT, condu, I); 267 267 return(list(nor, t)); 268 268 } -
Singular/LIB/normal.lib
r8e0ad0 r7c871e 4 4 info=" 5 5 LIBRARY: normal.lib Normalization of Affine Rings 6 AUTHORS: G.-M. Greuel, greuel@mathematik.uni-kl.de, 6 AUTHORS: J. Boehm boehm@mathematik.uni-kl.de, 7 @* W. Decker decker@mathematik.uni-kl.de, 8 @* G.-M. Greuel, greuel@mathematik.uni-kl.de, 7 9 @* S. Laplagne, slaplagn@dm.uba.ar, 8 @* G. Pfister, pfister@mathematik.uni-kl.de 9 @* P. Chini, chini@rhrk.uni-kl.de (normalConductor) 10 10 @* G. Pfister, pfister@mathematik.uni-kl.de, 11 @* A. Steenpass steenpass@mathematik.uni-kl.de, 12 @* S. Steidel steidel@mathematik.uni-kl.de, 13 @* P. Chini, chini@rhrk.uni-kl.de (normalConductor) 11 14 12 15 PROCEDURES: 13 16 normal(I,[...]); normalization of an affine ring 17 locNormal(I, [...]); normalization of R/I using local methods 18 modNormal(I, [...]); normalization of R/I using modular methods 14 19 normalP(I,[...]); normalization of an affine ring in positive characteristic 15 20 normalC(I,[...]); normalization of an affine ring through a chain of rings … … 28 33 isNormal(ideal) test if already normal 29 34 30 SEE ALSO: locnormal_lib;modnormal_lib35 SEE ALSO: integralbasis_lib 31 36 "; 32 37 … … 88 93 - \"var2\" -> uses a polynomial in the second variable as universal 89 94 denominator.@* 95 - \"GBRadical\" -> it computes a Groebner basis of the radical 96 ideal computed for the test ideal.@* 97 - \"noGBRadical\" -> it does not compute a Groebner basis of 98 the radical ideal computed for the test ideal.@* 90 99 If the optional parameter choose is not given or empty, only 91 100 \"equidim\" but no other option is used.@* … … 220 229 {useRing = 1;} 221 230 231 list options; 232 if (#[i]=="GBRadical") 233 {options = insert(options, "GBRadical");} 234 if (#[i]=="noGBRadical") 235 {options = insert(options, "noGBRadical");} 236 222 237 if ( (#[i]=="withDelta") or (#[i]=="wd") or (#[i]=="withdelta")) 223 238 { … … 389 404 for(i=1; i<=size(prim); i++) 390 405 { 391 out = normalM(prim[i], decomp, withDelta, denomOption, inputJ, inputC, normalCheck );406 out = normalM(prim[i], decomp, withDelta, denomOption, inputJ, inputC, normalCheck, options); 392 407 if(out == 0) 393 408 { … … 414 429 } 415 430 printlevel = printlevel + 1; 416 norComp = normalM(prim[i], decomp, withDelta, denomOption, inputJ, inputC, normalCheck );431 norComp = normalM(prim[i], decomp, withDelta, denomOption, inputJ, inputC, normalCheck, options); 417 432 printlevel = printlevel - 1; 418 433 for(j = 1; j <= size(norComp); j++) … … 4402 4417 // a different test ideal. 4403 4418 4404 static proc normalM(ideal I, int decomp, int withDelta, int denomOption, ideal inputJ, ideal inputC, int normalCheck ){4419 static proc normalM(ideal I, int decomp, int withDelta, int denomOption, ideal inputJ, ideal inputC, int normalCheck, list options){ 4405 4420 // Computes the normalization of a ring R / I using the module structure as far 4406 4421 // as possible. … … 4598 4613 if(normalCheck == 1) 4599 4614 { 4600 int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4615 int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4601 4616 if(check1) 4602 4617 { 4603 int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4618 int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4604 4619 printlevel = printlevel - 1; 4605 4620 option(set,save_opt); … … 4613 4628 } else 4614 4629 { 4615 list nor1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4616 list nor2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4630 list nor1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4631 list nor2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4617 4632 printlevel = printlevel - 1; 4618 4633 option(set,save_opt); … … 4741 4756 if(normalCheck == 1) 4742 4757 { 4743 int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4758 int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4744 4759 if(check1) 4745 4760 { 4746 int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4761 int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4747 4762 printlevel = printlevel - 1; 4748 4763 return(check2); … … 4754 4769 } else 4755 4770 { 4756 list nor1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4757 list nor2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck );4771 list nor1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4772 list nor2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options); 4758 4773 printlevel = printlevel - 1; 4759 4774 option(set,save_opt); … … 4773 4788 printlevel = printlevel + 1; 4774 4789 4775 if(normalCheck == 1) 4776 { 4777 int out = normalMEqui(I, J, condu, D, withDelta, normalCheck );4790 if(normalCheck == 1) 4791 { 4792 int out = normalMEqui(I, J, condu, D, withDelta, normalCheck, options); 4778 4793 printlevel = printlevel - 1; 4779 4794 option(set,save_opt); … … 4781 4796 } else 4782 4797 { 4783 list result = normalMEqui(I, J, condu, D, withDelta, normalCheck );4798 list result = normalMEqui(I, J, condu, D, withDelta, normalCheck, options); 4784 4799 printlevel = printlevel - 1; 4785 4800 option(set,save_opt); … … 4792 4807 /////////////////////////////////////////////////////////////////////////////// 4793 4808 4794 static proc normalMEqui(ideal I, ideal origJ, poly condu, poly D, int withDelta, int normalCheck )4809 static proc normalMEqui(ideal I, ideal origJ, poly condu, poly D, int withDelta, int normalCheck, list options) 4795 4810 // Here is where the normalization is actually computed. 4796 4811 … … 4802 4817 // If withDelta = 1, computes the delta invariant. 4803 4818 // If normalCheck = 1, it only checks if the ring is normal. 4819 4820 // Option gbRadical=1 computes a groebner basis of the radical output in the test ideal procedure 4821 4804 4822 { 4805 4823 ASSUME(1, not isQuotientRing(basering) ); … … 4912 4930 U[i]=lead(U[i])+reduce(U[i]-lead(U[i]),UU); 4913 4931 } 4914 testOut = testIdeal(I, U, origJ, c, D );4932 testOut = testIdeal(I, U, origJ, c, D, options); 4915 4933 cJ = testOut[1]; 4916 4934 … … 5179 5197 /////////////////////////////////////////////////////////////////////////////// 5180 5198 5181 static proc testIdeal(ideal I, ideal U, ideal origJ, poly c, poly D) 5199 // Checks if string s is an element of list l 5200 proc in_array(list l, string s) 5182 5201 { 5202 int i; 5203 int n = size(l); 5204 int found = 0; 5205 for(i = 1; i <= n; i++) { 5206 if(l[i] == s) {found = 1;} 5207 } 5208 return(found); 5209 } 5210 5211 static proc testIdeal(ideal I, ideal U, ideal origJ, poly c, poly D, list options) 5212 { 5183 5213 5184 5214 ASSUME(1, not isQuotientRing(basering) ); 5215 5216 5185 5217 5186 5218 // Internal procedure, used in normalM. … … 5210 5242 // ---------------- setting the ring to work in -------------------------- 5211 5243 int isGlobal = attrib(origEre,"global"); // Checks if the original ring has 5212 // global ordering.5244 // global ordering. 5213 5245 if(isGlobal != 1) 5214 5246 { … … 5240 5272 J = radical(J); 5241 5273 if(dbg > 1){"Computing the interreduction of the radical...";} 5242 J = groebner(J); 5243 //J = interred(J); 5274 5275 int t; 5276 if(in_array(options, "GBRadical")) { 5277 t = timer; 5278 J = groebnerDP(J); 5279 "DEBUG - time for GB of radical using dp ordering in all variables:", timer - t; 5280 } else { 5281 "DEBUG - we do not compute the GB of radical output"; 5282 } 5283 5244 5284 if(dbg > 1) 5245 5285 { … … 5313 5353 5314 5354 // ---------------------- step 4 of the mapping --------------------------- 5355 t = timer; 5315 5356 qring Q = groebner(I); 5357 "DEBUG - time for qring GB computation:", timer - t; 5358 5316 5359 ideal J = imap(R, J); 5317 5360 poly c = imap(R, c); 5361 5362 t = timer; 5318 5363 for(i = 1; i<=ncols(J); i++) 5319 5364 { … … 5327 5372 } 5328 5373 } 5374 "DEBUG - time for liftings:", timer - t; 5375 5329 5376 5330 5377 if(dbg > 1) … … 5336 5383 5337 5384 // --------------------------- prepare output ---------------------------- 5385 // Groebner basis in the ring with only the original variables 5386 5387 "time up to here: ", timer - t; 5388 t = timer; 5338 5389 J = groebner(J); 5390 "DEBUG - time for final GB computation:", timer - t; 5339 5391 5340 5392 setring R; … … 6722 6774 6723 6775 /////////////////////////////////////////////////////////////////////////// 6776 6777 // Computes the groebner basis using dp ordering 6778 static proc groebnerDP(ideal I); 6779 { 6780 def R0 = basering; 6781 def R1 = changeord(list(list("dp",1:nvars(basering)))); 6782 setring R1; 6783 ideal I=imap(R0,I); 6784 6785 I=groebner(I); 6786 6787 setring R0; 6788 ideal J = imap(R1, I); 6789 return(J); 6790 } 6791 6792 6793 6794 /////////////////////////////////////////////////////////////////////////// 6724 6795 proc norTest (ideal i, list nor, list #) 6725 6796 "USAGE: norTest(i,nor,[n]); i=prime ideal, nor=list, n=optional integer … … 7004 7075 normalConductor(I); 7005 7076 } 7077 7078 7079 //////////////////////////////////////////////////////////////////////// 7080 // 7081 // modNormal procedures 7082 // 7083 //////////////////////////////////////////////////////////////////////// 7084 7085 // AUTHORS: J. Boehm boehm@mathematik.uni-kl.de 7086 // W. Decker decker@mathematik.uni-kl.de 7087 // S. Laplagne slaplagn@dm.uba.ar 7088 // G. Pfister pfister@mathematik.uni-kl.de 7089 // A. Steenpass steenpass@mathematik.uni-kl.de 7090 // S. Steidel steidel@mathematik.uni-kl.de 7091 // @* 7092 // 7093 // OVERVIEW: 7094 // Suppose A is an affine domain over a perfect field.@* 7095 // This library implements a modular strategy for finding the normalization of A. 7096 // Following [1], the idea is to apply the normalization algorithm given in [2] 7097 // over finite fields and lift the results via Chinese remaindering and rational 7098 // reconstruction as described in [3]. This approach is inherently parallel.@* 7099 // The strategy is available both as a randomized and as a verified algorithm. 7100 // 7101 // REFERENCES: 7102 // 7103 // [1] Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Stefan Steidel, 7104 // Andreas Steenpass: Parallel algorithms for normalization, preprint, 2011. 7105 // 7106 // [2] Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings, 7107 // Journal of Symbolic Computation 9 (2010), p. 887-901 7108 // 7109 // [3] Janko Boehm, Wolfram Decker, Claus Fieker, Gerhard Pfister: 7110 // The use of Bad Primes in Rational Reconstruction, preprint, 2012. 7111 // 7112 // KEYWORDS: 7113 // normalization; modular methods 7114 7115 // Verify the char 0 result L of normalization of I modulo a prime p 7116 7117 static proc pTestNormal(ideal I, list L, int p, ideal normalIP) 7118 { 7119 // We change the characteristic of the ring to p. 7120 def R0 = basering; 7121 ideal U = L[1]; 7122 poly condu=L[2]; 7123 list rl = ringlist(R0); 7124 rl[1] = p; 7125 def @r = ring(rl); 7126 setring @r; 7127 ideal IP = fetch(R0,I); 7128 ideal UP = fetch(R0,U); 7129 poly conduP = fetch(R0, condu); 7130 ideal outP = fetch(R0,normalIP); 7131 poly denOutP = outP[1]; 7132 7133 // Check if the universal denominator is valid 7134 ideal cOut = conduP*outP; 7135 ideal dI = ideal(denOutP) + IP; 7136 int inc = size(reduce(cOut, groebner(dI), 5)); 7137 if(inc > 0) 7138 { 7139 "Inclusion is not satisfied. Unlucky prime?"; 7140 return(ideal(0)); 7141 } 7142 return(outComp(UP, outP, conduP, denOutP, IP)) 7143 } 7144 7145 //////////////////////////////////////////////////////////////////////////////// 7146 7147 7148 // Computes the normalization of I in characteristic p. 7149 // Returns an ideal Out such that the normalization mod p is the 7150 // module 1/condu * Out 7151 static proc modpNormal(ideal I, int p, poly condu,int printTimings,list #) 7152 { 7153 int tt = timer; 7154 int liftRelations; 7155 // We change the characteristic of the ring to p. 7156 def R0 = basering; 7157 list rl = ringlist(R0); 7158 rl[1] = p; 7159 def @r = ring(rl); 7160 int loc; 7161 int i; 7162 for ( i=1; i <= size(#); i++ ) 7163 { 7164 if ( typeof(#[i]) == "string" ) 7165 { 7166 if (#[i]=="inputJ") { loc = 1;ideal J=#[i][2];} 7167 } 7168 } 7169 setring @r; 7170 if (loc==1) {ideal JP = fetch(R0,J)}; 7171 //int t=timer; 7172 ideal IP = groebner(fetch(R0,I)); 7173 //"Time for groebner mod p "+string(timer -t); 7174 poly conduP = fetch(R0, condu); 7175 7176 option(redSB); 7177 7178 int t = timer; 7179 // We compute the normalization mod p 7180 if (loc==0) 7181 { 7182 //global 7183 list l = normal(IP); 7184 } else { 7185 //local 7186 list l = normal(IP,list(list("inputJ", JP))); 7187 } 7188 if (printTimings==1) {"Time for modular normal: "+string(timer - t);} 7189 7190 t = timer; 7191 7192 // Currently, the algorithm only works if no splitting occurs during the 7193 // normalization process. (For example, if I is prime.) 7194 if(size(l[2]) > 1){ 7195 ERROR("Original ideal is not prime (Not implemented.) or unlucky prime"); 7196 } 7197 7198 ideal outP = l[2][1]; 7199 poly denOutP = outP[size(outP)]; 7200 7201 // Check if the universal denominator is valid 7202 ideal cOut = conduP*outP; 7203 ideal dI = ideal(denOutP) + IP; 7204 int inc = size(reduce(cOut, groebner(dI), 5)); 7205 if(inc > 0) 7206 { 7207 ERROR("Inclusion is not satisfied. Unlucky prime?"); 7208 } 7209 7210 // We change the denominator to the universal denominator 7211 outP = changeDenominator(outP, denOutP, conduP, IP); 7212 if(size(outP) > 1) 7213 { 7214 ideal JP = conduP, outP[1..size(outP)-1]; 7215 } else 7216 { 7217 ERROR("Normal ring - Special case not fully implemented."); 7218 ideal JP = conduP; 7219 ideal norid = 0; 7220 export norid; 7221 def RP = @r; 7222 } 7223 7224 setring R0; 7225 ideal out = fetch(@r, JP); 7226 7227 if (printTimings==1) {"Prime: "+string(p);} 7228 tt = timer-tt; 7229 return(list(out, p, tt)); 7230 } 7231 7232 // Computes the normalization using modular methods. 7233 // Basic algorithm based on modstd. 7234 proc modNormal(ideal I, int nPrimes, list #) 7235 "USAGE: modNormal(I, n [,options]); I = prime ideal, n = positive integer, options = list of options. @* 7236 Optional parameters in list options (can be entered in any order):@* 7237 noVerificication: do not verify the result.@* 7238 printTimings: print timings.@* 7239 int ncores: number of cores to be used (default = 1). 7240 ASSUME: I is a prime ideal (the algorithm will also work for radical ideals as long as the 7241 normal command does not detect that the ideal under consideration is not prime). 7242 RETURN: a list of an ideal U and a universal denominator d such that U/d is the normalization. 7243 REMARKS: We use the algorithm given in [1] to compute the normalization of A = R/I where R is the 7244 basering. We apply the algorithm for n primes at a time until the result lifted to the 7245 rationals is correct modulo one additional prime. Depending on whether the option 7246 noVerificication is used or not, the result is returned as a probabilistic result 7247 or verified over the rationals.@* 7248 The normalization of A is represented as an R-module by returning a list of U and d, 7249 where U is an ideal of A and d is an element of A such that U/d is the normalization of A. 7250 In fact, U and d are returned as an ideal and a polynomial of the base ring R. 7251 KEYWORDS: normalization; modular techniques. 7252 SEE ALSO: normal_lib, locnormal_lib. 7253 EXAMPLE: example modNormal; shows an example 7254 " 7255 { 7256 7257 int i,noVerif,printTimings; 7258 int liftRelations; 7259 int ncores = 1; 7260 for ( i=1; i <= size(#); i++ ) 7261 { 7262 if ( typeof(#[i]) == "string" ) 7263 { 7264 if (#[i]=="noVerification") { noVerif = 1;} 7265 if (#[i]=="printTimings") { printTimings = 1;} 7266 } 7267 if ( typeof(#[i]) == "int" ) 7268 { 7269 ncores = #[i]; 7270 } 7271 } 7272 7273 7274 int totalTime = timer; 7275 7276 intvec LTimer; 7277 int t; 7278 7279 def R = basering; 7280 int j; 7281 7282 //-------------------- Initialize the list of primes ------------------------- 7283 int n2 = nPrimes; 7284 7285 7286 7287 //---Computation of the jacobian ideal and the universal denominator 7288 7289 list IM = mstd(I); 7290 I = IM[1]; 7291 int d = dim(I); 7292 ideal IMin = IM[2]; 7293 qring Q = I; // We work in the quotient by the groebner base of the ideal I 7294 option("redSB"); 7295 option("returnSB"); 7296 ideal I = fetch(R, I); 7297 attrib(I, "isSB", 1); 7298 ideal IMin = fetch(R, IMin); 7299 dbprint(dbg, "Computing the jacobian ideal..."); 7300 ideal J = minor(jacob(IMin), nvars(basering) - d, I); 7301 t=timer; 7302 J = modStd(J); 7303 if (printTimings==1) {"Time for modStd Jacobian "+string(timer-t);} 7304 7305 setring R; 7306 ideal J = fetch(Q, J); 7307 7308 //------------------ We check if the singular locus is empty ------------- 7309 if(J[1] == 1) 7310 { 7311 // The original ring R/I was normal. Nothing to do. 7312 return(ideal(1)); 7313 } 7314 7315 //--- Universal denominator--- 7316 poly condu = getSmallest(J); // Choses the polynomial of smallest degree 7317 // of J as universal denominator. 7318 if (printTimings==1) {"conductor: ", condu;} 7319 7320 //-------------- Main standard basis computations in positive ---------------- 7321 //---------------------- characteristic start here --------------------------- 7322 list resultNormal,currentPrimes; 7323 list resultNormalX,currentPrimesX; 7324 list LL; 7325 7326 ideal ChremLift; 7327 ideal Out; 7328 list OutCondu; 7329 7330 int ptn; 7331 int k = 1; 7332 int sh; 7333 int p; 7334 int h; 7335 7336 intvec L; 7337 bigint N; 7338 7339 int totalModularTime; 7340 int maxModularTime; 7341 int sumMaxModularTime; 7342 int sumTotalModularTime; 7343 7344 ideal normalIP; 7345 7346 I = groebner(I); 7347 // Largest prime: 2147483647 7348 // Max prime for gcd: 536870909 7349 7350 // loop increasing the number of primes by n2 until pTest is true 7351 list modarguments; 7352 list modresults; 7353 int lastPrime; 7354 while (ptn==0) 7355 { 7356 L = primeList(I,k*n2+1,intvec(536870627),1); 7357 maxModularTime=0; 7358 totalModularTime = timer; 7359 if (k==1) {sh=0;} else {sh=1;} 7360 if (ncores == 1) 7361 { 7362 for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++) 7363 { 7364 t = timer; 7365 normalIP = modpNormal(I, L[j], condu,printTimings,#)[1]; 7366 if(timer - t > maxModularTime) { maxModularTime = timer - t; } 7367 LTimer[j] = timer - t; 7368 setring R; 7369 resultNormalX[j] = normalIP; 7370 currentPrimesX[j] = bigint(L[j]); 7371 } 7372 lastPrime = L[k*n2+1]; 7373 } 7374 else 7375 { 7376 for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++) 7377 { 7378 modarguments[j-(k-1)*n2-sh] = list(I, L[j], condu, printTimings, #); 7379 } 7380 modresults = parallelWaitAll("modpNormal", modarguments, 0, ncores); 7381 for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++) 7382 { 7383 resultNormalX[j] = modresults[j-(k-1)*n2-sh][1]; 7384 currentPrimesX[j] = bigint(modresults[j-(k-1)*n2-sh][2]); 7385 LTimer[j] = modresults[j-(k-1)*n2-sh][3]; 7386 if(LTimer[j] > maxModularTime) { maxModularTime = LTimer[j]; } 7387 } 7388 normalIP = resultNormalX[k*n2+1]; 7389 lastPrime = modresults[n2-sh+1][2]; 7390 } 7391 7392 if (printTimings==1) {"List of times for all modular computations so far: "+string(LTimer);} 7393 if (printTimings==1) {"Maximal modular time of current step: "+string(maxModularTime);} 7394 sumMaxModularTime=sumMaxModularTime+maxModularTime; 7395 totalModularTime = timer - totalModularTime; 7396 sumTotalModularTime=sumTotalModularTime+totalModularTime; 7397 if (printTimings==1) {"Total modular time of current step: "+string(totalModularTime);} 7398 resultNormal=delete(resultNormalX,size(resultNormalX)); 7399 currentPrimes=delete(currentPrimesX,size(currentPrimesX)); 7400 //------------------------ Delete unlucky primes ----------------------------- 7401 //------------- unlucky if and only if the leading ideal is wrong ------------ 7402 // Polynomials are not homogeneous: h = 0 7403 LL = deleteUnluckyPrimes(resultNormal,currentPrimes,h); 7404 resultNormal = LL[1]; 7405 currentPrimes = LL[2]; 7406 if (printTimings==1) {"Number of lucky primes: ", size(currentPrimes);} 7407 7408 //------------------- Now all leading ideals are the same -------------------- 7409 //------------------- Lift results to basering via farey --------------------- 7410 N = currentPrimes[1]; 7411 for(i = 2; i <= size(currentPrimes); i++) 7412 { 7413 N = N*currentPrimes[i]; 7414 } 7415 // Chinese remainder 7416 ChremLift = chinrem(resultNormal,currentPrimes); 7417 // Farey lifting 7418 Out = farey(ChremLift,N); 7419 7420 OutCondu=Out,condu; 7421 // pTest 7422 if (pTestNormal(I,OutCondu,lastPrime,normalIP)==0) 7423 { 7424 if (printTimings==1) {"pTestNormal has failed, increasing the number of primes by "+string(n2);} 7425 k=k+1; 7426 } else 7427 { 7428 ptn=1; 7429 } 7430 } 7431 if (printTimings==1) 7432 { 7433 "Time for all modular computations: "+string(sumTotalModularTime); 7434 "Parallel time for all modular computations: "+string(sumMaxModularTime); 7435 "Time for randomized normal: "+string(timer - totalTime); 7436 "Simulated parallel time for randomized normal: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime); 7437 } 7438 // return the result if no verification 7439 if (noVerif==1) { 7440 Out[size(Out) + 1] = Out[1]; 7441 Out = Out[2..size(Out)]; 7442 OutCondu=modStd(Out),condu; 7443 return(OutCondu); 7444 }; 7445 7446 //------------------- Optional tests to ensure correctness -------------------- 7447 // Check for finiteness. We do this by checking if the reconstruction of 7448 // the ring structure is still valid 7449 7450 t = timer; 7451 int tVerif=timer; 7452 if (printTimings==1) {"Verification:";} 7453 setring R; 7454 7455 int isNormal = normalCheck(Out, I,printTimings); 7456 7457 7458 if(isNormal == 0) 7459 { 7460 ERROR("Not normal!"); 7461 } else { 7462 if (printTimings==1) {"Normal!";} 7463 } 7464 7465 7466 if (printTimings==1) 7467 { 7468 "Time for verifying normal: "+string(timer - t); 7469 "Time for all verification tests: "+string(timer - tVerif); 7470 "Simulated parallel time including verfications: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime); 7471 "Total time: "+string(timer - totalTime); 7472 } 7473 // We put the denominator at the end 7474 // however we return condu anyway 7475 Out[size(Out) + 1] = Out[1]; 7476 Out = Out[2..size(Out)]; 7477 OutCondu=modStd(Out),condu; 7478 return(OutCondu); 7479 } 7480 7481 example 7482 { "EXAMPLE:"; 7483 ring R = 0,(x,y,z),dp; 7484 int k = 4; 7485 poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1)); 7486 f = subst(f,z,3x-2y+1); 7487 ring S = 0,(x,y),dp; 7488 poly f = imap(R,f); 7489 ideal i = f; 7490 list L = modNormal(i,1,"noVerification"); 7491 } 7492 7493 7494 // Computes the Jacobian ideal 7495 // I is assumed to be a groebner base 7496 static proc jacobIdOne(ideal I,int printTimings) 7497 { 7498 def R = basering; 7499 7500 int d = dim(I); 7501 7502 if (printTimings==1) {"Computing the ideal of minors...";} 7503 ideal J = minor(jacob(I), nvars(basering) - d, I); 7504 if (printTimings==1) {"Computing the modstd of the ideal of minors...";} 7505 J = modStd(J); 7506 if (printTimings==1) 7507 { 7508 "Groebner base computed."; 7509 "ideal of minors: "; J; 7510 } 7511 return(J); 7512 } 7513 7514 // Procedure for comparing timings and outputs between the modular approach 7515 // and the classical approach. Remove static to be used. 7516 static proc norComp(ideal I, int nPrimes) 7517 { 7518 // nPrimes is the number of primes to use. 7519 7520 int t = timer; 7521 list Out2 = modNormal(I, nPrimes,"noVerification"); 7522 "Time modNormal: ", timer - t; 7523 t = timer; 7524 ideal Out1 = normal(I)[2][1]; 7525 "Time normal: ", timer - t; 7526 "Same output?"; 7527 outComp(Out1, Out2[1], Out1[size(Out1)], Out2[2], I); 7528 } 7529 7530 static proc outComp(ideal Out1, ideal Out2, poly den1, poly den2, ideal I) 7531 { 7532 I = groebner(I); 7533 Out1 = changeDenominator(Out1, den1, den1, I); 7534 Out2 = changeDenominator(Out2, den2, den1, I); 7535 Out1 = groebner(I+Out1); 7536 Out2 = groebner(I+Out2); 7537 return((size(reduce(Out1, Out2, 5)) == 0) * (size(reduce(Out2, Out1, 5)) == 0)); 7538 } 7539 7540 7541 // Make p homogeneous of degree d taking h as the aux variable of deg 1. 7542 static proc polyHomogenize(poly p, int d, intvec degs, poly h) 7543 { 7544 int i; 7545 poly q; 7546 for(i = 1; i <= size(p); i++) 7547 { 7548 q = q + p[i]*h^(d-deg(p[i], degs)); 7549 } 7550 return(q); 7551 } 7552 7553 7554 // verification procedure 7555 static proc normalCheck(ideal U, ideal I,int printTimings) 7556 // U / U[1] = output of the normalization 7557 { 7558 if (printTimings==1) {"normalCheck: computes the new ring structure and checks if the ring is normal";} 7559 7560 def R = basering; 7561 poly D = U[1]; // universal denominator 7562 7563 if (printTimings==1) {"Computing the new ring structure";} 7564 list ele = Normal::computeRing(U, I, "noRed"); 7565 7566 def origEre = ele[1]; 7567 setring origEre; 7568 if (printTimings==1) {"Number of variables: ", nvars(basering);} 7569 7570 if (printTimings==1) {"Computing the groebner base of the relations...";} 7571 norid = modStd(norid); 7572 7573 if (printTimings==1) {"Computing the jacobian ideal...";} 7574 ideal J = jacobIdOne(norid,printTimings); 7575 ideal JI = J + norid; 7576 if (printTimings==1) {"Computing the radical...";} 7577 ideal JR = radical(JI); 7578 poly testP = getSmallest(JR); // Choses the polynomial of smallest degree 7579 7580 qring Q = norid; 7581 ideal J = fetch(origEre, JR); 7582 poly D = fetch(origEre, testP); 7583 if (printTimings==1) {"Computing the quotient (DJ : J)...";} 7584 ideal oldU = 1; 7585 ideal U = quotient(D*J, J); 7586 U = groebner(U); 7587 7588 // ----------------- Grauer-Remmert criterion check ----------------------- 7589 // We check if the equality in Grauert - Remmert criterion is satisfied. 7590 int isNormal = Normal::checkInclusions(D*oldU, U); 7591 setring R; 7592 return(isNormal); 7593 } 7594 7595 7596 7597 7598 //////////////////////////////////////////////////////////////////////// 7599 // 7600 // locNormal procedures 7601 // 7602 //////////////////////////////////////////////////////////////////////// 7603 7604 // AUTHORS: J. Boehm boehm@mathematik.uni-kl.de 7605 // W. Decker decker@mathematik.uni-kl.de 7606 // S. Laplagne slaplagn@dm.uba.ar 7607 // G. Pfister pfister@mathematik.uni-kl.de 7608 // S. Steidel steidel@mathematik.uni-kl.de 7609 // A. Steenpass steenpass@mathematik.uni-kl.de 7610 // 7611 // OVERVIEW: 7612 // 7613 // Suppose A is an affine domain over a perfect field.@* 7614 // This library implements a local-to-global strategy for finding the normalization 7615 // of A. Following [1], the idea is to stratify the singular locus of A, apply the 7616 // normalization algorithm given in [2] locally at each stratum, and put the local 7617 // results together. This approach is inherently parallel.@* 7618 // Furthermore we allow for the optional modular computation of the local results 7619 // as provided by modnormal.lib. See again [1] for details. 7620 // 7621 // REFERENCES: 7622 // 7623 // [1] Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Stefan Steidel, 7624 // Andreas Steenpass: Parallel algorithms for normalization, http://arxiv.org/abs/1110.4299, 2011. 7625 // 7626 // [2] Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings, 7627 // Journal of Symbolic Computation 9 (2010), p. 887-901 7628 // 7629 // KEYWORDS: 7630 // normalization; modular methods 7631 7632 7633 proc locNormal(ideal I, list #) 7634 "USAGE: locNormal(I [,options]); I = prime ideal, options = list of options. @* 7635 Optional parameters in list options (can be entered in any order):@* 7636 modular: use a modular approach for the local computations. The number of primes is 7637 increased one at a time, starting with 2 primes, until the result stabelizes.@* 7638 noVerificication: if the modular approach is used, the result will not be verified. 7639 ASSUME: I is a prime ideal (the algorithm will also work for radical ideals as long as the 7640 normal command does not detect that the ideal under consideration is not prime). 7641 RETURN: a list of an ideal U and a universal denominator d such that U/d is the normalization. 7642 REMARKS: We use the local-to-global algorithm given in [1] to compute the normalization of 7643 A = R/I, where R is the basering.@* 7644 The idea is to stratify the singular locus of A, apply the normalization algorithm 7645 given in [2] locally at each stratum, and put the local results together.@* 7646 If the option modular is given, the result is returned as a probabilistic result 7647 or verified, depending on whether the option noVerificication is used or not.@* 7648 The normalization of A is represented as an R-module by returning a list of U and d, 7649 where U is an ideal of A and d is an element of A such that U/d is the normalization of A. 7650 In fact, U and d are returned as an ideal and a polynomial of the base ring R. 7651 7652 REFERENCES: 7653 [1] Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Stefan Steidel, 7654 Andreas Steenpass: Parallel algorithms for normalization, http://arxiv.org/abs/1110.4299, 2011.@* 7655 [2] Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings, 7656 Journal of Symbolic Computation 9 (2010), p. 887-901 7657 KEYWORDS: normalization; local methods; modular methods. 7658 SEE ALSO: normal_lib, modnormal_lib. 7659 EXAMPLE: example locNormal; shows an example 7660 " 7661 { 7662 // Computes the normalization by localizing at the different components of the singularity. 7663 int i; 7664 int totalLocalTime; 7665 int dbg = printlevel - voice + 2; 7666 def R = basering; 7667 7668 int totalTime = timer; 7669 intvec LTimer; 7670 int t; 7671 int printTimings=0; 7672 7673 int locmod; 7674 for ( i=1; i <= size(#); i++ ) 7675 { 7676 if ( typeof(#[i]) == "string" ) 7677 { 7678 if (#[i]=="modular") { locmod = 1;} 7679 if (#[i]=="printTimings") { printTimings = 1;} 7680 } 7681 } 7682 7683 // Computes the Singular Locus 7684 list IM = mstd(I); 7685 I = IM[1]; 7686 int d = dim(I); 7687 ideal IMin = IM[2]; 7688 qring Q = I; // We work in the quotient by the groebner base of the ideal I 7689 option("redSB"); 7690 option("returnSB"); 7691 ideal I = fetch(R, I); 7692 attrib(I, "isSB", 1); 7693 ideal IMin = fetch(R, IMin); 7694 dbprint(dbg, "Computing the jacobian ideal..."); 7695 ideal J = minor(jacob(IMin), nvars(basering) - d, I); 7696 t=timer; 7697 int ch = char(basering); 7698 if (ch==0) {J = modStd(J);} else {J = std(J);} 7699 if (printTimings==1) {"Time for modStd/std Jacobian "+string(timer-t);} 7700 7701 int dim_J=dim(J); 7702 setring R; 7703 ideal U; 7704 poly condu; 7705 ideal J = fetch(Q, J); 7706 7707 // Already normal 7708 if (dim_J < 0) 7709 { 7710 return(list(ideal(1), poly(1))); 7711 } 7712 7713 // We compute a universal denominator 7714 condu = getSmallest(J); 7715 J = J, I; 7716 if(dbg >= 2){ 7717 "Conductor: ", condu; 7718 "The original singular locus is"; 7719 groebner(J); 7720 if(dbg >= 2){pause();} 7721 ""; 7722 } 7723 t=timer; 7724 list pd = locIdeals(J); 7725 dbprint(dbg,pd); 7726 if (printTimings==1) { 7727 "Number of maximal components to localize at: ", size(pd); 7728 ""; 7729 } 7730 7731 ideal resT; 7732 ideal resu; 7733 poly denomOld; 7734 poly denom; 7735 totalLocalTime = timer; 7736 int maxLocalTime; 7737 list Lnor; 7738 list parallelArguments; 7739 for(i = 1; i <= size(pd); i++){ 7740 parallelArguments[i] = list(pd[i], I, condu, i, locmod, printTimings, #); 7741 } 7742 list parallelResults = parallelWaitAll("locNormal_parallelTask", 7743 parallelArguments); 7744 for(i = 1; i <= size(pd); i++){ 7745 // We sum the result to the previous results. 7746 resu = resu, parallelResults[i][1]; 7747 Lnor[i] = parallelResults[i][1]; 7748 if(parallelResults[i][2] > maxLocalTime) { 7749 maxLocalTime = parallelResults[i][2]; 7750 } 7751 LTimer[i] = parallelResults[i][2]; 7752 } 7753 if (printTimings==1) { 7754 "List of local times: "; LTimer; 7755 "Maximal local time: "+string(maxLocalTime); 7756 } 7757 totalLocalTime = timer - totalLocalTime; 7758 if (printTimings==1) { 7759 "Total time local computations: "+string(totalLocalTime); 7760 } 7761 7762 t=timer; 7763 if (ch==0) {resu = modStd(resu);} else {resu = std(resu);} 7764 if (printTimings==1) { 7765 "Time for combining the local results, modStd/std "+string(timer-t); 7766 } 7767 7768 totalTime = timer - totalTime; 7769 if (printTimings==1) { 7770 "Total time locNormal: "+string(totalTime); 7771 "Simulated parallel time: "+string(totalTime + maxLocalTime - totalLocalTime); 7772 } 7773 return(list(resu, condu)); 7774 } 7775 7776 example 7777 { "EXAMPLE:"; 7778 ring R = 0,(x,y,z),dp; 7779 int k = 4; 7780 poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1)); 7781 f = subst(f,z,3x-2y+1); 7782 ring S = 0,(x,y),dp; 7783 poly f = imap(R,f); 7784 ideal i = f; 7785 list L = locNormal(i); 7786 } 7787 7788 proc locNormal_parallelTask(ideal pdi, ideal I, poly condu, int i, int locmod, 7789 int printTimings, list #) 7790 { 7791 pdi=pdi; 7792 int t = timer; 7793 list opt = list(list("inputJ", pdi)) + #; 7794 if (printTimings==1) { 7795 "Local component ",i," of degree "+string(deg(pdi))+" and dimension " 7796 +string(dim(pdi)); 7797 } 7798 list n; 7799 ideal norT; 7800 poly denomT; 7801 if (locmod==1) { 7802 n = modNormal(I,1, opt); 7803 norT = n[1]; 7804 denomT = n[2]; 7805 } else { 7806 n = normal(I,opt); 7807 if(size(n[2]) > 1){ 7808 ERROR("Input was not prime..."); 7809 } 7810 norT = n[2][1]; 7811 denomT = norT[size(norT)]; 7812 } 7813 t = timer-t; 7814 // We compute the normalization of I localized at a component of the Singular 7815 // Locus 7816 if (printTimings==1) { 7817 "Output of normalization of component ", i, ": "; norT; 7818 ""; 7819 } 7820 ideal nor = normal::changeDenominator(norT, denomT, condu, I); 7821 return(list(nor, t)); 7822 } 7823 7824 static proc locComps(list l) 7825 { 7826 int d = size(l); 7827 int i; 7828 int j; 7829 intvec m = 1:d; // 1 = maximal ideal 7830 ideal IT; 7831 7832 // Check for maximal ideals 7833 for(i = 1; i<d; i++) 7834 { 7835 for(j = i+1; j <= d; j++) 7836 { 7837 if(idealInclusion(l[i], l[j])) 7838 { 7839 m[i] = 0; 7840 break; 7841 } 7842 } 7843 } 7844 list outL; 7845 for(i = 1; i<= d; i++) { 7846 if(m[i] == 1) { 7847 // Maximal ideal 7848 IT = l[i]; 7849 for(j = 1; j <= d; j++) { 7850 if(j != i) { 7851 if(idealInclusion(l[j], l[i])) { 7852 IT = intersect(IT, l[j]); 7853 } 7854 } 7855 } 7856 outL = insert(outL, IT); 7857 } 7858 } 7859 return(outL); 7860 } 7861 7862 // I C J ?? 7863 static proc idealInclusion(ideal I, ideal J) 7864 { 7865 J = groebner(J); 7866 return(size(reduce(I, J, 5)) == 0); 7867 } 7868 7869 // Computes the different localizations of the radical of I at all the points of the space. 7870 static proc locIdeals(ideal I){ 7871 int i, j; 7872 I = groebner(I); 7873 7874 // Minimal associated primes of I 7875 list l = minAssGTZ(I); 7876 //"Total number of components of the Singular Locus: ", size(l); 7877 7878 int s = size(l); 7879 int d = dim(I); 7880 if (d==0) {return(l)}; 7881 intvec m = (1:d); 7882 // 1 = maximal ideal 7883 ideal IT; 7884 7885 // inters will contain all the different intersections of components of I. 7886 // It is a list of lists. The j-th list contains the intersections of j components of I. 7887 list inters; 7888 list compIndex; // Indicate the index of the last component in the corresponding intersection 7889 // This is used to intersect it with the remaining components. 7890 for(i = 1; i<= d; i++) 7891 { 7892 l[i] = groebner(l[i]); 7893 } 7894 7895 // We add all the components to the list of intersections 7896 inters[1] = l; 7897 compIndex[1] = 1..s; 7898 7899 ideal J; 7900 int e; 7901 int a; 7902 7903 // Intersections of two or more components 7904 for(e = 1; e <= d; e++) 7905 { 7906 inters[e+1] = list(); 7907 a = 1; 7908 for(i = 1; j <= size(inters[e]); i++) 7909 { 7910 for(j = compIndex[e][i] + 1; j <= s; j++) 7911 { 7912 J = l[j] + inters[e][i]; 7913 J = groebner(J); 7914 if(J[1] != 1) 7915 { 7916 inters[e+1] = inters[e+1]+list(J); 7917 if(a == 1) 7918 { 7919 compIndex[e+1] = intvec(j); 7920 } else 7921 { 7922 compIndex[e+1][a] = j; 7923 } 7924 a++; 7925 } 7926 } 7927 } 7928 } 7929 7930 list ids; 7931 for(e = 1; e <= d+1; e++) 7932 { 7933 ids = ids + inters[e]; 7934 } 7935 return(locComps(ids)); 7936 } 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7006 7949 7007 7950 /////////////////////////////////////////////////////////////////////////// -
Singular/LIB/primdec.lib
r8e0ad0 r7c871e 4021 4021 option(redSB); 4022 4022 ASSUME(1, dim(I)==0); 4023 ideal F=finduni(I); //F[i] generates I intersected with K[var(i)]4023 ideal F=finduni(I); //F[i] generates I intersected with K[var(i)] 4024 4024 4025 4025 option(set,op); … … 6391 6391 for(j=nvars(P0);j>0;j--) {dp_w[j]=1;} 6392 6392 Pl[3]=list(list("dp",dp_w),list("C",0)); 6393 def @P=ring(Pl); 6393 def @P=ring(Pl); // Ring with same variables and DP ordering in all variables 6394 6394 setring @P; 6395 6395 ideal i=imap(P0,i); … … 6469 6469 intvec op = option(get); 6470 6470 list qr = simplifyIdeal(i); 6471 map phi = @P, qr[2]; 6472 6471 map phi = @P, qr[2]; // map from the same ring, to simplify the ideal 6472 6473 6473 6474 option(redSB); 6474 i = groebner(qr[1]); 6475 i = groebner(qr[1]); // We use the transformed variables, and we 6476 // will use map phi to go back to the original 6477 // variables 6475 6478 option(set, op); 6476 6479 int di = dim(i); … … 6545 6548 } 6546 6549 } 6547 rad=interred(phi(rad)); 6550 6551 rad=interred(phi(rad)); // Eliminate redundant polynomials 6548 6552 setring(P0); 6549 6553 i=imap(@P,rad);
Note: See TracChangeset
for help on using the changeset viewer.