source: git/Singular/polys-impl.cc @ d2cd2f7

fieker-DuValspielwiese
Last change on this file since d2cd2f7 was d2cd2f7, checked in by Hans Schönemann <hannes@…>, 26 years ago
*hannes: fixed memory leak in pFetchCopy git-svn-id: file:///usr/local/Singular/svn/trunk@2660 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys-impl.cc,v 1.20 1998-11-10 17:25:32 Singular Exp $ */
5
6/***************************************************************
7 *
8 * File:       polys-impl.cc
9 * Purpose:    low-level procuders for polys.
10 *
11 * If you touch anything here, you better know what you are doing.
12 * What is here should not be used directly from other routines -- the
13 * encapsulations in polys.[h,cc] should be used, instead.
14 *
15 ***************************************************************/
16#ifndef POLYS_IMPL_CC
17#define POLYS_IMPL_CC
18
19#include <stdio.h>
20#include <string.h>
21#include "mod2.h"
22#include "tok.h"
23#include "structs.h"
24#include "mmprivat.h"
25#include "mmemory.h"
26#include "febase.h"
27#include "numbers.h"
28#include "polys.h"
29#include "ring.h"
30#include "ipid.h"
31
32/***************************************************************
33 *
34 * Low - level routines which deal with var indicies
35 *
36 ***************************************************************/
37// And here is how we determine the way exponents are stored:
38// There are the following four possibilities:
39//
40//
41// BIGENDIAN -- lex order
42// e_1, e_2, ... , e_n,..,comp:  pVarOffset = -1,
43//                               pVarLowIndex = 0,
44//                               pVarHighIndex = pVariables-1
45//                               pVarCompIndex = pVariables + #(..)
46// BIGENDIAN -- rev lex order
47// e_n, ... , e_2, e_1,..,comp:  pVarOffset = pVariables,
48//                               pVarLowIndex = 0,
49//                               pVarHighIndex = pVariables-1
50//                               pVarCompIndex = pVariables + #(..)
51// LITTLEENDIAN -- rev lex order
52// comp,.., e_1, e_2, ... , e_n : pVarOffset = #(..),
53//                                pVarLowIndex = 1 + #(..),
54//                                pVarHighIndex = #(..) + pVariables
55//                                pVarCompIndex = 0
56// LITTLEENDIAN -- lex order
57// comp,..,e_n, .... , e_2, e_1 : pVarOffset = pVariables + 1 + #(..)
58//                                pVarLowIndex = 1 + #(..)
59//                                pVarHighIndex = #(..) + pVariables
60//                                pVarCompIndex = 0
61//
62// Furthermore, the size of the exponent vector is always a multiple
63// of the word size -- "empty exponents" (exactly #(..) ones) are
64// filled in between comp and first/last exponent -- i.e. comp and
65// first/last exponent might not be next to each other
66
67void pGetVarIndicies_Lex(int nvars, int* VarOffset, int &VarCompIndex,
68                                int &VarLowIndex, int &VarHighIndex)
69{
70  long temp = (nvars+1)*sizeof(Exponent_t);
71  if ((temp % sizeof(long)) == 0)
72    temp = temp / sizeof(long);
73  else
74    temp = (temp / sizeof(long)) + 1; // temp == pVariables1W
75#ifdef WORDS_BIGENDIAN
76  VarCompIndex = temp * sizeof(long)/sizeof(Exponent_t) - 1;
77  VarOffset[0] = VarCompIndex;
78  for (temp=1; temp<=nvars; temp++)
79    VarOffset[temp] = temp - 1;
80  VarLowIndex  = 0;
81  VarHighIndex = nvars - 1;
82#else //  ! WORDS_BIGENDIAN
83  temp *= sizeof(long)/sizeof(Exponent_t);
84  VarHighIndex = temp -1;
85  VarLowIndex = temp - nvars;
86  VarOffset[0] = 0;
87  for (long i = 1; i<=nvars;i++)
88    VarOffset[i] = temp - i;
89  VarCompIndex = 0;
90#endif // WORDS_BIGENDIAN
91}
92
93void pGetVarIndicies_RevLex(int nvars,int *VarOffset,int &VarCompIndex,
94                            int &VarLowIndex, int &VarHighIndex)
95{
96  long temp = (nvars+1)*sizeof(Exponent_t);
97  if ((temp % sizeof(long)) == 0)
98    temp = temp / sizeof(long);
99  else
100    temp = (temp / sizeof(long)) + 1; // temp == pVariables1W
101#ifdef WORDS_BIGENDIAN
102  VarCompIndex = temp * sizeof(long)/sizeof(Exponent_t) - 1;
103  VarOffset[0] = VarCompIndex;
104  for (temp=1; temp <= nvars; temp++)
105    VarOffset[temp] = nvars - temp;
106  VarLowIndex  = 0;
107  VarHighIndex = nvars-1;
108#else //  ! WORDS_BIGENDIAN
109  temp *= sizeof(long)/sizeof(Exponent_t);
110  VarHighIndex = temp -1;
111  VarLowIndex = temp - nvars;
112  VarOffset[0] = 0;
113  for (int i = 1; i<=nvars; i++)
114    VarOffset[i] = temp - nvars - 1 + i;
115  VarCompIndex = 0;
116#endif // WORDS_BIGENDIAN
117}
118
119void pGetVarIndicies(int nvars, int *VarOffset, int &VarCompIndex,
120                     int &VarLowIndex, int &VarHighIndex)
121{
122  pGetVarIndicies_Lex(nvars,VarOffset, VarCompIndex, VarLowIndex,VarHighIndex);
123}
124
125// gets var indicies w.r.t. the ring r
126void pGetVarIndicies(ring r, int *VarOffset, int &VarCompIndex,
127                     int &VarLowIndex, int &VarHighIndex)
128{
129  // at the moment, non-default var indicies are only used for simple orderings
130  if (rHasSimpleOrder(r))
131  {
132    short s_order;
133    if (r->order[0] == ringorder_c || r->order[0] == ringorder_C)
134      s_order = r->order[1];
135    else
136      s_order = r->order[0];
137
138    switch(s_order)
139    {
140        case ringorder_dp:
141        case ringorder_wp:
142        case ringorder_ds:
143        case ringorder_ws:
144        case ringorder_unspec:
145          pGetVarIndicies_RevLex(r->N, VarOffset, VarCompIndex, 
146                                 VarLowIndex, VarHighIndex);
147          break;
148
149#ifdef PDEBUG
150        case ringorder_lp:
151        case ringorder_Dp:
152        case ringorder_Wp:
153        case ringorder_Ds:
154        case ringorder_Ws:
155        case ringorder_ls:
156#else
157        default:
158#endif
159          pGetVarIndicies_Lex(r->N, VarOffset, VarCompIndex, 
160                              VarLowIndex, VarHighIndex);
161#ifdef PDEBUG
162          break;
163        default:
164          Werror("wrong internal ordering:%d at %s, l:%d\n",
165                 s_order,__FILE__,__LINE__);
166#endif
167    }
168  }
169  else
170    // default var indicies are used
171    pGetVarIndicies(r->N, VarOffset, VarCompIndex, VarLowIndex, VarHighIndex);
172}
173
174
175inline void RingCopy2ExpV(poly dest, poly src, ring src_r)
176{
177  for (int i=pVariables; i; i--)
178    pSetExp(dest, i, pRingGetExp(src_r, src, i));
179  pSetComp(dest, pRingGetComp(src_r, src));
180}
181
182// Returns a converted copy (in the sense that the returned poly is
183// poly of currRing) of poly p which is from ring r -- assumes that
184// currRing and r have the same number of variables, i.e. that polys
185// from r can be "fetched" into currRing
186#ifdef PDEBUG
187poly pDBFetchCopy(ring r, poly p,char *f,int l)
188#else
189poly _pFetchCopy(ring r, poly p)
190#endif
191{
192  poly res;
193  poly a;
194  if (p==NULL) return NULL;
195  if (r->VarOffset == pVarOffset)
196  {
197#ifdef PDEBUG
198    res = a = pDBNew(f,l);
199#else
200    res = a = pNew();
201#endif
202    pCopy2(a,p);
203    a->coef=nCopy(p->coef);
204    pSetm(a);
205    pIter(p);
206    while (p!=NULL)
207    {
208#ifdef PDEBUG
209      a = pNext(a) = pDBNew(f,l);
210#else
211      a = pNext(a) = pNew();
212#endif
213      pCopy2(a,p);
214      a->coef=nCopy(p->coef);
215      pSetm(a);
216      pIter(p);
217    }
218    pNext(a) = NULL;
219  }
220  else
221  {
222#ifdef PDEBUG
223    a = res = pDBInit(f,l);
224#else
225    a = res = pInit();
226#endif
227    res->coef = nCopy(p->coef);
228    RingCopy2ExpV(res, p, r);
229    pSetm(res);
230    pIter(p);
231    while (p != NULL)
232    {
233      // the VarOffset's are different: Hence we
234      // convert betweeen a lex order and a revlex order -- to speed
235      // up the sorting, we assemble new poly in inverse order
236#ifdef PDEBUG
237      res = pDBInit(f,l);
238#else
239      res = pInit();
240#endif
241      pNext(res) = a;
242      a = res;
243      res->coef = nCopy(p->coef);
244      RingCopy2ExpV(res, p, r);
245      pSetm(res);
246      pIter(p);
247    }
248  }
249#ifdef PDEBUG
250  res = pOrdPolyMerge(res);
251  pTest(res);
252  return res;
253#else
254  return pOrdPolyMerge(res);
255#endif
256}
257
258
259/***************************************************************
260 *
261 * Storage Managament Routines
262 *
263 ***************************************************************/
264
265#ifdef PDEBUG
266poly pDBNew(char *f, int l)
267{
268#ifdef MDEBUG
269  poly p = (poly) mmDBAllocSpecialized(f,l);
270#else
271  poly p = (poly) mmAllocSpecialized();
272#endif
273  memset(p,0,pMonomSize);
274  return p;
275}
276#endif
277
278/*2
279* create a new monomial and init
280*/
281#ifdef PDEBUG
282poly pDBInit(char * f, int l)
283{
284  poly p=pDBNew(f,l);
285  memset(p,0, pMonomSize);
286  nNew(&(p->coef));
287  return p;
288}
289#endif
290
291/*2
292* delete a poly, resets pointer
293* put the monomials in the freelist
294*/
295#ifdef PDEBUG
296void pDBDelete(poly * p, char * f, int l)
297{
298  poly h = *p;
299
300  while (h!=NULL)
301  {
302#ifdef LDEBUG
303    nDBDelete(&(h->coef),f,l);
304#else
305    nDelete(&(h->coef));
306#endif
307    pIter(h);
308#ifdef MDEBUG
309    mmDBFreeSpecialized((ADDRESS)*p,f,l);
310#else
311    mmFreeSpecialized((ADDRESS)*p);
312#endif
313    *p=h;
314    if (l>0) l= -l;
315  }
316  *p = NULL;
317}
318#else
319void _pDelete(poly* p)
320{
321  poly h = *p;
322  poly pp;
323
324  while (h!=NULL)
325  {
326    nDelete(&(h->coef));
327    pp=h;
328    pIter(h);
329    mmFreeSpecialized((ADDRESS)pp);
330  }
331  *p = NULL;
332}
333#endif
334
335/*2
336* remove first monom
337*/
338#ifdef PDEBUG
339void pDBDelete1(poly * p, char * f, int l)
340{
341  poly h = *p;
342
343  if (h==NULL) return;
344  nDelete(&(h->coef));
345  *p = pNext(h);
346#ifdef MDEBUG
347  mmDBFreeSpecialized((ADDRESS)h,f,l);
348#else
349  mmFreeSpecialized((ADDRESS)h);
350#endif
351}
352#else
353void _pDelete1(poly* p)
354{
355  poly h = *p;
356
357  if (h==NULL) return;
358  nDelete(&(h->coef));
359  *p = pNext(h);
360  mmFreeSpecialized((ADDRESS)h);
361}
362#endif
363
364void ppDelete(poly* p, ring rg)
365{
366  ring origRing = currRing;
367  rChangeCurrRing(rg, FALSE);
368  pDelete(p);
369  rChangeCurrRing(origRing, FALSE);
370}
371
372/*2
373* remove first monom
374*/
375#ifdef PDEBUG
376void pDBFree1(poly p, char * f, int l)
377{
378  if (p!=NULL)
379  {
380    p->coef=NULL;//nDelete(&(p->coef));
381#ifdef MDEBUG
382    mmDBFreeSpecialized((ADDRESS)p,f,l);
383#else
384    mmFreeSpecialized((ADDRESS)p);
385#endif
386  }
387}
388#endif
389
390/*2
391* creates a copy of p
392*/
393#ifdef PDEBUG
394poly pDBCopy(poly p,char *f,int l)
395#else
396poly _pCopy(poly p)
397#endif
398{
399  poly w, a;
400
401  if (p==NULL) return NULL;
402  pDBTest(p,f,l);
403#ifdef PDEBUG
404  w = a = pDBNew(f,l);
405#else
406  w = a = pNew();
407#endif
408  memcpy(w,p,pMonomSize);
409  w->coef=nCopy(p->coef);
410  if (pNext(p)!=NULL)
411  {
412    pIter(p);
413    do
414    {
415#ifdef PDEBUG
416      a = pNext(a) = pDBNew(f,l);
417#else
418      a = pNext(a) = pNew();
419#endif
420      memcpy(a,p,pMonomSize);
421      a->coef=nCopy(p->coef);
422      pIter(p);
423    }
424    while (p!=NULL);
425  }
426  pNext(a) = NULL;
427  return w;
428}
429
430
431/*2
432* creates a copy of the initial monomial of p
433* sets the coeff of the copy to a defined value
434*/
435#ifdef PDEBUG
436poly pDBCopy1(poly p,char *f,int l)
437#else
438poly _pCopy1(poly p)
439#endif
440{
441  poly w;
442#ifdef PDEBUG
443  w = pDBNew(f,l);
444#else
445  w = pNew();
446#endif
447  pCopy2(w,p);
448  nNew(&(w->coef));
449  pNext(w) = NULL;
450  return w;
451}
452
453/*2
454* returns (a copy of) the head term of a
455*/
456#ifdef PDEBUG
457poly pDBHead(poly p,char *f, int l)
458#else
459poly _pHead(poly p)
460#endif
461{
462  poly w=NULL;
463
464  if (p!=NULL)
465  {
466#ifdef PDEBUG
467    w = pDBNew(f,l);
468#else
469    w = pNew();
470#endif
471    pCopy2(w,p);
472    pSetCoeff0(w,nCopy(pGetCoeff(p)));
473    pNext(w) = NULL;
474  }
475  return w;
476}
477
478poly pHeadProc(poly p)
479{
480  return pHead(p);
481}
482
483/*2
484* returns (a copy of) the head term of a without the coef
485*/
486#ifdef PDEBUG
487poly pDBHead0(poly p,char *f, int l)
488#else
489poly _pHead0(poly p)
490#endif
491{
492  poly w=NULL;
493
494  if (p!=NULL)
495  {
496#ifdef PDEBUG
497    w = pDBNew(f,l);
498#else
499    w = pNew();
500#endif
501    pCopy2(w,p);
502    pSetCoeff0(w,NULL);
503    pNext(w) = NULL;
504  }
505  return w;
506}
507
508
509/***************************************************************
510 *
511 * Routines for turned on debugging
512 *
513 ***************************************************************/
514
515#ifdef PDEBUG
516
517#if PDEBUG != 0
518Exponent_t pPDSetExp(poly p, int v, Exponent_t e, char* f, int l)
519{
520  if (v == 0)
521  {
522    Print("zero index to exponent in %s:%d\n", f, l);
523  }
524  if (v > pVariables)
525  {
526    Print("index %d to exponent too large in %s:%d\n", v, f, l);
527  }
528  return (p)->exp[_pExpIndex(v)]=(e);
529}
530
531Exponent_t pPDGetExp(poly p, int v, char* f, int l)
532{
533  if (v == 0)
534  {
535    Print("zero index to exponent in %s:%d\n", f, l);
536  }
537  if (v > pVariables)
538  {
539    Print("index %d to exponent too large in %s:%d\n", v, f, l);
540  }
541  return (p)->exp[_pExpIndex(v)];
542}
543
544Exponent_t pPDRingSetExp(ring r, poly p, int v, Exponent_t e, char* f, int l)
545{
546  if (v == 0)
547  {
548    Print("zero index to exponent in %s:%d\n", f, l);
549  }
550  if (v > r->N)
551  {
552    Print("index %d to exponent too large in %s:%d\n", v, f, l);
553  }
554  return (p)->exp[_pRingExpIndex(r, v)]=(e);
555}
556
557Exponent_t pPDRingGetExp(ring r, poly p, int v, char* f, int l)
558{
559  if (v == 0)
560  {
561    Print("zero index to exponent in %s:%d\n", f, l);
562  }
563  if (v > r->N)
564  {
565    Print("index %d to exponent too large in %s:%d\n", v, f, l);
566  }
567  return (p)->exp[_pRingExpIndex(r,v)];
568}
569
570Exponent_t pPDIncrExp(poly p, int v, char* f, int l)
571{
572  if (v == 0)
573  {
574    Print("zero index to exponent in %s:%d\n", f, l);
575  }
576  if (v > pVariables)
577  {
578    Print("index %d to exponent too large in %s:%d\n", v, f, l);
579  }
580  return ((p)->exp[_pExpIndex(v)])++;
581}
582
583Exponent_t pPDDecrExp(poly p, int v, char* f, int l)
584{
585  if (v == 0)
586  {
587    Print("zero index to exponent in %s:%d\n", f, l);
588  }
589  if (v > pVariables)
590  {
591    Print("index %d to exponent too large in %s:%d\n", v, f, l);
592  }
593  return ((p)->exp[_pExpIndex(v)])--;
594}
595
596Exponent_t pPDAddExp(poly p, int v, Exponent_t e, char* f, int l)
597{
598  if (v == 0)
599  {
600    Print("zero index to exponent in %s:%d\n", f, l);
601  }
602  if (v > pVariables)
603  {
604    Print("index %d to exponent too large in %s:%d\n", v, f, l);
605  }
606  return ((p)->exp[_pExpIndex(v)]) += (e);
607}
608
609Exponent_t pPDSubExp(poly p, int v, Exponent_t e, char* f, int l)
610{
611  if (v == 0)
612  {
613    Print("zero index to exponent in %s:%d\n", f, l);
614  }
615  if (v > pVariables)
616  {
617    Print("index %d to exponent too large in %s:%d\n", v, f, l);
618  }
619  return ((p)->exp[_pExpIndex(v)]) -= (e);
620}
621
622Exponent_t pPDMultExp(poly p, int v, Exponent_t e, char* f, int l)
623{
624  if (v == 0)
625  {
626    Print("zero index to exponent in %s:%d\n", f, l);
627  }
628  if (v > pVariables)
629  {
630    Print("index %d to exponent too large in %s:%d\n", v, f, l);
631  }
632  return ((p)->exp[_pExpIndex(v)]) *= (e);
633}
634
635// checks whether fast monom add did not overflow
636void pDBMonAddFast(poly p1, poly p2, char* f, int l)
637{
638  poly ptemp = pNew();
639  pCopy2(ptemp, p1);
640
641  __pMonAddFast(p1, p2);
642
643  for (int i=1; i<=pVariables; i++)
644  {
645    pAddExp(ptemp, i, pGetExp(p2, i));
646  }
647  pGetOrder(ptemp) += pGetOrder(p2);
648
649  if (! pEqual(ptemp, p1))
650  {
651    Print("Error in pMonAddFast in %s:%d\n", f, l);
652  }
653
654  pFree1(ptemp);
655}
656
657void pDBCopyAddFast(poly p1, poly p2, poly p3, char* f, int l)
658{
659  if (p2 == p1 || p3 == p1)
660  {
661    Print("Error in pCopyAddFast: Destination equals source in %s:%d\n", f, l);
662  }
663  poly ptemp = pNew();
664  __pCopyAddFast(ptemp, p2, p3);
665
666  pCopy2(p1, p2);
667  pDBMonAddFast(p1, p3, f, l);
668
669  if (! pEqual(ptemp, p1))
670    Print("Error in pCopyMonAddFast in %s:%d\n", f, l);
671  pFree1(ptemp);
672}
673
674void pDBCopyAddFastHomog(poly p1, poly p2, poly p3, Order_t Order,
675                         char* f, int l)
676{
677  pDBCopyAddFast(p1, p2, p3, f, l);
678  if (p1->Order != Order)
679    Print("Error in pCopyAddFastHomog: Order is different from sum\n");
680}
681
682   
683
684static BOOLEAN OldpDivisibleBy(poly a, poly b)
685{
686  if ((a!=NULL)&&((pGetComp(a)==0) || (pGetComp(a) == pGetComp(b))))
687  {
688    for (int i = 1; i<=pVariables; i++)
689      if (pGetExp(a, i) > pGetExp(b,i)) return FALSE;
690    return TRUE;
691  }
692  return FALSE;
693}
694
695
696BOOLEAN pDBDivisibleBy(poly a, poly b, char* f, int l)
697{
698  BOOLEAN istrue = OldpDivisibleBy(a,b);
699  BOOLEAN f_istrue = _pDivisibleBy_orig(a, b);
700
701  if (istrue != f_istrue)
702  {
703    Print("Error in pDivisibleBy in %s:%d\n", f, l);
704    _pDivisibleBy_orig(a, b);
705  }
706  return f_istrue;
707}
708
709BOOLEAN pDBDivisibleBy1(poly a, poly b, char* f, int l)
710{
711  BOOLEAN istrue = OldpDivisibleBy(a,b);
712  BOOLEAN f_istrue = _pDivisibleBy1_orig(a, b);
713
714  if (istrue != f_istrue)
715  {
716    Print("Error in pDivisibleBy1 in %s:%d\n", f, l);
717    _pDivisibleBy1_orig(a, b);
718  }
719  return f_istrue;
720}
721
722BOOLEAN pDBDivisibleBy2(poly a, poly b, char* f, int l)
723{
724  BOOLEAN istrue = OldpDivisibleBy(a,b);
725  BOOLEAN f_istrue = __pDivisibleBy(a, b);
726
727  if (istrue != f_istrue)
728  {
729    Print("Error in pDivisibleBy2 in %s:%d\n", f, l);
730    __pDivisibleBy(a, b);
731  }
732  return f_istrue;
733}
734
735#endif // PDEBUG != 0
736
737
738BOOLEAN pDBTest(poly p, char *f, int l)
739{
740  poly old=NULL;
741  BOOLEAN ismod=FALSE;
742  while (p!=NULL)
743  {
744#ifdef MDEBUG
745    if (!mmDBTestBlock(p,mm_specSize,f,l))
746      return FALSE;
747#endif
748#ifdef LDEBUG
749    if (!nDBTest(p->coef,f,l))
750      return FALSE;
751#endif
752    if ((p->coef==NULL)&&(nGetChar()<2))
753    {
754      Print("NULL coef in poly in %s:%d\n",f,l);
755      return FALSE;
756    }
757    if (nIsZero(p->coef))
758    {
759      Print("zero coef in poly in %s:%d\n",f,l);
760      return FALSE;
761    }
762    int i=pVariables;
763#ifndef DRING
764    for(;i;i--)
765    {
766      if (pGetExp(p,i)<0)
767      {
768        Print("neg. Exponent in %s:%d\n",f,l);
769        return FALSE;
770      }
771    }
772    if (pGetComp(p)<0)
773    {
774      Print("neg Component in %s:%d\n",f,l);
775      return FALSE;
776    }
777#endif
778    if (ismod==0)
779    {
780      if (pGetComp(p)>0) ismod=1;
781      else               ismod=2;
782    }
783    else if (ismod==1)
784    {
785      if (pGetComp(p)==0)
786      {
787        Print("mix vec./poly in %s:%d\n",f,l);
788        return FALSE;
789      }
790    }
791    else if (ismod==2)
792    {
793      if (pGetComp(p)!=0)
794      {
795        Print("mix poly/vec. in %s:%d\n",f,l);
796        return FALSE;
797      }
798    }
799    i=p->Order;
800    pSetm(p);
801    if(i!=p->Order)
802    {
803      Print("wrong ord-field in %s:%d\n",f,l);
804      return FALSE;
805    }
806    old=p;
807    pIter(p);
808    if (pComp(old,p)!=1)
809    {
810      PrintS("wrong order (");
811      wrp(old);
812      Print(") in %s:%d\n",f,l);
813      return FALSE;
814    }
815  }
816  return TRUE;
817}
818#endif // PDEBUG
819
820
821#endif // POLYS_IMPL_CC
Note: See TracBrowser for help on using the repository browser.