source: git/kernel/p_polys.cc @ 47d83a

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