source: git/kernel/p_polys.cc @ 645a19

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