source: git/Singular/p_polys.cc @ 5038cd

spielwiese
Last change on this file since 5038cd was 5038cd, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* buckets in local case git-svn-id: file:///usr/local/Singular/svn/trunk@4763 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.2 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.10 2000-11-23 17:34:12 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*/
171inline long _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
178long pDeg(poly a, ring r)
179{
180  return _pDeg(a, r);
181}
182
183/*2
184* compute the degree of the leading monomial of p
185* with respect to weigths 1
186* (all are 1 so save multiplications or they are of different signs)
187* the ordering is not compatible with degree so do not use p->Order
188*/
189inline long _pTotaldegree(poly p, ring r)
190{
191  p_LmCheckPolyRing(p, r);
192  return (long) p_ExpVectorQuerSum(p, r);
193}
194long pTotaldegree(poly p, ring r)
195{
196  return (long) _pTotaldegree(p, r);
197}
198
199// pWTotalDegree for weighted orderings
200// whose first block covers all variables
201long pWFirstTotalDegree(poly p, ring r)
202{
203  int i;
204  long sum = 0;
205 
206  for (i=1; i<= r->firstBlockEnds; i++)
207  {
208    sum += p_GetExp(p, i, r)*r->firstwv[i-1];
209  }
210  return sum;
211}
212
213
214/*2
215* compute the degree of the leading monomial of p
216* with respect to weigths from the ordering
217* the ordering is not compatible with degree so do not use p->Order
218*/
219long pWTotaldegree(poly p, ring r)
220{
221  p_LmCheckPolyRing(p, r);
222  int i, k;
223  long j =0;
224
225  // iterate through each block:
226  for (i=0;r->order[i]!=0;i++)
227  {
228    switch(r->order[i])
229    {
230      case ringorder_wp:
231      case ringorder_ws:
232      case ringorder_Wp:
233      case ringorder_Ws:
234        for (k=r->block0[i];k<=r->block1[i];k++)
235        { // in jedem block:
236          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - r->block0[i]];
237        }
238        break;
239      case ringorder_M:
240      case ringorder_lp:
241      case ringorder_dp:
242      case ringorder_ds:
243      case ringorder_Dp:
244      case ringorder_Ds:
245        for (k=r->block0[i];k<=r->block1[i];k++)
246        {
247          j+= p_GetExp(p,k,r);
248        }
249        break;
250      case ringorder_c:
251      case ringorder_C:
252      case ringorder_S:
253      case ringorder_s:
254        break;
255      case ringorder_a:
256        for (k=r->block0[i];k<=r->block1[i];k++)
257        { // only one line
258          j+= p_GetExp(p,k, r)*r->wvhdl[i][ k- r->block0[i]];
259        }
260        return j;
261    }
262  }
263  return  j;
264}
265
266int pWeight(int i, ring r)
267{
268  if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
269  {
270    return 1;
271  }
272  return r->firstwv[i-1];
273}
274
275long pWDegree(poly p, ring r)
276{
277  if (r->firstwv==NULL) return pTotaldegree(p, r);
278  p_LmCheckPolyRing(p, r);
279  int i, k;
280  long j =0;
281
282  for(i=1;i<=r->firstBlockEnds;i++)
283    j+=p_GetExp(p, i, r)*r->firstwv[i-1];
284
285  for (;i<=r->N;i++)
286    j+=p_GetExp(p,i, r)*pWeight(i, r);
287
288  return j;
289}
290
291
292/* ---------------------------------------------------------------------*/
293/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
294/*  compute in l also the pLength of p                                   */
295
296/*2
297* compute the length of a polynomial (in l)
298* and the degree of the monomial with maximal degree: the last one
299*/
300long pLDeg0(poly p,int *l, ring r)
301{
302  p_CheckPolyRing(p, r);
303  Exponent_t k= p_GetComp(p, r);
304  int ll=1;
305
306  if (k > 0)
307  {
308    while ((pNext(p)!=NULL) && (p_GetComp(pNext(p), r)==k))
309    {
310      pIter(p);
311      ll++;
312    }
313  }
314  else
315  {
316     while (pNext(p)!=NULL)
317     {
318       pIter(p);
319       ll++;
320     }
321  }
322  *l=ll;
323  return p_GetOrder(p, r);
324}
325
326/*2
327* compute the length of a polynomial (in l)
328* and the degree of the monomial with maximal degree: the last one
329* but search in all components before syzcomp
330*/
331long pLDeg0c(poly p,int *l, ring r)
332{
333  p_CheckPolyRing(p, r);
334  long o;
335  int ll=1;
336
337  if (! rIsSyzIndexRing(r))
338  {
339    while (pNext(p) != NULL) 
340    {
341      pIter(p);
342      ll++;
343    }
344    o = pFDeg(p, r);
345  }
346  else
347  {
348    int curr_limit = rGetCurrSyzLimit(r);
349    poly pp = p;
350    while ((p=pNext(p))!=NULL)
351    {
352      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
353        ll++;
354      else break;
355      pp = p;
356    }
357    o = pFDeg(pp, r);
358  }
359  *l=ll;
360  return o;
361}
362
363/*2
364* compute the length of a polynomial (in l)
365* and the degree of the monomial with maximal degree: the first one
366* this works for the polynomial case with degree orderings
367* (both c,dp and dp,c)
368*/
369long pLDegb(poly p,int *l, ring r)
370{
371  p_CheckPolyRing(p, r);
372  Exponent_t k= p_GetComp(p, r);
373  long o = pFDeg(p, r);
374  int ll=1;
375
376  if (k != 0)
377  {
378    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
379    {
380      ll++;
381    }
382  }
383  else
384  {
385    while ((p=pNext(p)) !=NULL)
386    {
387      ll++;
388    }
389  }
390  *l=ll;
391  return o;
392}
393
394/*2
395* compute the length of a polynomial (in l)
396* and the degree of the monomial with maximal degree:
397* this is NOT the last one, we have to look for it
398*/
399long pLDeg1(poly p,int *l, ring r)
400{
401  p_CheckPolyRing(p, r);
402  Exponent_t k= p_GetComp(p, r);
403  int ll=1;
404  long  t,max;
405
406  max=pFDeg(p, r);
407  if (k > 0)
408  {
409    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
410    {
411      t=pFDeg(p, r);
412      if (t>max) max=t;
413      ll++;
414    }
415  }
416  else
417  {
418    while ((p=pNext(p))!=NULL)
419    {
420      t=pFDeg(p, r);
421      if (t>max) max=t;
422      ll++;
423    }
424  }
425  *l=ll;
426  return max;
427}
428
429/*2
430* compute the length of a polynomial (in l)
431* and the degree of the monomial with maximal degree:
432* this is NOT the last one, we have to look for it
433* in all components
434*/
435long pLDeg1c(poly p,int *l, ring r)
436{
437  p_CheckPolyRing(p, r);
438  int ll=1;
439  long  t,max;
440
441  max=pFDeg(p, r);
442  if (rIsSyzIndexRing(r))
443  {
444    long limit = rGetCurrSyzLimit(r);
445    while ((p=pNext(p))!=NULL)
446    {
447      if (p_GetComp(p, r)<=limit)
448      {
449        if ((t=pFDeg(p, r))>max) max=t;
450        ll++;
451      }
452      else break;
453    }
454  }
455  else
456  {
457    while ((p=pNext(p))!=NULL)
458    {
459      if ((t=pFDeg(p, r))>max) max=t;
460      ll++;
461    }
462  }
463  *l=ll;
464  return max;
465}
466
467// like pLDeg1, only pFDeg == Deg
468long pLDeg1_Deg(poly p,int *l, ring r)
469{
470  p_CheckPolyRing(p, r);
471  Exponent_t k= p_GetComp(p, r);
472  int ll=1;
473  long  t,max;
474
475  max=_pDeg(p, r);
476  if (k > 0)
477  {
478    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
479    {
480      t=_pDeg(p, r);
481      if (t>max) max=t;
482      ll++;
483    }
484  }
485  else
486  {
487    while ((p=pNext(p))!=NULL)
488    {
489      t=_pDeg(p, r);
490      if (t>max) max=t;
491      ll++;
492    }
493  }
494  *l=ll;
495  return max;
496}
497
498long pLDeg1c_Deg(poly p,int *l, ring r)
499{
500  p_CheckPolyRing(p, r);
501  int ll=1;
502  long  t,max;
503
504  max=_pDeg(p, r);
505  if (rIsSyzIndexRing(r))
506  {
507    long limit = rGetCurrSyzLimit(r);
508    while ((p=pNext(p))!=NULL)
509    {
510      if (p_GetComp(p, r)<=limit)
511      {
512        if ((t=_pDeg(p, r))>max) max=t;
513        ll++;
514      }
515      else break;
516    }
517  }
518  else
519  {
520    while ((p=pNext(p))!=NULL)
521    {
522      if ((t=_pDeg(p, r))>max) max=t;
523      ll++;
524    }
525  }
526  *l=ll;
527  return max;
528}
529
530// like pLDeg1, only pFDeg == pTotoalDegree
531long pLDeg1_Totaldegree(poly p,int *l, ring r)
532{
533  p_CheckPolyRing(p, r);
534  Exponent_t k= p_GetComp(p, r);
535  int ll=1;
536  long  t,max;
537
538  max=_pTotaldegree(p, r);
539  if (k > 0)
540  {
541    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
542    {
543      t=_pTotaldegree(p, r);
544      if (t>max) max=t;
545      ll++;
546    }
547  }
548  else
549  {
550    while ((p=pNext(p))!=NULL)
551    {
552      t=_pTotaldegree(p, r);
553      if (t>max) max=t;
554      ll++;
555    }
556  }
557  *l=ll;
558  return max;
559}
560
561long pLDeg1c_Totaldegree(poly p,int *l, ring r)
562{
563  p_CheckPolyRing(p, r);
564  int ll=1;
565  long  t,max;
566
567  max=_pTotaldegree(p, r);
568  if (rIsSyzIndexRing(r))
569  {
570    long limit = rGetCurrSyzLimit(r);
571    while ((p=pNext(p))!=NULL)
572    {
573      if (p_GetComp(p, r)<=limit)
574      {
575        if ((t=_pTotaldegree(p, r))>max) max=t;
576        ll++;
577      }
578      else break;
579    }
580  }
581  else
582  {
583    while ((p=pNext(p))!=NULL)
584    {
585      if ((t=_pTotaldegree(p, r))>max) max=t;
586      ll++;
587    }
588  }
589  *l=ll;
590  return max;
591}
592
593/***************************************************************
594 *
595 * Maximal Exponent business
596 *
597 ***************************************************************/
598
599static inline unsigned long 
600p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r, 
601              unsigned long number_of_exp)
602{
603  const unsigned long bitmask = r->bitmask;
604  unsigned long ml1 = l1 & bitmask;
605  unsigned long ml2 = l2 & bitmask;
606  unsigned long max = (ml1 > ml2 ? ml1 : ml2);
607  unsigned long j = number_of_exp - 1;
608
609  if (j > 0)
610  {
611    unsigned long mask = bitmask << r->BitsPerExp;
612    while (1)
613    {
614      ml1 = l1 & mask;
615      ml2 = l2 & mask;
616      max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
617      j--;
618      if (j == 0) break;
619      mask = mask << r->BitsPerExp;
620    }
621  }
622  return max;
623}
624
625static inline unsigned long
626p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r)
627{
628  return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
629}
630
631poly p_GetMaxExpP(poly p, ring r)
632{
633  p_CheckPolyRing(p, r);
634  if (p == NULL) return p_Init(r);
635  poly max = p_LmInit(p, r);
636  pIter(p);
637  if (p == NULL) return max;
638  int i, offset;
639  unsigned long l_p, l_max;
640  unsigned long divmask = r->divmask;
641 
642  do
643  {
644    offset = r->VarL_Offset[0];
645    l_p = p->exp[offset];
646    l_max = max->exp[offset];
647    // do the divisibility trick to find out whether l has an exponent
648    if (l_p > l_max || 
649        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
650      max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
651
652    for (i=1; i<r->VarL_Size; i++)
653    {
654      offset = r->VarL_Offset[i];
655      l_p = p->exp[offset];
656      l_max = max->exp[offset];
657      // do the divisibility trick to find out whether l has an exponent
658      if (l_p > l_max || 
659          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
660        max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
661    }
662    pIter(p);
663  }
664  while (p != NULL);
665  return max;
666}
667
668unsigned long p_GetMaxExpL(poly p, ring r, unsigned long l_max)
669{
670  unsigned long l_p, divmask = r->divmask;
671  int i;
672 
673  while (p != NULL)
674  {
675    l_p = p->exp[r->VarL_Offset[0]];
676    if (l_p > l_max ||
677        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
678      l_max = p_GetMaxExpL2(l_max, l_p, r);
679    for (i=1; i<r->VarL_Size; i++)
680    {
681      l_p = p->exp[r->VarL_Offset[i]];
682      // do the divisibility trick to find out whether l has an exponent
683      if (l_p > l_max || 
684          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
685        l_max = p_GetMaxExpL2(l_max, l_p, r);
686    }
687    pIter(p);
688  }
689  return l_max;
690}
691
692
693
694   
695/***************************************************************
696 *
697 * Misc things
698 *
699 ***************************************************************/
700// returns TRUE, if all monoms have the same component
701BOOLEAN p_OneComp(poly p, ring r)
702{
703  if(p!=NULL)
704  {
705    long i = p_GetComp(p, r);
706    while (pNext(p)!=NULL)
707    {
708      pIter(p);
709      if(i != p_GetComp(p, r)) return FALSE;
710    }
711  }
712  return TRUE;
713}
714
715/*2
716*test if a monomial /head term is a pure power
717*/
718int p_IsPurePower(const poly p, const ring r)
719{
720  int i,k=0;
721
722  for (i=r->N;i;i--)
723  {
724    if (p_GetExp(p,i, r)!=0)
725    {
726      if(k!=0) return 0;
727      k=i;
728    }
729  }
730  return k;
731}
Note: See TracBrowser for help on using the repository browser.