source: git/polys/monomials/p_polys.cc @ 1b816a3

spielwiese
Last change on this file since 1b816a3 was 1b816a3, checked in by Hans Schoenemann <hannes@…>, 13 years ago
p_Divide, p_DivideM
  • Property mode set to 100644
File size: 25.6 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$
10 *******************************************************************/
11
12
13#include <auxialiary.h>
14
15#include "ring.h"
16#include "p_polys.h"
17#include "ring.h"
18#include "ideals.h"
19#include "int64vec.h"
20#ifndef NDEBUG
21#include <kernel/febase.h>
22#endif
23
24/***************************************************************
25 *
26 * Completing what needs to be set for the monomial
27 *
28 ***************************************************************/
29// this is special for the syz stuff
30static int* _components = NULL;
31static long* _componentsShifted = NULL;
32static int _componentsExternal = 0;
33
34BOOLEAN pSetm_error=0;
35
36#ifndef NDEBUG
37# define MYTEST 0
38#else /* ifndef NDEBUG */
39# define MYTEST 0
40#endif /* ifndef NDEBUG */
41
42void p_Setm_General(poly p, const ring r)
43{
44  p_LmCheckPolyRing(p, r);
45  int pos=0;
46  if (r->typ!=NULL)
47  {
48    loop
49    {
50      long ord=0;
51      sro_ord* o=&(r->typ[pos]);
52      switch(o->ord_typ)
53      {
54        case ro_dp:
55        {
56          int a,e;
57          a=o->data.dp.start;
58          e=o->data.dp.end;
59          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r);
60          p->exp[o->data.dp.place]=ord;
61          break;
62        }
63        case ro_wp_neg:
64          ord=POLY_NEGWEIGHT_OFFSET;
65          // no break;
66        case ro_wp:
67        {
68          int a,e;
69          a=o->data.wp.start;
70          e=o->data.wp.end;
71          int *w=o->data.wp.weights;
72#if 1
73          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r)*w[i-a];
74#else
75          long ai;
76          int ei,wi;
77          for(int i=a;i<=e;i++)
78          {
79             ei=p_GetExp(p,i,r);
80             wi=w[i-a];
81             ai=ei*wi;
82             if (ai/ei!=wi) pSetm_error=TRUE;
83             ord+=ai;
84             if (ord<ai) pSetm_error=TRUE;
85          }
86#endif
87          p->exp[o->data.wp.place]=ord;
88          break;
89        }
90      case ro_wp64:
91        {
92          int64 ord=0;
93          int a,e;
94          a=o->data.wp64.start;
95          e=o->data.wp64.end;
96          int64 *w=o->data.wp64.weights64;
97          int64 ei,wi,ai;
98          for(int i=a;i<=e;i++)
99          {
100            //Print("exp %d w %d \n",p_GetExp(p,i,r),(int)w[i-a]);
101            //ord+=((int64)p_GetExp(p,i,r))*w[i-a];
102            ei=(int64)p_GetExp(p,i,r);
103            wi=w[i-a];
104            ai=ei*wi;
105            if(ei!=0 && ai/ei!=wi)
106            {
107              pSetm_error=TRUE;
108              #if SIZEOF_LONG == 4
109              Print("ai %lld, wi %lld\n",ai,wi);
110              #else
111              Print("ai %ld, wi %ld\n",ai,wi);
112              #endif
113            }
114            ord+=ai;
115            if (ord<ai)
116            {
117              pSetm_error=TRUE;
118              #if SIZEOF_LONG == 4
119              Print("ai %lld, ord %lld\n",ai,ord);
120              #else
121              Print("ai %ld, ord %ld\n",ai,ord);
122              #endif
123            }
124          }
125          int64 mask=(int64)0x7fffffff;
126          long a_0=(long)(ord&mask); //2^31
127          long a_1=(long)(ord >>31 ); /*(ord/(mask+1));*/
128
129          //Print("mask: %x,  ord: %d,  a_0: %d,  a_1: %d\n"
130          //,(int)mask,(int)ord,(int)a_0,(int)a_1);
131                    //Print("mask: %d",mask);
132
133          p->exp[o->data.wp64.place]=a_1;
134          p->exp[o->data.wp64.place+1]=a_0;
135//            if(p_Setm_error) Print("***************************\n
136//                                    ***************************\n
137//                                    **WARNING: overflow error**\n
138//                                    ***************************\n
139//                                    ***************************\n");
140          break;
141        }
142        case ro_cp:
143        {
144          int a,e;
145          a=o->data.cp.start;
146          e=o->data.cp.end;
147          int pl=o->data.cp.place;
148          for(int i=a;i<=e;i++) { p->exp[pl]=p_GetExp(p,i,r); pl++; }
149          break;
150        }
151        case ro_syzcomp:
152        {
153          int c=p_GetComp(p,r);
154          long sc = c;
155          int* Components = (_componentsExternal ? _components :
156                             o->data.syzcomp.Components);
157          long* ShiftedComponents = (_componentsExternal ? _componentsShifted:
158                                     o->data.syzcomp.ShiftedComponents);
159          if (ShiftedComponents != NULL)
160          {
161            assume(Components != NULL);
162            assume(c == 0 || Components[c] != 0);
163            sc = ShiftedComponents[Components[c]];
164            assume(c == 0 || sc != 0);
165          }
166          p->exp[o->data.syzcomp.place]=sc;
167          break;
168        }
169        case ro_syz:
170        {
171          const unsigned long c = p_GetComp(p, r);
172          const short place = o->data.syz.place;
173          const int limit = o->data.syz.limit;
174         
175          if (c > limit)
176            p->exp[place] = o->data.syz.curr_index;
177          else if (c > 0)
178          {
179            assume( (1 <= c) && (c <= limit) );
180            p->exp[place]= o->data.syz.syz_index[c];
181          }
182          else
183          {
184            assume(c == 0);
185            p->exp[place]= 0;
186          }
187          break;
188        }
189        // Prefix for Induced Schreyer ordering
190        case ro_isTemp: // Do nothing?? (to be removed into suffix later on...?)
191        {
192          assume(p != NULL);
193
194#ifndef NDEBUG
195#if MYTEST
196          Print("p_Setm_General: isTemp ord: pos: %d, p: ", pos);  p_DebugPrint(p, r, r, 1);
197#endif
198#endif
199          int c = p_GetComp(p, r);
200
201          assume( c >= 0 );
202
203          // Let's simulate case ro_syz above....
204          // Should accumulate (by Suffix) and be a level indicator
205          const int* const pVarOffset = o->data.isTemp.pVarOffset;
206
207          assume( pVarOffset != NULL );
208
209          // TODO: Can this be done in the suffix???
210          for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
211          {
212            const int vo = pVarOffset[i];
213            if( vo != -1) // TODO: optimize: can be done once!
214            {
215              // Hans! Please don't break it again! p_SetExp(p, ..., r, vo) is correct:
216              p_SetExp(p, p_GetExp(p, i, r), r, vo); // copy put them verbatim
217              // Hans! Please don't break it again! p_GetExp(p, r, vo) is correct:
218              assume( p_GetExp(p, r, vo) == p_GetExp(p, i, r) ); // copy put them verbatim
219            }
220          }
221           
222#ifndef NDEBUG
223          for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
224          {
225            const int vo = pVarOffset[i];
226            if( vo != -1) // TODO: optimize: can be done once!
227            {
228              // Hans! Please don't break it again! p_GetExp(p, r, vo) is correct:
229              assume( p_GetExp(p, r, vo) == p_GetExp(p, i, r) ); // copy put them verbatim
230            }
231          }
232#if MYTEST
233//          if( p->exp[o->data.isTemp.start] > 0 )
234//          {
235//            PrintS("Initial Value: "); p_DebugPrint(p, r, r, 1);
236//          }
237#endif
238#endif
239          break;
240        }
241
242        // Suffix for Induced Schreyer ordering
243        case ro_is:
244        {
245#ifndef NDEBUG
246#if MYTEST
247          Print("p_Setm_General: ro_is ord: pos: %d, p: ", pos);  p_DebugPrint(p, r, r, 1);
248#endif
249#endif
250
251          assume(p != NULL);
252
253          int c = p_GetComp(p, r);
254
255          assume( c >= 0 );
256          const ideal F = o->data.is.F;
257          const int limit = o->data.is.limit;
258
259          if( F != NULL && c > limit )
260          {
261#ifndef NDEBUG
262#if MYTEST
263            Print("p_Setm_General: ro_is : in rSetm: pos: %d, c: %d >  limit: %d\n", c, pos, limit); // p_DebugPrint(p, r, r, 1);
264#endif
265#endif
266
267            c -= limit;
268            assume( c > 0 );
269            c--;
270
271            assume( c < IDELEMS(F) ); // What about others???
272
273            const poly pp = F->m[c]; // get reference monomial!!!
274
275#ifndef NDEBUG
276#if MYTEST
277            Print("Respective F[c - %d: %d] pp: ", limit, c); 
278            p_DebugPrint(pp, r, r, 1);
279#endif
280#endif
281
282
283            assume(pp != NULL);
284            if(pp == NULL) break;
285
286            const int start = o->data.is.start;
287            const int end = o->data.is.end;
288
289            assume(start <= end);
290             
291//          const int limit = o->data.is.limit;
292          assume( limit >= 0 );
293
294//        const int st = o->data.isTemp.start;       
295
296          if( c > limit )
297            p->exp[start] = 1;
298//          else
299//            p->exp[start] = 0;
300
301             
302#ifndef NDEBUG
303            Print("p_Setm_General: is(-Temp-) :: c: %d, limit: %d, [st:%d] ===>>> %ld\n", c, limit, start, p->exp[start]);
304#endif       
305   
306
307            for( int i = start; i <= end; i++) // v[0] may be here...
308              p->exp[i] += pp->exp[i]; // !!!!!!!! ADD corresponding LT(F)
309
310       
311
312             
313#ifndef NDEBUG
314            const int* const pVarOffset = o->data.is.pVarOffset;
315
316            assume( pVarOffset != NULL );
317
318            for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
319            {
320              const int vo = pVarOffset[i];
321              if( vo != -1) // TODO: optimize: can be done once!
322                // Hans! Please don't break it again! p_GetExp(p/pp, r, vo) is correct:
323                assume( p_GetExp(p, r, vo) == (p_GetExp(p, i, r) + p_GetExp(pp, r, vo)) );
324            }
325            // TODO: how to check this for computed values???
326#endif
327          } else
328          {
329            const int* const pVarOffset = o->data.is.pVarOffset;
330
331            // What about v[0] - component: it will be added later by
332            // suffix!!!
333            // TODO: Test it!
334            const int vo = pVarOffset[0];
335            if( vo != -1 )
336              p->exp[vo] = c; // initial component v[0]!
337
338#ifndef NDEBUG
339#if MYTEST
340            Print("p_Setm_General: ro_is :: c: %d <= limit: %d, vo: %d, exp: %d\n", c, limit, vo, p->exp[vo]);
341            p_DebugPrint(p, r, r, 1);
342#endif       
343#endif       
344          }
345           
346
347          break;
348        }
349        default:
350          dReportError("wrong ord in rSetm:%d\n",o->ord_typ);
351          return;
352      }
353      pos++;
354      if (pos == r->OrdSize) return;
355    }
356  }
357}
358
359void p_Setm_Syz(poly p, ring r, int* Components, long* ShiftedComponents)
360{
361  _components = Components;
362  _componentsShifted = ShiftedComponents;
363  _componentsExternal = 1;
364  p_Setm_General(p, r);
365  _componentsExternal = 0;
366}
367
368// dummy for lp, ls, etc
369void p_Setm_Dummy(poly p, const ring r)
370{
371  p_LmCheckPolyRing(p, r);
372}
373
374// for dp, Dp, ds, etc
375void p_Setm_TotalDegree(poly p, const ring r)
376{
377  p_LmCheckPolyRing(p, r);
378  p->exp[r->pOrdIndex] = p_Totaldegree(p, r);
379}
380
381// for wp, Wp, ws, etc
382void p_Setm_WFirstTotalDegree(poly p, const ring r)
383{
384  p_LmCheckPolyRing(p, r);
385  p->exp[r->pOrdIndex] = pWFirstTotalDegree(p, r);
386}
387
388p_SetmProc p_GetSetmProc(ring r)
389{
390  // covers lp, rp, ls,
391  if (r->typ == NULL) return p_Setm_Dummy;
392
393  if (r->OrdSize == 1)
394  {
395    if (r->typ[0].ord_typ == ro_dp &&
396        r->typ[0].data.dp.start == 1 &&
397        r->typ[0].data.dp.end == r->N &&
398        r->typ[0].data.dp.place == r->pOrdIndex)
399      return p_Setm_TotalDegree;
400    if (r->typ[0].ord_typ == ro_wp &&
401        r->typ[0].data.wp.start == 1 &&
402        r->typ[0].data.wp.end == r->N &&
403        r->typ[0].data.wp.place == r->pOrdIndex &&
404        r->typ[0].data.wp.weights == r->firstwv)
405      return p_Setm_WFirstTotalDegree;
406  }
407  return p_Setm_General;
408}
409
410
411/* -------------------------------------------------------------------*/
412/* several possibilities for pFDeg: the degree of the head term       */
413
414/* comptible with ordering */
415long pDeg(poly a, const ring r)
416{
417  p_LmCheckPolyRing(a, r);
418  return p_GetOrder(a, r);
419}
420
421// pWTotalDegree for weighted orderings
422// whose first block covers all variables
423static inline long _pWFirstTotalDegree(poly p, const ring r)
424{
425  int i;
426  long sum = 0;
427
428  for (i=1; i<= r->firstBlockEnds; i++)
429  {
430    sum += p_GetExp(p, i, r)*r->firstwv[i-1];
431  }
432  return sum;
433}
434
435long pWFirstTotalDegree(poly p, const ring r)
436{
437  return (long) _pWFirstTotalDegree(p, r);
438}
439
440/*2
441* compute the degree of the leading monomial of p
442* with respect to weigths from the ordering
443* the ordering is not compatible with degree so do not use p->Order
444*/
445long pWTotaldegree(poly p, const ring r)
446{
447  p_LmCheckPolyRing(p, r);
448  int i, k;
449  long j =0;
450
451  // iterate through each block:
452  for (i=0;r->order[i]!=0;i++)
453  {
454    int b0=r->block0[i];
455    int b1=r->block1[i];
456    switch(r->order[i])
457    {
458      case ringorder_M:
459        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
460        { // in jedem block:
461          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - b0 /*r->block0[i]*/]*r->OrdSgn;
462        }
463        break;
464      case ringorder_wp:
465      case ringorder_ws:
466      case ringorder_Wp:
467      case ringorder_Ws:
468        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
469        { // in jedem block:
470          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - b0 /*r->block0[i]*/];
471        }
472        break;
473      case ringorder_lp:
474      case ringorder_ls:
475      case ringorder_rs:
476      case ringorder_dp:
477      case ringorder_ds:
478      case ringorder_Dp:
479      case ringorder_Ds:
480      case ringorder_rp:
481        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
482        {
483          j+= p_GetExp(p,k,r);
484        }
485        break;
486      case ringorder_a64:
487        {
488          int64* w=(int64*)r->wvhdl[i];
489          for (k=0;k<=(b1 /*r->block1[i]*/ - b0 /*r->block0[i]*/);k++)
490          {
491            //there should be added a line which checks if w[k]>2^31
492            j+= p_GetExp(p,k+1, r)*(long)w[k];
493          }
494          //break;
495          return j;
496        }
497      case ringorder_c:
498      case ringorder_C:
499      case ringorder_S:
500      case ringorder_s:
501      case ringorder_IS:
502      case ringorder_aa:
503        break;
504      case ringorder_a:
505        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
506        { // only one line
507          j+= p_GetExp(p,k, r)*r->wvhdl[i][ k- b0 /*r->block0[i]*/];
508        }
509        //break;
510        return j;
511
512#ifndef NDEBUG
513      default:
514        Print("missing order %d in pWTotaldegree\n",r->order[i]);
515        break;
516#endif
517    }
518  }
519  return  j;
520}
521
522int pWeight(int i, const ring r)
523{
524  if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
525  {
526    return 1;
527  }
528  return r->firstwv[i-1];
529}
530
531long pWDegree(poly p, const ring r)
532{
533  if (r->firstwv==NULL) return p_Totaldegree(p, r);
534  p_LmCheckPolyRing(p, r);
535  int i;
536  long j =0;
537
538  for(i=1;i<=r->firstBlockEnds;i++)
539    j+=p_GetExp(p, i, r)*r->firstwv[i-1];
540
541  for (;i<=r->N;i++)
542    j+=p_GetExp(p,i, r)*pWeight(i, r);
543
544  return j;
545}
546
547
548/* ---------------------------------------------------------------------*/
549/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
550/*  compute in l also the pLength of p                                   */
551
552/*2
553* compute the length of a polynomial (in l)
554* and the degree of the monomial with maximal degree: the last one
555*/
556long pLDeg0(poly p,int *l, const ring r)
557{
558  p_CheckPolyRing(p, r);
559  long k= p_GetComp(p, r);
560  int ll=1;
561
562  if (k > 0)
563  {
564    while ((pNext(p)!=NULL) && (p_GetComp(pNext(p), r)==k))
565    {
566      pIter(p);
567      ll++;
568    }
569  }
570  else
571  {
572     while (pNext(p)!=NULL)
573     {
574       pIter(p);
575       ll++;
576     }
577  }
578  *l=ll;
579  return r->pFDeg(p, r);
580}
581
582/*2
583* compute the length of a polynomial (in l)
584* and the degree of the monomial with maximal degree: the last one
585* but search in all components before syzcomp
586*/
587long pLDeg0c(poly p,int *l, const ring r)
588{
589  assume(p!=NULL);
590#ifdef PDEBUG
591  _p_Test(p,r,PDEBUG);
592#endif
593  p_CheckPolyRing(p, r);
594  long o;
595  int ll=1;
596
597  if (! rIsSyzIndexRing(r))
598  {
599    while (pNext(p) != NULL)
600    {
601      pIter(p);
602      ll++;
603    }
604    o = r->pFDeg(p, r);
605  }
606  else
607  {
608    int curr_limit = rGetCurrSyzLimit(r);
609    poly pp = p;
610    while ((p=pNext(p))!=NULL)
611    {
612      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
613        ll++;
614      else break;
615      pp = p;
616    }
617#ifdef PDEBUG
618    _p_Test(pp,r,PDEBUG);
619#endif
620    o = r->pFDeg(pp, r);
621  }
622  *l=ll;
623  return o;
624}
625
626/*2
627* compute the length of a polynomial (in l)
628* and the degree of the monomial with maximal degree: the first one
629* this works for the polynomial case with degree orderings
630* (both c,dp and dp,c)
631*/
632long pLDegb(poly p,int *l, const ring r)
633{
634  p_CheckPolyRing(p, r);
635  long k= p_GetComp(p, r);
636  long o = r->pFDeg(p, r);
637  int ll=1;
638
639  if (k != 0)
640  {
641    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
642    {
643      ll++;
644    }
645  }
646  else
647  {
648    while ((p=pNext(p)) !=NULL)
649    {
650      ll++;
651    }
652  }
653  *l=ll;
654  return o;
655}
656
657/*2
658* compute the length of a polynomial (in l)
659* and the degree of the monomial with maximal degree:
660* this is NOT the last one, we have to look for it
661*/
662long pLDeg1(poly p,int *l, const ring r)
663{
664  p_CheckPolyRing(p, r);
665  long k= p_GetComp(p, r);
666  int ll=1;
667  long  t,max;
668
669  max=r->pFDeg(p, r);
670  if (k > 0)
671  {
672    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
673    {
674      t=r->pFDeg(p, r);
675      if (t>max) max=t;
676      ll++;
677    }
678  }
679  else
680  {
681    while ((p=pNext(p))!=NULL)
682    {
683      t=r->pFDeg(p, r);
684      if (t>max) max=t;
685      ll++;
686    }
687  }
688  *l=ll;
689  return max;
690}
691
692/*2
693* compute the length of a polynomial (in l)
694* and the degree of the monomial with maximal degree:
695* this is NOT the last one, we have to look for it
696* in all components
697*/
698long pLDeg1c(poly p,int *l, const ring r)
699{
700  p_CheckPolyRing(p, r);
701  int ll=1;
702  long  t,max;
703
704  max=r->pFDeg(p, r);
705  if (rIsSyzIndexRing(r))
706  {
707    long limit = rGetCurrSyzLimit(r);
708    while ((p=pNext(p))!=NULL)
709    {
710      if (p_GetComp(p, r)<=limit)
711      {
712        if ((t=r->pFDeg(p, r))>max) max=t;
713        ll++;
714      }
715      else break;
716    }
717  }
718  else
719  {
720    while ((p=pNext(p))!=NULL)
721    {
722      if ((t=r->pFDeg(p, r))>max) max=t;
723      ll++;
724    }
725  }
726  *l=ll;
727  return max;
728}
729
730// like pLDeg1, only pFDeg == pDeg
731long pLDeg1_Deg(poly p,int *l, const ring r)
732{
733  assume(r->pFDeg == pDeg);
734  p_CheckPolyRing(p, r);
735  long k= p_GetComp(p, r);
736  int ll=1;
737  long  t,max;
738
739  max=p_GetOrder(p, r);
740  if (k > 0)
741  {
742    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
743    {
744      t=p_GetOrder(p, r);
745      if (t>max) max=t;
746      ll++;
747    }
748  }
749  else
750  {
751    while ((p=pNext(p))!=NULL)
752    {
753      t=p_GetOrder(p, r);
754      if (t>max) max=t;
755      ll++;
756    }
757  }
758  *l=ll;
759  return max;
760}
761
762long pLDeg1c_Deg(poly p,int *l, const ring r)
763{
764  assume(r->pFDeg == pDeg);
765  p_CheckPolyRing(p, r);
766  int ll=1;
767  long  t,max;
768
769  max=p_GetOrder(p, r);
770  if (rIsSyzIndexRing(r))
771  {
772    long limit = rGetCurrSyzLimit(r);
773    while ((p=pNext(p))!=NULL)
774    {
775      if (p_GetComp(p, r)<=limit)
776      {
777        if ((t=p_GetOrder(p, r))>max) max=t;
778        ll++;
779      }
780      else break;
781    }
782  }
783  else
784  {
785    while ((p=pNext(p))!=NULL)
786    {
787      if ((t=p_GetOrder(p, r))>max) max=t;
788      ll++;
789    }
790  }
791  *l=ll;
792  return max;
793}
794
795// like pLDeg1, only pFDeg == pTotoalDegree
796long pLDeg1_Totaldegree(poly p,int *l, const ring r)
797{
798  p_CheckPolyRing(p, r);
799  long k= p_GetComp(p, r);
800  int ll=1;
801  long  t,max;
802
803  max=p_Totaldegree(p, r);
804  if (k > 0)
805  {
806    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
807    {
808      t=p_Totaldegree(p, r);
809      if (t>max) max=t;
810      ll++;
811    }
812  }
813  else
814  {
815    while ((p=pNext(p))!=NULL)
816    {
817      t=p_Totaldegree(p, r);
818      if (t>max) max=t;
819      ll++;
820    }
821  }
822  *l=ll;
823  return max;
824}
825
826long pLDeg1c_Totaldegree(poly p,int *l, const ring r)
827{
828  p_CheckPolyRing(p, r);
829  int ll=1;
830  long  t,max;
831
832  max=p_Totaldegree(p, r);
833  if (rIsSyzIndexRing(r))
834  {
835    long limit = rGetCurrSyzLimit(r);
836    while ((p=pNext(p))!=NULL)
837    {
838      if (p_GetComp(p, r)<=limit)
839      {
840        if ((t=p_Totaldegree(p, r))>max) max=t;
841        ll++;
842      }
843      else break;
844    }
845  }
846  else
847  {
848    while ((p=pNext(p))!=NULL)
849    {
850      if ((t=p_Totaldegree(p, r))>max) max=t;
851      ll++;
852    }
853  }
854  *l=ll;
855  return max;
856}
857
858// like pLDeg1, only pFDeg == pWFirstTotalDegree
859long pLDeg1_WFirstTotalDegree(poly p,int *l, const ring r)
860{
861  p_CheckPolyRing(p, r);
862  long k= p_GetComp(p, r);
863  int ll=1;
864  long  t,max;
865
866  max=_pWFirstTotalDegree(p, r);
867  if (k > 0)
868  {
869    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
870    {
871      t=_pWFirstTotalDegree(p, r);
872      if (t>max) max=t;
873      ll++;
874    }
875  }
876  else
877  {
878    while ((p=pNext(p))!=NULL)
879    {
880      t=_pWFirstTotalDegree(p, r);
881      if (t>max) max=t;
882      ll++;
883    }
884  }
885  *l=ll;
886  return max;
887}
888
889long pLDeg1c_WFirstTotalDegree(poly p,int *l, const ring r)
890{
891  p_CheckPolyRing(p, r);
892  int ll=1;
893  long  t,max;
894
895  max=_pWFirstTotalDegree(p, r);
896  if (rIsSyzIndexRing(r))
897  {
898    long limit = rGetCurrSyzLimit(r);
899    while ((p=pNext(p))!=NULL)
900    {
901      if (p_GetComp(p, r)<=limit)
902      {
903        if ((t=p_Totaldegree(p, r))>max) max=t;
904        ll++;
905      }
906      else break;
907    }
908  }
909  else
910  {
911    while ((p=pNext(p))!=NULL)
912    {
913      if ((t=p_Totaldegree(p, r))>max) max=t;
914      ll++;
915    }
916  }
917  *l=ll;
918  return max;
919}
920
921/***************************************************************
922 *
923 * Maximal Exponent business
924 *
925 ***************************************************************/
926
927static inline unsigned long
928p_GetMaxExpL2(unsigned long l1, unsigned long l2, const ring r,
929              unsigned long number_of_exp)
930{
931  const unsigned long bitmask = r->bitmask;
932  unsigned long ml1 = l1 & bitmask;
933  unsigned long ml2 = l2 & bitmask;
934  unsigned long max = (ml1 > ml2 ? ml1 : ml2);
935  unsigned long j = number_of_exp - 1;
936
937  if (j > 0)
938  {
939    unsigned long mask = bitmask << r->BitsPerExp;
940    while (1)
941    {
942      ml1 = l1 & mask;
943      ml2 = l2 & mask;
944      max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
945      j--;
946      if (j == 0) break;
947      mask = mask << r->BitsPerExp;
948    }
949  }
950  return max;
951}
952
953static inline unsigned long
954p_GetMaxExpL2(unsigned long l1, unsigned long l2, const ring r)
955{
956  return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
957}
958
959poly p_GetMaxExpP(poly p, const ring r)
960{
961  p_CheckPolyRing(p, r);
962  if (p == NULL) return p_Init(r);
963  poly max = p_LmInit(p, r);
964  pIter(p);
965  if (p == NULL) return max;
966  int i, offset;
967  unsigned long l_p, l_max;
968  unsigned long divmask = r->divmask;
969
970  do
971  {
972    offset = r->VarL_Offset[0];
973    l_p = p->exp[offset];
974    l_max = max->exp[offset];
975    // do the divisibility trick to find out whether l has an exponent
976    if (l_p > l_max ||
977        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
978      max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
979
980    for (i=1; i<r->VarL_Size; i++)
981    {
982      offset = r->VarL_Offset[i];
983      l_p = p->exp[offset];
984      l_max = max->exp[offset];
985      // do the divisibility trick to find out whether l has an exponent
986      if (l_p > l_max ||
987          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
988        max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
989    }
990    pIter(p);
991  }
992  while (p != NULL);
993  return max;
994}
995
996unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max)
997{
998  unsigned long l_p, divmask = r->divmask;
999  int i;
1000
1001  while (p != NULL)
1002  {
1003    l_p = p->exp[r->VarL_Offset[0]];
1004    if (l_p > l_max ||
1005        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
1006      l_max = p_GetMaxExpL2(l_max, l_p, r);
1007    for (i=1; i<r->VarL_Size; i++)
1008    {
1009      l_p = p->exp[r->VarL_Offset[i]];
1010      // do the divisibility trick to find out whether l has an exponent
1011      if (l_p > l_max ||
1012          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
1013        l_max = p_GetMaxExpL2(l_max, l_p, r);
1014    }
1015    pIter(p);
1016  }
1017  return l_max;
1018}
1019
1020
1021
1022
1023/***************************************************************
1024 *
1025 * Misc things
1026 *
1027 ***************************************************************/
1028// returns TRUE, if all monoms have the same component
1029BOOLEAN p_OneComp(poly p, const ring r)
1030{
1031  if(p!=NULL)
1032  {
1033    long i = p_GetComp(p, r);
1034    while (pNext(p)!=NULL)
1035    {
1036      pIter(p);
1037      if(i != p_GetComp(p, r)) return FALSE;
1038    }
1039  }
1040  return TRUE;
1041}
1042
1043/*2
1044*test if a monomial /head term is a pure power
1045*/
1046int p_IsPurePower(const poly p, const ring r)
1047{
1048  int i,k=0;
1049
1050  for (i=r->N;i;i--)
1051  {
1052    if (p_GetExp(p,i, r)!=0)
1053    {
1054      if(k!=0) return 0;
1055      k=i;
1056    }
1057  }
1058  return k;
1059}
1060
1061/*2
1062*test if a polynomial is univariate
1063* return -1 for constant,
1064* 0 for not univariate,s
1065* i if dep. on var(i)
1066*/
1067int p_IsUnivariate(poly p, const ring r)
1068{
1069  int i,k=-1;
1070
1071  while (p!=NULL)
1072  {
1073    for (i=r->N;i;i--)
1074    {
1075      if (p_GetExp(p,i, r)!=0)
1076      {
1077        if((k!=-1)&&(k!=i)) return 0;
1078        k=i;
1079      }
1080    }
1081    pIter(p);
1082  }
1083  return k;
1084}
1085
1086// set entry e[i] to 1 if var(i) occurs in p, ignore var(j) if e[j]>0
1087int  p_GetVariables(poly p, int * e, const ring r)
1088{
1089  int i;
1090  int n=0;
1091  while(p!=NULL)
1092  {
1093    n=0;
1094    for(i=r->N; i>0; i--)
1095    {
1096      if(e[i]==0)
1097      {
1098        if (p_GetExp(p,i,r)>0)
1099        {
1100          e[i]=1;
1101          n++;
1102        }
1103      }
1104      else
1105        n++;
1106    }
1107    if (n==r->N) break;
1108    pIter(p);
1109  }
1110  return n;
1111}
1112
1113
1114/*2
1115* returns a polynomial representing the integer i
1116*/
1117poly p_ISet(int i, const ring r)
1118{
1119  poly rc = NULL;
1120  if (i!=0)
1121  {
1122    rc = p_Init(r);
1123    pSetCoeff0(rc,n_Init(i,r));
1124    if (r->cf->nIsZero(p_GetCoeff(rc,r)))
1125      p_LmDelete(&rc,r);
1126  }
1127  return rc;
1128}
1129
1130/*2
1131* an optimized version of p_ISet for the special case 1
1132*/
1133poly p_One(const ring r)
1134{
1135  poly rc = p_Init(r);
1136  pSetCoeff0(rc,n_Init(1,r));
1137  return rc;
1138}
1139
1140/*2
1141* returns a polynomial representing the number n
1142* destroys n
1143*/
1144poly p_NSet(number n, const ring r)
1145{
1146  if (r->cf->nIsZero(n))
1147  {
1148    r->cf->cfDelete(&n, r);
1149    return NULL;
1150  }
1151  else
1152  {
1153    poly rc = p_Init(r);
1154    pSetCoeff0(rc,n);
1155    return rc;
1156  }
1157}
1158
1159/***************************************************************
1160 *
1161 * p_ShallowDelete
1162 *
1163 ***************************************************************/
1164#undef LINKAGE
1165#define LINKAGE
1166#undef p_Delete
1167#define p_Delete p_ShallowDelete
1168#undef n_Delete
1169#define n_Delete(n, r) ((void)0)
1170
1171#include <kernel/p_Delete__T.cc>
1172
Note: See TracBrowser for help on using the repository browser.