source: git/Singular/dyn_modules/gfanlib/ppinitialReduction.cc @ 78abc7

spielwiese
Last change on this file since 78abc7 was 78abc7, checked in by Yue Ren <ren@…>, 9 years ago
chg: status update 18.08.
  • Property mode set to 100644
File size: 15.5 KB
Line 
1#include <kernel/polys.h>
2#include <Singular/ipid.h>
3
4#include <libpolys/polys/monomials/p_polys.h>
5#include <singularWishlist.h>
6#include <tropicalStrategy.h>
7
8#include <map>
9#include <set>
10
11/***
12 * changes a polynomial g with the help p-t such that
13 * 1) each term of g has a distinct monomial in x
14 * 2) no term of g has a coefficient divisible by p
15 * in particular, this means that all g_\alpha can be obtained
16 * by reading the coefficients and that g is initially reduced
17 * with respect to p-t
18 **/
19static bool pReduce(poly &g, const number p, const ring r)
20{
21  if (g==NULL)
22    return false;
23
24  poly toBeChecked = pNext(g);
25  pNext(g) = NULL; poly gEnd = g;
26  poly gCache;
27
28  number coeff, pPower; int power; poly subst;
29  while(toBeChecked)
30  {
31    for (gCache = g; gCache; pIter(gCache))
32      if (p_LeadmonomDivisibleBy(gCache,toBeChecked,r)) break;
33    if (gCache)
34    {
35      n_Power(p,p_GetExp(toBeChecked,1,r)-p_GetExp(gCache,1,r),&pPower,r->cf);
36      coeff = n_Mult(p_GetCoeff(toBeChecked,r),pPower,r->cf);
37      p_SetCoeff(gCache,n_Add(p_GetCoeff(gCache,r),coeff,r->cf),r);
38      n_Delete(&pPower,r->cf); n_Delete(&coeff,r->cf);
39      toBeChecked=p_LmDeleteAndNext(toBeChecked,r);
40    }
41    else
42    {
43      if (n_DivBy(p_GetCoeff(toBeChecked,r),p,r->cf))
44      {
45        coeff=n_Div(p_GetCoeff(toBeChecked,r),p,r->cf);
46        power=1;
47        while (n_DivBy(coeff,p,r->cf))
48        {
49          coeff=n_Div(p_GetCoeff(pNext(g),r),p,r->cf);
50          power++;
51          if (power<1)
52          {
53            WerrorS("pReduce: overflow in exponent");
54            return true;
55          }
56        }
57        subst=p_LmInit(toBeChecked,r);
58        p_AddExp(subst,1,power,r);
59        p_SetCoeff(subst,coeff,r);
60        p_Setm(subst,r); p_Test(subst,r);
61        toBeChecked=p_LmDeleteAndNext(toBeChecked,r);
62        toBeChecked=p_Add_q(toBeChecked,subst,r);
63        p_Test(toBeChecked,r);
64      }
65      else
66      {
67        pNext(gEnd)=toBeChecked;
68        pIter(gEnd); pIter(toBeChecked);
69        pNext(gEnd)=NULL;
70      }
71    }
72  }
73  p_Test(g,r);
74  return false;
75}
76
77
78#ifndef NDEBUG
79BOOLEAN pppReduce(leftv res, leftv args)
80{
81  leftv u = args;
82  if ((u != NULL) && (u->Typ() == POLY_CMD))
83  {
84    poly g; number p = n_Init(3,currRing->cf);
85    omUpdateInfo();
86    Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
87    g = (poly) u->CopyD();
88    (void) pReduce(g,p,currRing);
89    p_Delete(&g,currRing);
90    omUpdateInfo();
91    Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
92    g = (poly) u->CopyD();
93    (void) pReduce(g,p,currRing);
94    n_Delete(&p,currRing->cf);
95    res->rtyp = POLY_CMD;
96    res->data = (char*) g;
97    return FALSE;
98  }
99  return TRUE;
100}
101#endif //NDEBUG
102
103
104/***
105 * reduces h initially with respect to g,
106 * returns false if h was initially reduced in the first place,
107 * returns true if reductions have taken place.
108 * assumes that h and g are in pReduced form and homogeneous in x of the same degree
109 **/
110bool ppreduceInitially(poly &h, const poly g, const ring r)
111{
112  if (h==NULL || g==NULL)
113    return false;
114  p_Test(h,r);
115  p_Test(g,r);
116  poly hCache;
117  for (hCache=h; hCache; pIter(hCache))
118    if (p_LeadmonomDivisibleBy(g,hCache,r)) break;
119  if (hCache)
120  {
121    number gAlpha = p_GetCoeff(g,r);
122    poly hAlphaT = p_Init(r);
123    p_SetCoeff(hAlphaT,n_Copy(p_GetCoeff(hCache,r),r->cf),r);
124    p_SetExp(hAlphaT,1,p_GetExp(hCache,1,r)-p_GetExp(g,1,r),r);
125    for (int i=2; i<=r->N; i++)
126      p_SetExp(hAlphaT,i,0,r);
127    p_Setm(hAlphaT,r); p_Test(hAlphaT,r);
128    poly q1 = p_Mult_nn(h,gAlpha,r); p_Test(q1,r);
129    poly q2 = p_Mult_q(p_Copy(g,r),hAlphaT,r); p_Test(q2,r);
130    q2 = p_Neg(q2,r); p_Test(q2,r);
131    h = p_Add_q(q1,q2,r);
132    p_Test(h,r);
133    return true;
134  }
135  return false;
136}
137
138
139#ifndef NDEBUG
140BOOLEAN ppreduceInitially0(leftv res, leftv args)
141{
142  leftv u = args;
143  if ((u != NULL) && (u->Typ() == POLY_CMD))
144  {
145    leftv v = u->next;
146    if ((v != NULL) && (v->Typ() == POLY_CMD))
147    {
148      poly g,h;
149      omUpdateInfo();
150      Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
151      h = (poly) u->CopyD();
152      g = (poly) v->CopyD();
153      (void)ppreduceInitially(h,g,currRing);
154      p_Delete(&h,currRing);
155      p_Delete(&g,currRing);
156      omUpdateInfo();
157      Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
158      h = (poly) u->CopyD();
159      g = (poly) v->CopyD();
160      (void)ppreduceInitially(h,g,currRing);
161      p_Delete(&g,currRing);
162      res->rtyp = POLY_CMD;
163      res->data = (char*) h;
164      return FALSE;
165    }
166  }
167  return TRUE;
168}
169#endif //NDEBUG
170
171
172/***
173 * reduces I initially with respect to itself and with respect to p-t.
174 * also sorts the generators of I with respect to the leading monomials in descending order.
175 * assumes that I is generated by elements which are homogeneous in x of the same degree.
176 **/
177bool ppreduceInitially(ideal I, const number p, const ring r)
178{
179  int m=idSize(I),n=m; poly cache;
180  do
181  {
182    int j=0;
183    for (int i=1; i<n; i++)
184    {
185      if (p_LmCmp(I->m[i-1],I->m[i],r)<0)
186      {
187        cache=I->m[i-1];
188        I->m[i-1]=I->m[i];
189        I->m[i]=cache;
190        j = i;
191      }
192    }
193    n=j;
194  } while(n);
195  for (int i=1; i<m; i++)
196    if (pReduce(I->m[i],p,r)) return true;
197
198  /***
199   * the first pass. removing terms with the same monomials in x as lt(g_i) out of g_j for i<j
200   **/
201  for (int i=0; i<m-1; i++)
202    for (int j=i+1; j<m; j++)
203      if (ppreduceInitially(I->m[j], I->m[i], r) && pReduce(I->m[j],p,r)) return true;
204
205  /***
206   * the second pass. removing terms divisible by lt(g_j) out of g_i for i<j
207   **/
208  for (int i=0; i<m-1; i++)
209    for (int j=i+1; j<m; j++)
210      if (ppreduceInitially(I->m[i], I->m[j],r) && pReduce(I->m[i],p,r)) return true;
211
212  /***
213   * removes the elements of I which have been reduced to 0 in the previous two passes
214   **/
215  idSkipZeroes(I);
216  return false;
217}
218
219
220#ifndef NDEBUG
221BOOLEAN ppreduceInitially1(leftv res, leftv args)
222{
223  leftv u = args;
224  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
225  {
226    leftv v = u->next;
227    if ((v != NULL) && (v->Typ() == NUMBER_CMD))
228    {
229      ideal I; number p;
230      omUpdateInfo();
231      Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
232      I = (ideal) u->CopyD();
233      p = (number) v->CopyD();
234      (void) ppreduceInitially(I,p,currRing);
235      id_Delete(&I,currRing);
236      n_Delete(&p,currRing->cf);
237      omUpdateInfo();
238      Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
239      I = (ideal) u->CopyD();
240      p = (number) v->CopyD();
241      (void) ppreduceInitially(I,p,currRing);
242      n_Delete(&p,currRing->cf);
243      res->rtyp = IDEAL_CMD;
244      res->data = (char*) I;
245      return FALSE;
246    }
247  }
248  return TRUE;
249}
250#endif //NDEBUG
251
252
253/***
254 * inserts g into I and reduces I with respect to itself and p-t
255 * assumes that I was already sorted and initially reduced in the first place
256 **/
257bool ppreduceInitially(ideal I, const number p, const poly g, const ring r)
258{
259  int n=idSize(I);
260  idInsertPoly(I,g);
261  int j;
262  for (j=n; j>0; j--)
263  {
264    if (p_LmCmp(I->m[j], I->m[j-1],r)>0)
265    {
266      poly cache = I->m[j];
267      I->m[j] = I->m[j-1];
268      I->m[j-1] = cache;
269    }
270    else
271      break;
272  }
273
274  /***
275   * the first pass. removing terms with the same monomials in x as lt(g_i) out of g_j for i<j
276   * removing terms with the same monomials in x as lt(g_j) out of g_k for j<k
277   **/
278  for (int i=0; i<j; i++)
279    if (ppreduceInitially(I->m[j], I->m[i], r) && pReduce(I->m[j],p,r)) return true;
280  for (int k=j+1; k<n; k++)
281    if (ppreduceInitially(I->m[k], I->m[j], r) && pReduce(I->m[k],p,r)) return true;
282
283  /***
284   * the second pass. removing terms divisible by lt(g_j) and lt(g_k) out of g_i for i<j<k
285   * removing terms divisible by lt(g_k) out of g_j for j<k
286   **/
287  for (int i=0; i<j; i++)
288    for (int k=j; k<n; k++)
289      if (ppreduceInitially(I->m[i], I->m[k], r) && pReduce(I->m[i],p,r)) return true;
290  for (int k=j+1; k<n; k++)
291    if (ppreduceInitially(I->m[j], I->m[k], r) && pReduce(I->m[j],p,r)) return true;
292
293  /***
294   * removes the elements of I which have been reduced to 0 in the previous two passes
295   **/
296  idSkipZeroes(I);
297  return false;
298}
299
300
301#ifndef NDEBUG
302BOOLEAN ppreduceInitially2(leftv res, leftv args)
303{
304  leftv u = args;
305  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
306  {
307    leftv v = u->next;
308    if ((v != NULL) && (v->Typ() == NUMBER_CMD))
309    {
310      leftv w = v->next;
311      if ((w != NULL) && (w->Typ() == POLY_CMD))
312      {
313        ideal I; number p; poly g;
314        omUpdateInfo();
315        Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
316        I = (ideal) u->CopyD();
317        p = (number) v->CopyD();
318        g = (poly) w->CopyD();
319        (void) ppreduceInitially(I,p,g,currRing);
320        id_Delete(&I,currRing);
321        n_Delete(&p,currRing->cf);
322        omUpdateInfo();
323        Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
324        I = (ideal) u->CopyD();
325        p = (number) v->CopyD();
326        g = (poly) w->CopyD();
327        (void) ppreduceInitially(I,p,g,currRing);
328        n_Delete(&p,currRing->cf);
329        res->rtyp = IDEAL_CMD;
330        res->data = (char*) I;
331        return FALSE;
332      }
333    }
334  }
335  return TRUE;
336}
337#endif //NDEBUG
338
339
340/***
341 * reduces H initially with respect to itself, with respect to p-t,
342 * and with respect to G.
343 * assumes that the generators of H are homogeneous in x of the same degree,
344 * assumes that the generators of G are homogeneous in x of lesser degree.
345 **/
346bool ppreduceInitially(ideal H, const number p, const ideal G, const ring r)
347{
348  /***
349   * Step 1: reduce H initially with respect to itself and with respect to p-t
350   **/
351  if (ppreduceInitially(H,p,r)) return true;
352
353  /***
354   * Step 2: initialize a working list T and an ideal I in which the reductions will take place
355   **/
356  int m=idSize(H),n=0;
357  ideal I = idInit(m), T = idInit(m);
358  for (int i=0; i<m; i++)
359  {
360    I->m[i]=H->m[i];
361    if (pNext(H->m[i])) T->m[n++]=H->m[i];
362  }
363  poly g; int k=n;
364  do
365  {
366    int j=0;
367    for (int i=1; i<k; i++)
368    {
369      if (p_LmCmp(pNext(T->m[i-1]),pNext(T->m[i]),r)<0)
370      {
371        g=T->m[i-1];
372        T->m[i-1]=I->m[i];
373        T->m[i]=g;
374        j = i;
375      }
376    }
377    k=j;
378  } while(k);
379
380  /***
381   * Step 3: as long as the working list is not empty, successively reduce terms in it
382   *   by adding suitable elements to I and reducing it initially with respect to itself
383   **/
384  k=idSize(G);
385  while (n)
386  {
387    int i=0; for (; i<k; i++)
388      if (p_LeadmonomDivisibleBy(G->m[i],pNext(T->m[0]),r)) break;
389    if (i<k)
390    {
391      g = p_Init(r);
392      for (int j=2; j<=r->N; j++)
393        p_SetExp(g,j,p_GetExp(pNext(T->m[0]),j,r)-p_GetExp(G->m[i],j,r),r);
394      p_SetCoeff(g,n_Init(1,r->cf),r); p_Setm(g,r);
395      g = p_Mult_q(g,p_Copy(G->m[i],r),r);
396      ppreduceInitially(I,p,g,r);
397    }
398    else
399      pIter(T->m[0]);
400    for (int i=0; i<n;)
401    {
402      if (!pNext(T->m[i]))
403      {
404        for (int j=i; j<n-1; j++)
405          T->m[j]=T->m[j+1];
406        T->m[--n]=NULL;
407      }
408      else
409        i++;
410    }
411    int l = n;
412    do
413    {
414      int j=0;
415      for (int i=1; i<l; i++)
416      {
417        if (p_LmCmp(pNext(T->m[i-1]),pNext(T->m[i]),r)<0)
418        {
419          g=T->m[i-1];
420          T->m[i-1]=I->m[i];
421          T->m[i]=g;
422          j = i;
423        }
424      }
425      l=j;
426    } while(l);
427  }
428
429  /***
430   * Step 4: cleanup, delete all polynomials in I which have been added in Step 3
431   **/
432  k=idSize(I);
433  for (int i=0; i<k; i++)
434  {
435    for (int j=0; j<m; j++)
436    {
437      if (p_LeadmonomDivisibleBy(H->m[j],I->m[i],r))
438      {
439        I->m[i]=NULL;
440        break;
441      }
442    }
443  }
444  id_Delete(&I,r);
445  id_Delete(&T,r);
446  return false;
447}
448
449
450#ifndef NDEBUG
451BOOLEAN ppreduceInitially3(leftv res, leftv args)
452{
453  leftv u = args;
454  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
455  {
456    leftv v = u->next;
457    if ((v != NULL) && (v->Typ() == NUMBER_CMD))
458    {
459      leftv w = v->next;
460      if ((w != NULL) && (w->Typ() == IDEAL_CMD))
461      {
462        ideal H,G; number p;
463        omUpdateInfo();
464        Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
465        H = (ideal) u->CopyD();
466        p = (number) v->CopyD();
467        G = (ideal) w->CopyD();
468        (void) ppreduceInitially(H,p,G,currRing);
469        id_Delete(&H,currRing);
470        id_Delete(&G,currRing);
471        n_Delete(&p,currRing->cf);
472        omUpdateInfo();
473        Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
474        H = (ideal) u->CopyD();
475        p = (number) v->CopyD();
476        G = (ideal) w->CopyD();
477        (void) ppreduceInitially(H,p,G,currRing);
478        n_Delete(&p,currRing->cf);
479        id_Delete(&G,currRing);
480        res->rtyp = IDEAL_CMD;
481        res->data = (char*) H;
482        return FALSE;
483      }
484    }
485  }
486  return TRUE;
487}
488#endif //NDEBUG
489
490
491/**
492 * reduces I initially with respect to itself.
493 * assumes that the generators of I are homogeneous in x and that p-t is in I.
494 */
495bool ppreduceInitially(ideal I, ring r, number p)
496{
497  assume(!n_IsUnit(p,r->cf));
498
499  /***
500   * Step 1: split up I into components of same degree in x
501   *  the lowest component should only contain p-t
502   **/
503  std::map<long,ideal> H; int n = idSize(I);
504  for (int i=0; i<n; i++)
505  {
506    long d = 0;
507    for (int j=2; j<=r->N; j++)
508      d += p_GetExp(I->m[i],j,r);
509    std::map<long,ideal>::iterator it = H.find(d);
510    if (it != H.end())
511      idInsertPoly(it->second,I->m[i]);
512    else
513    {
514      std::pair<long,ideal> Hd(d,idInit(1));
515      Hd.second->m[0] = I->m[i];
516      H.insert(Hd);
517    }
518  }
519
520  std::map<long,ideal>::iterator it=H.begin();
521  ideal Hi = it->second;
522  assume(idSize(Hi)==1);
523  assume(pLength(Hi->m[0])==2);
524  it++;
525  Hi = it->second;
526
527  /***
528   * Step 2: reduce each component initially with respect to itself
529   *  and all lower components
530   **/
531  if (ppreduceInitially(Hi,p,r)) return true;
532
533  ideal G = idInit(n); int m=0;
534  ideal GG = (ideal) omAllocBin(sip_sideal_bin);
535  GG->nrows = 1; GG->rank = 1; GG->m=NULL;
536
537  for (it++; it!=H.end(); it++)
538  {
539    int l=idSize(Hi); int k=l; poly cache;
540    /**
541     * sorts Hi according to degree in t in descending order
542     * (lowest first, highest last)
543     */
544    do
545    {
546      int j=0;
547      for (int i=1; i<k; i++)
548      {
549        if (p_GetExp(Hi->m[i-1],1,r)<p_GetExp(Hi->m[i],1,r))
550        {
551          cache=Hi->m[i-1];
552          Hi->m[i-1]=Hi->m[i];
553          Hi->m[i]=cache;
554          j = i;
555        }
556      }
557      k=j;
558    } while(k);
559    int kG=n-m, kH=0;
560    for (int i=n-m-l; i<n; i++)
561    {
562      if (kG==n)
563      {
564        memcpy(&(G->m[i]),&(Hi->m[kH]),(n-i)*sizeof(poly));
565        break;
566      }
567      if (p_GetExp(G->m[kG],1,r)>p_GetExp(Hi->m[kH],1,r))
568        G->m[i] = G->m[kG++];
569      else
570        G->m[i] = Hi->m[kH++];
571    }
572    m += l; IDELEMS(GG) = m; GG->m = &G->m[n-m];
573    if (ppreduceInitially(it->second,p,GG,r)) return true;
574    idShallowDelete(&Hi); Hi = it->second;
575  }
576  idShallowDelete(&Hi);
577
578  omFreeBin((ADDRESS)GG, sip_sideal_bin); idShallowDelete(&G);
579  return false;
580}
581
582
583// #ifndef NDEBUG
584// BOOLEAN ppreduceInitially4(leftv res, leftv args)
585// {
586//   leftv u = args;
587//   if ((u != NULL) && (u->Typ() == IDEAL_CMD))
588//   {
589//     ideal I;
590//     omUpdateInfo();
591//     Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
592//     I = (ideal) u->CopyD();
593//     (void) ppreduceInitially(I,currRing);
594//     id_Delete(&I,currRing);
595//     omUpdateInfo();
596//     Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
597//     I = (ideal) u->CopyD();
598//     (void) ppreduceInitially(I,currRing);
599//     res->rtyp = IDEAL_CMD;
600//     res->data = (char*) I;
601//     return FALSE;
602//   }
603//   return TRUE;
604// }
605// #endif
606
607
608// BOOLEAN ppreduceInitially(leftv res, leftv args)
609// {
610//   leftv u = args;
611//   if ((u != NULL) && (u->Typ() == IDEAL_CMD))
612//   {
613//     ideal I = (ideal) u->CopyD();
614//     (void) ppreduceInitially(I,currRing);
615//     res->rtyp = IDEAL_CMD;
616//     res->data = (char*) I;
617//     return FALSE;
618//   }
619//   return TRUE;
620// }
Note: See TracBrowser for help on using the repository browser.