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

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