source: git/kernel/polys.cc @ b547dc

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