source: git/kernel/p_polys.cc @ 8391d8

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