source: git/kernel/p_polys.cc @ 9f73e80

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