source: git/kernel/p_polys.cc @ 07ae7c

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