source: git/Singular/p_polys.cc @ fdca1c0

fieker-DuValspielwiese
Last change on this file since fdca1c0 was d242f68, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* bug fixes git-svn-id: file:///usr/local/Singular/svn/trunk@4716 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    p_polys.cc
6 *  Purpose: implementation of currRing independent poly procedures
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: p_polys.cc,v 1.8 2000-11-09 16:32:53 obachman Exp $
10 *******************************************************************/
11
12#include "mod2.h"
13#include "structs.h"
14#include "tok.h"
15#include "p_polys.h"
16#include "ring.h"
17
18/***************************************************************
19 *
20 * Completing what needs to be set for the monomial
21 *
22 ***************************************************************/
23// this is special for the syz stuff
24static int* _Components = NULL;
25static long* _ShiftedComponents = NULL;
26static int _ExternalComponents = 0;
27
28void p_Setm_General(poly p, ring r)
29{
30  p_LmCheckPolyRing(p, r);
31  int pos=0;
32  if (r->typ!=NULL)
33  {
34    loop
35    {
36      long ord=0;
37      sro_ord* o=&(r->typ[pos]);
38      switch(o->ord_typ)
39      {
40        case ro_dp:
41        {
42          int a,e;
43          a=o->data.dp.start;
44          e=o->data.dp.end;
45          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r);
46          p->exp[o->data.dp.place]=ord;
47          break;
48        }
49        case ro_wp_neg:
50          ord=POLY_NEGWEIGHT_OFFSET;
51          // no break;
52        case ro_wp:
53        {
54          int a,e;
55          a=o->data.wp.start;
56          e=o->data.wp.end;
57          int *w=o->data.wp.weights;
58          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r)*w[i-a];
59          p->exp[o->data.wp.place]=ord;
60          break;
61        }
62        case ro_cp:
63        {
64          int a,e;
65          a=o->data.cp.start;
66          e=o->data.cp.end;
67          int pl=o->data.cp.place;
68          for(int i=a;i<=e;i++) { p->exp[pl]=p_GetExp(p,i,r); pl++; }
69          break;
70        }
71        case ro_syzcomp:
72        {
73          int c=p_GetComp(p,r);
74          long sc = c;
75          int* Components = (_ExternalComponents ? _Components : 
76                             o->data.syzcomp.Components);
77          long* ShiftedComponents = (_ExternalComponents ? _ShiftedComponents: 
78                                     o->data.syzcomp.ShiftedComponents);
79          if (ShiftedComponents != NULL)
80          {
81            assume(Components != NULL);
82            assume(c == 0 || Components[c] != 0);
83            sc = ShiftedComponents[Components[c]];
84            assume(c == 0 || sc != 0);
85          }
86          p->exp[o->data.syzcomp.place]=sc;
87          break;
88        }
89        case ro_syz:
90        {
91          int c=p_GetComp(p, r);
92          if (c > o->data.syz.limit)
93            p->exp[o->data.syz.place] = o->data.syz.curr_index;
94          else if (c > 0)
95            p->exp[o->data.syz.place]= o->data.syz.syz_index[c];
96          else
97          {
98            assume(c == 0);
99            p->exp[o->data.syz.place]= 0;
100          }
101          break;
102        }
103        default:
104          dReportError("wrong ord in rSetm:%d\n",o->ord_typ);
105          return;
106      }
107      pos++;
108      if (pos == r->OrdSize) return;
109    }
110  }
111}
112
113void p_Setm_Syz(poly p, ring r, int* Components, long* ShiftedComponents)
114{
115  _Components = Components;
116  _ShiftedComponents = ShiftedComponents;
117  _ExternalComponents = 1;
118  p_Setm_General(p, r);
119  _ExternalComponents = 0;
120}
121
122// dummy for lp, ls, etc
123void p_Setm_Dummy(poly p, ring r)
124{
125  p_LmCheckPolyRing(p, r);
126}
127
128// for dp, Dp, ds, etc
129void p_Setm_TotalDegree(poly p, ring r)
130{
131  p_LmCheckPolyRing(p, r);
132  p->exp[r->pOrdIndex] = p_ExpVectorQuerSum(p, r);
133}
134
135// for wp, Wp, ws, etc
136void p_Setm_WFirstTotalDegree(poly p, ring r)
137{
138  p_LmCheckPolyRing(p, r);
139  p->exp[r->pOrdIndex] = pWFirstTotalDegree(p, r);
140}
141
142p_SetmProc p_GetSetmProc(ring r)
143{
144  // covers lp, rp, ls,
145  if (r->typ == NULL) return p_Setm_Dummy;
146
147  if (r->OrdSize == 1)
148  {
149    if (r->typ[0].ord_typ == ro_dp && 
150        r->typ[0].data.dp.start == 1 &&
151        r->typ[0].data.dp.end == r->N &&
152        r->typ[0].data.dp.place == r->pOrdIndex)
153      return p_Setm_TotalDegree;
154    if (r->typ[0].ord_typ == ro_wp && 
155        r->typ[0].data.wp.start == 1 &&
156        r->typ[0].data.wp.end == r->N &&
157        r->typ[0].data.wp.place == r->pOrdIndex &&
158        r->typ[0].data.wp.weights == r->firstwv)
159      return p_Setm_WFirstTotalDegree;
160  }
161  return p_Setm_General;
162}
163
164
165/* -------------------------------------------------------------------*/
166/* several possibilities for pFDeg: the degree of the head term       */
167/*2
168* compute the degree of the leading monomial of p
169* the ordering is compatible with degree, use a->order
170*/
171long pDeg(poly a, ring r)
172{
173  p_LmCheckPolyRing(a, r);
174  assume(p_GetOrder(a, r) == pWTotaldegree(a, r));
175  return p_GetOrder(a, r);
176}
177
178/*2
179* compute the degree of the leading monomial of p
180* with respect to weigths 1
181* (all are 1 so save multiplications or they are of different signs)
182* the ordering is not compatible with degree so do not use p->Order
183*/
184long pTotaldegree(poly p, ring r)
185{
186  p_LmCheckPolyRing(p, r);
187  return (long) p_ExpVectorQuerSum(p, r);
188}
189
190
191// pWTotalDegree for weighted orderings which cover all variables
192// whose first block covers all variables
193long pWFirstTotalDegree(poly p, ring r)
194{
195  int i;
196  long sum = 0;
197 
198  for (i=1; i<= r->firstBlockEnds; i++)
199  {
200    sum += p_GetExp(p, i, r)*r->firstwv[i-1];
201  }
202  return sum;
203}
204
205
206/*2
207* compute the degree of the leading monomial of p
208* with respect to weigths from the ordering
209* the ordering is not compatible with degree so do not use p->Order
210*/
211long pWTotaldegree(poly p, ring r)
212{
213  p_LmCheckPolyRing(p, r);
214  int i, k;
215  long j =0;
216
217  // iterate through each block:
218  for (i=0;r->order[i]!=0;i++)
219  {
220    switch(r->order[i])
221    {
222      case ringorder_wp:
223      case ringorder_ws:
224      case ringorder_Wp:
225      case ringorder_Ws:
226        for (k=r->block0[i];k<=r->block1[i];k++)
227        { // in jedem block:
228          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - r->block0[i]];
229        }
230        break;
231      case ringorder_M:
232      case ringorder_lp:
233      case ringorder_dp:
234      case ringorder_ds:
235      case ringorder_Dp:
236      case ringorder_Ds:
237        for (k=r->block0[i];k<=r->block1[i];k++)
238        {
239          j+= p_GetExp(p,k,r);
240        }
241        break;
242      case ringorder_c:
243      case ringorder_C:
244      case ringorder_S:
245      case ringorder_s:
246        break;
247      case ringorder_a:
248        for (k=r->block0[i];k<=r->block1[i];k++)
249        { // only one line
250          j+= p_GetExp(p,k, r)*r->wvhdl[i][ k- r->block0[i]];
251        }
252        return j;
253    }
254  }
255  return  j;
256}
257
258int pWeight(int i, ring r)
259{
260  if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
261  {
262    return 1;
263  }
264  return r->firstwv[i-1];
265}
266
267long pWDegree(poly p, ring r)
268{
269  if (r->firstwv==NULL) return pTotaldegree(p, r);
270  p_LmCheckPolyRing(p, r);
271  int i, k;
272  long j =0;
273
274  for(i=1;i<=r->firstBlockEnds;i++)
275    j+=p_GetExp(p, i, r)*r->firstwv[i-1];
276
277  for (;i<=r->N;i++)
278    j+=p_GetExp(p,i, r)*pWeight(i, r);
279
280  return j;
281}
282
283
284/* ---------------------------------------------------------------------*/
285/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
286/*  compute in l also the pLength of p                                   */
287
288/*2
289* compute the length of a polynomial (in l)
290* and the degree of the monomial with maximal degree: the last one
291*/
292long pLDeg0(poly p,int *l, ring r)
293{
294  p_CheckPolyRing(p, r);
295  Exponent_t k= p_GetComp(p, r);
296  int ll=1;
297
298  while ((pNext(p)!=NULL) && (p_GetComp(pNext(p), r)==k))
299  {
300    pIter(p);
301    ll++;
302  }
303  *l=ll;
304  return p_GetOrder(p, r);
305}
306
307/*2
308* compute the length of a polynomial (in l)
309* and the degree of the monomial with maximal degree: the last one
310* but search in all components before syzcomp
311*/
312#if 0
313long pLDeg0c(poly p,int *l, ring r)
314{
315  p_CheckPolyRing(p, r);
316  long o=pFDeg(p, r);
317  int ll=1;
318
319  if (! rIsSyzIndexRing(r))
320  {
321    while ((p=pNext(p))!=NULL)
322    {
323      o=pFDeg(p, r);
324      ll++;
325    }
326  }
327  else
328  {
329    int curr_limit = rGetCurrSyzLimit(r);
330    while ((p=pNext(p))!=NULL)
331    {
332      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
333      {
334        o=pFDeg(p, r);
335        ll++;
336      }
337      else break;
338    }
339  }
340  *l=ll;
341  return o;
342}
343#else
344long pLDeg0c(poly p,int *l, ring r)
345{
346  p_CheckPolyRing(p, r);
347  long o;
348  int ll=1;
349
350  if (! rIsSyzIndexRing(r))
351  {
352    while (pNext(p) != NULL) 
353    {
354      pIter(p);
355      ll++;
356    }
357    o = pFDeg(p, r);
358  }
359  else
360  {
361    int curr_limit = rGetCurrSyzLimit(r);
362    poly pp = p;
363    while ((p=pNext(p))!=NULL)
364    {
365      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
366        ll++;
367      else break;
368      pp = p;
369    }
370    o = pFDeg(pp, r);
371  }
372  *l=ll;
373  return o;
374}
375#endif
376
377/*2
378* compute the length of a polynomial (in l)
379* and the degree of the monomial with maximal degree: the first one
380* this works for the polynomial case with degree orderings
381* (both c,dp and dp,c)
382*/
383long pLDegb(poly p,int *l, ring r)
384{
385  p_CheckPolyRing(p, r);
386  Exponent_t k= p_GetComp(p, r);
387  long o = pFDeg(p, r);
388  int ll=1;
389
390  while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
391  {
392    ll++;
393  }
394  *l=ll;
395  return o;
396}
397
398/*2
399* compute the length of a polynomial (in l)
400* and the degree of the monomial with maximal degree:
401* this is NOT the last one, we have to look for it
402*/
403long pLDeg1(poly p,int *l, ring r)
404{
405  p_CheckPolyRing(p, r);
406  Exponent_t k= p_GetComp(p, r);
407  int ll=1;
408  long  t,max;
409
410  max=pFDeg(p);
411  while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
412  {
413    t=pFDeg(p, r);
414    if (t>max) max=t;
415    ll++;
416  }
417  *l=ll;
418  return max;
419}
420
421/*2
422* compute the length of a polynomial (in l)
423* and the degree of the monomial with maximal degree:
424* this is NOT the last one, we have to look for it
425* in all components
426*/
427long pLDeg1c(poly p,int *l, ring r)
428{
429  p_CheckPolyRing(p, r);
430  int ll=1;
431  long  t,max;
432
433  max=pFDeg(p, r);
434  while ((p=pNext(p))!=NULL)
435  {
436    if (! rIsSyzIndexRing(r) ||
437        (p_GetComp(p, r)<=rGetCurrSyzLimit(r)))
438    {
439       if ((t=pFDeg(p, r))>max) max=t;
440       ll++;
441    }
442    else break;
443  }
444  *l=ll;
445  return max;
446}
447
448/***************************************************************
449 *
450 * Maximal Exponent business
451 *
452 ***************************************************************/
453
454static inline unsigned long 
455p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r, 
456              unsigned long number_of_exp)
457{
458  const unsigned long bitmask = r->bitmask;
459  unsigned long ml1 = l1 & bitmask;
460  unsigned long ml2 = l2 & bitmask;
461  unsigned long max = (ml1 > ml2 ? ml1 : ml2);
462  unsigned long j = number_of_exp - 1;
463
464  if (j > 0)
465  {
466    unsigned long mask = bitmask << r->BitsPerExp;
467    while (1)
468    {
469      ml1 = l1 & mask;
470      ml2 = l2 & mask;
471      max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
472      j--;
473      if (j == 0) break;
474      mask = mask << r->BitsPerExp;
475    }
476  }
477  return max;
478}
479
480static inline unsigned long
481p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r)
482{
483  return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
484}
485
486poly p_GetMaxExpP(poly p, ring r)
487{
488  p_CheckPolyRing(p, r);
489  if (p == NULL) return p_Init(r);
490  poly max = p_LmInit(p, r);
491  pIter(p);
492  if (p == NULL) return max;
493  int i, offset;
494  unsigned long l_p, l_max;
495  unsigned long divmask = r->divmask;
496 
497  do
498  {
499    offset = r->VarL_Offset[0];
500    l_p = p->exp[offset];
501    l_max = max->exp[offset];
502    // do the divisibility trick to find out whether l has an exponent
503    if (l_p > l_max || 
504        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
505      max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
506
507    for (i=1; i<r->VarL_Size; i++)
508    {
509      offset = r->VarL_Offset[i];
510      l_p = p->exp[offset];
511      l_max = max->exp[offset];
512      // do the divisibility trick to find out whether l has an exponent
513      if (l_p > l_max || 
514          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
515        max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
516    }
517    pIter(p);
518  }
519  while (p != NULL);
520  return max;
521}
522
523unsigned long p_GetMaxExpL(poly p, ring r, unsigned long l_max)
524{
525  unsigned long l_p, divmask = r->divmask;
526  int i;
527 
528  while (p != NULL)
529  {
530    l_p = p->exp[r->VarL_Offset[0]];
531    if (l_p > l_max ||
532        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
533      l_max = p_GetMaxExpL2(l_max, l_p, r);
534    for (i=1; i<r->VarL_Size; i++)
535    {
536      l_p = p->exp[r->VarL_Offset[i]];
537      // do the divisibility trick to find out whether l has an exponent
538      if (l_p > l_max || 
539          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
540        l_max = p_GetMaxExpL2(l_max, l_p, r);
541    }
542    pIter(p);
543  }
544  return l_max;
545}
546
547
548   
Note: See TracBrowser for help on using the repository browser.