Changeset 7c871e in git


Ignore:
Timestamp:
Sep 6, 2023, 12:34:53 PM (9 months ago)
Author:
slap <slaplagne@…>
Branches:
(u'spielwiese', 'c7af8613769b29c741d6c338945669719f1fc4f8')
Children:
52f69966ea5a90890641163cbd32e35badcc23f8
Parents:
8e0ad00ce244dfd0756200662572aef8402f13d5
Message:
Libraries merged

We merge libraries normal, modnormal and locnormal.
Location:
Singular/LIB
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • Singular/LIB/locnormal.lib

    r8e0ad0 r7c871e  
    264264    "";
    265265  }
    266   ideal nor = changeDenom(norT, denomT, condu, I);
     266  ideal nor = normal::changeDenominator(norT, denomT, condu, I);
    267267  return(list(nor, t));
    268268}
  • Singular/LIB/normal.lib

    r8e0ad0 r7c871e  
    44info="
    55LIBRARY:  normal.lib     Normalization of Affine Rings
    6 AUTHORS:  G.-M. Greuel,  greuel@mathematik.uni-kl.de,
     6AUTHORS:  J. Boehm       boehm@mathematik.uni-kl.de,
     7@*        W. Decker      decker@mathematik.uni-kl.de,
     8@*        G.-M. Greuel,  greuel@mathematik.uni-kl.de,
    79@*        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)
    1114
    1215PROCEDURES:
    1316 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
    1419 normalP(I,[...]);   normalization of an affine ring in positive characteristic
    1520 normalC(I,[...]);   normalization of an affine ring through a chain of rings
     
    2833 isNormal(ideal)     test if already normal
    2934
    30 SEE ALSO: locnormal_lib;modnormal_lib
     35SEE ALSO: integralbasis_lib
    3136";
    3237
     
    8893         - \"var2\" -> uses a polynomial in the second variable as universal
    8994         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.@*
    9099         If the optional parameter choose is not given or empty, only
    91100         \"equidim\" but no other option is used.@*
     
    220229      {useRing = 1;}
    221230
     231      list options;
     232      if (#[i]=="GBRadical")
     233      {options = insert(options, "GBRadical");}
     234      if (#[i]=="noGBRadical")
     235      {options = insert(options, "noGBRadical");}
     236
    222237      if ( (#[i]=="withDelta") or (#[i]=="wd") or (#[i]=="withdelta"))
    223238      {
     
    389404    for(i=1; i<=size(prim); i++)
    390405    {
    391       out = normalM(prim[i], decomp, withDelta, denomOption, inputJ, inputC, normalCheck);
     406      out = normalM(prim[i], decomp, withDelta, denomOption, inputJ, inputC, normalCheck, options);
    392407      if(out == 0)
    393408      {
     
    414429      }
    415430      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);
    417432      printlevel = printlevel - 1;
    418433      for(j = 1; j <= size(norComp); j++)
     
    44024417// a different test ideal.
    44034418
    4404 static proc normalM(ideal I, int decomp, int withDelta, int denomOption, ideal inputJ, ideal inputC, int normalCheck){
     4419static proc normalM(ideal I, int decomp, int withDelta, int denomOption, ideal inputJ, ideal inputC, int normalCheck, list options){
    44054420// Computes the normalization of a ring R / I using the module structure as far
    44064421// as possible.
     
    45984613        if(normalCheck == 1)
    45994614        {
    4600           int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck);
     4615          int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options);
    46014616          if(check1)
    46024617          {
    4603             int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck);
     4618            int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options);
    46044619            printlevel = printlevel - 1;
    46054620            option(set,save_opt);
     
    46134628        } else
    46144629        {
    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);
    46174632          printlevel = printlevel - 1;
    46184633          option(set,save_opt);
     
    47414756      if(normalCheck == 1)
    47424757      {
    4743         int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck);
     4758        int check1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options);
    47444759        if(check1)
    47454760        {
    4746           int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck);
     4761          int check2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault, normalCheck, options);
    47474762          printlevel = printlevel - 1;
    47484763          return(check2);
     
    47544769      } else
    47554770      {
    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);
    47584773        printlevel = printlevel - 1;
    47594774        option(set,save_opt);
     
    47734788  printlevel = printlevel + 1;
    47744789
    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);
    47784793    printlevel = printlevel - 1;
    47794794    option(set,save_opt);
     
    47814796  } else
    47824797  {
    4783     list result = normalMEqui(I, J, condu, D, withDelta, normalCheck);
     4798    list result = normalMEqui(I, J, condu, D, withDelta, normalCheck, options);
    47844799    printlevel = printlevel - 1;
    47854800    option(set,save_opt);
     
    47924807///////////////////////////////////////////////////////////////////////////////
    47934808
    4794 static proc normalMEqui(ideal I, ideal origJ, poly condu, poly D, int withDelta, int normalCheck)
     4809static proc normalMEqui(ideal I, ideal origJ, poly condu, poly D, int withDelta, int normalCheck, list options)
    47954810// Here is where the normalization is actually computed.
    47964811
     
    48024817// If withDelta = 1, computes the delta invariant.
    48034818// 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
    48044822{
    48054823  ASSUME(1, not isQuotientRing(basering) );
     
    49124930       U[i]=lead(U[i])+reduce(U[i]-lead(U[i]),UU);
    49134931    }
    4914     testOut = testIdeal(I, U, origJ, c, D);
     4932    testOut = testIdeal(I, U, origJ, c, D, options);
    49154933    cJ = testOut[1];
    49164934
     
    51795197///////////////////////////////////////////////////////////////////////////////
    51805198
    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
     5200proc in_array(list l, string s)
    51825201{
     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
     5211static proc testIdeal(ideal I, ideal U, ideal origJ, poly c, poly D, list options)
     5212{
    51835213
    51845214  ASSUME(1, not isQuotientRing(basering) );
     5215 
     5216 
    51855217
    51865218// Internal procedure, used in normalM.
     
    52105242  // ---------------- setting the ring to work in  --------------------------
    52115243  int isGlobal = attrib(origEre,"global");      // Checks if the original ring has
    5212                                          // global ordering.
     5244                                                // global ordering.
    52135245  if(isGlobal != 1)
    52145246  {
     
    52405272  J = radical(J);
    52415273  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 
    52445284  if(dbg > 1)
    52455285  {
     
    53135353
    53145354  // ---------------------- step 4 of the mapping ---------------------------
     5355  t = timer;
    53155356  qring Q = groebner(I);
     5357  "DEBUG - time for qring GB computation:", timer - t;
     5358
    53165359  ideal J = imap(R, J);
    53175360  poly c = imap(R, c);
     5361 
     5362  t = timer;
    53185363  for(i = 1; i<=ncols(J); i++)
    53195364  {
     
    53275372    }
    53285373  }
     5374  "DEBUG - time for liftings:", timer - t;
     5375
    53295376
    53305377  if(dbg > 1)
     
    53365383
    53375384  // --------------------------- prepare output ----------------------------
     5385  // Groebner basis in the ring with only the original variables
     5386 
     5387  "time up to here: ", timer - t;
     5388  t = timer;
    53385389  J = groebner(J);
     5390  "DEBUG - time for final GB computation:", timer - t;
    53395391
    53405392  setring R;
     
    67226774
    67236775///////////////////////////////////////////////////////////////////////////
     6776
     6777// Computes the groebner basis using dp ordering
     6778static 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///////////////////////////////////////////////////////////////////////////
    67246795proc norTest (ideal i, list nor, list #)
    67256796"USAGE:   norTest(i,nor,[n]); i=prime ideal, nor=list, n=optional integer
     
    70047075normalConductor(I);
    70057076}
     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
     7117static 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
     7151static 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.
     7234proc 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).
     7240ASSUME:  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).
     7242RETURN:  a list of an ideal U and a universal denominator d such that U/d is the normalization.
     7243REMARKS: 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.
     7251KEYWORDS: normalization; modular techniques.
     7252SEE ALSO: normal_lib, locnormal_lib.
     7253EXAMPLE: 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
     7481example
     7482{ "EXAMPLE:";
     7483ring R = 0,(x,y,z),dp;
     7484int k = 4;
     7485poly 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));
     7486f = subst(f,z,3x-2y+1);
     7487ring S = 0,(x,y),dp;
     7488poly f = imap(R,f);
     7489ideal i = f;
     7490list L = modNormal(i,1,"noVerification");
     7491}
     7492
     7493
     7494// Computes the Jacobian ideal
     7495// I is assumed to be a groebner base
     7496static 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.
     7516static 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
     7530static 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.
     7542static 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
     7555static 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
     7633proc 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.
     7639ASSUME:  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).
     7641RETURN:  a list of an ideal U and a universal denominator d such that U/d is the normalization.
     7642REMARKS: 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
     7652REFERENCES:
     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
     7657KEYWORDS: normalization; local methods; modular methods.
     7658SEE ALSO: normal_lib, modnormal_lib.
     7659EXAMPLE: 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
     7776example
     7777{ "EXAMPLE:";
     7778ring R = 0,(x,y,z),dp;
     7779int k = 4;
     7780poly 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));
     7781f = subst(f,z,3x-2y+1);
     7782ring S = 0,(x,y),dp;
     7783poly f = imap(R,f);
     7784ideal i = f;
     7785list L = locNormal(i);
     7786}
     7787
     7788proc 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
     7824static 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 ??
     7863static 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.
     7870static 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
    70067949
    70077950///////////////////////////////////////////////////////////////////////////
  • Singular/LIB/primdec.lib

    r8e0ad0 r7c871e  
    40214021   option(redSB);
    40224022   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)]
    40244024
    40254025   option(set,op);
     
    63916391  for(j=nvars(P0);j>0;j--) {dp_w[j]=1;}
    63926392  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
    63946394  setring @P;
    63956395  ideal i=imap(P0,i);
     
    64696469  intvec op = option(get);
    64706470  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 
    64736474  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
    64756478  option(set, op);
    64766479  int di = dim(i);
     
    65456548    }
    65466549  }
    6547   rad=interred(phi(rad));
     6550   
     6551  rad=interred(phi(rad));  // Eliminate redundant polynomials
    65486552  setring(P0);
    65496553  i=imap(@P,rad);
Note: See TracChangeset for help on using the changeset viewer.