source: git/Singular/p_polys.cc @ 958e16

spielwiese
Last change on this file since 958e16 was 958e16, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merged number-ops git-svn-id: file:///usr/local/Singular/svn/trunk@5035 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 16.9 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.15 2001-01-09 15:40:12 Singular 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
201inline long _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
213long pWFirstTotalDegree(poly p, ring r)
214{
215  return (long) _pWFirstTotalDegree(p, r);
216}
217
218/*2
219* compute the degree of the leading monomial of p
220* with respect to weigths from the ordering
221* the ordering is not compatible with degree so do not use p->Order
222*/
223long pWTotaldegree(poly p, ring r)
224{
225  p_LmCheckPolyRing(p, r);
226  int i, k;
227  long j =0;
228
229  // iterate through each block:
230  for (i=0;r->order[i]!=0;i++)
231  {
232    switch(r->order[i])
233    {
234      case ringorder_wp:
235      case ringorder_ws:
236      case ringorder_Wp:
237      case ringorder_Ws:
238        for (k=r->block0[i];k<=r->block1[i];k++)
239        { // in jedem block:
240          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - r->block0[i]];
241        }
242        break;
243      case ringorder_M:
244      case ringorder_lp:
245      case ringorder_dp:
246      case ringorder_ds:
247      case ringorder_Dp:
248      case ringorder_Ds:
249      case ringorder_rp:
250        for (k=r->block0[i];k<=r->block1[i];k++)
251        {
252          j+= p_GetExp(p,k,r);
253        }
254        break;
255      case ringorder_c:
256      case ringorder_C:
257      case ringorder_S:
258      case ringorder_s:
259      case ringorder_aa:
260        break;
261      case ringorder_a:
262        for (k=r->block0[i];k<=r->block1[i];k++)
263        { // only one line
264          j+= p_GetExp(p,k, r)*r->wvhdl[i][ k- r->block0[i]];
265        }
266        return j;
267    }
268  }
269  return  j;
270}
271
272int pWeight(int i, ring r)
273{
274  if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
275  {
276    return 1;
277  }
278  return r->firstwv[i-1];
279}
280
281long pWDegree(poly p, ring r)
282{
283  if (r->firstwv==NULL) return pTotaldegree(p, r);
284  p_LmCheckPolyRing(p, r);
285  int i, k;
286  long j =0;
287
288  for(i=1;i<=r->firstBlockEnds;i++)
289    j+=p_GetExp(p, i, r)*r->firstwv[i-1];
290
291  for (;i<=r->N;i++)
292    j+=p_GetExp(p,i, r)*pWeight(i, r);
293
294  return j;
295}
296
297
298/* ---------------------------------------------------------------------*/
299/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
300/*  compute in l also the pLength of p                                   */
301
302/*2
303* compute the length of a polynomial (in l)
304* and the degree of the monomial with maximal degree: the last one
305*/
306long pLDeg0(poly p,int *l, ring r)
307{
308  p_CheckPolyRing(p, r);
309  Exponent_t k= p_GetComp(p, r);
310  int ll=1;
311
312  if (k > 0)
313  {
314    while ((pNext(p)!=NULL) && (p_GetComp(pNext(p), r)==k))
315    {
316      pIter(p);
317      ll++;
318    }
319  }
320  else
321  {
322     while (pNext(p)!=NULL)
323     {
324       pIter(p);
325       ll++;
326     }
327  }
328  *l=ll;
329  return r->pFDeg(p, r);
330}
331
332/*2
333* compute the length of a polynomial (in l)
334* and the degree of the monomial with maximal degree: the last one
335* but search in all components before syzcomp
336*/
337long pLDeg0c(poly p,int *l, ring r)
338{
339  p_CheckPolyRing(p, r);
340  long o;
341  int ll=1;
342
343  if (! rIsSyzIndexRing(r))
344  {
345    while (pNext(p) != NULL) 
346    {
347      pIter(p);
348      ll++;
349    }
350    o = r->pFDeg(p, r);
351  }
352  else
353  {
354    int curr_limit = rGetCurrSyzLimit(r);
355    poly pp = p;
356    while ((p=pNext(p))!=NULL)
357    {
358      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
359        ll++;
360      else break;
361      pp = p;
362    }
363    o = r->pFDeg(pp, r);
364  }
365  *l=ll;
366  return o;
367}
368
369/*2
370* compute the length of a polynomial (in l)
371* and the degree of the monomial with maximal degree: the first one
372* this works for the polynomial case with degree orderings
373* (both c,dp and dp,c)
374*/
375long pLDegb(poly p,int *l, ring r)
376{
377  p_CheckPolyRing(p, r);
378  Exponent_t k= p_GetComp(p, r);
379  long o = r->pFDeg(p, r);
380  int ll=1;
381
382  if (k != 0)
383  {
384    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
385    {
386      ll++;
387    }
388  }
389  else
390  {
391    while ((p=pNext(p)) !=NULL)
392    {
393      ll++;
394    }
395  }
396  *l=ll;
397  return o;
398}
399
400/*2
401* compute the length of a polynomial (in l)
402* and the degree of the monomial with maximal degree:
403* this is NOT the last one, we have to look for it
404*/
405long pLDeg1(poly p,int *l, ring r)
406{
407  p_CheckPolyRing(p, r);
408  Exponent_t k= p_GetComp(p, r);
409  int ll=1;
410  long  t,max;
411
412  max=r->pFDeg(p, r);
413  if (k > 0)
414  {
415    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
416    {
417      t=r->pFDeg(p, r);
418      if (t>max) max=t;
419      ll++;
420    }
421  }
422  else
423  {
424    while ((p=pNext(p))!=NULL)
425    {
426      t=r->pFDeg(p, r);
427      if (t>max) max=t;
428      ll++;
429    }
430  }
431  *l=ll;
432  return max;
433}
434
435/*2
436* compute the length of a polynomial (in l)
437* and the degree of the monomial with maximal degree:
438* this is NOT the last one, we have to look for it
439* in all components
440*/
441long pLDeg1c(poly p,int *l, ring r)
442{
443  p_CheckPolyRing(p, r);
444  int ll=1;
445  long  t,max;
446
447  max=r->pFDeg(p, r);
448  if (rIsSyzIndexRing(r))
449  {
450    long limit = rGetCurrSyzLimit(r);
451    while ((p=pNext(p))!=NULL)
452    {
453      if (p_GetComp(p, r)<=limit)
454      {
455        if ((t=r->pFDeg(p, r))>max) max=t;
456        ll++;
457      }
458      else break;
459    }
460  }
461  else
462  {
463    while ((p=pNext(p))!=NULL)
464    {
465      if ((t=r->pFDeg(p, r))>max) max=t;
466      ll++;
467    }
468  }
469  *l=ll;
470  return max;
471}
472
473// like pLDeg1, only pFDeg == pDeg
474long pLDeg1_Deg(poly p,int *l, ring r)
475{
476  assume(r->pFDeg == pDeg);
477  p_CheckPolyRing(p, r);
478  Exponent_t k= p_GetComp(p, r);
479  int ll=1;
480  long  t,max;
481
482  max=_pDeg(p, r);
483  if (k > 0)
484  {
485    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
486    {
487      t=_pDeg(p, r);
488      if (t>max) max=t;
489      ll++;
490    }
491  }
492  else
493  {
494    while ((p=pNext(p))!=NULL)
495    {
496      t=_pDeg(p, r);
497      if (t>max) max=t;
498      ll++;
499    }
500  }
501  *l=ll;
502  return max;
503}
504
505long pLDeg1c_Deg(poly p,int *l, ring r)
506{
507  assume(r->pFDeg == pDeg);
508  p_CheckPolyRing(p, r);
509  int ll=1;
510  long  t,max;
511
512  max=_pDeg(p, r);
513  if (rIsSyzIndexRing(r))
514  {
515    long limit = rGetCurrSyzLimit(r);
516    while ((p=pNext(p))!=NULL)
517    {
518      if (p_GetComp(p, r)<=limit)
519      {
520        if ((t=_pDeg(p, r))>max) max=t;
521        ll++;
522      }
523      else break;
524    }
525  }
526  else
527  {
528    while ((p=pNext(p))!=NULL)
529    {
530      if ((t=_pDeg(p, r))>max) max=t;
531      ll++;
532    }
533  }
534  *l=ll;
535  return max;
536}
537
538// like pLDeg1, only pFDeg == pTotoalDegree
539long pLDeg1_Totaldegree(poly p,int *l, ring r)
540{
541  p_CheckPolyRing(p, r);
542  Exponent_t k= p_GetComp(p, r);
543  int ll=1;
544  long  t,max;
545
546  max=_pTotaldegree(p, r);
547  if (k > 0)
548  {
549    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
550    {
551      t=_pTotaldegree(p, r);
552      if (t>max) max=t;
553      ll++;
554    }
555  }
556  else
557  {
558    while ((p=pNext(p))!=NULL)
559    {
560      t=_pTotaldegree(p, r);
561      if (t>max) max=t;
562      ll++;
563    }
564  }
565  *l=ll;
566  return max;
567}
568
569long pLDeg1c_Totaldegree(poly p,int *l, ring r)
570{
571  p_CheckPolyRing(p, r);
572  int ll=1;
573  long  t,max;
574
575  max=_pTotaldegree(p, r);
576  if (rIsSyzIndexRing(r))
577  {
578    long limit = rGetCurrSyzLimit(r);
579    while ((p=pNext(p))!=NULL)
580    {
581      if (p_GetComp(p, r)<=limit)
582      {
583        if ((t=_pTotaldegree(p, r))>max) max=t;
584        ll++;
585      }
586      else break;
587    }
588  }
589  else
590  {
591    while ((p=pNext(p))!=NULL)
592    {
593      if ((t=_pTotaldegree(p, r))>max) max=t;
594      ll++;
595    }
596  }
597  *l=ll;
598  return max;
599}
600
601// like pLDeg1, only pFDeg == pWFirstTotalDegree
602long pLDeg1_WFirstTotalDegree(poly p,int *l, ring r)
603{
604  p_CheckPolyRing(p, r);
605  Exponent_t k= p_GetComp(p, r);
606  int ll=1;
607  long  t,max;
608
609  max=_pWFirstTotalDegree(p, r);
610  if (k > 0)
611  {
612    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
613    {
614      t=_pWFirstTotalDegree(p, r);
615      if (t>max) max=t;
616      ll++;
617    }
618  }
619  else
620  {
621    while ((p=pNext(p))!=NULL)
622    {
623      t=_pWFirstTotalDegree(p, r);
624      if (t>max) max=t;
625      ll++;
626    }
627  }
628  *l=ll;
629  return max;
630}
631
632long pLDeg1c_WFirstTotalDegree(poly p,int *l, ring r)
633{
634  p_CheckPolyRing(p, r);
635  int ll=1;
636  long  t,max;
637
638  max=_pWFirstTotalDegree(p, r);
639  if (rIsSyzIndexRing(r))
640  {
641    long limit = rGetCurrSyzLimit(r);
642    while ((p=pNext(p))!=NULL)
643    {
644      if (p_GetComp(p, r)<=limit)
645      {
646        if ((t=_pTotaldegree(p, r))>max) max=t;
647        ll++;
648      }
649      else break;
650    }
651  }
652  else
653  {
654    while ((p=pNext(p))!=NULL)
655    {
656      if ((t=_pTotaldegree(p, r))>max) max=t;
657      ll++;
658    }
659  }
660  *l=ll;
661  return max;
662}
663
664/***************************************************************
665 *
666 * Maximal Exponent business
667 *
668 ***************************************************************/
669
670static inline unsigned long 
671p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r, 
672              unsigned long number_of_exp)
673{
674  const unsigned long bitmask = r->bitmask;
675  unsigned long ml1 = l1 & bitmask;
676  unsigned long ml2 = l2 & bitmask;
677  unsigned long max = (ml1 > ml2 ? ml1 : ml2);
678  unsigned long j = number_of_exp - 1;
679
680  if (j > 0)
681  {
682    unsigned long mask = bitmask << r->BitsPerExp;
683    while (1)
684    {
685      ml1 = l1 & mask;
686      ml2 = l2 & mask;
687      max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
688      j--;
689      if (j == 0) break;
690      mask = mask << r->BitsPerExp;
691    }
692  }
693  return max;
694}
695
696static inline unsigned long
697p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r)
698{
699  return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
700}
701
702poly p_GetMaxExpP(poly p, ring r)
703{
704  p_CheckPolyRing(p, r);
705  if (p == NULL) return p_Init(r);
706  poly max = p_LmInit(p, r);
707  pIter(p);
708  if (p == NULL) return max;
709  int i, offset;
710  unsigned long l_p, l_max;
711  unsigned long divmask = r->divmask;
712 
713  do
714  {
715    offset = r->VarL_Offset[0];
716    l_p = p->exp[offset];
717    l_max = max->exp[offset];
718    // do the divisibility trick to find out whether l has an exponent
719    if (l_p > l_max || 
720        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
721      max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
722
723    for (i=1; i<r->VarL_Size; i++)
724    {
725      offset = r->VarL_Offset[i];
726      l_p = p->exp[offset];
727      l_max = max->exp[offset];
728      // do the divisibility trick to find out whether l has an exponent
729      if (l_p > l_max || 
730          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
731        max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
732    }
733    pIter(p);
734  }
735  while (p != NULL);
736  return max;
737}
738
739unsigned long p_GetMaxExpL(poly p, ring r, unsigned long l_max)
740{
741  unsigned long l_p, divmask = r->divmask;
742  int i;
743 
744  while (p != NULL)
745  {
746    l_p = p->exp[r->VarL_Offset[0]];
747    if (l_p > l_max ||
748        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
749      l_max = p_GetMaxExpL2(l_max, l_p, r);
750    for (i=1; i<r->VarL_Size; i++)
751    {
752      l_p = p->exp[r->VarL_Offset[i]];
753      // do the divisibility trick to find out whether l has an exponent
754      if (l_p > l_max || 
755          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
756        l_max = p_GetMaxExpL2(l_max, l_p, r);
757    }
758    pIter(p);
759  }
760  return l_max;
761}
762
763
764
765   
766/***************************************************************
767 *
768 * Misc things
769 *
770 ***************************************************************/
771// returns TRUE, if all monoms have the same component
772BOOLEAN p_OneComp(poly p, ring r)
773{
774  if(p!=NULL)
775  {
776    long i = p_GetComp(p, r);
777    while (pNext(p)!=NULL)
778    {
779      pIter(p);
780      if(i != p_GetComp(p, r)) return FALSE;
781    }
782  }
783  return TRUE;
784}
785
786/*2
787*test if a monomial /head term is a pure power
788*/
789int p_IsPurePower(const poly p, const ring r)
790{
791  int i,k=0;
792
793  for (i=r->N;i;i--)
794  {
795    if (p_GetExp(p,i, r)!=0)
796    {
797      if(k!=0) return 0;
798      k=i;
799    }
800  }
801  return k;
802}
803
804/*2
805* returns a polynomial representing the integer i
806*/
807poly p_ISet(int i, ring r)
808{
809  poly rc = NULL;
810  if (i!=0)
811  {
812    rc = p_Init(r);
813    pSetCoeff0(rc,r->cf->nInit(i));
814    if (r->cf->nIsZero(p_GetCoeff(rc,r)))
815      p_DeleteLm(&rc,r);
816  }
817  return rc;
818}
819
820/*2
821* returns a polynomial representing the number n
822* destroys n
823*/
824poly p_NSet(number n, ring r)
825{
826  if (r->cf->nIsZero(n))
827  {
828    r->cf->cfDelete(&n, r);
829    return NULL;
830  }
831  else
832  {
833    poly rc = p_Init(r);
834    pSetCoeff0(rc,n);
835    return rc;
836  }
837}
838
Note: See TracBrowser for help on using the repository browser.