source: git/Singular/p_polys.cc @ 50cbdc

spielwiese
Last change on this file since 50cbdc was 50cbdc, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merge-2-0-2 git-svn-id: file:///usr/local/Singular/svn/trunk@5619 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.0 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.17 2001-08-27 14:47:32 Singular Exp $
10 *******************************************************************/
11
12#include "mod2.h"
13#include "structs.h"
14#include "tok.h"
15#include "p_polys.h"
16#include "ring.h"
17
18/***************************************************************
19 *
20 * Completing what needs to be set for the monomial
21 *
22 ***************************************************************/
23// this is special for the syz stuff
24static int* _Components = NULL;
25static long* _ShiftedComponents = NULL;
26static int _ExternalComponents = 0;
27
28void p_Setm_General(poly p, ring r)
29{
30  p_LmCheckPolyRing(p, r);
31  int pos=0;
32  if (r->typ!=NULL)
33  {
34    loop
35    {
36      long ord=0;
37      sro_ord* o=&(r->typ[pos]);
38      switch(o->ord_typ)
39      {
40        case ro_dp:
41        {
42          int a,e;
43          a=o->data.dp.start;
44          e=o->data.dp.end;
45          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r);
46          p->exp[o->data.dp.place]=ord;
47          break;
48        }
49        case ro_wp_neg:
50          ord=POLY_NEGWEIGHT_OFFSET;
51          // no break;
52        case ro_wp:
53        {
54          int a,e;
55          a=o->data.wp.start;
56          e=o->data.wp.end;
57          int *w=o->data.wp.weights;
58          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r)*w[i-a];
59          p->exp[o->data.wp.place]=ord;
60          break;
61        }
62        case ro_cp:
63        {
64          int a,e;
65          a=o->data.cp.start;
66          e=o->data.cp.end;
67          int pl=o->data.cp.place;
68          for(int i=a;i<=e;i++) { p->exp[pl]=p_GetExp(p,i,r); pl++; }
69          break;
70        }
71        case ro_syzcomp:
72        {
73          int c=p_GetComp(p,r);
74          long sc = c;
75          int* Components = (_ExternalComponents ? _Components :
76                             o->data.syzcomp.Components);
77          long* ShiftedComponents = (_ExternalComponents ? _ShiftedComponents:
78                                     o->data.syzcomp.ShiftedComponents);
79          if (ShiftedComponents != NULL)
80          {
81            assume(Components != NULL);
82            assume(c == 0 || Components[c] != 0);
83            sc = ShiftedComponents[Components[c]];
84            assume(c == 0 || sc != 0);
85          }
86          p->exp[o->data.syzcomp.place]=sc;
87          break;
88        }
89        case ro_syz:
90        {
91          int c=p_GetComp(p, r);
92          if (c > o->data.syz.limit)
93            p->exp[o->data.syz.place] = o->data.syz.curr_index;
94          else if (c > 0)
95            p->exp[o->data.syz.place]= o->data.syz.syz_index[c];
96          else
97          {
98            assume(c == 0);
99            p->exp[o->data.syz.place]= 0;
100          }
101          break;
102        }
103        default:
104          dReportError("wrong ord in rSetm:%d\n",o->ord_typ);
105          return;
106      }
107      pos++;
108      if (pos == r->OrdSize) return;
109    }
110  }
111}
112
113void p_Setm_Syz(poly p, ring r, int* Components, long* ShiftedComponents)
114{
115  _Components = Components;
116  _ShiftedComponents = ShiftedComponents;
117  _ExternalComponents = 1;
118  p_Setm_General(p, r);
119  _ExternalComponents = 0;
120}
121
122// dummy for lp, ls, etc
123void p_Setm_Dummy(poly p, ring r)
124{
125  p_LmCheckPolyRing(p, r);
126}
127
128// for dp, Dp, ds, etc
129void p_Setm_TotalDegree(poly p, ring r)
130{
131  p_LmCheckPolyRing(p, r);
132  p->exp[r->pOrdIndex] = p_ExpVectorQuerSum(p, r);
133}
134
135// for wp, Wp, ws, etc
136void p_Setm_WFirstTotalDegree(poly p, ring r)
137{
138  p_LmCheckPolyRing(p, r);
139  p->exp[r->pOrdIndex] = pWFirstTotalDegree(p, r);
140}
141
142p_SetmProc p_GetSetmProc(ring r)
143{
144  // covers lp, rp, ls,
145  if (r->typ == NULL) return p_Setm_Dummy;
146
147  if (r->OrdSize == 1)
148  {
149    if (r->typ[0].ord_typ == ro_dp &&
150        r->typ[0].data.dp.start == 1 &&
151        r->typ[0].data.dp.end == r->N &&
152        r->typ[0].data.dp.place == r->pOrdIndex)
153      return p_Setm_TotalDegree;
154    if (r->typ[0].ord_typ == ro_wp &&
155        r->typ[0].data.wp.start == 1 &&
156        r->typ[0].data.wp.end == r->N &&
157        r->typ[0].data.wp.place == r->pOrdIndex &&
158        r->typ[0].data.wp.weights == r->firstwv)
159      return p_Setm_WFirstTotalDegree;
160  }
161  return p_Setm_General;
162}
163
164
165/* -------------------------------------------------------------------*/
166/* several possibilities for pFDeg: the degree of the head term       */
167/*2
168* compute the degree of the leading monomial of p
169* the ordering is compatible with degree, use a->order
170*/
171inline long _pDeg(poly a, ring r)
172{
173  p_LmCheckPolyRing(a, r);
174  assume(p_GetOrder(a, r) == pWTotaldegree(a, r));
175  return p_GetOrder(a, r);
176}
177
178long pDeg(poly a, ring r)
179{
180  return _pDeg(a, r);
181}
182
183/*2
184* compute the degree of the leading monomial of p
185* with respect to weigths 1
186* (all are 1 so save multiplications or they are of different signs)
187* the ordering is not compatible with degree so do not use p->Order
188*/
189inline long _pTotaldegree(poly p, ring r)
190{
191  p_LmCheckPolyRing(p, r);
192  return (long) p_ExpVectorQuerSum(p, r);
193}
194long pTotaldegree(poly p, ring r)
195{
196  return (long) _pTotaldegree(p, r);
197}
198
199// pWTotalDegree for weighted orderings
200// whose first block covers all variables
201inline long _pWFirstTotalDegree(poly p, ring r)
202{
203  int i;
204  long sum = 0;
205
206  for (i=1; i<= r->firstBlockEnds; i++)
207  {
208    sum += p_GetExp(p, i, r)*r->firstwv[i-1];
209  }
210  return sum;
211}
212
213long pWFirstTotalDegree(poly p, ring r)
214{
215  return (long) _pWFirstTotalDegree(p, r);
216}
217
218/*2
219* compute the degree of the leading monomial of p
220* with respect to weigths from the ordering
221* the ordering is not compatible with degree so do not use p->Order
222*/
223long pWTotaldegree(poly p, ring r)
224{
225  p_LmCheckPolyRing(p, r);
226  int i, k;
227  long j =0;
228
229  // iterate through each block:
230  for (i=0;r->order[i]!=0;i++)
231  {
232    switch(r->order[i])
233    {
234      case ringorder_wp:
235      case ringorder_ws:
236      case ringorder_Wp:
237      case ringorder_Ws:
238        for (k=r->block0[i];k<=r->block1[i];k++)
239        { // in jedem block:
240          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - r->block0[i]];
241        }
242        break;
243      case ringorder_M:
244      case ringorder_lp:
245      case ringorder_dp:
246      case ringorder_ds:
247      case ringorder_Dp:
248      case ringorder_Ds:
249      case ringorder_rp:
250        for (k=r->block0[i];k<=r->block1[i];k++)
251        {
252          j+= p_GetExp(p,k,r);
253        }
254        break;
255      case ringorder_c:
256      case ringorder_C:
257      case ringorder_S:
258      case ringorder_s:
259      case ringorder_aa:
260        break;
261      case ringorder_a:
262        for (k=r->block0[i];k<=r->block1[i];k++)
263        { // only one line
264          j+= p_GetExp(p,k, r)*r->wvhdl[i][ k- r->block0[i]];
265        }
266        return j;
267    }
268  }
269  return  j;
270}
271
272int pWeight(int i, ring r)
273{
274  if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
275  {
276    return 1;
277  }
278  return r->firstwv[i-1];
279}
280
281long pWDegree(poly p, ring r)
282{
283  if (r->firstwv==NULL) return pTotaldegree(p, r);
284  p_LmCheckPolyRing(p, r);
285  int i, k;
286  long j =0;
287
288  for(i=1;i<=r->firstBlockEnds;i++)
289    j+=p_GetExp(p, i, r)*r->firstwv[i-1];
290
291  for (;i<=r->N;i++)
292    j+=p_GetExp(p,i, r)*pWeight(i, r);
293
294  return j;
295}
296
297
298/* ---------------------------------------------------------------------*/
299/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
300/*  compute in l also the pLength of p                                   */
301
302/*2
303* compute the length of a polynomial (in l)
304* and the degree of the monomial with maximal degree: the last one
305*/
306long pLDeg0(poly p,int *l, ring r)
307{
308  p_CheckPolyRing(p, r);
309  Exponent_t k= p_GetComp(p, r);
310  int ll=1;
311
312  if (k > 0)
313  {
314    while ((pNext(p)!=NULL) && (p_GetComp(pNext(p), r)==k))
315    {
316      pIter(p);
317      ll++;
318    }
319  }
320  else
321  {
322     while (pNext(p)!=NULL)
323     {
324       pIter(p);
325       ll++;
326     }
327  }
328  *l=ll;
329  return r->pFDeg(p, r);
330}
331
332/*2
333* compute the length of a polynomial (in l)
334* and the degree of the monomial with maximal degree: the last one
335* but search in all components before syzcomp
336*/
337long pLDeg0c(poly p,int *l, ring r)
338{
339  assume(p!=NULL);
340#ifdef PDEBUG
341  _p_Test(p,r,PDEBUG);
342#endif
343  p_CheckPolyRing(p, r);
344  long o;
345  int ll=1;
346
347  if (! rIsSyzIndexRing(r))
348  {
349    while (pNext(p) != NULL)
350    {
351      pIter(p);
352      ll++;
353    }
354    o = r->pFDeg(p, r);
355  }
356  else
357  {
358    int curr_limit = rGetCurrSyzLimit(r);
359    poly pp = p;
360    while ((p=pNext(p))!=NULL)
361    {
362      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
363        ll++;
364      else break;
365      pp = p;
366    }
367#ifdef PDEBUG
368    _p_Test(pp,r,PDEBUG);
369#endif
370    o = r->pFDeg(pp, r);
371  }
372  *l=ll;
373  return o;
374}
375
376/*2
377* compute the length of a polynomial (in l)
378* and the degree of the monomial with maximal degree: the first one
379* this works for the polynomial case with degree orderings
380* (both c,dp and dp,c)
381*/
382long pLDegb(poly p,int *l, ring r)
383{
384  p_CheckPolyRing(p, r);
385  Exponent_t k= p_GetComp(p, r);
386  long o = r->pFDeg(p, r);
387  int ll=1;
388
389  if (k != 0)
390  {
391    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
392    {
393      ll++;
394    }
395  }
396  else
397  {
398    while ((p=pNext(p)) !=NULL)
399    {
400      ll++;
401    }
402  }
403  *l=ll;
404  return o;
405}
406
407/*2
408* compute the length of a polynomial (in l)
409* and the degree of the monomial with maximal degree:
410* this is NOT the last one, we have to look for it
411*/
412long pLDeg1(poly p,int *l, ring r)
413{
414  p_CheckPolyRing(p, r);
415  Exponent_t k= p_GetComp(p, r);
416  int ll=1;
417  long  t,max;
418
419  max=r->pFDeg(p, r);
420  if (k > 0)
421  {
422    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
423    {
424      t=r->pFDeg(p, r);
425      if (t>max) max=t;
426      ll++;
427    }
428  }
429  else
430  {
431    while ((p=pNext(p))!=NULL)
432    {
433      t=r->pFDeg(p, r);
434      if (t>max) max=t;
435      ll++;
436    }
437  }
438  *l=ll;
439  return max;
440}
441
442/*2
443* compute the length of a polynomial (in l)
444* and the degree of the monomial with maximal degree:
445* this is NOT the last one, we have to look for it
446* in all components
447*/
448long pLDeg1c(poly p,int *l, ring r)
449{
450  p_CheckPolyRing(p, r);
451  int ll=1;
452  long  t,max;
453
454  max=r->pFDeg(p, r);
455  if (rIsSyzIndexRing(r))
456  {
457    long limit = rGetCurrSyzLimit(r);
458    while ((p=pNext(p))!=NULL)
459    {
460      if (p_GetComp(p, r)<=limit)
461      {
462        if ((t=r->pFDeg(p, r))>max) max=t;
463        ll++;
464      }
465      else break;
466    }
467  }
468  else
469  {
470    while ((p=pNext(p))!=NULL)
471    {
472      if ((t=r->pFDeg(p, r))>max) max=t;
473      ll++;
474    }
475  }
476  *l=ll;
477  return max;
478}
479
480// like pLDeg1, only pFDeg == pDeg
481long pLDeg1_Deg(poly p,int *l, ring r)
482{
483  assume(r->pFDeg == pDeg);
484  p_CheckPolyRing(p, r);
485  Exponent_t k= p_GetComp(p, r);
486  int ll=1;
487  long  t,max;
488
489  max=_pDeg(p, r);
490  if (k > 0)
491  {
492    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
493    {
494      t=_pDeg(p, r);
495      if (t>max) max=t;
496      ll++;
497    }
498  }
499  else
500  {
501    while ((p=pNext(p))!=NULL)
502    {
503      t=_pDeg(p, r);
504      if (t>max) max=t;
505      ll++;
506    }
507  }
508  *l=ll;
509  return max;
510}
511
512long pLDeg1c_Deg(poly p,int *l, ring r)
513{
514  assume(r->pFDeg == pDeg);
515  p_CheckPolyRing(p, r);
516  int ll=1;
517  long  t,max;
518
519  max=_pDeg(p, r);
520  if (rIsSyzIndexRing(r))
521  {
522    long limit = rGetCurrSyzLimit(r);
523    while ((p=pNext(p))!=NULL)
524    {
525      if (p_GetComp(p, r)<=limit)
526      {
527        if ((t=_pDeg(p, r))>max) max=t;
528        ll++;
529      }
530      else break;
531    }
532  }
533  else
534  {
535    while ((p=pNext(p))!=NULL)
536    {
537      if ((t=_pDeg(p, r))>max) max=t;
538      ll++;
539    }
540  }
541  *l=ll;
542  return max;
543}
544
545// like pLDeg1, only pFDeg == pTotoalDegree
546long pLDeg1_Totaldegree(poly p,int *l, ring r)
547{
548  p_CheckPolyRing(p, r);
549  Exponent_t k= p_GetComp(p, r);
550  int ll=1;
551  long  t,max;
552
553  max=_pTotaldegree(p, r);
554  if (k > 0)
555  {
556    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
557    {
558      t=_pTotaldegree(p, r);
559      if (t>max) max=t;
560      ll++;
561    }
562  }
563  else
564  {
565    while ((p=pNext(p))!=NULL)
566    {
567      t=_pTotaldegree(p, r);
568      if (t>max) max=t;
569      ll++;
570    }
571  }
572  *l=ll;
573  return max;
574}
575
576long pLDeg1c_Totaldegree(poly p,int *l, ring r)
577{
578  p_CheckPolyRing(p, r);
579  int ll=1;
580  long  t,max;
581
582  max=_pTotaldegree(p, r);
583  if (rIsSyzIndexRing(r))
584  {
585    long limit = rGetCurrSyzLimit(r);
586    while ((p=pNext(p))!=NULL)
587    {
588      if (p_GetComp(p, r)<=limit)
589      {
590        if ((t=_pTotaldegree(p, r))>max) max=t;
591        ll++;
592      }
593      else break;
594    }
595  }
596  else
597  {
598    while ((p=pNext(p))!=NULL)
599    {
600      if ((t=_pTotaldegree(p, r))>max) max=t;
601      ll++;
602    }
603  }
604  *l=ll;
605  return max;
606}
607
608// like pLDeg1, only pFDeg == pWFirstTotalDegree
609long pLDeg1_WFirstTotalDegree(poly p,int *l, ring r)
610{
611  p_CheckPolyRing(p, r);
612  Exponent_t k= p_GetComp(p, r);
613  int ll=1;
614  long  t,max;
615
616  max=_pWFirstTotalDegree(p, r);
617  if (k > 0)
618  {
619    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
620    {
621      t=_pWFirstTotalDegree(p, r);
622      if (t>max) max=t;
623      ll++;
624    }
625  }
626  else
627  {
628    while ((p=pNext(p))!=NULL)
629    {
630      t=_pWFirstTotalDegree(p, r);
631      if (t>max) max=t;
632      ll++;
633    }
634  }
635  *l=ll;
636  return max;
637}
638
639long pLDeg1c_WFirstTotalDegree(poly p,int *l, ring r)
640{
641  p_CheckPolyRing(p, r);
642  int ll=1;
643  long  t,max;
644
645  max=_pWFirstTotalDegree(p, r);
646  if (rIsSyzIndexRing(r))
647  {
648    long limit = rGetCurrSyzLimit(r);
649    while ((p=pNext(p))!=NULL)
650    {
651      if (p_GetComp(p, r)<=limit)
652      {
653        if ((t=_pTotaldegree(p, r))>max) max=t;
654        ll++;
655      }
656      else break;
657    }
658  }
659  else
660  {
661    while ((p=pNext(p))!=NULL)
662    {
663      if ((t=_pTotaldegree(p, r))>max) max=t;
664      ll++;
665    }
666  }
667  *l=ll;
668  return max;
669}
670
671/***************************************************************
672 *
673 * Maximal Exponent business
674 *
675 ***************************************************************/
676
677static inline unsigned long
678p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r,
679              unsigned long number_of_exp)
680{
681  const unsigned long bitmask = r->bitmask;
682  unsigned long ml1 = l1 & bitmask;
683  unsigned long ml2 = l2 & bitmask;
684  unsigned long max = (ml1 > ml2 ? ml1 : ml2);
685  unsigned long j = number_of_exp - 1;
686
687  if (j > 0)
688  {
689    unsigned long mask = bitmask << r->BitsPerExp;
690    while (1)
691    {
692      ml1 = l1 & mask;
693      ml2 = l2 & mask;
694      max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
695      j--;
696      if (j == 0) break;
697      mask = mask << r->BitsPerExp;
698    }
699  }
700  return max;
701}
702
703static inline unsigned long
704p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r)
705{
706  return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
707}
708
709poly p_GetMaxExpP(poly p, ring r)
710{
711  p_CheckPolyRing(p, r);
712  if (p == NULL) return p_Init(r);
713  poly max = p_LmInit(p, r);
714  pIter(p);
715  if (p == NULL) return max;
716  int i, offset;
717  unsigned long l_p, l_max;
718  unsigned long divmask = r->divmask;
719
720  do
721  {
722    offset = r->VarL_Offset[0];
723    l_p = p->exp[offset];
724    l_max = max->exp[offset];
725    // do the divisibility trick to find out whether l has an exponent
726    if (l_p > l_max ||
727        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
728      max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
729
730    for (i=1; i<r->VarL_Size; i++)
731    {
732      offset = r->VarL_Offset[i];
733      l_p = p->exp[offset];
734      l_max = max->exp[offset];
735      // do the divisibility trick to find out whether l has an exponent
736      if (l_p > l_max ||
737          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
738        max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
739    }
740    pIter(p);
741  }
742  while (p != NULL);
743  return max;
744}
745
746unsigned long p_GetMaxExpL(poly p, ring r, unsigned long l_max)
747{
748  unsigned long l_p, divmask = r->divmask;
749  int i;
750
751  while (p != NULL)
752  {
753    l_p = p->exp[r->VarL_Offset[0]];
754    if (l_p > l_max ||
755        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
756      l_max = p_GetMaxExpL2(l_max, l_p, r);
757    for (i=1; i<r->VarL_Size; i++)
758    {
759      l_p = p->exp[r->VarL_Offset[i]];
760      // do the divisibility trick to find out whether l has an exponent
761      if (l_p > l_max ||
762          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
763        l_max = p_GetMaxExpL2(l_max, l_p, r);
764    }
765    pIter(p);
766  }
767  return l_max;
768}
769
770/***************************************************************
771 *
772 * Misc things
773 *
774 ***************************************************************/
775// returns TRUE, if all monoms have the same component
776BOOLEAN p_OneComp(poly p, ring r)
777{
778  if(p!=NULL)
779  {
780    long i = p_GetComp(p, r);
781    while (pNext(p)!=NULL)
782    {
783      pIter(p);
784      if(i != p_GetComp(p, r)) return FALSE;
785    }
786  }
787  return TRUE;
788}
789
790/*2
791*test if a monomial /head term is a pure power
792*/
793int p_IsPurePower(const poly p, const ring r)
794{
795  int i,k=0;
796
797  for (i=r->N;i;i--)
798  {
799    if (p_GetExp(p,i, r)!=0)
800    {
801      if(k!=0) return 0;
802      k=i;
803    }
804  }
805  return k;
806}
807
808/*2
809* returns a polynomial representing the integer i
810*/
811poly p_ISet(int i, ring r)
812{
813  poly rc = NULL;
814  if (i!=0)
815  {
816    rc = p_Init(r);
817    pSetCoeff0(rc,r->cf->nInit(i));
818    if (r->cf->nIsZero(p_GetCoeff(rc,r)))
819      p_DeleteLm(&rc,r);
820  }
821  return rc;
822}
823
824/*2
825* returns a polynomial representing the number n
826* destroys n
827*/
828poly p_NSet(number n, ring r)
829{
830  if (r->cf->nIsZero(n))
831  {
832    r->cf->cfDelete(&n, r);
833    return NULL;
834  }
835  else
836  {
837    poly rc = p_Init(r);
838    pSetCoeff0(rc,n);
839    return rc;
840  }
841}
Note: See TracBrowser for help on using the repository browser.