source: git/kernel/polys.cc @ 66bff8

spielwiese
Last change on this file since 66bff8 was 66bff8, checked in by Hans Schoenemann <hannes@…>, 13 years ago
code cleanup: pGetMaxPower, pDivByMonom, pCancelPolyByMonom git-svn-id: file:///usr/local/Singular/svn/trunk@13701 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 19.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5
6/*
7* ABSTRACT - all basic methods to manipulate polynomials
8*/
9
10/* includes */
11#include <stdio.h>
12#include <string.h>
13#include <ctype.h>
14#include <kernel/mod2.h>
15#include <kernel/options.h>
16#include <omalloc/omalloc.h>
17#include <kernel/febase.h>
18#include <kernel/numbers.h>
19#include <kernel/polys.h>
20#include <kernel/ring.h>
21#include <kernel/sbuckets.h>
22
23#ifdef HAVE_PLURAL
24#include <kernel/gring.h>
25#include <kernel/sca.h>
26#endif
27
28/* ----------- global variables, set by pSetGlobals --------------------- */
29/* computes length and maximal degree of a POLYnomial */
30pLDegProc pLDeg;
31/* computes the degree of the initial term, used for std */
32pFDegProc pFDeg;
33/* the monomial ordering of the head monomials a and b */
34/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
35
36int pVariables;     // number of variables
37
38/* 1 for polynomial ring, -1 otherwise */
39int     pOrdSgn;
40// it is of type int, not BOOLEAN because it is also in ip
41/* TRUE if the monomial ordering is not compatible with pFDeg */
42BOOLEAN pLexOrder;
43
44/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
45/* the highest monomial below pHEdge */
46poly      ppNoether = NULL;
47
48/* -------------------------------------------------------- */
49/*2
50* change all global variables to fit the description of the new ring
51*/
52
53
54void pSetGlobals(const ring r, BOOLEAN complete)
55{
56  int i;
57  if (ppNoether!=NULL) pDelete(&ppNoether);
58  pVariables = r->N;
59  pOrdSgn = r->OrdSgn;
60  pFDeg=r->pFDeg;
61  pLDeg=r->pLDeg;
62  pLexOrder=r->LexOrder;
63
64  if (complete)
65  {
66    test &= ~ TEST_RINGDEP_OPTS;
67    test |= r->options;
68  }
69}
70
71// resets the pFDeg and pLDeg: if pLDeg is not given, it is
72// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
73// only uses pFDeg (and not pDeg, or pTotalDegree, etc)
74void pSetDegProcs(pFDegProc new_FDeg, pLDegProc new_lDeg)
75{
76  assume(new_FDeg != NULL);
77  pFDeg = new_FDeg;
78  currRing->pFDeg = new_FDeg;
79
80  if (new_lDeg == NULL)
81    new_lDeg = currRing->pLDegOrig;
82
83  pLDeg = new_lDeg;
84  currRing->pLDeg = new_lDeg;
85}
86
87
88// restores pFDeg and pLDeg:
89extern void pRestoreDegProcs(pFDegProc old_FDeg, pLDegProc old_lDeg)
90{
91  assume(old_FDeg != NULL && old_lDeg != NULL);
92  pFDeg = old_FDeg;
93  currRing->pFDeg = old_FDeg;
94  pLDeg = old_lDeg;
95  currRing->pLDeg = old_lDeg;
96}
97
98/*2
99* assumes that the head term of b is a multiple of the head term of a
100* and return the multiplicant *m
101*/
102poly pDivide(poly a, poly b)
103{
104  int i;
105  poly result = pInit();
106
107  for(i=(int)pVariables; i; i--)
108    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
109  pSetComp(result, pGetComp(a) - pGetComp(b));
110  pSetm(result);
111  return result;
112}
113
114#ifdef HAVE_RINGS   //TODO Oliver
115#define pDiv_nn(p, n)              p_Div_nn(p, n, currRing)
116
117poly p_Div_nn(poly p, const number n, const ring r)
118{
119  pAssume(!n_IsZero(n,r));
120  p_Test(p, r);
121
122  poly q = p;
123  while (p != NULL)
124  {
125    number nc = pGetCoeff(p);
126    pSetCoeff0(p, n_Div(nc, n, r));
127    n_Delete(&nc, r);
128    pIter(p);
129  }
130  p_Test(q, r);
131  return q;
132}
133#endif
134
135/*2
136* divides a by the monomial b, ignores monomials which are not divisible
137* assumes that b is not NULL
138*/
139poly pDivideM(poly a, poly b)
140{
141  if (a==NULL) return NULL;
142  poly result=a;
143  poly prev=NULL;
144  int i;
145#ifdef HAVE_RINGS
146  number inv=pGetCoeff(b);
147#else
148  number inv=nInvers(pGetCoeff(b));
149#endif
150
151  while (a!=NULL)
152  {
153    if (pDivisibleBy(b,a))
154    {
155      for(i=(int)pVariables; i; i--)
156         pSubExp(a,i, pGetExp(b,i));
157      pSubComp(a, pGetComp(b));
158      pSetm(a);
159      prev=a;
160      pIter(a);
161    }
162    else
163    {
164      if (prev==NULL)
165      {
166        pLmDelete(&result);
167        a=result;
168      }
169      else
170      {
171        pLmDelete(&pNext(prev));
172        a=pNext(prev);
173      }
174    }
175  }
176#ifdef HAVE_RINGS
177  if (nIsUnit(inv))
178  {
179    inv = nInvers(inv);
180    pMult_nn(result,inv);
181    nDelete(&inv);
182  }
183  else
184  {
185    pDiv_nn(result,inv);
186  }
187#else
188  pMult_nn(result,inv);
189  nDelete(&inv);
190#endif
191  pDelete(&b);
192  return result;
193}
194
195/*2
196* returns the LCM of the head terms of a and b in *m
197*/
198void pLcm(poly a, poly b, poly m)
199{
200  int i;
201  for (i=pVariables; i; i--)
202  {
203    pSetExp(m,i, si_max( pGetExp(a,i), pGetExp(b,i)));
204  }
205  pSetComp(m, si_max(pGetComp(a), pGetComp(b)));
206  /* Don't do a pSetm here, otherwise hres/lres chockes */
207}
208
209/*2
210* convert monomial given as string to poly, e.g. 1x3y5z
211*/
212const char * p_Read(const char *st, poly &rc, const ring r)
213{
214  if (r==NULL) { rc=NULL;return st;}
215  int i,j;
216  rc = p_Init(r);
217  const char *s = r->cf->nRead(st,&(rc->coef));
218  if (s==st)
219  /* i.e. it does not start with a coeff: test if it is a ringvar*/
220  {
221    j = r_IsRingVar(s,r);
222    if (j >= 0)
223    {
224      p_IncrExp(rc,1+j,r);
225      while (*s!='\0') s++;
226      goto done;
227    }
228  }
229  while (*s!='\0')
230  {
231    char ss[2];
232    ss[0] = *s++;
233    ss[1] = '\0';
234    j = r_IsRingVar(ss,r);
235    if (j >= 0)
236    {
237      const char *s_save=s;
238      s = eati(s,&i);
239      if (((unsigned long)i) >  r->bitmask)
240      {
241        // exponent to large: it is not a monomial
242        p_LmDelete(&rc,r);
243        return s_save;
244      }
245      p_AddExp(rc,1+j, (long)i, r);
246    }
247    else
248    {
249      // 1st char of is not a varname
250      p_LmDelete(&rc,r);
251      s--;
252      return s;
253    }
254  }
255done:
256  if (r->cf->nIsZero(pGetCoeff(rc))) p_LmDelete(&rc,r);
257  else
258  {
259#ifdef HAVE_PLURAL
260    // in super-commutative ring
261    // squares of anti-commutative variables are zeroes!
262    if(rIsSCA(r))
263    {
264      const unsigned int iFirstAltVar = scaFirstAltVar(r);
265      const unsigned int iLastAltVar  = scaLastAltVar(r);
266
267      assume(rc != NULL);
268
269      for(unsigned int k = iFirstAltVar; k <= iLastAltVar; k++)
270        if( p_GetExp(rc, k, r) > 1 )
271        {
272          p_LmDelete(&rc, r);
273          goto finish;
274        }
275    }
276#endif
277    p_Setm(rc,r);
278  }
279finish:
280  return s;
281}
282
283BOOLEAN _p_Test(poly p, ring r, int level);
284poly pmInit(const char *st, BOOLEAN &ok)
285{
286  poly p;
287  const char *s=p_Read(st,p,currRing);
288  if (*s!='\0')
289  {
290    if ((s!=st)&&isdigit(st[0]))
291    {
292      errorreported=TRUE;
293    }
294    ok=FALSE;
295    pDelete(&p);
296    return NULL;
297  }
298  #ifdef PDEBUG
299  _p_Test(p,currRing,PDEBUG);
300  #endif
301  ok=!errorreported;
302  return p;
303}
304
305/*2
306*make p homogeneous by multiplying the monomials by powers of x_varnum
307*assume: deg(var(varnum))==1
308*/
309poly pHomogen (poly p, int varnum)
310{
311  pFDegProc deg;
312  if (pLexOrder && (currRing->order[0]==ringorder_lp))
313    deg=p_Totaldegree;
314  else
315    deg=pFDeg;
316
317  poly q=NULL, qn;
318  int  o,ii;
319  sBucket_pt bp;
320
321  if (p!=NULL)
322  {
323    if ((varnum < 1) || (varnum > pVariables))
324    {
325      return NULL;
326    }
327    o=deg(p,currRing);
328    q=pNext(p);
329    while (q != NULL)
330    {
331      ii=deg(q,currRing);
332      if (ii>o) o=ii;
333      pIter(q);
334    }
335    q = pCopy(p);
336    bp = sBucketCreate(currRing);
337    while (q != NULL)
338    {
339      ii = o-deg(q,currRing);
340      if (ii!=0)
341      {
342        pAddExp(q,varnum, (long)ii);
343        pSetm(q);
344      }
345      qn = pNext(q);
346      pNext(q) = NULL;
347      sBucket_Add_p(bp, q, 1);
348      q = qn;
349    }
350    sBucketDestroyAdd(bp, &q, &ii);
351  }
352  return q;
353}
354
355/*4
356*Returns the exponent of the maximal power of the leading monomial of
357*p2 in that of p1
358*/
359/*----------utilities for syzygies--------------*/
360poly pTakeOutComp(poly * p, int k)
361{
362  poly q = *p,qq=NULL,result = NULL;
363
364  if (q==NULL) return NULL;
365  BOOLEAN use_setmcomp=rOrd_SetCompRequiresSetm(currRing);
366  if (pGetComp(q)==k)
367  {
368    result = q;
369    do
370    {
371      pSetComp(q,0);
372      if (use_setmcomp) pSetmComp(q);
373      qq = q;
374      pIter(q);
375    }
376    while ((q!=NULL) && (pGetComp(q)==k));
377    *p = q;
378    pNext(qq) = NULL;
379  }
380  if (q==NULL) return result;
381  if (pGetComp(q) > k)
382  {
383    pSubComp(q,1);
384    if (use_setmcomp) pSetmComp(q);
385  }
386  poly pNext_q;
387  while ((pNext_q=pNext(q))!=NULL)
388  {
389    if (pGetComp(pNext_q)==k)
390    {
391      if (result==NULL)
392      {
393        result = pNext_q;
394        qq = result;
395      }
396      else
397      {
398        pNext(qq) = pNext_q;
399        pIter(qq);
400      }
401      pNext(q) = pNext(pNext_q);
402      pNext(qq) =NULL;
403      pSetComp(qq,0);
404      if (use_setmcomp) pSetmComp(qq);
405    }
406    else
407    {
408      /*pIter(q);*/ q=pNext_q;
409      if (pGetComp(q) > k)
410      {
411        pSubComp(q,1);
412        if (use_setmcomp) pSetmComp(q);
413      }
414    }
415  }
416  return result;
417}
418
419// Splits *p into two polys: *q which consists of all monoms with
420// component == comp and *p of all other monoms *lq == pLength(*q)
421void pTakeOutComp(poly *r_p, long comp, poly *r_q, int *lq)
422{
423  spolyrec pp, qq;
424  poly p, q, p_prev;
425  int l = 0;
426
427#ifdef HAVE_ASSUME
428  int lp = pLength(*r_p);
429#endif
430
431  pNext(&pp) = *r_p;
432  p = *r_p;
433  p_prev = &pp;
434  q = &qq;
435
436  while(p != NULL)
437  {
438    while (pGetComp(p) == comp)
439    {
440      pNext(q) = p;
441      pIter(q);
442      pSetComp(p, 0);
443      pSetmComp(p);
444      pIter(p);
445      l++;
446      if (p == NULL)
447      {
448        pNext(p_prev) = NULL;
449        goto Finish;
450      }
451    }
452    pNext(p_prev) = p;
453    p_prev = p;
454    pIter(p);
455  }
456
457  Finish:
458  pNext(q) = NULL;
459  *r_p = pNext(&pp);
460  *r_q = pNext(&qq);
461  *lq = l;
462#ifdef HAVE_ASSUME
463  assume(pLength(*r_p) + pLength(*r_q) == lp);
464#endif
465  pTest(*r_p);
466  pTest(*r_q);
467}
468
469void pDecrOrdTakeOutComp(poly *r_p, long comp, long order,
470                         poly *r_q, int *lq)
471{
472  spolyrec pp, qq;
473  poly p, q, p_prev;
474  int l = 0;
475
476  pNext(&pp) = *r_p;
477  p = *r_p;
478  p_prev = &pp;
479  q = &qq;
480
481#ifdef HAVE_ASSUME
482  if (p != NULL)
483  {
484    while (pNext(p) != NULL)
485    {
486      assume(pGetOrder(p) >= pGetOrder(pNext(p)));
487      pIter(p);
488    }
489  }
490  p = *r_p;
491#endif
492
493  while (p != NULL && pGetOrder(p) > order) pIter(p);
494
495  while(p != NULL && pGetOrder(p) == order)
496  {
497    while (pGetComp(p) == comp)
498    {
499      pNext(q) = p;
500      pIter(q);
501      pIter(p);
502      pSetComp(p, 0);
503      pSetmComp(p);
504      l++;
505      if (p == NULL || pGetOrder(p) != order)
506      {
507        pNext(p_prev) = p;
508        goto Finish;
509      }
510    }
511    pNext(p_prev) = p;
512    p_prev = p;
513    pIter(p);
514  }
515
516  Finish:
517  pNext(q) = NULL;
518  *r_p = pNext(&pp);
519  *r_q = pNext(&qq);
520  *lq = l;
521}
522
523#if 1
524poly pTakeOutComp1(poly * p, int k)
525{
526  poly q = *p;
527
528  if (q==NULL) return NULL;
529
530  poly qq=NULL,result = NULL;
531
532  if (pGetComp(q)==k)
533  {
534    result = q; /* *p */
535    while ((q!=NULL) && (pGetComp(q)==k))
536    {
537      pSetComp(q,0);
538      pSetmComp(q);
539      qq = q;
540      pIter(q);
541    }
542    *p = q;
543    pNext(qq) = NULL;
544  }
545  if (q==NULL) return result;
546//  if (pGetComp(q) > k) pGetComp(q)--;
547  while (pNext(q)!=NULL)
548  {
549    if (pGetComp(pNext(q))==k)
550    {
551      if (result==NULL)
552      {
553        result = pNext(q);
554        qq = result;
555      }
556      else
557      {
558        pNext(qq) = pNext(q);
559        pIter(qq);
560      }
561      pNext(q) = pNext(pNext(q));
562      pNext(qq) =NULL;
563      pSetComp(qq,0);
564      pSetmComp(qq);
565    }
566    else
567    {
568      pIter(q);
569//      if (pGetComp(q) > k) pGetComp(q)--;
570    }
571  }
572  return result;
573}
574#endif
575
576void pDeleteComp(poly * p,int k)
577{
578  poly q;
579
580  while ((*p!=NULL) && (pGetComp(*p)==k)) pLmDelete(p);
581  if (*p==NULL) return;
582  q = *p;
583  if (pGetComp(q)>k)
584  {
585    pSubComp(q,1);
586    pSetmComp(q);
587  }
588  while (pNext(q)!=NULL)
589  {
590    if (pGetComp(pNext(q))==k)
591      pLmDelete(&(pNext(q)));
592    else
593    {
594      pIter(q);
595      if (pGetComp(q)>k)
596      {
597        pSubComp(q,1);
598        pSetmComp(q);
599      }
600    }
601  }
602}
603/*----------end of utilities for syzygies--------------*/
604
605/*2
606* pair has no common factor ? or is no polynomial
607*/
608BOOLEAN pHasNotCF(poly p1, poly p2)
609{
610
611  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
612    return FALSE;
613  int i = pVariables;
614  loop
615  {
616    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
617    i--;
618    if (i == 0)                                         return TRUE;
619  }
620}
621
622/*2
623*divides p1 by its leading coefficient
624*/
625void pNorm(poly p1)
626{
627#ifdef HAVE_RINGS
628  if (rField_is_Ring(currRing))
629  {
630    Werror("pNorm not possible in the case of coefficient rings.");
631  }
632  else
633#endif
634  if (p1!=NULL)
635  {
636    if (pNext(p1)==NULL)
637    {
638      pSetCoeff(p1,nInit(1));
639      return;
640    }
641    poly h;
642    if (!nIsOne(pGetCoeff(p1)))
643    {
644      number k, c;
645      nNormalize(pGetCoeff(p1));
646      k = pGetCoeff(p1);
647      c = nInit(1);
648      pSetCoeff0(p1,c);
649      h = pNext(p1);
650      while (h!=NULL)
651      {
652        c=nDiv(pGetCoeff(h),k);
653        // no need to normalize: Z/p, R
654        // normalize already in nDiv: Q_a, Z/p_a
655        // remains: Q
656        if (rField_is_Q() && (!nIsOne(c))) nNormalize(c);
657        pSetCoeff(h,c);
658        pIter(h);
659      }
660      nDelete(&k);
661    }
662    else
663    {
664      if (nNormalize != nDummy2)
665      {
666        h = pNext(p1);
667        while (h!=NULL)
668        {
669          nNormalize(pGetCoeff(h));
670          pIter(h);
671        }
672      }
673    }
674  }
675}
676
677/*2
678*normalize all coefficients
679*/
680void p_Normalize(poly p,const ring r)
681{
682  if (rField_has_simple_inverse(r)) return; /* Z/p, GF(p,n), R, long R/C */
683  while (p!=NULL)
684  {
685#ifdef LDEBUG
686    if (currRing==r) {nTest(pGetCoeff(p));}
687#endif
688    n_Normalize(pGetCoeff(p),r);
689    pIter(p);
690  }
691}
692
693// splits p into polys with Exp(n) == 0 and Exp(n) != 0
694// Poly with Exp(n) != 0 is reversed
695static void pSplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero)
696{
697  if (p == NULL)
698  {
699    *non_zero = NULL;
700    *zero = NULL;
701    return;
702  }
703  spolyrec sz;
704  poly z, n_z, next;
705  z = &sz;
706  n_z = NULL;
707
708  while(p != NULL)
709  {
710    next = pNext(p);
711    if (pGetExp(p, n) == 0)
712    {
713      pNext(z) = p;
714      pIter(z);
715    }
716    else
717    {
718      pNext(p) = n_z;
719      n_z = p;
720    }
721    p = next;
722  }
723  pNext(z) = NULL;
724  *zero = pNext(&sz);
725  *non_zero = n_z;
726  return;
727}
728
729/*3
730* substitute the n-th variable by 1 in p
731* destroy p
732*/
733static poly pSubst1 (poly p,int n)
734{
735  poly qq=NULL, result = NULL;
736  poly zero=NULL, non_zero=NULL;
737
738  // reverse, so that add is likely to be linear
739  pSplitAndReversePoly(p, n, &non_zero, &zero);
740
741  while (non_zero != NULL)
742  {
743    assume(pGetExp(non_zero, n) != 0);
744    qq = non_zero;
745    pIter(non_zero);
746    qq->next = NULL;
747    pSetExp(qq,n,0);
748    pSetm(qq);
749    result = pAdd(result,qq);
750  }
751  p = pAdd(result, zero);
752  pTest(p);
753  return p;
754}
755
756/*3
757* substitute the n-th variable by number e in p
758* destroy p
759*/
760static poly pSubst2 (poly p,int n, number e)
761{
762  assume( ! nIsZero(e) );
763  poly qq,result = NULL;
764  number nn, nm;
765  poly zero, non_zero;
766
767  // reverse, so that add is likely to be linear
768  pSplitAndReversePoly(p, n, &non_zero, &zero);
769
770  while (non_zero != NULL)
771  {
772    assume(pGetExp(non_zero, n) != 0);
773    qq = non_zero;
774    pIter(non_zero);
775    qq->next = NULL;
776    nPower(e, pGetExp(qq, n), &nn);
777    nm = nMult(nn, pGetCoeff(qq));
778#ifdef HAVE_RINGS
779    if (nIsZero(nm))
780    {
781      pLmFree(&qq);
782      nDelete(&nm);
783    }
784    else
785#endif
786    {
787      pSetCoeff(qq, nm);
788      pSetExp(qq, n, 0);
789      pSetm(qq);
790      result = pAdd(result,qq);
791    }
792    nDelete(&nn);
793  }
794  p = pAdd(result, zero);
795  pTest(p);
796  return p;
797}
798
799
800/* delete monoms whose n-th exponent is different from zero */
801poly pSubst0(poly p, int n)
802{
803  spolyrec res;
804  poly h = &res;
805  pNext(h) = p;
806
807  while (pNext(h)!=NULL)
808  {
809    if (pGetExp(pNext(h),n)!=0)
810    {
811      pLmDelete(&pNext(h));
812    }
813    else
814    {
815      pIter(h);
816    }
817  }
818  pTest(pNext(&res));
819  return pNext(&res);
820}
821
822/*2
823* substitute the n-th variable by e in p
824* destroy p
825*/
826poly pSubst(poly p, int n, poly e)
827{
828  if (e == NULL) return pSubst0(p, n);
829
830  if (pIsConstant(e))
831  {
832    if (nIsOne(pGetCoeff(e))) return pSubst1(p,n);
833    else return pSubst2(p, n, pGetCoeff(e));
834  }
835
836#ifdef HAVE_PLURAL
837  if (rIsPluralRing(currRing))
838  {
839    return nc_pSubst(p,n,e);
840  }
841#endif
842
843  int exponent,i;
844  poly h, res, m;
845  int *me,*ee;
846  number nu,nu1;
847
848  me=(int *)omAlloc((pVariables+1)*sizeof(int));
849  ee=(int *)omAlloc((pVariables+1)*sizeof(int));
850  if (e!=NULL) pGetExpV(e,ee);
851  res=NULL;
852  h=p;
853  while (h!=NULL)
854  {
855    if ((e!=NULL) || (pGetExp(h,n)==0))
856    {
857      m=pHead(h);
858      pGetExpV(m,me);
859      exponent=me[n];
860      me[n]=0;
861      for(i=pVariables;i>0;i--)
862        me[i]+=exponent*ee[i];
863      pSetExpV(m,me);
864      if (e!=NULL)
865      {
866        nPower(pGetCoeff(e),exponent,&nu);
867        nu1=nMult(pGetCoeff(m),nu);
868        nDelete(&nu);
869        pSetCoeff(m,nu1);
870      }
871      res=pAdd(res,m);
872    }
873    pLmDelete(&h);
874  }
875  omFreeSize((ADDRESS)me,(pVariables+1)*sizeof(int));
876  omFreeSize((ADDRESS)ee,(pVariables+1)*sizeof(int));
877  return res;
878}
879
880/* Returns TRUE if
881     * LM(p) | LM(lcm)
882     * LC(p) | LC(lcm) only if ring
883     * Exists i, j:
884         * LE(p, i)  != LE(lcm, i)
885         * LE(p1, i) != LE(lcm, i)   ==> LCM(p1, p) != lcm
886         * LE(p, j)  != LE(lcm, j)
887         * LE(p2, j) != LE(lcm, j)   ==> LCM(p2, p) != lcm
888*/
889BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
890{
891  int k, j;
892
893  if (lcm==NULL) return FALSE;
894
895  for (j=pVariables; j; j--)
896    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
897  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
898  for (j=pVariables; j; j--)
899  {
900    if (pGetExp(p1,j)!=pGetExp(lcm,j))
901    {
902      if (pGetExp(p,j)!=pGetExp(lcm,j))
903      {
904        for (k=pVariables; k>j; k--)
905        {
906          if ((pGetExp(p,k)!=pGetExp(lcm,k))
907          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
908            return TRUE;
909        }
910        for (k=j-1; k; k--)
911        {
912          if ((pGetExp(p,k)!=pGetExp(lcm,k))
913          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
914            return TRUE;
915        }
916        return FALSE;
917      }
918    }
919    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
920    {
921      if (pGetExp(p,j)!=pGetExp(lcm,j))
922      {
923        for (k=pVariables; k>j; k--)
924        {
925          if ((pGetExp(p,k)!=pGetExp(lcm,k))
926          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
927            return TRUE;
928        }
929        for (k=j-1; k!=0 ; k--)
930        {
931          if ((pGetExp(p,k)!=pGetExp(lcm,k))
932          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
933            return TRUE;
934        }
935        return FALSE;
936      }
937    }
938  }
939  return FALSE;
940}
941#ifdef HAVE_RATGRING
942BOOLEAN pCompareChainPart (poly p,poly p1,poly p2,poly lcm)
943{
944  int k, j;
945
946  if (lcm==NULL) return FALSE;
947
948  for (j=currRing->real_var_end; j>=currRing->real_var_start; j--)
949    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
950  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
951  for (j=currRing->real_var_end; j>=currRing->real_var_start; j--)
952  {
953    if (pGetExp(p1,j)!=pGetExp(lcm,j))
954    {
955      if (pGetExp(p,j)!=pGetExp(lcm,j))
956      {
957        for (k=pVariables; k>j; k--)
958        for (k=currRing->real_var_end; k>j; k--)
959        {
960          if ((pGetExp(p,k)!=pGetExp(lcm,k))
961          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
962            return TRUE;
963        }
964        for (k=j-1; k>=currRing->real_var_start; k--)
965        {
966          if ((pGetExp(p,k)!=pGetExp(lcm,k))
967          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
968            return TRUE;
969        }
970        return FALSE;
971      }
972    }
973    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
974    {
975      if (pGetExp(p,j)!=pGetExp(lcm,j))
976      {
977        for (k=currRing->real_var_end; k>j; k--)
978        {
979          if ((pGetExp(p,k)!=pGetExp(lcm,k))
980          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
981            return TRUE;
982        }
983        for (k=j-1; k>=currRing->real_var_start; k--)
984        {
985          if ((pGetExp(p,k)!=pGetExp(lcm,k))
986          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
987            return TRUE;
988        }
989        return FALSE;
990      }
991    }
992  }
993  return FALSE;
994}
995#endif
996
997int pSize(poly p)
998{
999  int count = 0;
1000  while ( p != NULL )
1001  {
1002    count+= nSize( pGetCoeff( p ) );
1003    pIter( p );
1004  }
1005  return count;
1006}
1007
1008/*2
1009* returns the length of a (numbers of monomials)
1010* respect syzComp
1011*/
1012poly pLast(poly a, int &l)
1013{
1014  if (a == NULL)
1015  {
1016    l = 0;
1017    return NULL;
1018  }
1019  l = 1;
1020  if (! rIsSyzIndexRing(currRing))
1021  {
1022    while (pNext(a)!=NULL)
1023    {
1024      pIter(a);
1025      l++;
1026    }
1027  }
1028  else
1029  {
1030    int curr_limit = rGetCurrSyzLimit(currRing);
1031    poly pp = a;
1032    while ((a=pNext(a))!=NULL)
1033    {
1034      if (pGetComp(a)<=curr_limit/*syzComp*/)
1035        l++;
1036      else break;
1037      pp = a;
1038    }
1039    a=pp;
1040  }
1041  return a;
1042}
1043
Note: See TracBrowser for help on using the repository browser.