source: git/kernel/longalg.cc @ 259111f

spielwiese
Last change on this file since 259111f was 259111f, checked in by Hans Schönemann <hannes@…>, 14 years ago
*hannes: syntax fix git-svn-id: file:///usr/local/Singular/svn/trunk@12185 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 48.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longalg.cc,v 1.61 2009-10-10 10:44:37 Singular Exp $ */
5/*
6* ABSTRACT:   algebraic numbers
7*/
8
9#include <stdio.h>
10#include <string.h>
11#include "mod2.h"
12#include "structs.h"
13#include "omalloc.h"
14#include "febase.h"
15#include "longrat.h"
16#include "modulop.h"
17#include "numbers.h"
18#include "polys.h"
19#include "ideals.h"
20#include "ring.h"
21#ifdef HAVE_FACTORY
22#include "factory.h"
23#include "clapsing.h"
24#include "clapconv.h"
25#endif
26#include "longalg.h"
27
28naIdeal naI=NULL;
29
30int naNumbOfPar;
31napoly naMinimalPoly;
32#define naParNames (currRing->parameter)
33static int naIsChar0;
34static ring naMapRing;
35
36#ifdef LDEBUG
37#define naTest(a) naDBTest(a,__FILE__,__LINE__)
38BOOLEAN naDBTest(number a, const char *f,const int l);
39#else
40#define naTest(a)
41#endif
42
43number (*naMap)(number from);
44/* procedure variables */
45static numberfunc
46                nacMult, nacSub, nacAdd, nacDiv, nacIntDiv;
47static number   (*nacGcd)(number a, number b, const ring r);
48static number   (*nacLcm)(number a, number b, const ring r);
49static number   (*nacInit)(int i, const ring r);
50static int      (*nacInt)(number &n, const ring r);
51static void     (*nacDelete)(number *a, const ring r);
52#undef n_Delete
53#define n_Delete(A,R) nacDelete(A,R)
54       void     (*nacNormalize)(number &a);
55static number   (*nacNeg)(number a);
56static void     (*nacWrite)(number &a);
57       number   (*nacCopy)(number a);
58static number   (*nacInvers)(number a);
59       BOOLEAN  (*nacIsZero)(number a);
60static BOOLEAN  (*nacIsOne)(number a);
61static BOOLEAN  (*nacIsMOne)(number a);
62static BOOLEAN  (*nacGreaterZero)(number a);
63static const char   * (*nacRead) (const char *s, number *a);
64static napoly napRedp(napoly q);
65static napoly napTailred(napoly q);
66static BOOLEAN napDivPoly(napoly p, napoly q);
67static int napExpi(int i, napoly a, napoly b);
68       ring nacRing;
69
70#define napCopy(p)       p_Copy(p,nacRing)
71
72void naCoefNormalize(number pp);
73
74static number nadGcd( number a, number b, const ring r) { return nacInit(1,r); }
75/*2
76*  sets the appropriate operators
77*/
78void naSetChar(int i, ring r)
79{
80  if (naI!=NULL)
81  {
82    int j;
83    for (j=naI->anz-1; j>=0; j--)
84       p_Delete (&naI->liste[j],nacRing);
85    omFreeSize((ADDRESS)naI->liste,naI->anz*sizeof(napoly));
86    omFreeBin((ADDRESS)naI, snaIdeal_bin);
87    naI=NULL;
88  }
89  naMap = naCopy;
90
91  if (r->minpoly!=NULL)
92  {
93    naMinimalPoly=((lnumber)r->minpoly)->z;
94    omCheckAddr(naMinimalPoly);
95  }
96  else
97    naMinimalPoly = NULL;
98  if (r->minideal!=NULL)
99  {
100    naI=(naIdeal)omAllocBin(snaIdeal_bin);
101    naI->anz=IDELEMS(r->minideal);
102    naI->liste=(napoly*)omAlloc(naI->anz*sizeof(napoly));
103    int j;
104    for (j=naI->anz-1; j>=0; j--)
105    {
106      lnumber a = (lnumber)pGetCoeff(r->minideal->m[j]);
107      naI->liste[j]=napCopy(a->z);
108    }
109  }
110
111  naNumbOfPar=rPar(r);
112  if (i == 1)
113  {
114    naIsChar0 = 1;
115  }
116  else if (i < 0)
117  {
118    naIsChar0 = 0;
119    npSetChar(-i, r->algring); // to be changed HS
120  }
121#ifdef TEST
122  else
123  {
124    Print("naSetChar:c=%d param=%d\n",i,rPar(r));
125  }
126#endif
127  nacRing        = r->algring;
128  nacInit        = nacRing->cf->cfInit;
129  nacInt         = nacRing->cf->n_Int;
130  nacCopy        = nacRing->cf->nCopy;
131  nacAdd         = nacRing->cf->nAdd;
132  nacSub         = nacRing->cf->nSub;
133  nacNormalize   = nacRing->cf->nNormalize;
134  nacNeg         = nacRing->cf->nNeg;
135  nacIsZero      = nacRing->cf->nIsZero;
136  nacRead        = nacRing->cf->nRead;
137  nacWrite       = nacRing->cf->nWrite;
138  nacGreaterZero = nacRing->cf->nGreaterZero;
139  nacIsOne       = nacRing->cf->nIsOne;
140  nacIsMOne      = nacRing->cf->nIsMOne;
141  nacGcd         = nacRing->cf->nGcd;
142  nacLcm         = nacRing->cf->nLcm;
143  nacMult        = nacRing->cf->nMult;
144  nacDiv         = nacRing->cf->nDiv;
145  nacIntDiv      = nacRing->cf->nIntDiv;
146  nacInvers      = nacRing->cf->nInvers;
147  nacDelete      = nacRing->cf->cfDelete;
148}
149
150/*============= procedure for polynomials: napXXXX =======================*/
151
152
153
154#ifdef LDEBUG
155static void napTest(napoly p)
156{
157  while (p != NULL)
158  {
159    if (naIsChar0)
160      nlDBTest(pGetCoeff(p), "", 0);
161    pIter(p);
162  }
163}
164#else
165#define napTest(p) ((void) 0)
166#endif
167
168#define napSetCoeff(p,n) {n_Delete(&pGetCoeff(p),nacRing);pGetCoeff(p)=n;}
169#define napComp(p,q)     p_LmCmp((poly)p,(poly)q, nacRing)
170#define napMultT(A,E)    A=(napoly)p_Mult_mm((poly)A,(poly)E,nacRing)
171#define napDeg(p)        (int)p_ExpVectorQuerSum(p, nacRing)
172
173/*3
174* creates  an napoly
175*/
176napoly napInitz(number z)
177{
178  napoly a = (napoly)p_Init(nacRing);
179  pGetCoeff(a) = z;
180  return a;
181}
182
183/*3
184* copy a napoly. poly
185*/
186static napoly napCopyNeg(napoly p)
187{
188  napoly r=napCopy(p);
189  r=(napoly)p_Neg((poly)r, nacRing);
190  return r;
191}
192
193/*3
194* returns ph * z
195*/
196static void napMultN(napoly p, number z)
197{
198  number t;
199  poly pp=p;
200
201  while (p!=NULL)
202  {
203    t = nacMult(pGetCoeff(p), z);
204    n_Delete(&pGetCoeff(p),nacRing);
205    pGetCoeff(p) = t;
206    pIter(p);
207  }
208  p_Normalize(pp,nacRing);
209}
210
211/*3
212*  division with rest; f = g*q + r, returns r and destroy f
213*/
214napoly napRemainder(napoly f, const napoly  g)
215{
216  napoly a, h, qq;
217
218  qq = (napoly)p_Init(nacRing);
219  pNext(qq) = NULL;
220  p_Normalize(g, nacRing);
221  p_Normalize(f, nacRing);
222  a = f;
223  do
224  {
225    napSetExp(qq,1, p_GetExp(a,1,nacRing) - p_GetExp(g,1,nacRing));
226    napSetm(qq);
227    pGetCoeff(qq) = nacDiv(pGetCoeff(a), pGetCoeff(g));
228    pGetCoeff(qq) = nacNeg(pGetCoeff(qq));
229    h = napCopy(g);
230    napMultT(h, qq);
231    n_Delete(&pGetCoeff(qq),nacRing);
232    a = napAdd(a, h);
233  }
234  while ((a!=NULL) && (p_GetExp(a,1,nacRing) >= p_GetExp(g,1,nacRing)));
235  omFreeBinAddr(qq);
236  return a;
237}
238
239/*3
240*  division with rest; f = g*q + r,  destroy f
241*/
242static void napDivMod(napoly f, napoly  g, napoly *q, napoly *r)
243{
244  napoly a, h, b, qq;
245
246  qq = (napoly)p_Init(nacRing);
247  pNext(qq) = b = NULL;
248  p_Normalize(g,nacRing);
249  p_Normalize(f,nacRing);
250  a = f;
251  do
252  {
253    napSetExp(qq,1, p_GetExp(a,1,nacRing) - p_GetExp(g,1,nacRing));
254    p_Setm(qq,nacRing);
255    pGetCoeff(qq) = nacDiv(pGetCoeff(a), pGetCoeff(g));
256    nacNormalize(pGetCoeff(qq));
257    b = napAdd(b, napCopy(qq));
258    pGetCoeff(qq) = nacNeg(pGetCoeff(qq));
259    h = napCopy(g);
260    napMultT(h, qq);
261    n_Delete(&pGetCoeff(qq),nacRing);
262    a = napAdd(a, h);
263  }
264  while ((a!=NULL) && (p_GetExp(a,1,nacRing) >= p_GetExp(g,1,nacRing)));
265  omFreeBinAddr(qq);
266  *q = b;
267  *r = a;
268}
269
270/*3
271*  returns z with z*x mod c = 1
272*/
273static napoly napInvers(napoly x, const napoly c)
274{
275  napoly y, r, qa, qn, q;
276  number t, h;
277
278  if (p_GetExp(x,1,nacRing) >= p_GetExp(c,1,nacRing))
279    x = napRemainder(x, c);
280  if (x==NULL)
281  {
282    goto zero_divisor;
283  }
284  if (p_GetExp(x,1,nacRing)==0)
285  {
286    if (!nacIsOne(pGetCoeff(x)))
287    {
288      t = nacInvers(pGetCoeff(x));
289      nacNormalize(t);
290      n_Delete(&pGetCoeff(x),nacRing);
291      pGetCoeff(x) = t;
292    }
293    return x;
294  }
295  y = napCopy(c);
296  napDivMod(y, x, &qa, &r);
297  if (r==NULL)
298  {
299    goto zero_divisor;
300  }
301  if (p_GetExp(r,1,nacRing)==0)
302  {
303    t = nacInvers(pGetCoeff(r));
304    t = nacNeg(t);
305    napMultN(qa, t);
306    n_Delete(&t,nacRing);
307    p_Delete(&x,nacRing);
308    p_Delete(&r,nacRing);
309    return qa;
310  }
311  y = x;
312  x = r;
313  napDivMod(y, x, &q, &r);
314  if (r==NULL)
315  {
316    goto zero_divisor;
317  }
318  if (p_GetExp(r,1,nacRing)==0)
319  {
320    q = p_Mult_q(q, qa,nacRing);
321    q = napAdd(q, p_ISet(1,nacRing));
322    t = nacInvers(pGetCoeff(r));
323    napMultN(q, t);
324    n_Delete(&t,nacRing);
325    p_Delete(&x,nacRing);
326    p_Delete(&r,nacRing);
327    if (p_GetExp(q,1,nacRing) >= p_GetExp(c,1,nacRing))
328      q = napRemainder(q, c);
329    return q;
330  }
331  q = p_Mult_q(q, napCopy(qa),nacRing);
332  q = napAdd(q, p_ISet(1,nacRing));
333  qa = napNeg(qa);
334  loop
335  {
336    y = x;
337    x = r;
338    napDivMod(y, x, &qn, &r);
339    if (r==NULL)
340    {
341      break;
342    }
343    if (p_GetExp(r,1,nacRing)==0)
344    {
345      q = p_Mult_q(q, qn,nacRing);
346      q = napNeg(q);
347      q = napAdd(q, qa);
348      t = nacInvers(pGetCoeff(r));
349      napMultN(q, t);
350      n_Delete(&t,nacRing);
351      p_Delete(&x,nacRing);
352      p_Delete(&r,nacRing);
353      if (p_GetExp(q,1,nacRing) >= p_GetExp(c,1,nacRing))
354        q = napRemainder(q, c);
355      return q;
356    }
357    y = q;
358    q = p_Mult_q(napCopy(q), qn, nacRing);
359    q = napNeg(q);
360    q = napAdd(q, qa);
361    qa = y;
362  }
363// zero divisor found:
364zero_divisor:
365  Werror("zero divisor found - your minpoly is not irreducible");
366  return x;
367}
368
369/*3
370* the max degree of an napoly poly (used for test of "simple" et al.)
371*/
372static int  napMaxDeg(napoly p)
373{
374  int  d = 0;
375  while(p!=NULL)
376  {
377    d=si_max(d,napDeg(p));
378    pIter(p);
379  }
380  return d;
381}
382
383/*3
384* the max degree of an napoly poly (used for test of "simple" et al.)
385*/
386static int  napMaxDegLen(napoly p, int &l)
387{
388  int  d = 0;
389  int ll=0;
390  while(p!=NULL)
391  {
392    d=si_max(d,napDeg(p));
393    pIter(p);
394    ll++;
395  }
396  l=ll;
397  return d;
398}
399
400
401/*3
402*writes a polynomial number
403*/
404void napWrite(napoly p,const BOOLEAN has_denom)
405{
406  if (p==NULL)
407    StringAppendS("0");
408  else if (p_LmIsConstant(p,nacRing))
409  {
410    BOOLEAN kl=FALSE;
411    if (has_denom)
412    {
413      number den=nacRing->cf->cfGetDenom(pGetCoeff(p), nacRing);
414      kl=!n_IsOne(den,nacRing);
415      n_Delete(&den, nacRing);
416    }
417    if (kl) StringAppendS("(");
418    //StringAppendS("-1");
419    nacWrite(pGetCoeff(p));
420    if (kl) StringAppendS(")");
421  }
422  else
423  {
424    StringAppendS("(");
425    loop
426    {
427      BOOLEAN wroteCoeff=FALSE;
428      if ((p_LmIsConstant(p,nacRing))
429      || ((!nacIsOne(pGetCoeff(p)))
430        && (!nacIsMOne(pGetCoeff(p)))))
431      {
432        nacWrite(pGetCoeff(p));
433        wroteCoeff=(currRing->ShortOut==0);
434      }
435      else if (nacIsMOne(pGetCoeff(p)))
436      {
437        StringAppendS("-");
438      }
439      int  i;
440      for (i = 0; i < naNumbOfPar; i++)
441      {
442        int e=p_GetExp(p,i+1,nacRing);
443        if (e > 0)
444        {
445          if (wroteCoeff)
446            StringAppendS("*");
447          else
448            wroteCoeff=(currRing->ShortOut==0);
449          StringAppendS(naParNames[i]);
450          if (e > 1)
451          {
452            if (currRing->ShortOut == 0)
453              StringAppendS("^");
454            StringAppend("%d", e);
455          }
456        }
457      } /*for*/
458      pIter(p);
459      if (p==NULL)
460        break;
461      if (nacGreaterZero(pGetCoeff(p)))
462        StringAppendS("+");
463    }
464    StringAppendS(")");
465  }
466}
467
468
469static const char *napHandleMons(const char *s, int i, napoly ex)
470{
471  int  j;
472  if (strncmp(s,naParNames[i],strlen(naParNames[i]))==0)
473  {
474    s+=strlen(naParNames[i]);
475    if ((*s >= '0') && (*s <= '9'))
476    {
477      s = eati(s, &j);
478      napAddExp(ex,i+1,j);
479    }
480    else
481      napAddExp(ex,i+1,1);
482  }
483  return s;
484}
485static const char *napHandlePars(const char *s, int i, napoly ex)
486{
487  int  j;
488  if (strcmp(s,naParNames[i])==0)
489  {
490    s+=strlen(naParNames[i]);
491    napSetExp(ex,i+1,1);
492  }
493  return s;
494}
495
496/*3  reads a monomial  */
497static const char  *napRead(const char *s, napoly *b)
498{
499  napoly a;
500  int  i;
501  a = (napoly)p_Init(nacRing);
502  if ((*s >= '0') && (*s <= '9'))
503  {
504    s = nacRead(s, &pGetCoeff(a));
505    if (nacIsZero(pGetCoeff(a)))
506    {
507      p_LmDelete(&a,nacRing);
508      *b = NULL;
509      return s;
510    }
511  }
512  else
513    pGetCoeff(a) = nacInit(1,nacRing);
514  i = 0;
515  const char  *olds=s;
516  loop
517  {
518    s = napHandlePars(s, i, a);
519    if (olds == s)
520      i++;
521    else if (*s == '\0')
522    {
523      *b = a;
524      return s;
525    }
526    if (i >= naNumbOfPar)
527      break;
528  }
529  i=0;
530  loop
531  {
532    olds = s;
533    s = napHandleMons(s, i, a);
534    if (olds == s)
535      i++;
536    else
537      i = 0;
538    if ((*s == '\0') || (i >= naNumbOfPar))
539      break;
540  }
541  *b = a;
542  return s;
543}
544
545static int napExp(napoly a, napoly b)
546{
547  while (pNext(a)!=NULL) pIter(a);
548  int m = p_GetExp(a,1,nacRing);
549  if (m==0) return 0;
550  while (pNext(b)!=NULL) pIter(b);
551  int mm=p_GetExp(b,1,nacRing);
552  if (m > mm) m = mm;
553  return m;
554}
555
556/*
557* finds the smallest i-th exponent in a and b
558* used to find it in a fraction
559*/
560static int napExpi(int i, napoly a, napoly b)
561{
562  if (a==NULL || b==NULL) return 0;
563  int m = p_GetExp(a,i+1,nacRing);
564  if (m==0) return 0;
565  while (pNext(a) != NULL)
566  {
567    pIter(a);
568    if (m > p_GetExp(a,i+1,nacRing))
569    {
570      m = p_GetExp(a,i+1,nacRing);
571      if (m==0) return 0;
572    }
573  }
574  do
575  {
576    if (m > p_GetExp(b,i+1,nacRing))
577    {
578      m = p_GetExp(b,i+1,nacRing);
579      if (m==0) return 0;
580    }
581    pIter(b);
582  }
583  while (b != NULL);
584  return m;
585}
586
587static void napContent(napoly ph)
588{
589  number h,d;
590  napoly p;
591
592  p = ph;
593  if (nacIsOne(pGetCoeff(p)))
594    return;
595  h = nacCopy(pGetCoeff(p));
596  pIter(p);
597  do
598  {
599    d=nacGcd(pGetCoeff(p), h, nacRing);
600    if(nacIsOne(d))
601    {
602      n_Delete(&h,nacRing);
603      n_Delete(&d,nacRing);
604      return;
605    }
606    n_Delete(&h,nacRing);
607    h = d;
608    pIter(p);
609  }
610  while (p!=NULL);
611  h = nacInvers(d);
612  n_Delete(&d,nacRing);
613  p = ph;
614  while (p!=NULL)
615  {
616    d = nacMult(pGetCoeff(p), h);
617    n_Delete(&pGetCoeff(p),nacRing);
618    pGetCoeff(p) = d;
619    pIter(p);
620  }
621  n_Delete(&h,nacRing);
622}
623
624static void napCleardenom(napoly ph)
625{
626  number d, h;
627  napoly p;
628
629  if (!naIsChar0)
630    return;
631  p = ph;
632  h = nacInit(1,nacRing);
633  while (p!=NULL)
634  {
635    d = nacLcm(h, pGetCoeff(p), nacRing);
636    n_Delete(&h,nacRing);
637    h = d;
638    pIter(p);
639  }
640  if(!nacIsOne(h))
641  {
642    p = ph;
643    while (p!=NULL)
644    {
645      d=nacMult(h, pGetCoeff(p));
646      n_Delete(&pGetCoeff(p),nacRing);
647      nacNormalize(d);
648      pGetCoeff(p) = d;
649      pIter(p);
650    }
651    n_Delete(&h,nacRing);
652  }
653  napContent(ph);
654}
655
656static napoly napGcd0(napoly a, napoly b)
657{
658  number x, y;
659  if (!naIsChar0)
660    return p_ISet(1,nacRing);
661  x = nacCopy(pGetCoeff(a));
662  if (nacIsOne(x))
663    return napInitz(x);
664  while (pNext(a)!=NULL)
665  {
666    pIter(a);
667    y = nacGcd(x, pGetCoeff(a), nacRing);
668    n_Delete(&x,nacRing);
669    x = y;
670    if (nacIsOne(x))
671      return napInitz(x);
672  }
673  do
674  {
675    y = nacGcd(x, pGetCoeff(b), nacRing);
676    n_Delete(&x,nacRing);
677    x = y;
678    if (nacIsOne(x))
679      return napInitz(x);
680    pIter(b);
681  }
682  while (b!=NULL);
683  return napInitz(x);
684}
685
686/*3
687* result =gcd(a,b)
688*/
689static napoly napGcd(napoly a, napoly b)
690{
691  int i;
692  napoly g, x, y, h;
693  if ((a==NULL)
694  || ((pNext(a)==NULL)&&(nacIsZero(pGetCoeff(a)))))
695  {
696    if ((b==NULL)
697    || ((pNext(b)==NULL)&&(nacIsZero(pGetCoeff(b)))))
698    {
699      return p_ISet(1,nacRing);
700    }
701    return napCopy(b);
702  }
703  else
704  if ((b==NULL)
705  || ((pNext(b)==NULL)&&(nacIsZero(pGetCoeff(b)))))
706  {
707    return napCopy(a);
708  }
709  if (naMinimalPoly != NULL)
710  {
711    if (p_GetExp(a,1,nacRing) >= p_GetExp(b,1,nacRing))
712    {
713      x = a;
714      y = b;
715    }
716    else
717    {
718      x = b;
719      y = a;
720    }
721    if (!naIsChar0) g = p_ISet(1,nacRing);
722    else            g = napGcd0(x, y);
723    if (pNext(y)==NULL)
724    {
725      napSetExp(g,1, napExp(x, y));
726      p_Setm(g,nacRing);
727      return g;
728    }
729    x = napCopy(x);
730    y = napCopy(y);
731    loop
732    {
733      h = napRemainder(x, y);
734      if (h==NULL)
735      {
736        napCleardenom(y);
737        if (!nacIsOne(pGetCoeff(g)))
738          napMultN(y, pGetCoeff(g));
739        p_LmDelete(&g,nacRing);
740        return y;
741      }
742      else if (pNext(h)==NULL)
743        break;
744      x = y;
745      y = h;
746    }
747    p_Delete(&y,nacRing);
748    p_LmDelete(&h,nacRing);
749    napSetExp(g,1, napExp(a, b));
750    p_Setm(g,nacRing);
751    return g;
752  }
753  // Hmm ... this is a memory leak
754  // x = (napoly)p_Init(nacRing);
755  g=a;
756  h=b;
757  if (!naIsChar0) x = p_ISet(1,nacRing);
758  else            x = napGcd0(g,h);
759  for (i=(naNumbOfPar-1); i>=0; i--)
760  {
761    napSetExp(x,i+1, napExpi(i,a,b));
762    p_Setm(x,nacRing);
763  }
764  return x;
765}
766
767
768number napLcm(napoly a)
769{
770  number h = nacInit(1,nacRing);
771
772  if (naIsChar0)
773  {
774    number d;
775    napoly b = a;
776
777    while (b!=NULL)
778    {
779      d = nacLcm(h, pGetCoeff(b), nacRing);
780      n_Delete(&h,nacRing);
781      h = d;
782      pIter(b);
783    }
784  }
785  return h;
786}
787
788
789/*2
790* meins  (for reduction in algebraic extension)
791* checks if head of p divides head of q
792* doesn't delete p and q
793*/
794static BOOLEAN napDivPoly (napoly p, napoly q)
795{
796  int j=1;   /* evtl. von naNumber.. -1 abwaerts zaehlen */
797
798  while (p_GetExp(p,j,nacRing) <= p_GetExp(q,j,nacRing))
799  {
800    j++;
801    if (j > naNumbOfPar)
802      return 1;
803  }
804  return 0;
805}
806
807
808/*2
809* meins  (for reduction in algebraic extension)
810* Normalform of poly with naI
811* changes q and returns it
812*/
813napoly napRedp (napoly q)
814{
815  napoly h = (napoly)p_Init(nacRing);
816  int i=0,j;
817
818  loop
819  {
820    if (napDivPoly (naI->liste[i], q))
821    {
822      /* h = lt(q)/lt(naI->liste[i])*/
823      pGetCoeff(h) = nacCopy(pGetCoeff(q));
824      for (j=naNumbOfPar; j>0; j--)
825        napSetExp(h,j, p_GetExp(q,j,nacRing) - p_GetExp(naI->liste[i],j,nacRing));
826      p_Setm(h,nacRing);
827      h = p_Mult_q(h, napCopy(naI->liste[i]),nacRing);
828      h = napNeg (h);
829      q = napAdd (q, napCopy(h));
830      p_Delete (&pNext(h),nacRing);
831      if (q == NULL)
832      {
833        p_Delete(&h,nacRing);
834        return q;
835      }
836      /* try to reduce further */
837      i = 0;
838    }
839    else
840    {
841      i++;
842      if (i >= naI->anz)
843      {
844        p_Delete(&h,nacRing);
845        return q;
846      }
847    }
848  }
849}
850
851
852/*2
853* meins  (for reduction in algebraic extension)
854* reduces the tail of Poly q
855* needs q != NULL
856* changes q and returns it
857*/
858napoly napTailred (napoly q)
859{
860  napoly h;
861
862  h = pNext(q);
863  while (h != NULL)
864  {
865     h = napRedp (h);
866     if (h == NULL)
867        return q;
868     pIter(h);
869  }
870  return q;
871}
872
873
874/*================ procedure for rational functions: naXXXX =================*/
875
876/*2
877*  z:= i
878*/
879number naInit(int i, const ring r)
880{
881  if (i!=0)
882  {
883    number c=n_Init(i,r->algring);
884    if (!n_IsZero(c,r->algring))
885    {
886      poly z=p_Init(r->algring);
887      pSetCoeff0(z,c);
888      lnumber l = (lnumber)omAllocBin(rnumber_bin);
889      l->z = z;
890      l->s = 2;
891      l->n = NULL;
892      return (number)l;
893    }
894  }
895  /*else*/
896  return NULL;
897}
898
899number  naPar(int i)
900{
901  lnumber l = (lnumber)omAllocBin(rnumber_bin);
902  l->s = 2;
903  l->z = p_ISet(1,nacRing);
904  napSetExp(l->z,i,1);
905  p_Setm(l->z,nacRing);
906  l->n = NULL;
907  return (number)l;
908}
909
910int     naParDeg(number n)     /* i := deg(n) */
911{
912  lnumber l = (lnumber)n;
913  if (l==NULL) return -1;
914  return napDeg(l->z);
915}
916
917//int     naParDeg(number n)     /* i := deg(n) */
918//{
919//  lnumber l = (lnumber)n;
920//  if (l==NULL) return -1;
921//  return napMaxDeg(l->z)+napMaxDeg(l->n);
922//}
923
924int     naSize(number n)     /* size desc. */
925{
926  lnumber l = (lnumber)n;
927  if (l==NULL) return -1;
928  int len_z;
929  int len_n;
930  int o=napMaxDegLen(l->z,len_z)+napMaxDegLen(l->n,len_n);
931  return (len_z+len_n)+o;
932}
933
934/*2
935* convert a number to int (if possible)
936*/
937int naInt(number &n, const ring r)
938{
939  lnumber l=(lnumber)n;
940  if ((l!=NULL)&&(l->n==NULL)&&(p_IsConstant(l->z,r->algring)))
941  {
942    return nacInt(pGetCoeff(l->z),r->algring);
943  }
944  return 0;
945}
946
947/*2
948*  deletes p
949*/
950void naDelete(number *p, const ring r)
951{
952  if ((*p)!=r->minpoly)
953  {
954    lnumber l = (lnumber) * p;
955    if (l==NULL) return;
956    p_Delete(&(l->z),r->algring);
957    p_Delete(&(l->n),r->algring);
958    omFreeBin((ADDRESS)l,  rnumber_bin);
959  }
960  *p = NULL;
961}
962
963/*2
964* copy p to erg
965*/
966number naCopy(number p)
967{
968  if (p==NULL) return NULL;
969  naTest(p);
970  lnumber erg;
971  lnumber src = (lnumber)p;
972  erg = (lnumber)omAlloc0Bin(rnumber_bin);
973  erg->z = p_Copy(src->z, nacRing);
974  erg->n = p_Copy(src->n, nacRing);
975  erg->s = src->s;
976  return (number)erg;
977}
978number na_Copy(number p, const ring r)
979{
980  if (p==NULL) return NULL;
981  lnumber erg;
982  lnumber src = (lnumber)p;
983  erg = (lnumber)omAlloc0Bin(rnumber_bin);
984  erg->z = p_Copy(src->z,r->algring);
985  erg->n = p_Copy(src->n,r->algring);
986  erg->s = src->s;
987  return (number)erg;
988}
989
990/*2
991* a dummy number: 0
992*/
993void naNew(number *z)
994{
995  *z = NULL;
996}
997
998/*2
999*  addition; lu:= la + lb
1000*/
1001number naAdd(number la, number lb)
1002{
1003  napoly x, y;
1004  lnumber lu;
1005  lnumber a = (lnumber)la;
1006  lnumber b = (lnumber)lb;
1007  if (a==NULL) return naCopy(lb);
1008  if (b==NULL) return naCopy(la);
1009  omCheckAddrSize(a,sizeof(snumber));
1010  omCheckAddrSize(b,sizeof(snumber));
1011  lu = (lnumber)omAllocBin(rnumber_bin);
1012  if (b->n!=NULL) x = pp_Mult_qq(a->z, b->n,nacRing);
1013  else            x = napCopy(a->z);
1014  if (a->n!=NULL) y = pp_Mult_qq(b->z, a->n,nacRing);
1015  else            y = napCopy(b->z);
1016  lu->z = napAdd(x, y);
1017  if (lu->z==NULL)
1018  {
1019    omFreeBin((ADDRESS)lu,  rnumber_bin);
1020    return (number)NULL;
1021  }
1022  if (a->n!=NULL)
1023  {
1024    if (b->n!=NULL) x = pp_Mult_qq(a->n, b->n,nacRing);
1025    else            x = napCopy(a->n);
1026  }
1027  else
1028  {
1029    if (b->n!=NULL) x = napCopy(b->n);
1030    else            x = NULL;
1031  }
1032  //if (x!=NULL)
1033  //{
1034  //  if (p_LmIsConstant(x,nacRing))
1035  //  {
1036  //    number inv=nacInvers(pGetCoeff(x));
1037  //    napMultN(lu->z,inv);
1038  //    n_Delete(&inv,nacRing);
1039  //    napDelete(&x);
1040  //  }
1041  //}
1042  lu->n = x;
1043  lu->s = FALSE;
1044  number luu=(number)lu;
1045  naCoefNormalize(luu);
1046  lu=(lnumber)luu;
1047  naTest((number)lu);
1048  return (number)lu;
1049}
1050
1051/*2
1052*  subtraction; r:= la - lb
1053*/
1054number naSub(number la, number lb)
1055{
1056  lnumber lu;
1057
1058  if (lb==NULL) return naCopy(la);
1059  if (la==NULL)
1060  {
1061    lu = (lnumber)naCopy(lb);
1062    lu->z = napNeg(lu->z);
1063    return (number)lu;
1064  }
1065
1066  lnumber a = (lnumber)la;
1067  lnumber b = (lnumber)lb;
1068
1069  omCheckAddrSize(a,sizeof(snumber));
1070  omCheckAddrSize(b,sizeof(snumber));
1071
1072  napoly x, y;
1073  lu = (lnumber)omAllocBin(rnumber_bin);
1074  if (b->n!=NULL) x = pp_Mult_qq(a->z, b->n,nacRing);
1075  else            x = napCopy(a->z);
1076  if (a->n!=NULL) y = p_Mult_q(napCopy(b->z), napCopyNeg(a->n),nacRing);
1077  else            y = napCopyNeg(b->z);
1078  lu->z = napAdd(x, y);
1079  if (lu->z==NULL)
1080  {
1081    omFreeBin((ADDRESS)lu,  rnumber_bin);
1082    return (number)NULL;
1083  }
1084  if (a->n!=NULL)
1085  {
1086    if (b->n!=NULL) x = pp_Mult_qq(a->n, b->n,nacRing);
1087    else            x = napCopy(a->n);
1088  }
1089  else
1090  {
1091    if (b->n!=NULL) x = napCopy(b->n);
1092    else            x = NULL;
1093  }
1094  //if (x!=NULL)
1095  //{
1096  //  if (p_LmIsConstant(x,nacRing))
1097  //  {
1098  //    number inv=nacInvers(pGetCoeff(x));
1099  //    napMultN(lu->z,inv);
1100  //    n_Delete(&inv,nacRing);
1101  //    napDelete(&x);
1102  //  }
1103  //}
1104  lu->n = x;
1105  lu->s = FALSE;
1106  number luu=(number)lu;
1107  naCoefNormalize(luu);
1108  lu=(lnumber)luu;
1109  naTest((number)lu);
1110  return (number)lu;
1111}
1112
1113/*2
1114*  multiplication; r:= la * lb
1115*/
1116number naMult(number la, number lb)
1117{
1118  if ((la==NULL) || (lb==NULL))
1119    return NULL;
1120
1121  lnumber a = (lnumber)la;
1122  lnumber b = (lnumber)lb;
1123  lnumber lo;
1124  napoly x;
1125
1126  omCheckAddrSize(a,sizeof(snumber));
1127  omCheckAddrSize(b,sizeof(snumber));
1128  naTest(la);
1129  naTest(lb);
1130
1131  lo = (lnumber)omAllocBin(rnumber_bin);
1132  lo->z = pp_Mult_qq(a->z, b->z,nacRing);
1133
1134  if (a->n==NULL)
1135  {
1136    if (b->n==NULL)
1137      x = NULL;
1138    else
1139      x = napCopy(b->n);
1140  }
1141  else
1142  {
1143    if (b->n==NULL)
1144    {
1145      x = napCopy(a->n);
1146    }
1147    else
1148    {
1149      x = pp_Mult_qq(b->n, a->n, nacRing);
1150    }
1151  }
1152  if (naMinimalPoly!=NULL)
1153  {
1154    if (p_GetExp(lo->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1155      lo->z = napRemainder(lo->z, naMinimalPoly);
1156    if ((x!=NULL) && (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing)))
1157      x = napRemainder(x, naMinimalPoly);
1158  }
1159  if (naI!=NULL)
1160  {
1161    lo->z = napRedp (lo->z);
1162    if (lo->z != NULL)
1163       lo->z = napTailred (lo->z);
1164    if (x!=NULL)
1165    {
1166      x = napRedp (x);
1167      if (x!=NULL)
1168        x = napTailred (x);
1169    }
1170  }
1171  if ((x!=NULL) && (p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
1172    p_Delete(&x,nacRing);
1173  lo->n = x;
1174  if(lo->z==NULL)
1175  {
1176    omFreeBin((ADDRESS)lo, rnumber_bin);
1177    lo=NULL;
1178  }
1179  else
1180  {
1181    lo->s = 0;
1182    number luu=(number)lo;
1183    naCoefNormalize(luu);
1184    lo=(lnumber)luu;
1185  }
1186  naTest((number)lo);
1187  return (number)lo;
1188}
1189
1190number naIntDiv(number la, number lb)
1191{
1192  lnumber res;
1193  lnumber a = (lnumber)la;
1194  lnumber b = (lnumber)lb;
1195  if (a==NULL)
1196  {
1197    return NULL;
1198  }
1199  if (b==NULL)
1200  {
1201    WerrorS(nDivBy0);
1202    return NULL;
1203  }
1204  naNormalize(la);
1205  assume(a->z!=NULL && b->z!=NULL);
1206  assume(a->n==NULL && b->n==NULL);
1207  res = (lnumber)omAllocBin(rnumber_bin);
1208  res->z = napCopy(a->z);
1209  res->n = napCopy(b->z);
1210  res->s = 0;
1211  number nres=(number)res;
1212  naNormalize(nres);
1213
1214  //napDelete(&res->n);
1215  naTest(nres);
1216  return nres;
1217}
1218
1219/*2
1220*  division; lo:= la / lb
1221*/
1222number naDiv(number la, number lb)
1223{
1224  lnumber lo;
1225  lnumber a = (lnumber)la;
1226  lnumber b = (lnumber)lb;
1227  napoly x;
1228
1229  if (a==NULL)
1230    return NULL;
1231
1232  if (b==NULL)
1233  {
1234    WerrorS(nDivBy0);
1235    return NULL;
1236  }
1237  omCheckAddrSize(a,sizeof(snumber));
1238  omCheckAddrSize(b,sizeof(snumber));
1239  lo = (lnumber)omAllocBin(rnumber_bin);
1240  if (b->n!=NULL)
1241    lo->z = pp_Mult_qq(a->z, b->n,nacRing);
1242  else
1243    lo->z = napCopy(a->z);
1244  if (a->n!=NULL)
1245    x = pp_Mult_qq(b->z, a->n, nacRing);
1246  else
1247    x = napCopy(b->z);
1248  if (naMinimalPoly!=NULL)
1249  {
1250    if (p_GetExp(lo->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1251      lo->z = napRemainder(lo->z, naMinimalPoly);
1252    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1253      x = napRemainder(x, naMinimalPoly);
1254  }
1255  if (naI!=NULL)
1256  {
1257    lo->z = napRedp (lo->z);
1258    if (lo->z != NULL)
1259       lo->z = napTailred (lo->z);
1260    if (x!=NULL)
1261    {
1262      x = napRedp (x);
1263      if (x!=NULL)
1264        x = napTailred (x);
1265    }
1266  }
1267  if ((p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
1268    p_Delete(&x,nacRing);
1269  lo->n = x;
1270  number luu=(number)lo;
1271  naCoefNormalize(luu);
1272  lo=(lnumber)luu;
1273  naTest((number)lo);
1274  return (number)lo;
1275}
1276
1277/*2
1278*  za:= - za
1279*/
1280number naNeg(number za)
1281{
1282  if (za!=NULL)
1283  {
1284    lnumber e = (lnumber)za;
1285    naTest(za);
1286    e->z = napNeg(e->z);
1287  }
1288  return za;
1289}
1290
1291/*2
1292* 1/a
1293*/
1294number naInvers(number a)
1295{
1296  lnumber lo;
1297  lnumber b = (lnumber)a;
1298  napoly x;
1299
1300  if (b==NULL)
1301  {
1302    WerrorS(nDivBy0);
1303    return NULL;
1304  }
1305  omCheckAddrSize(b,sizeof(snumber));
1306  lo = (lnumber)omAlloc0Bin(rnumber_bin);
1307  lo->s = b->s;
1308  if (b->n!=NULL)
1309    lo->z = napCopy(b->n);
1310  else
1311    lo->z = p_ISet(1,nacRing);
1312  x = b->z;
1313  if ((!p_LmIsConstant(x,nacRing)) || !nacIsOne(pGetCoeff(x)))
1314    x = napCopy(x);
1315  else
1316  {
1317    lo->n = NULL;
1318    naTest((number)lo);
1319    return (number)lo;
1320  }
1321  if (naMinimalPoly!=NULL)
1322  {
1323    x = napInvers(x, naMinimalPoly);
1324    x = p_Mult_q(x, lo->z,nacRing);
1325    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1326      x = napRemainder(x, naMinimalPoly);
1327    lo->z = x;
1328    lo->n = NULL;
1329    lo->s = 2;
1330    while (x!=NULL)
1331    {
1332      nacNormalize(pGetCoeff(x));
1333      pIter(x);
1334    }
1335  }
1336  else
1337    lo->n = x;
1338  if (lo->n!=NULL)
1339  {
1340     number luu=(number)lo;
1341     naNormalize(luu);
1342     lo=(lnumber)luu;
1343  }
1344  naTest((number)lo);
1345  return (number)lo;
1346}
1347
1348
1349BOOLEAN naIsZero(number za)
1350{
1351  lnumber zb = (lnumber)za;
1352  naTest(za);
1353#ifdef LDEBUG
1354  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(2)");
1355#endif
1356  return (zb==NULL);
1357}
1358
1359
1360BOOLEAN naGreaterZero(number za)
1361{
1362  lnumber zb = (lnumber)za;
1363#ifdef LDEBUG
1364  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(3)");
1365#endif
1366  naTest(za);
1367  if (zb!=NULL)
1368  {
1369    return (nacGreaterZero(pGetCoeff(zb->z))||(!p_LmIsConstant(zb->z,nacRing)));
1370  }
1371  /* else */ return FALSE;
1372}
1373
1374
1375/*2
1376* a = b ?
1377*/
1378BOOLEAN naEqual (number a, number b)
1379{
1380  if(a==b) return TRUE;
1381  if((a==NULL)&&(b!=NULL)) return FALSE;
1382  if((b==NULL)&&(a!=NULL)) return FALSE;
1383
1384  lnumber aa=(lnumber)a;
1385  lnumber bb=(lnumber)b;
1386
1387  int an_deg=0;
1388  if(aa->n!=NULL)
1389    an_deg=napDeg(aa->n);
1390  int bn_deg=0;
1391  if(bb->n!=NULL)
1392    bn_deg=napDeg(bb->n);
1393  if(an_deg+napDeg(bb->z)!=bn_deg+napDeg(aa->z))
1394    return FALSE;
1395#if 0
1396  naNormalize(a);
1397  aa=(lnumber)a;
1398  naNormalize(b);
1399  bb=(lnumber)b;
1400  if((aa->n==NULL)&&(bb->n!=NULL)) return FALSE;
1401  if((bb->n==NULL)&&(aa->n!=NULL)) return FALSE;
1402  if(napComp(aa->z,bb->z)!=0) return FALSE;
1403  if((aa->n!=NULL) && (napComp(aa->n,bb->n))) return FALSE;
1404#endif
1405  number h = naSub(a, b);
1406  BOOLEAN bo = naIsZero(h);
1407  naDelete(&h,currRing);
1408  return bo;
1409}
1410
1411
1412BOOLEAN naGreater (number a, number b)
1413{
1414  if (naIsZero(a))
1415    return FALSE;
1416  if (naIsZero(b))
1417    return TRUE; /* a!= 0)*/
1418  return napDeg(((lnumber)a)->z)>napDeg(((lnumber)b)->z);
1419}
1420
1421/*2
1422* reads a number
1423*/
1424const char  *naRead(const char *s, number *p)
1425{
1426  napoly x;
1427  lnumber a;
1428  s = napRead(s, &x);
1429  if (x==NULL)
1430  {
1431    *p = NULL;
1432    return s;
1433  }
1434  *p = (number)omAlloc0Bin(rnumber_bin);
1435  a = (lnumber)*p;
1436  if ((naMinimalPoly!=NULL)
1437  && (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing)))
1438    a->z = napRemainder(x, naMinimalPoly);
1439  else if (naI!=NULL)
1440  {
1441    a->z = napRedp(x);
1442    if (a->z != NULL)
1443      a->z = napTailred (a->z);
1444  }
1445  else
1446    a->z = x;
1447  if(a->z==NULL)
1448  {
1449    omFreeBin((ADDRESS)*p, rnumber_bin);
1450    *p=NULL;
1451  }
1452  else
1453  {
1454    a->n = NULL;
1455    a->s = 0;
1456    naTest(*p);
1457  }
1458  return s;
1459}
1460
1461/*2
1462* tries to convert a number to a name
1463*/
1464char * naName(number n)
1465{
1466  lnumber ph = (lnumber)n;
1467  if (ph==NULL)
1468    return NULL;
1469  int i;
1470  char *s=(char *)omAlloc(4* naNumbOfPar);
1471  char *t=(char *)omAlloc(8);
1472  s[0]='\0';
1473  for (i = 0; i <= naNumbOfPar - 1; i++)
1474  {
1475    int e=p_GetExp(ph->z,i+1,nacRing);
1476    if (e > 0)
1477    {
1478      if (e >1)
1479      {
1480        sprintf(t,"%s%d",naParNames[i],e);
1481        strcat(s,t);
1482      }
1483      else
1484      {
1485        strcat(s,naParNames[i]);
1486      }
1487    }
1488  }
1489  omFreeSize((ADDRESS)t,8);
1490  if (s[0]=='\0')
1491  {
1492    omFree((ADDRESS)s);
1493    return NULL;
1494  }
1495  return s;
1496}
1497
1498/*2
1499*  writes a number
1500*/
1501void naWrite(number &phn)
1502{
1503  lnumber ph = (lnumber)phn;
1504  if (ph==NULL)
1505    StringAppendS("0");
1506  else
1507  {
1508    phn->s = 0;
1509    //naNormalize(phn);
1510    BOOLEAN has_denom=(ph->n!=NULL);
1511    napWrite(ph->z,has_denom/*(ph->n!=NULL)*/);
1512    if (has_denom/*(ph->n!=NULL)*/)
1513    {
1514      StringAppendS("/");
1515      napWrite(ph->n,TRUE);
1516    }
1517  }
1518}
1519
1520/*2
1521* za == 1 ?
1522*/
1523BOOLEAN naIsOne(number za)
1524{
1525  lnumber a = (lnumber)za;
1526  napoly x, y;
1527  number t;
1528  if (a==NULL) return FALSE;
1529  omCheckAddrSize(a,sizeof(snumber));
1530#ifdef LDEBUG
1531  if (a->z==NULL)
1532  {
1533    WerrorS("internal zero error(4)");
1534    return FALSE;
1535  }
1536#endif
1537  if (a->n==NULL)
1538  {
1539    if (p_LmIsConstant(a->z,nacRing))
1540    {
1541      return nacIsOne(pGetCoeff(a->z));
1542    }
1543    else                 return FALSE;
1544  }
1545#if 0
1546  x = a->z;
1547  y = a->n;
1548  do
1549  {
1550    if (napComp(x, y))
1551      return FALSE;
1552    else
1553    {
1554      t = nacSub(pGetCoeff(x), pGetCoeff(y));
1555      if (!nacIsZero(t))
1556      {
1557        n_Delete(&t,nacRing);
1558        return FALSE;
1559      }
1560      else
1561        n_Delete(&t,nacRing);
1562    }
1563    pIter(x);
1564    pIter(y);
1565  }
1566  while ((x!=NULL) && (y!=NULL));
1567  if ((x!=NULL) || (y!=NULL)) return FALSE;
1568  p_Delete(&a->z,nacRing);
1569  p_Delete(&a->n,nacRing);
1570  a->z = p_ISet(1,nacRing);
1571  a->n = NULL;
1572  a->s = 2;
1573  return TRUE;
1574#else
1575  return FALSE;
1576#endif
1577}
1578
1579/*2
1580* za == -1 ?
1581*/
1582BOOLEAN naIsMOne(number za)
1583{
1584  lnumber a = (lnumber)za;
1585  napoly x, y;
1586  number t;
1587  if (a==NULL) return FALSE;
1588  omCheckAddrSize(a,sizeof(snumber));
1589#ifdef LDEBUG
1590  if (a->z==NULL)
1591  {
1592    WerrorS("internal zero error(5)");
1593    return FALSE;
1594  }
1595#endif
1596  if (a->n==NULL)
1597  {
1598    if (p_LmIsConstant(a->z,nacRing)) return nacIsMOne(pGetCoeff(a->z));
1599    /*else                   return FALSE;*/
1600  }
1601  return FALSE;
1602}
1603
1604/*2
1605* returns the i-th power of p (i>=0)
1606*/
1607void naPower(number p, int i, number *rc)
1608{
1609  number x;
1610  *rc = naInit(1,currRing);
1611  for (; i > 0; i--)
1612  {
1613    x = naMult(*rc, p);
1614    naDelete(rc,currRing);
1615    *rc = x;
1616  }
1617}
1618
1619/*2
1620* result =gcd(a,b)
1621*/
1622number naGcd(number a, number b, const ring r)
1623{
1624  if (a==NULL)  return naCopy(b);
1625  if (b==NULL)  return naCopy(a);
1626
1627  lnumber x, y;
1628  lnumber result = (lnumber)omAlloc0Bin(rnumber_bin);
1629
1630  x = (lnumber)a;
1631  y = (lnumber)b;
1632  if ((naNumbOfPar == 1) && (naMinimalPoly!=NULL))
1633  {
1634    if (pNext(x->z)!=NULL)
1635      result->z = p_Copy(x->z, r->algring);
1636    else
1637      result->z = napGcd0(x->z, y->z);
1638  }
1639  else
1640#ifndef HAVE_FACTORY
1641    result->z = napGcd(x->z, y->z); // change from napGcd0
1642#else
1643  {
1644    int c=ABS(nGetChar());
1645    if (c==1) c=0;
1646    setCharacteristic( c );
1647
1648    napoly rz=napGcd(x->z, y->z);
1649    CanonicalForm F, G, R;
1650    R=convSingPFactoryP(rz,r->algring);
1651    p_Normalize(x->z,nacRing);
1652    F=convSingPFactoryP(x->z,r->algring)/R;
1653    p_Normalize(y->z,nacRing);
1654    G=convSingPFactoryP(y->z,r->algring)/R;
1655    F = gcd( F, G );
1656    if (F.isOne())
1657      result->z= rz;
1658    else
1659    {
1660      p_Delete(&rz,r->algring);
1661      result->z=convFactoryPSingP( F*R,r->algring );
1662      p_Normalize(result->z,nacRing);
1663    }
1664  }
1665#endif
1666  naTest((number)result);
1667  return (number)result;
1668}
1669
1670
1671/*2
1672* naNumbOfPar = 1:
1673* clears denominator         algebraic case;
1674* tries to simplify ratio    transcendental case;
1675*
1676* cancels monomials
1677* occuring in denominator
1678* and enumerator  ?          naNumbOfPar != 1;
1679*
1680* #defines for Factory:
1681* FACTORY_GCD_TEST: do not apply built in gcd for
1682*   univariate polynomials, always use Factory
1683*/
1684//#define FACTORY_GCD_TEST
1685void naCoefNormalize(number pp)
1686{
1687  if (pp==NULL) return;
1688  lnumber p = (lnumber)pp;
1689  number nz; // all denom. of the numerator
1690  nz=p_GetAllDenom(p->z,nacRing);
1691  number nn;
1692  nn=p_GetAllDenom(p->n,nacRing);
1693  BOOLEAN norm=FALSE;
1694  if (!n_IsOne(nz,nacRing))
1695  {
1696    norm=TRUE;
1697    p->z=p_Mult_nn(p->z,nz,nacRing);
1698    if (p->n==NULL)
1699    {
1700      p->n=p_NSet(nz,nacRing);
1701    }
1702    else
1703    {
1704      p->n=p_Mult_nn(p->n,nz,nacRing);
1705      n_Delete(&nz, nacRing);
1706    }
1707  }
1708  else
1709  {
1710    n_Delete(&nz, nacRing);
1711  }
1712  if (!n_IsOne(nn,nacRing))
1713  {
1714    norm=TRUE;
1715    p->n=p_Mult_nn(p->n,nn,nacRing);
1716    p->z=p_Mult_nn(p->z,nn,nacRing);
1717    n_Delete(&nn, nacRing);
1718  }
1719  else
1720  {
1721    n_Delete(&nn, nacRing);
1722  }
1723  if (norm)
1724  {
1725    p_Normalize(p->z,nacRing);
1726    p_Normalize(p->n,nacRing);
1727  }
1728  if ((p->n!=NULL)
1729  && (p_IsConstant(p->n,nacRing))
1730  && (n_IsOne(pGetCoeff(p->n),nacRing)))
1731  {
1732    p_Delete(&(p->n), nacRing);
1733    p->n = NULL;
1734  }
1735}
1736void naNormalize(number &pp)
1737{
1738
1739  //naTest(pp); // input may not be "normal"
1740  lnumber p = (lnumber)pp;
1741
1742  if ((p==NULL) /*|| (p->s==2)*/)
1743    return;
1744  naCoefNormalize(pp);
1745  p->s = 2;
1746  napoly x = p->z;
1747  napoly y = p->n;
1748
1749  BOOLEAN norm=FALSE;
1750
1751  if ((y!=NULL) && (naMinimalPoly!=NULL))
1752  {
1753    y = napInvers(y, naMinimalPoly);
1754    x = p_Mult_q(x, y,nacRing);
1755    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1756      x = napRemainder(x, naMinimalPoly);
1757    p->z = x;
1758    p->n = y = NULL;
1759    norm=naIsChar0;
1760  }
1761
1762  /* check for degree of x too high: */
1763  if ((x!=NULL) && (naMinimalPoly!=NULL) && (x!=naMinimalPoly)
1764  && (p_GetExp(x,1,nacRing)>p_GetExp(naMinimalPoly,1,nacRing)))
1765  // DO NOT REDUCE naMinimalPoly with itself
1766  {
1767    x = napRemainder(x, naMinimalPoly);
1768    p->z = x;
1769    norm=naIsChar0;
1770  }
1771  /* normalize all coefficients in n and z (if in Q) */
1772  if (norm) 
1773  {
1774    naCoefNormalize(pp);
1775    x = p->z;
1776    y = p->n;
1777  }
1778  if (y==NULL) return;
1779
1780  if ((naMinimalPoly == NULL) && (x!=NULL) && (y!=NULL))
1781  {
1782    int i;
1783    for (i=naNumbOfPar-1; i>=0; i--)
1784    {
1785      napoly xx=x;
1786      napoly yy=y;
1787      int m = napExpi(i, yy, xx);
1788      if (m != 0)          // in this case xx!=NULL!=yy
1789      {
1790        while (xx != NULL)
1791        {
1792          napAddExp(xx,i+1, -m);
1793          pIter(xx);
1794        }
1795        while (yy != NULL)
1796        {
1797          napAddExp(yy,i+1, -m);
1798          pIter(yy);
1799        }
1800      }
1801    }
1802  }
1803  if (p_LmIsConstant(y,nacRing)) /* i.e. => simplify to (1/c)*z / monom */
1804  {
1805    if (nacIsOne(pGetCoeff(y)))
1806    {
1807      p_LmDelete(&y,nacRing);
1808      p->n = NULL;
1809      naTest(pp);
1810      return;
1811    }
1812    number h1 = nacInvers(pGetCoeff(y));
1813    nacNormalize(h1);
1814    napMultN(x, h1);
1815    n_Delete(&h1,nacRing);
1816    p_LmDelete(&y,nacRing);
1817    p->n = NULL;
1818    naTest(pp);
1819    return;
1820  }
1821#ifndef FACTORY_GCD_TEST
1822  if (naNumbOfPar == 1) /* apply built-in gcd */
1823  {
1824    napoly x1,y1;
1825    if (p_GetExp(x,1,nacRing) >= p_GetExp(y,1,nacRing))
1826    {
1827      x1 = napCopy(x);
1828      y1 = napCopy(y);
1829    }
1830    else
1831    {
1832      x1 = napCopy(y);
1833      y1 = napCopy(x);
1834    }
1835    napoly r;
1836    loop
1837    {
1838      r = napRemainder(x1, y1);
1839      if ((r==NULL) || (pNext(r)==NULL)) break;
1840      x1 = y1;
1841      y1 = r;
1842    }
1843    if (r!=NULL)
1844    {
1845      p_Delete(&r,nacRing);
1846      p_Delete(&y1,nacRing);
1847    }
1848    else
1849    {
1850      napDivMod(x, y1, &(p->z), &r);
1851      napDivMod(y, y1, &(p->n), &r);
1852      p_Delete(&y1,nacRing);
1853    }
1854    x = p->z;
1855    y = p->n;
1856    /* collect all denoms from y and multiply x and y by it */
1857    if (naIsChar0)
1858    {
1859      number n=napLcm(y);
1860      napMultN(x,n);
1861      napMultN(y,n);
1862      n_Delete(&n,nacRing);
1863      while(x!=NULL)
1864      {
1865        nacNormalize(pGetCoeff(x));
1866        pIter(x);
1867      }
1868      x = p->z;
1869      while(y!=NULL)
1870      {
1871        nacNormalize(pGetCoeff(y));
1872        pIter(y);
1873      }
1874      y = p->n;
1875    }
1876    if (pNext(y)==NULL)
1877    {
1878      if (nacIsOne(pGetCoeff(y)))
1879      {
1880        if (p_GetExp(y,1,nacRing)==0)
1881        {
1882          p_LmDelete(&y,nacRing);
1883          p->n = NULL;
1884        }
1885        naTest(pp);
1886        return;
1887      }
1888    }
1889  }
1890#endif /* FACTORY_GCD_TEST */
1891#ifdef HAVE_FACTORY
1892#ifndef FACTORY_GCD_TEST
1893  else
1894#endif
1895  {
1896    napoly xx,yy;
1897    singclap_algdividecontent(x,y,xx,yy);
1898    if (xx!=NULL)
1899    {
1900      p->z=xx;
1901      p->n=yy;
1902      p_Delete(&x,nacRing);
1903      p_Delete(&y,nacRing);
1904    }
1905  }
1906#endif
1907  /* remove common factors from z and n */
1908  x=p->z;
1909  y=p->n;
1910  if(!nacGreaterZero(pGetCoeff(y)))
1911  {
1912    x=napNeg(x);
1913    y=napNeg(y);
1914  }
1915  number g=nacCopy(pGetCoeff(x));
1916  pIter(x);
1917  while (x!=NULL)
1918  {
1919    number d=nacGcd(g,pGetCoeff(x), nacRing);
1920    if(nacIsOne(d))
1921    {
1922      n_Delete(&g,nacRing);
1923      n_Delete(&d,nacRing);
1924      naTest(pp);
1925      return;
1926    }
1927    n_Delete(&g,nacRing);
1928    g = d;
1929    pIter(x);
1930  }
1931  while (y!=NULL)
1932  {
1933    number d=nacGcd(g,pGetCoeff(y), nacRing);
1934    if(nacIsOne(d))
1935    {
1936      n_Delete(&g,nacRing);
1937      n_Delete(&d,nacRing);
1938      naTest(pp);
1939      return;
1940    }
1941    n_Delete(&g,nacRing);
1942    g = d;
1943    pIter(y);
1944  }
1945  x=p->z;
1946  y=p->n;
1947  while (x!=NULL)
1948  {
1949    number d = nacIntDiv(pGetCoeff(x),g);
1950    napSetCoeff(x,d);
1951    pIter(x);
1952  }
1953  while (y!=NULL)
1954  {
1955    number d = nacIntDiv(pGetCoeff(y),g);
1956    napSetCoeff(y,d);
1957    pIter(y);
1958  }
1959  n_Delete(&g,nacRing);
1960  naTest(pp);
1961}
1962
1963/*2
1964* returns in result->n 1
1965* and in     result->z the lcm(a->z,b->n)
1966*/
1967number naLcm(number la, number lb, const ring r)
1968{
1969  lnumber result;
1970  lnumber a = (lnumber)la;
1971  lnumber b = (lnumber)lb;
1972  result = (lnumber)omAlloc0Bin(rnumber_bin);
1973  //if (((naMinimalPoly==NULL) && (naI==NULL)) || !naIsChar0)
1974  //{
1975  //  result->z = p_ISet(1,nacRing);
1976  //  return (number)result;
1977  //}
1978  //naNormalize(lb);
1979  naTest(la);
1980  naTest(lb);
1981  napoly x = p_Copy(a->z, r->algring);
1982  number t = napLcm(b->z); // get all denom of b->z
1983  if (!nacIsOne(t))
1984  {
1985    number bt, rr;
1986    napoly xx=x;
1987    while (xx!=NULL)
1988    {
1989      bt = nacGcd(t, pGetCoeff(xx), r->algring);
1990      rr = nacMult(t, pGetCoeff(xx));
1991      n_Delete(&pGetCoeff(xx),r->algring);
1992      pGetCoeff(xx) = nacDiv(rr, bt);
1993      nacNormalize(pGetCoeff(xx));
1994      n_Delete(&bt,r->algring);
1995      n_Delete(&rr,r->algring);
1996      pIter(xx);
1997    }
1998  }
1999  n_Delete(&t,r->algring);
2000  result->z = x;
2001#ifdef HAVE_FACTORY
2002  if (b->n!=NULL)
2003  {
2004    result->z=singclap_alglcm(result->z,b->n);
2005    p_Delete(&x,r->algring);
2006  }
2007#endif
2008  naTest(la);
2009  naTest(lb);
2010  naTest((number)result);
2011  return ((number)result);
2012}
2013
2014/*2
2015* input: a set of constant polynomials
2016* sets the global variable naI
2017*/
2018void naSetIdeal(ideal I)
2019{
2020  int i;
2021
2022  if (idIs0(I))
2023  {
2024    for (i=naI->anz-1; i>=0; i--)
2025      p_Delete(&naI->liste[i],nacRing);
2026    omFreeBin((ADDRESS)naI, snaIdeal_bin);
2027    naI=NULL;
2028  }
2029  else
2030  {
2031    lnumber h;
2032    number a;
2033    napoly x;
2034
2035    naI=(naIdeal)omAllocBin(snaIdeal_bin);
2036    naI->anz=IDELEMS(I);
2037    naI->liste=(napoly*)omAlloc(naI->anz*sizeof(napoly));
2038    for (i=IDELEMS(I)-1; i>=0; i--)
2039    {
2040      h=(lnumber)pGetCoeff(I->m[i]);
2041      /* We only need the enumerator of h, as we expect it to be a polynomial */
2042      naI->liste[i]=napCopy(h->z);
2043      /* If it isn't normalized (lc = 1) do this */
2044      if (!nacIsOne(pGetCoeff(naI->liste[i])))
2045      {
2046        x=naI->liste[i];
2047        nacNormalize(pGetCoeff(x));
2048        a=nacCopy(pGetCoeff(x));
2049        number aa=nacInvers(a);
2050        n_Delete(&a,nacRing);
2051        napMultN(x,aa);
2052        n_Delete(&aa,nacRing);
2053      }
2054    }
2055  }
2056}
2057
2058/*2
2059* map Z/p -> Q(a)
2060*/
2061number naMapP0(number c)
2062{
2063  if (npIsZero(c)) return NULL;
2064  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2065  l->s=2;
2066  l->z=(napoly)p_Init(nacRing);
2067  int i=(int)((long)c);
2068  if (i>((long)naMapRing->ch>>2)) i-=(long)naMapRing->ch;
2069  pGetCoeff(l->z)=nlInit(i, nacRing);
2070  l->n=NULL;
2071  return (number)l;
2072}
2073
2074/*2
2075* map Q -> Q(a)
2076*/
2077number naMap00(number c)
2078{
2079  if (nlIsZero(c)) return NULL;
2080  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2081  l->s=0;
2082  l->z=(napoly)p_Init(nacRing);
2083  pGetCoeff(l->z)=nlCopy(c);
2084  l->n=NULL;
2085  return (number)l;
2086}
2087
2088/*2
2089* map Z/p -> Z/p(a)
2090*/
2091number naMapPP(number c)
2092{
2093  if (npIsZero(c)) return NULL;
2094  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2095  l->s=2;
2096  l->z=(napoly)p_Init(nacRing);
2097  pGetCoeff(l->z)=c; /* omit npCopy, because npCopy is a no-op */
2098  l->n=NULL;
2099  return (number)l;
2100}
2101
2102/*2
2103* map Z/p' -> Z/p(a)
2104*/
2105number naMapPP1(number c)
2106{
2107  if (npIsZero(c)) return NULL;
2108  int i=(int)((long)c);
2109  if (i>(long)naMapRing->ch) i-=(long)naMapRing->ch;
2110  number n=npInit(i,naMapRing);
2111  if (npIsZero(n)) return NULL;
2112  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2113  l->s=2;
2114  l->z=(napoly)p_Init(nacRing);
2115  pGetCoeff(l->z)=n;
2116  l->n=NULL;
2117  return (number)l;
2118}
2119
2120/*2
2121* map Q -> Z/p(a)
2122*/
2123number naMap0P(number c)
2124{
2125  if (nlIsZero(c)) return NULL;
2126  number n=npInit(nlModP(c,npPrimeM),nacRing);
2127  if (npIsZero(n)) return NULL;
2128  npTest(n);
2129  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2130  l->s=2;
2131  l->z=(napoly)p_Init(nacRing);
2132  pGetCoeff(l->z)=n;
2133  l->n=NULL;
2134  return (number)l;
2135}
2136
2137static number (*nacMap)(number);
2138static int naParsToCopy;
2139static napoly napMap(napoly p)
2140{
2141  napoly w, a;
2142
2143  if (p==NULL) return NULL;
2144  a = w = (napoly)p_Init(nacRing);
2145  int i;
2146  for(i=1;i<=naParsToCopy;i++)
2147    napSetExp(a,i,napGetExpFrom(p,i,naMapRing));
2148  p_Setm(a,nacRing);
2149  pGetCoeff(w) = nacMap(pGetCoeff(p));
2150  loop
2151  {
2152    pIter(p);
2153    if (p==NULL) break;
2154    pNext(a) = (napoly)p_Init(nacRing);
2155    pIter(a);
2156    for(i=1;i<=naParsToCopy;i++)
2157      napSetExp(a,i,napGetExpFrom(p,i,naMapRing));
2158    p_Setm(a,nacRing);
2159    pGetCoeff(a) = nacMap(pGetCoeff(p));
2160  }
2161  pNext(a) = NULL;
2162  return w;
2163}
2164
2165static napoly napPerm(napoly p,const int *par_perm,const ring src_ring,const nMapFunc nMap)
2166{
2167  napoly w, a;
2168
2169  if (p==NULL) return NULL;
2170  w = (napoly)p_Init(nacRing);
2171  int i;
2172  BOOLEAN not_null=TRUE;
2173  loop
2174  {
2175    for(i=1;i<=rPar(src_ring);i++)
2176    {
2177      int e;
2178      if (par_perm!=NULL) e=par_perm[i-1];
2179      else                e=-i;
2180      int ee=napGetExpFrom(p,i,src_ring);
2181      if (e<0)
2182        napSetExp(w,-e,ee);
2183      else if (ee>0)
2184        not_null=FALSE;
2185    }
2186    pGetCoeff(w) = nMap(pGetCoeff(p));
2187    p_Setm(w,nacRing);
2188    pIter(p);
2189    if (!not_null)
2190    {
2191      if (p==NULL)
2192      {
2193        p_Delete(&w,nacRing);
2194        return NULL;
2195      }
2196      /* else continue*/
2197      n_Delete(&(pGetCoeff(w)),nacRing);
2198    }
2199    else
2200    {
2201      if (p==NULL) return w;
2202      else
2203      {
2204        pNext(w)=napPerm(p,par_perm,src_ring,nMap);
2205        return w;
2206      }
2207    }
2208  }
2209}
2210
2211/*2
2212* map _(a) -> _(b)
2213*/
2214number naMapQaQb(number c)
2215{
2216  if (c==NULL) return NULL;
2217  lnumber erg= (lnumber)omAlloc0Bin(rnumber_bin);
2218  lnumber src =(lnumber)c;
2219  erg->s=src->s;
2220  erg->z=napMap(src->z);
2221  erg->n=napMap(src->n);
2222  if (naMinimalPoly!=NULL)
2223  {
2224    if (p_GetExp(erg->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
2225    {
2226      erg->z = napRemainder(erg->z, naMinimalPoly);
2227      if (erg->z==NULL)
2228      {
2229        number t_erg=(number)erg;
2230        naDelete(&t_erg,currRing);
2231        return (number)NULL;
2232      }
2233    }
2234    if (erg->n!=NULL)
2235    {
2236      if (p_GetExp(erg->n,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
2237        erg->n = napRemainder(erg->n, naMinimalPoly);
2238      if ((p_LmIsConstant(erg->n,nacRing)) && nacIsOne(pGetCoeff(erg->n)))
2239        p_Delete(&(erg->n),nacRing);
2240    }
2241  }
2242  return (number)erg;
2243}
2244
2245nMapFunc naSetMap(ring src, ring dst)
2246{
2247  naMapRing=src;
2248  if (rField_is_Q_a(dst)) /* -> Q(a) */
2249  {
2250    if (rField_is_Q(src))
2251    {
2252      return naMap00;   /*Q -> Q(a)*/
2253    }
2254    if (rField_is_Zp(src))
2255    {
2256      return naMapP0;  /* Z/p -> Q(a)*/
2257    }
2258    if (rField_is_Q_a(src))
2259    {
2260      int i;
2261      naParsToCopy=0;
2262      for(i=0;i<rPar(src);i++)
2263      {
2264        if ((i>=rPar(dst))
2265        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
2266           return NULL;
2267        naParsToCopy++;
2268      }
2269      nacMap=nacCopy;
2270      if ((naParsToCopy==rPar(dst))&&(naParsToCopy==rPar(src)))
2271        return naCopy;    /* Q(a) -> Q(a) */
2272      return naMapQaQb;   /* Q(a..) -> Q(a..) */
2273    }
2274  }
2275  /*-----------------------------------------------------*/
2276  if (rField_is_Zp_a(dst)) /* -> Z/p(a) */
2277  {
2278    if (rField_is_Q(src))
2279    {
2280      return naMap0P;   /*Q -> Z/p(a)*/
2281    }
2282    if (rField_is_Zp(src))
2283    {
2284      if (src->ch==dst->ch)
2285      {
2286        return naMapPP;  /* Z/p -> Z/p(a)*/
2287      }
2288      else
2289      {
2290        return naMapPP1;  /* Z/p' -> Z/p(a)*/
2291      }
2292    }
2293    if (rField_is_Zp_a(src))
2294    {
2295      if (rChar(src)==rChar(dst))
2296      {
2297        nacMap=nacCopy;
2298      }
2299      else
2300      {
2301        nacMap = npMapP;
2302      }
2303      int i;
2304      naParsToCopy=0;
2305      for(i=0;i<rPar(src);i++)
2306      {
2307        if ((i>=rPar(dst))
2308        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
2309           return NULL;
2310        naParsToCopy++;
2311      }
2312      if ((naParsToCopy==rPar(dst))&&(naParsToCopy==rPar(src))
2313      && (nacMap==nacCopy))
2314        return naCopy;    /* Z/p(a) -> Z/p(a) */
2315      return naMapQaQb;   /* Z/p(a),Z/p'(a) -> Z/p(b)*/
2316    }
2317  }
2318  return NULL;      /* default */
2319}
2320
2321/*2
2322* convert a napoly number into a poly
2323*/
2324poly naPermNumber(number z, int * par_perm, int P, ring oldRing)
2325{
2326  if (z==NULL) return NULL;
2327  poly res=NULL;
2328  poly p;
2329  napoly za=((lnumber)z)->z;
2330  napoly zb=((lnumber)z)->n;
2331  nMapFunc nMap=naSetMap(oldRing,currRing);
2332  if (currRing->parameter!=NULL)
2333    nMap=currRing->algring->cf->cfSetMap(oldRing->algring, nacRing);
2334  else
2335    nMap=currRing->cf->cfSetMap(oldRing->algring, currRing);
2336  if (nMap==NULL) return NULL; /* emergency exit only */
2337  do
2338  {
2339    p = pInit();
2340    pNext(p)=NULL;
2341    nNew(&pGetCoeff(p));
2342    int i;
2343    for(i=pVariables;i;i--)
2344       pSetExp(p,i, 0);
2345    pSetComp(p, 0);
2346    napoly pa=NULL;
2347    lnumber pan;
2348    if (currRing->parameter!=NULL)
2349    {
2350      assume(oldRing->algring!=NULL);
2351      pGetCoeff(p)=(number)omAlloc0Bin(rnumber_bin);
2352      pan=(lnumber)pGetCoeff(p);
2353      pan->s=2;
2354      pan->z=napInitz(nMap(pGetCoeff(za)));
2355      pa=pan->z;
2356    }
2357    else
2358    {
2359      pGetCoeff(p)=nMap(pGetCoeff(za));
2360    }
2361    for(i=0;i<P;i++)
2362    {
2363      if(napGetExpFrom(za,i+1,oldRing)!=0)
2364      {
2365        if(par_perm==NULL)
2366        {
2367          if ((rPar(currRing)>=i) && (pa!=NULL))
2368          {
2369            napSetExp(pa,i+1,napGetExpFrom(za,i+1,oldRing));
2370            p_Setm(pa,nacRing);
2371          }
2372          else
2373          {
2374            pDelete(&p);
2375            break;
2376          }
2377        }
2378        else if(par_perm[i]>0)
2379          pSetExp(p,par_perm[i],napGetExpFrom(za,i+1,oldRing));
2380        else if((par_perm[i]<0)&&(pa!=NULL))
2381        {
2382          napSetExp(pa,-par_perm[i], napGetExpFrom(za,i+1,oldRing));
2383          p_Setm(pa,nacRing);
2384        }
2385        else
2386        {
2387          pDelete(&p);
2388          break;
2389        }
2390      }
2391    }
2392    if (p!=NULL)
2393    {
2394      pSetm(p);
2395      if (zb!=NULL)
2396      {
2397        if  (currRing->P>0)
2398        {
2399          pan->n=napPerm(zb,par_perm,oldRing,nMap);
2400          if(pan->n==NULL) /* error in mapping or mapping to variable */
2401            pDelete(&p);
2402        }
2403        else
2404          pDelete(&p);
2405      }
2406      pTest(p);
2407      res=pAdd(res,p);
2408    }
2409    pIter(za);
2410  }
2411  while (za!=NULL);
2412  pTest(res);
2413  return res;
2414}
2415
2416number   naGetDenom(number &n, const ring r)
2417{
2418  lnumber x=(lnumber)n;
2419  if (x->n!=NULL)
2420  {
2421    lnumber rr=(lnumber)omAlloc0Bin(rnumber_bin);
2422    rr->z=p_Copy(x->n,r->algring);
2423    rr->s = 2;
2424    return (number)rr;
2425  }
2426  return n_Init(1,r);
2427}
2428
2429number   naGetNumerator(number &n, const ring r)
2430{
2431  lnumber x=(lnumber)n;
2432  lnumber rr=(lnumber)omAlloc0Bin(rnumber_bin);
2433  rr->z=p_Copy(x->z,r->algring);
2434  rr->s = 2;
2435  return (number)rr;
2436}
2437
2438#ifdef LDEBUG
2439BOOLEAN naDBTest(number a, const char *f,const int l)
2440{
2441  lnumber x=(lnumber)a;
2442  if (x == NULL)
2443    return TRUE;
2444  omCheckAddrSize(a, sizeof(snumber));
2445  napoly p = x->z;
2446  if (p==NULL)
2447  {
2448    Print("0/* in %s:%d\n",f,l);
2449    return FALSE;
2450  }
2451  while(p!=NULL)
2452  {
2453    if ((naIsChar0 && nlIsZero(pGetCoeff(p)))
2454    || ((!naIsChar0) && npIsZero(pGetCoeff(p))))
2455    {
2456      Print("coeff 0 in %s:%d\n",f,l);
2457      return FALSE;
2458    }
2459    if((naMinimalPoly!=NULL)
2460    &&(p_GetExp(p,1,nacRing)>p_GetExp(naMinimalPoly,1,nacRing))
2461    &&(p!=naMinimalPoly))
2462    {
2463      Print("deg>minpoly in %s:%d\n",f,l);
2464      return FALSE;
2465    }
2466    //if (naIsChar0 && (((int)p->ko &3) == 0) && (p->ko->s==0) && (x->s==2))
2467    //{
2468    //  Print("normalized with non-normal coeffs in %s:%d\n",f,l);
2469    //  return FALSE;
2470    //}
2471    if (naIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
2472      return FALSE;
2473    pIter(p);
2474  }
2475  p = x->n;
2476  while(p!=NULL)
2477  {
2478    if (naIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
2479      return FALSE;
2480    pIter(p);
2481  }
2482  return TRUE;
2483}
2484#endif
Note: See TracBrowser for help on using the repository browser.