source: git/dyn_modules/callgfanlib/initialReduction.cc @ 7a4e77

spielwiese
Last change on this file since 7a4e77 was 7a4e77, checked in by Yue Ren <ren@…>, 10 years ago
new: reduceInitially(poly &h, const poly g)
  • Property mode set to 100644
File size: 7.6 KB
Line 
1#include <kernel/polys.h>
2#include <libpolys/polys/monomials/p_polys.h>
3#include <singularWishlist.h>
4
5#include <Singular/ipid.h>
6
7/***
8 * changes a polynomial g with the help p-t such that
9 * 1) each term of g has a distinct monomial in x
10 * 2) no term of g has a coefficient divisible by p
11 * in particular, this means that all g_\alpha can be obtained
12 * by reading the coefficients and that g is initially reduced
13 * with respect to p-t
14 **/
15static bool pReduce(poly g, const number p)
16{
17  poly toBeChecked = pNext(g);
18  pNext(g) = NULL; poly gEnd = g;
19  poly gCache;
20
21  number coeff, pPower; int power; poly subst;
22  while(toBeChecked)
23  {
24    for (gCache = g; gCache; pIter(gCache))
25      if (p_LeadmonomDivisibleBy(gCache,toBeChecked,currRing)) break;
26    if (gCache)
27    {
28      n_Power(p,p_GetExp(toBeChecked,1,currRing)-p_GetExp(gCache,1,currRing),&pPower,currRing->cf);
29      coeff = n_Mult(p_GetCoeff(toBeChecked,currRing),pPower,currRing->cf);
30      p_SetCoeff(gCache,n_Add(p_GetCoeff(gCache,currRing),coeff,currRing->cf),currRing);
31      n_Delete(&pPower,currRing->cf); n_Delete(&coeff,currRing->cf);
32      toBeChecked=p_LmDeleteAndNext(toBeChecked,currRing);
33    }
34    else
35    {
36      if (n_DivBy(p_GetCoeff(toBeChecked,currRing),p,currRing->cf))
37      {
38        coeff=n_Div(p_GetCoeff(toBeChecked,currRing),p,currRing->cf);
39        power=1;
40        while (n_DivBy(coeff,p,currRing->cf))
41        {
42          coeff=n_Div(p_GetCoeff(pNext(g),currRing),p,currRing->cf);
43          power++;
44          if (power<1)
45          {
46            WerrorS("pReduce: overflow in exponent");
47            return true;
48          }
49        }
50        subst=p_LmInit(toBeChecked,currRing);
51        p_AddExp(subst,1,power,currRing);
52        p_SetCoeff(subst,coeff,currRing);
53        p_Setm(subst,currRing); pTest(subst);
54        toBeChecked=p_LmDeleteAndNext(toBeChecked,currRing);
55        toBeChecked=p_Add_q(toBeChecked,subst,currRing);
56        pTest(toBeChecked);
57      }
58      else
59      {
60        pNext(gEnd)=toBeChecked;
61        pIter(gEnd); pIter(toBeChecked);
62        pNext(gEnd)=NULL;
63      }
64    }
65  }
66  return false;
67}
68
69
70#ifndef NDEBUG
71BOOLEAN pReduce(leftv res, leftv args)
72{
73  leftv u = args;
74  if ((u != NULL) && (u->Typ() == POLY_CMD))
75  {
76    poly g; number p = n_Init(3,currRing->cf);
77    omUpdateInfo();
78    Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
79    g = (poly) u->CopyD();
80    (void) pReduce(g,p);
81    p_Delete(&g,currRing);
82    omUpdateInfo();
83    Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
84    g = (poly) u->CopyD();
85    (void) pReduce(g,p);
86    n_Delete(&p,currRing->cf);
87    res->rtyp = POLY_CMD;
88    res->data = (char*) g;
89    return FALSE;
90  }
91  return TRUE;
92}
93#endif //NDEBUG
94
95
96/***
97 * Returns, if it exists, a pointer to the first term in g
98 * that is divisible by (the leading monomial of) m or, if it does not exist, the NULL pointer
99 * If g is homogeneous in x with the same degree as m,
100 * then it returns the first term with the same monomial in x as m,
101 * if the t-degree of the term is higher than the t-degree of m, or NULL otherwise.
102 **/
103static inline poly firstTermDivisibleBy(const poly g, const poly m)
104{
105  poly gCache = NULL;
106  for (gCache=g; gCache; pIter(gCache))
107    if (p_LeadmonomDivisibleBy(m,gCache,currRing)) break;
108  return gCache;
109}
110
111
112/***
113 * reduces h initially with respect to g,
114 * returns NULL if h was initially reduced in the first place. if reductions have taken place,
115 * returns a pointer to a term from which onwards changes have taken place.
116 * assumes that h and g are in pReduced form and homogeneous in x of the same degree
117 **/
118poly reduceInitially(poly &h, const poly g)
119{
120  poly hCache=h;
121  if (p_LeadmonomDivisibleBy(g,hCache,currRing))
122  {
123    number gAlpha = p_GetCoeff(g,currRing);
124    poly hAlphaT = p_Init(currRing);
125    p_SetCoeff(hAlphaT,n_Copy(p_GetCoeff(hCache,currRing),currRing->cf),currRing);
126    p_SetExp(hAlphaT,1,p_GetExp(hCache,1,currRing)-p_GetExp(g,1,currRing),currRing);
127    for (int i=2; i<=currRing->N; i++)
128      p_SetExp(hAlphaT,i,0,currRing);
129    p_Setm(hAlphaT,currRing); pTest(hAlphaT);
130    h = p_Add_q(p_Mult_nn(h,gAlpha,currRing),
131                p_Neg(p_Mult_q(p_Copy(g,currRing),hAlphaT,currRing),currRing),
132                currRing);
133    pTest(h);
134    return(h);
135  }
136  for (; pNext(hCache); pIter(hCache))
137    if (p_LeadmonomDivisibleBy(g,pNext(hCache),currRing)) break;
138  if (pNext(hCache))
139  {
140    number gAlpha = p_GetCoeff(g,currRing);
141    poly hAlphaT = p_Init(currRing);
142    p_SetCoeff(hAlphaT,n_Copy(p_GetCoeff(pNext(hCache),currRing),currRing->cf),currRing);
143    p_SetExp(hAlphaT,1,p_GetExp(pNext(hCache),1,currRing)-p_GetExp(g,1,currRing),currRing);
144    for (int i=2; i<=currRing->N; i++)
145      p_SetExp(hAlphaT,i,0,currRing);
146    p_Setm(hAlphaT,currRing); pTest(hAlphaT);
147    h = p_Add_q(p_Mult_nn(h,gAlpha,currRing),
148                p_Neg(p_Mult_q(p_Copy(g,currRing),hAlphaT,currRing),currRing),
149                currRing);
150    pTest(h);
151  }
152  return pNext(hCache);
153}
154
155
156#ifndef NDEBUG
157BOOLEAN reduceInitially0(leftv res, leftv args)
158{
159  leftv u = args;
160  if ((u != NULL) && (u->Typ() == POLY_CMD))
161  {
162    leftv v = u->next;
163    if ((v != NULL) && (v->Typ() == POLY_CMD))
164    {
165      poly g,h;
166      omUpdateInfo();
167      Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
168      h = (poly) u->CopyD();
169      g = (poly) v->CopyD();
170      (void)reduceInitially(h,g);
171      p_Delete(&h,currRing);
172      p_Delete(&g,currRing);
173      omUpdateInfo();
174      Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
175      h = (poly) u->CopyD();
176      g = (poly) v->CopyD();
177      (void)reduceInitially(h,g);
178      p_Delete(&g,currRing);
179      res->rtyp = POLY_CMD;
180      res->data = (char*) h;
181      return FALSE;
182    }
183  }
184  return TRUE;
185}
186#endif //NDEBUG
187
188
189static inline void sortByLeadmonom(ideal I)
190{
191  poly cache; int i, n=IDELEMS(I), newn;
192  do
193  {
194    newn=0;
195    for (i=1; i<n; i++)
196    {
197      if (pLmCmp(I->m[i-1],I->m[i])<0)
198      {
199        cache=I->m[i-1];
200        I->m[i-1]=I->m[i];
201        I->m[i]=cache;
202        newn = i;
203      }
204    }
205    n=newn;
206  } while(n);
207}
208
209
210/***
211 * reduces I initially with respect to itself and with respect to p-t.
212 * assumes that I is generated by elements which are homogeneous in x of the same degree.
213 **/
214bool reduceInitially(ideal I, const number p)
215{
216  sortByLeadmonom(I); int i,j;
217  for (i=1; i<IDELEMS(I); i++)
218    if (pReduce(I->m[i],p)) return true;
219
220  /***
221   * the first pass. removing terms with the same monomials in x as lt(g_i) out of g_j for i<j
222   **/
223  poly cache = NULL;
224  for (i=0; i<IDELEMS(I)-1; i++)
225  {
226    for (j=i+1; j<IDELEMS(I); j++)
227    {
228      cache = reduceInitially(I->m[j], I->m[i]);
229      if (cache)
230      {
231        if(pReduce(cache,p)) return true;
232        cache = NULL;
233      }
234    }
235  }
236
237  /***
238   * the second pass. removing terms divisible by lt(g_j) out of g_i for i<j
239   **/
240  for (i=0; i<IDELEMS(I)-1; i++)
241  {
242    for (j=i+1; j<IDELEMS(I); j++)
243    {
244      cache = reduceInitially(I->m[i], I->m[j]);
245      if (cache)
246      {
247        if (pReduce(cache,p)) return true;
248        cache = NULL;
249      }
250    }
251  }
252  return false;
253}
254
255
256#ifndef NDEBUG
257BOOLEAN reduceInitially1(leftv res, leftv args)
258{
259  leftv u = args;
260  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
261  {
262    leftv v = u->next;
263    if ((v != NULL) && (v->Typ() == NUMBER_CMD))
264    {
265      ideal I = (ideal) u->CopyD();
266      number p = (number) v->CopyD();
267      omUpdateInfo();
268      Print("usedBytesBefore=%ld\n",om_Info.UsedBytes);
269      (void) reduceInitially(I,p);
270      omUpdateInfo();
271      Print("usedBytesAfter=%ld\n",om_Info.UsedBytes);
272      n_Delete(&p,currRing->cf);
273      res->rtyp = IDEAL_CMD;
274      res->data = (char*) I;
275      return FALSE;
276    }
277  }
278  return TRUE;
279}
280#endif //NDEBUG
Note: See TracBrowser for help on using the repository browser.