source: git/Singular/dyn_modules/gfanlib/ppinitialReduction.cc @ d4049c

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